{-# LANGUAGE CPP #-} {-# LANGUAGE Haskell2010 #-} -- | -- Copyright: © 2019-2020 Herbert Valerio Riedel -- SPDX-License-Identifier: GPL-2.0-or-later -- module Endianness ( Word8, Word16, Word32, Word64 , ByteOrder(LittleEndian,BigEndian), targetByteOrder , byteSwap16 , byteSwap32 , byteSwap64 , pokeWord16be , pokeWord32be , pokeWord64be , peekWord16be , peekWord32be , peekWord64be ) where import Data.Word (Word16, Word32, Word64, Word8) import Foreign.Ptr import Foreign.Storable import GHC.ByteOrder (ByteOrder (..), targetByteOrder) #if MIN_VERSION_base(4,7,0) import Data.Word (byteSwap16, byteSwap32, byteSwap64) #else import Data.Bits -- supply missing byteSwap operations byteSwap16 :: Word16 -> Word16 byteSwap16 = (`rotateL` 8) byteSwap32 :: Word32 -> Word32 byteSwap32 x = (x `shiftR` 24) .|. ((x .&. 0x00ff0000) `shiftR` 8) .|. ((x .&. 0x0000ff00) `shiftL` 8) .|. (x `shiftL` 24) byteSwap64 :: Word64 -> Word64 byteSwap64 x = xh .|. (xl `shiftL` 32) where xl = fromIntegral (byteSwap32 (fromIntegral x)) xh = fromIntegral (byteSwap32 (fromIntegral (x `shiftR` 32))) #endif pokeWord16be :: Ptr Word16 -> Word16 -> IO () pokeWord16be = case targetByteOrder of BigEndian -> poke LittleEndian -> \p w -> poke p (byteSwap16 w) pokeWord32be :: Ptr Word32 -> Word32 -> IO () pokeWord32be = case targetByteOrder of BigEndian -> poke LittleEndian -> \p w -> poke p (byteSwap32 w) pokeWord64be :: Ptr Word64 -> Word64 -> IO () pokeWord64be = case targetByteOrder of BigEndian -> poke LittleEndian -> \p w -> poke p (byteSwap64 w) peekWord16be :: Ptr Word16 -> IO Word16 peekWord16be = case targetByteOrder of BigEndian -> peek LittleEndian -> \p -> fmap byteSwap16 (peek p) peekWord32be :: Ptr Word32 -> IO Word32 peekWord32be = case targetByteOrder of BigEndian -> peek LittleEndian -> \p -> fmap byteSwap32 (peek p) peekWord64be :: Ptr Word64 -> IO Word64 peekWord64be = case targetByteOrder of BigEndian -> peek LittleEndian -> \p -> fmap byteSwap64 (peek p)