From 505f8e66aff350b74c2cc876ce36fad44e7e9e19 Mon Sep 17 00:00:00 2001 From: Alexander Kobjolke Date: Wed, 18 Oct 2023 11:25:25 +0200 Subject: [PATCH] Add encodeWithSize to Encode --- src/FilePack/Encode.hs | 70 +++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 22 deletions(-) diff --git a/src/FilePack/Encode.hs b/src/FilePack/Encode.hs index 91cc71e..e71e4f7 100644 --- a/src/FilePack/Encode.hs +++ b/src/FilePack/Encode.hs @@ -7,43 +7,69 @@ import Data.ByteString.Char8 qualified as BC import Data.Text (Text) import Data.Text.Encoding (encodeUtf8) import Data.Word (Word32, Word8) +import System.Posix (CMode (..), FileMode) 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 - encode = id + encode = id instance Encode Text where - encode = encodeUtf8 + encode = encodeUtf8 instance Encode String where - encode = BC.pack + encode = BC.pack type Byte = Word8 -{- | @word32ToBytes@ splits a 32bit word into its 4 byte components. - - >>> word32ToBytes 0xdeadbeef - (222,173,190,239) --} +-- | @word32ToBytes@ splits a 32bit word into its 4 byte components. +-- +-- >>> word32ToBytes 0xdeadbeef +-- (222,173,190,239) +-- +-- >>> word32ToBytes 4 +-- (0,0,0,4) word32ToBytes :: Word32 -> (Byte, Byte, Byte, Byte) word32ToBytes word = (a, b, c, d) - where - !a = fromIntegral $ (word .&. 0xff000000) `shift` (-24) - !b = fromIntegral $ (word .&. 0x00ff0000) `shift` (-16) - !c = fromIntegral $ (word .&. 0x0000ff00) `shift` (-8) - !d = fromIntegral $ (word .&. 0x000000ff) `shift` (-0) + where + !a = fromIntegral $ (word .&. 0xff000000) `shift` (-24) + !b = fromIntegral $ (word .&. 0x00ff0000) `shift` (-16) + !c = fromIntegral $ (word .&. 0x0000ff00) `shift` (-8) + !d = fromIntegral $ (word .&. 0x000000ff) `shift` (-0) -{- | @word32ToByteString@ encodes a 32-bit wide word into a bytestring. - - >>> word32ToByteString 0xdeadbeef - "\222\173\190\239" --} +-- | @word32ToByteString@ encodes a 32-bit wide word into a bytestring. +-- +-- >>> word32ToByteString 0xdeadbeef +-- "\222\173\190\239" word32ToByteString :: Word32 -> ByteString word32ToByteString word = - let (a, b, c, d) = word32ToBytes word - in BS.pack [a, b, c, d] + let (a, b, c, d) = word32ToBytes word + in BS.pack [a, b, c, d] 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