Add encodeWithSize to Encode

This commit is contained in:
Alexander Kobjolke 2023-10-18 11:25:25 +02:00
parent 4f5bf0599a
commit 505f8e66af

View file

@ -7,43 +7,69 @@ import Data.ByteString.Char8 qualified as BC
import Data.Text (Text) import Data.Text (Text)
import Data.Text.Encoding (encodeUtf8) import Data.Text.Encoding (encodeUtf8)
import Data.Word (Word32, Word8) import Data.Word (Word32, Word8)
import System.Posix (CMode (..), FileMode)
class Encode a where class Encode a where
encode :: a -> ByteString encode :: a -> ByteString
encode = BS.drop 4 . encodeWithSize
encodeWithSize :: a -> ByteString
encodeWithSize x =
let s = encode x
l = fromIntegral $ BS.length s
in word32ToByteString l <> s
{-# MINIMAL encode | encodeWithSize #-}
instance Encode ByteString where instance Encode ByteString where
encode = id encode = id
instance Encode Text where instance Encode Text where
encode = encodeUtf8 encode = encodeUtf8
instance Encode String where instance Encode String where
encode = BC.pack encode = BC.pack
type Byte = Word8 type Byte = Word8
{- | @word32ToBytes@ splits a 32bit word into its 4 byte components. -- | @word32ToBytes@ splits a 32bit word into its 4 byte components.
--
>>> word32ToBytes 0xdeadbeef -- >>> word32ToBytes 0xdeadbeef
(222,173,190,239) -- (222,173,190,239)
-} --
-- >>> word32ToBytes 4
-- (0,0,0,4)
word32ToBytes :: Word32 -> (Byte, Byte, Byte, Byte) word32ToBytes :: Word32 -> (Byte, Byte, Byte, Byte)
word32ToBytes word = (a, b, c, d) word32ToBytes word = (a, b, c, d)
where where
!a = fromIntegral $ (word .&. 0xff000000) `shift` (-24) !a = fromIntegral $ (word .&. 0xff000000) `shift` (-24)
!b = fromIntegral $ (word .&. 0x00ff0000) `shift` (-16) !b = fromIntegral $ (word .&. 0x00ff0000) `shift` (-16)
!c = fromIntegral $ (word .&. 0x0000ff00) `shift` (-8) !c = fromIntegral $ (word .&. 0x0000ff00) `shift` (-8)
!d = fromIntegral $ (word .&. 0x000000ff) `shift` (-0) !d = fromIntegral $ (word .&. 0x000000ff) `shift` (-0)
{- | @word32ToByteString@ encodes a 32-bit wide word into a bytestring. -- | @word32ToByteString@ encodes a 32-bit wide word into a bytestring.
--
>>> word32ToByteString 0xdeadbeef -- >>> word32ToByteString 0xdeadbeef
"\222\173\190\239" -- "\222\173\190\239"
-}
word32ToByteString :: Word32 -> ByteString word32ToByteString :: Word32 -> ByteString
word32ToByteString word = word32ToByteString word =
let (a, b, c, d) = word32ToBytes word let (a, b, c, d) = word32ToBytes word
in BS.pack [a, b, c, d] in BS.pack [a, b, c, d]
instance Encode Word32 where instance Encode Word32 where
encode = word32ToByteString encode = word32ToByteString
encodeWithSize w =
let (a, b, c, d) = word32ToBytes w
in BS.pack
[ 0
, 0
, 0
, 4
, a
, b
, c
, d
]
instance Encode FileMode where
encode (CMode mode) = encode mode