hw-prim 0.6.2.15 → 0.6.2.17
raw patch · 4 files changed
+74/−50 lines, 4 filesPVP: minor bump suggested
API additions: PVP suggests at least a minor version bump
API changes (from Hackage documentation)
+ HaskellWorks.Data.ByteString: rechunkPadded :: Int -> [ByteString] -> [ByteString]
+ HaskellWorks.Data.ByteString.Lazy: rechunk :: Int -> ByteString -> ByteString
+ HaskellWorks.Data.ByteString.Lazy: rechunkPadded :: Int -> ByteString -> ByteString
Files
- hw-prim.cabal +1/−1
- src/HaskellWorks/Data/ByteString.hs +62/−47
- src/HaskellWorks/Data/ByteString/Lazy.hs +8/−0
- test/HaskellWorks/Data/ByteStringSpec.hs +3/−2
hw-prim.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack name: hw-prim-version: 0.6.2.15+version: 0.6.2.17 synopsis: Primitive functions and data types description: Primitive functions and data types. category: Data
src/HaskellWorks/Data/ByteString.hs view
@@ -1,12 +1,14 @@ {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiWayIf #-} module HaskellWorks.Data.ByteString ( chunkedBy , ToByteString(..) , ToByteStrings(..)+ , rechunk+ , rechunkPadded , resegment , resegmentPadded- , rechunk , hGetContentsChunkedBy ) where @@ -104,61 +106,74 @@ rechunk :: Int -> [BS.ByteString] -> [BS.ByteString] rechunk size = go- where go (bs:bss) = let bsLen = BS.length bs in- if bsLen > 0- then if bsLen < size- then case size - bsLen of- bsNeed -> case bss of- (cs:css) -> case BS.length cs of- csLen | csLen > bsNeed -> (bs <> BS.take bsNeed cs ):go (BS.drop bsNeed cs:css)- csLen | csLen == bsNeed -> (bs <> cs ):go css- _ | otherwise -> go ((bs <> cs) :css)- [] -> [bs]- else if size == bsLen- then bs:go bss- else BS.take size bs:go (BS.drop size bs:bss)- else go bss+ where go (bs:bss) = let bsLen = BS.length bs in if bsLen > 0+ then if bsLen < size+ then let bsNeed = size - bsLen in case bss of+ (cs:css) -> case BS.length cs of+ csLen | csLen > bsNeed -> (bs <> BS.take bsNeed cs ):go (BS.drop bsNeed cs:css)+ csLen | csLen == bsNeed -> (bs <> cs ):go css+ _ -> go ((bs <> cs) :css)+ [] -> [bs]+ else if size == bsLen+ then bs:go bss+ else BS.take size bs:go (BS.drop size bs:bss)+ else go bss go [] = [] +rechunkPadded :: Int -> [BS.ByteString] -> [BS.ByteString]+rechunkPadded size = go+ where go (bs:bss) = let bsLen = BS.length bs in if bsLen > 0+ then if bsLen < size+ then let bsNeed = size - bsLen in case bss of+ (cs:css) -> case BS.length cs of+ csLen | csLen > bsNeed -> (bs <> BS.take bsNeed cs ):go (BS.drop bsNeed cs:css)+ csLen | csLen == bsNeed -> (bs <> cs ):go css+ _ -> go ((bs <> cs) :css)+ [] -> [bs <> BS.replicate bsNeed 0]+ else if size == bsLen+ then bs:go bss+ else BS.take size bs:go (BS.drop size bs:bss)+ else go bss+ go [] = []+ resegment :: Int -> [BS.ByteString] -> [BS.ByteString]-resegment multiple = go- where go (bs:bss) = case BS.length bs of- bsLen -> if bsLen < multiple- then case multiple - bsLen of- bsNeed -> case bss of- (cs:css) -> case BS.length cs of- csLen | csLen > bsNeed -> (bs <> BS.take bsNeed cs ):go (BS.drop bsNeed cs:css)- csLen | csLen == bsNeed -> (bs <> cs ):go css- _ | otherwise -> go ((bs <> cs) :css)- [] -> [bs]- else case (bsLen `div` multiple) * multiple of- bsCroppedLen -> if bsCroppedLen == bsLen- then bs:go bss- else BS.take bsCroppedLen bs:go (BS.drop bsCroppedLen bs:bss)+resegment size = go+ where go (bs:bss) = let bsLen = BS.length bs in if bsLen > 0+ then if bsLen < size+ then case bss of+ (cs:css) -> let bsNeed = size - bsLen; csLen = BS.length cs in if+ | csLen > bsNeed -> (bs <> BS.take bsNeed cs ):go (BS.drop bsNeed cs:css)+ | csLen == bsNeed -> (bs <> cs ):go css+ | otherwise -> go ((bs <> cs) :css)+ [] -> [bs]+ else let bsCroppedLen = (bsLen `div` size) * size in if bsCroppedLen == bsLen+ then bs:go bss+ else BS.take bsCroppedLen bs:go (BS.drop bsCroppedLen bs:bss)+ else go bss go [] = [] resegmentPadded :: Int -> [BS.ByteString] -> [BS.ByteString]-resegmentPadded multiple = go- where go (bs:bss) = case BS.length bs of- bsLen -> if bsLen < multiple- then case multiple - bsLen of- bsNeed -> case bss of- (cs:css) -> case BS.length cs of- csLen | csLen > bsNeed -> (bs <> BS.take bsNeed cs ):go (BS.drop bsNeed cs:css)- csLen | csLen == bsNeed -> (bs <> cs ):go css- _ | otherwise -> go ((bs <> cs) :css)- [] -> [bs <> BS.replicate bsNeed 0]- else case (bsLen `div` multiple) * multiple of- bsCroppedLen -> if bsCroppedLen == bsLen- then bs:go bss- else BS.take bsCroppedLen bs:go (BS.drop bsCroppedLen bs:bss)+resegmentPadded size = go+ where go (bs:bss) = let bsLen = BS.length bs in if bsLen > 0+ then if bsLen < size+ then let bsNeed = size - bsLen in case bss of+ (cs:css) -> case BS.length cs of+ csLen | csLen > bsNeed -> (bs <> BS.take bsNeed cs ):go (BS.drop bsNeed cs:css)+ csLen | csLen == bsNeed -> (bs <> cs ):go css+ _ -> go ((bs <> cs) :css)+ [] -> [bs <> BS.replicate bsNeed 0]+ else case (bsLen `div` size) * size of+ bsCroppedLen -> if bsCroppedLen == bsLen+ then bs:go bss+ else BS.take bsCroppedLen bs:go (BS.drop bsCroppedLen bs:bss)+ else go bss go [] = [] hGetContentsChunkedBy :: Int -> IO.Handle -> IO [BS.ByteString] hGetContentsChunkedBy k h = lazyRead where lazyRead = IO.unsafeInterleaveIO loop loop = do- c <- BSI.createAndTrim k $ \p -> IO.hGetBuf h p k- if BS.null c- then IO.hClose h >> return []- else (c:) <$> lazyRead+ c <- BSI.createAndTrim k $ \p -> IO.hGetBuf h p k+ if BS.null c+ then IO.hClose h >> return []+ else (c:) <$> lazyRead
src/HaskellWorks/Data/ByteString/Lazy.hs view
@@ -5,6 +5,8 @@ ( ToLazyByteString(..) , resegment , resegmentPadded+ , rechunk+ , rechunkPadded , hGetContentsChunkedBy ) where @@ -64,6 +66,12 @@ resegmentPadded :: Int -> LBS.ByteString -> LBS.ByteString resegmentPadded multiple = LBS.fromChunks . BS.resegmentPadded multiple . LBS.toChunks++rechunk :: Int -> LBS.ByteString -> LBS.ByteString+rechunk multiple = LBS.fromChunks . BS.rechunk multiple . LBS.toChunks++rechunkPadded :: Int -> LBS.ByteString -> LBS.ByteString+rechunkPadded multiple = LBS.fromChunks . BS.rechunkPadded multiple . LBS.toChunks hGetContentsChunkedBy :: Int -> IO.Handle -> IO LBS.ByteString hGetContentsChunkedBy k h = lazyRead
test/HaskellWorks/Data/ByteStringSpec.hs view
@@ -22,8 +22,9 @@ it "resegment creates correctly sized segments" $ requireProperty $ do bss <- forAll $ (BS.pack <$>) <$> G.list (R.linear 0 8) (G.list (R.linear 0 24) (G.word8 R.constantBounded)) chunkSize <- forAll $ G.int (R.linear 1 4)- forM_ (drop 1 (reverse (BS.resegment chunkSize bss))) $ \bs -> do- (BS.length bs) `mod` chunkSize === 0+ let withoutLast = reverse (drop 1 (reverse (BS.resegment chunkSize bss)))+ let disalignments = (\n -> n - (n `div` chunkSize) * chunkSize) . BS.length <$> withoutLast+ disalignments === replicate (length disalignments) 0 it "resegmentPadded does not modify data" $ requireProperty $ do bss <- forAll $ (BS.pack <$>) <$> G.list (R.linear 0 8) (G.list (R.linear 0 24) (G.word8 R.constantBounded)) chunkSize <- forAll $ G.int (R.linear 1 4)