expose new Word operation to swap endianness for Word{16,32,64}
authorIan Lynagh <ian@well-typed.com>
Sun, 9 Jun 2013 11:01:22 +0000 (12:01 +0100)
committerIan Lynagh <ian@well-typed.com>
Sun, 9 Jun 2013 11:01:22 +0000 (12:01 +0100)
Patch from Vincent Hanquez.

Data/Word.hs
GHC/Word.hs

index 39aa1a8..c844c4d 100644 (file)
@@ -22,6 +22,9 @@ module Data.Word
         Word,
         Word8, Word16, Word32, Word64,
 
+        -- * byte swapping
+        byteSwap16, byteSwap32, byteSwap64,
+
         -- * Notes
 
         -- $notes
@@ -33,6 +36,21 @@ import GHC.Word
 
 #ifdef __HUGS__
 import Hugs.Word
+
+byteSwap16 :: Word16 -> Word16
+byteSwap16 w = (w `shift` -8) .|. (w `shift` 8)
+
+byteSwap32 :: Word32 -> Word32
+byteSwap32 w =
+         (w `shift` -24)             .|. (w `shift` 24)
+    .|. ((w `shift` -8) .&. 0xff00) .|. ((w .&. 0xff00) `shift` 8)
+
+byteSwap64 :: Word64 -> Word64
+byteSwap64 w =
+        (w `shift` -56)                  .|. (w `shift` 56)
+    .|. ((w `shift` -40) .&. 0xff00)     .|. ((w .&. 0xff00) `shift` 40)
+    .|. ((w `shift` -24) .&. 0xff0000)   .|. ((w .&. 0xff0000) `shift` 24)
+    .|. ((w `shift` -8)  .&. 0xff000000) .|. ((w .&. 0xff000000) `shift` 8)
 #endif
 
 {- $notes
index 75957df..3419a24 100644 (file)
 module GHC.Word (
     Word(..), Word8(..), Word16(..), Word32(..), Word64(..),
     uncheckedShiftL64#,
-    uncheckedShiftRL64#
+    uncheckedShiftRL64#,
+    byteSwap16,
+    byteSwap32,
+    byteSwap64
     ) where
 
 import Data.Bits
@@ -300,6 +303,9 @@ instance Bits Word16 where
 instance FiniteBits Word16 where
     finiteBitSize _ = 16
 
+byteSwap16 :: Word16 -> Word16
+byteSwap16 (W16# w#) = W16# (byteSwap16# w#)
+
 {-# RULES
 "fromIntegral/Word8->Word16"   fromIntegral = \(W8# x#) -> W16# x#
 "fromIntegral/Word16->Word16"  fromIntegral = id :: Word16 -> Word16
@@ -524,6 +530,9 @@ instance Read Word32 where
     readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
 #endif
 
+byteSwap32 :: Word32 -> Word32
+byteSwap32 (W32# w#) = W32# (byteSwap32# w#)
+
 ------------------------------------------------------------------------
 -- type Word64
 ------------------------------------------------------------------------
@@ -772,3 +781,10 @@ instance Ix Word64 where
 instance Read Word64 where
     readsPrec p s = [(fromInteger x, r) | (x, r) <- readsPrec p s]
 
+#if WORD_SIZE_IN_BITS < 64
+byteSwap64 :: Word64 -> Word64
+byteSwap64 (W64# w#) = W64# (byteSwap64# w#)
+#else
+byteSwap64 :: Word64 -> Word64
+byteSwap64 (W64# w#) = W64# (byteSwap# w#)
+#endif