module System.Nix.Util where
import Control.Monad
import Data.Binary.Get
import Data.Binary.Put
import qualified Data.ByteString.Lazy as LBS
putInt :: Integral a => a -> Put
putInt = putWord64le . fromIntegral
getInt :: Integral a => Get a
getInt = fromIntegral <$> getWord64le
putByteStringLen :: LBS.ByteString -> Put
putByteStringLen x = do
putInt $ fromIntegral $ len
putLazyByteString x
when (len `mod` 8 /= 0) $
pad $ fromIntegral $ 8 - (len `mod` 8)
where len = LBS.length x
pad x = forM_ (take x $ cycle [0]) putWord8
putByteStrings :: Foldable t => t LBS.ByteString -> Put
putByteStrings xs = do
putInt $ fromIntegral $ length xs
mapM_ putByteStringLen xs
getByteStringLen :: Get LBS.ByteString
getByteStringLen = do
len <- getInt
st <- getLazyByteString len
when (len `mod` 8 /= 0) $ do
pads <- unpad $ fromIntegral $ 8 - (len `mod` 8)
unless (all (==0) pads) $ fail $ "No zeroes" ++ show (st, len, pads)
return st
where unpad x = sequence $ replicate x getWord8
getByteStrings :: Get [LBS.ByteString]
getByteStrings = do
count <- getInt
res <- sequence $ replicate count getByteStringLen
return res