{-# LANGUAGE MagicHash #-} {-# LANGUAGE UnboxedTuples #-} {-# LANGUAGE BangPatterns #-} module Basement.Base16 ( unsafeConvertByte , hexWord16 , hexWord32 , escapeByte , Base16Escape(..) ) where import GHC.Prim import GHC.Types import GHC.Word import Basement.Types.Char7 data Base16Escape = Base16Escape {-# UNPACK #-} !Char7 {-# UNPACK #-} !Char7 -- | Convert a byte value in Word# to two Word#s containing -- the hexadecimal representation of the Word# -- -- The output words# are guaranteed to be included in the 0 to 2^7-1 range -- -- Note that calling convertByte with a value greater than 256 -- will cause segfault or other horrible effect. unsafeConvertByte :: Word# -> (# Word#, Word# #) unsafeConvertByte b = (# r tableHi b, r tableLo b #) where r :: Table -> Word# -> Word# r (Table !table) index = indexWord8OffAddr# table (word2Int# index) {-# INLINE unsafeConvertByte #-} escapeByte :: Word8 -> Base16Escape escapeByte !(W8# b) = Base16Escape (r tableHi b) (r tableLo b) where r :: Table -> Word# -> Char7 r (Table !table) index = Char7 (W8# (indexWord8OffAddr# table (word2Int# index))) {-# INLINE escapeByte #-} -- | hex word16 hexWord16 :: Word16 -> (Char, Char, Char, Char) hexWord16 (W16# w) = (toChar w1,toChar w2,toChar w3,toChar w4) where toChar :: Word# -> Char toChar c = C# (chr# (word2Int# c)) !(# w1, w2 #) = unsafeConvertByte (uncheckedShiftRL# w 8#) !(# w3, w4 #) = unsafeConvertByte (and# w 0xff##) -- | hex word32 hexWord32 :: Word32 -> (Char, Char, Char, Char, Char, Char, Char, Char) hexWord32 (W32# w) = (toChar w1,toChar w2,toChar w3,toChar w4 ,toChar w5,toChar w6,toChar w7,toChar w8) where toChar :: Word# -> Char toChar c = C# (chr# (word2Int# c)) !(# w1, w2 #) = unsafeConvertByte (uncheckedShiftRL# w 24#) !(# w3, w4 #) = unsafeConvertByte (and# (uncheckedShiftRL# w 16#) 0xff##) !(# w5, w6 #) = unsafeConvertByte (and# (uncheckedShiftRL# w 8#) 0xff##) !(# w7, w8 #) = unsafeConvertByte (and# w 0xff##) data Table = Table Addr# tableLo:: Table tableLo = Table "0123456789abcdef0123456789abcdef\ \0123456789abcdef0123456789abcdef\ \0123456789abcdef0123456789abcdef\ \0123456789abcdef0123456789abcdef\ \0123456789abcdef0123456789abcdef\ \0123456789abcdef0123456789abcdef\ \0123456789abcdef0123456789abcdef\ \0123456789abcdef0123456789abcdef"# tableHi :: Table tableHi = Table "00000000000000001111111111111111\ \22222222222222223333333333333333\ \44444444444444445555555555555555\ \66666666666666667777777777777777\ \88888888888888889999999999999999\ \aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb\ \ccccccccccccccccdddddddddddddddd\ \eeeeeeeeeeeeeeeeffffffffffffffff"#