module Pairing.ByteRepr where import Protolude import Data.ByteString as B import Data.ByteString.Builder class ByteRepr a where mkRepr :: a -> Maybe ByteString fromRepr :: a -> ByteString -> Maybe a reprLength :: a -> Int toBytes :: Integer -> ByteString toBytes x = B.reverse . B.unfoldr (fmap go) . Just $ changeSign x where changeSign :: Num a => a -> a changeSign | x < 0 = subtract 1 . negate | otherwise = identity go :: Integer -> (Word8, Maybe Integer) go x = ( b, i ) where b = changeSign (fromInteger x) i | x >= 128 = Just (x `shiftR` 8 ) | otherwise = Nothing toPaddedBytes :: Int -> Integer -> Maybe ByteString toPaddedBytes len a = if B.length bs > len then Nothing else Just (B.append (B.replicate (len - B.length bs) 0x0) bs) where bs = toBytes a fromBytesToInteger :: ByteString -> Integer fromBytesToInteger = B.foldl' f 0 where f a b = a `shiftL` 8 .|. fromIntegral b