foundation-0.0.4: Foundation/Internal/ByteSwap.hs
-- |
-- 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