-- | -- Module : Foundation.Internal.ByteSwap -- License : BSD-style -- Maintainer : Foundation -- Stability : experimental -- Portability : portable -- {-# LANGUAGE CPP #-} module Foundation.Internal.ByteSwap ( byteSwap16 , byteSwap32 , byteSwap64 , ByteSwap , byteSwap ) where import Foundation.Internal.Base (Word16, Word32, Word64) #if MIN_VERSION_base(4,7,0) import Data.Word (byteSwap16, byteSwap32, byteSwap64) #else import Foundation.Internal.Base (fromInteger) import Data.Bits ((.|.), (.&.), unsafeShiftL, unsafeShiftR) import Data.Word (Word16, Word32, Word64) -- | compatibility implementation (i.e. may be slow) -- -- Swap the bytes position (inverting order) as would be done in GHC >= 7.8 byteSwap16 :: Word16 -> Word16 byteSwap16 w = w1 .|. w2 where w1,w2 :: Word16 w1 = (w `unsafeShiftL` 8) .&. 0xFF00 w2 = (w `unsafeShiftR` 8) .&. 0x00FF -- | compatibility implementation (i.e. may be slow) -- -- Swap the bytes position (inverting order) as would be done in GHC >= 7.8 byteSwap32 :: Word32 -> Word32 byteSwap32 w = w1 .|. w2 .|. w3 .|. w4 where w1,w2,w3,w4 :: Word32 w1 = (w `unsafeShiftL` 24) .&. 0xFF000000 w2 = (w `unsafeShiftR` 24) .&. 0x000000FF w3 = (w `unsafeShiftL` 8) .&. 0x00FF0000 w4 = (w `unsafeShiftR` 8) .&. 0x0000FF00 -- | compatibility implementation (i.e. may be slow) -- -- Swap the bytes position (inverting order) as would be done in GHC >= 7.8 byteSwap64 :: Word64 -> Word64 byteSwap64 w = w1 .|. w2 .|. w3 .|. w4 .|. w5 .|. w6 .|. w7 .|. w8 where w1,w2,w3,w4,w5,w6,w7,w8 :: Word64 w1 = (w `unsafeShiftL` 56) .&. 0xFF00000000000000 w2 = (w `unsafeShiftR` 56) .&. 0x00000000000000FF w3 = (w `unsafeShiftL` 40) .&. 0x00FF000000000000 w4 = (w `unsafeShiftR` 40) .&. 0x000000000000FF00 w5 = (w `unsafeShiftL` 24) .&. 0x0000FF0000000000 w6 = (w `unsafeShiftR` 24) .&. 0x0000000000FF0000 w7 = (w `unsafeShiftL` 8) .&. 0x000000FF00000000 w8 = (w `unsafeShiftR` 8) .&. 0x00000000FF000000 #endif -- | Class of types that can be byte-swapped. -- -- e.g. Word16, Word32, Word64 class ByteSwap a where byteSwap :: a -> a instance ByteSwap Word16 where byteSwap = byteSwap16 instance ByteSwap Word32 where byteSwap = byteSwap32 instance ByteSwap Word64 where byteSwap = byteSwap64