-
Notifications
You must be signed in to change notification settings - Fork 2
/
WordString.hs
66 lines (50 loc) · 2.21 KB
/
WordString.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
{-|
Module : WordString
Description : Word8 string helper functions
Copyright : (c) Nico Naus, 2022
Maintainer : niconaus@vt.edu
Stability : experimental
This module defines several helper functions to perform operations on word8 strings
-}
module WordString where
import Data.Binary ( Word8, Word16, Word32, Word64 )
import Data.ByteString.Builder
( toLazyByteString, word16BE, word32BE, word64BE )
import qualified Data.ByteString.Lazy as BS
import Data.Binary.Get
( getWord16be, getWord32be, getWord64be, runGet )
import Data.Bits ( Bits(testBit) )
-- Unsigned addition
uAdd :: [Word8] -> [Word8] -> [Word8]
uAdd w1 w2 | length w1 == 1 = encodeWord8 $ decodeWord8 w1 + decodeWord8 w2
| length w1 == 2 = encodeWord16 $ decodeWord16 w1 + decodeWord16 w2
| length w1 == 4 = encodeWord32 $ decodeWord32 w1 + decodeWord32 w2
| length w1 == 8 = encodeWord64 $ decodeWord64 w1 + decodeWord64 w2
uAdd _ _ = error "addition not defined for this length"
--Sign extension
signExtend :: Word8 -> [Word8] -> [Word8]
signExtend i wx | length wx > fromEnum i = error "sign extend cannot shorten word"
| otherwise = concat $ replicate (fromEnum i-length wx) (if getSign wx then [255] else [0]) ++ [wx]
zeroExtend :: Word8 -> [Word8] -> [Word8]
zeroExtend i wx | length wx > fromEnum i = error "unsigned extend cannot shorten word"
| otherwise = replicate (fromEnum i-length wx) 0 ++ wx
getSign :: [Word8] -> Bool
getSign xs = testBit (last xs) 7
-- From and to Word
encodeWord8 :: Word8 -> [Word8]
encodeWord8 x = [x]
decodeWord8 :: [Word8] -> Word8
decodeWord8 [x] = x
decodeWord8 xs = error $ "Bytestring too long or short to be a word8: " ++ show xs
encodeWord16 :: Word16 -> [Word8]
encodeWord16 = BS.unpack . toLazyByteString . word16BE
decodeWord16 :: [Word8] -> Word16
decodeWord16 xs = runGet getWord16be (BS.pack xs)
encodeWord32 :: Word32 -> [Word8]
encodeWord32 = BS.unpack . toLazyByteString . word32BE
decodeWord32 :: [Word8] -> Word32
decodeWord32 xs = runGet getWord32be (BS.pack xs)
encodeWord64 :: Word64 -> [Word8]
encodeWord64 = BS.unpack . toLazyByteString . word64BE
decodeWord64 :: [Word8] -> Word64
decodeWord64 x = runGet getWord64be (BS.pack x)