on master help sign in
Add readChunksFromToWith, read ranges from Handle
commitdebc6a95d4c95c26169fb0a80f96537a6ece4ded authorRanjeet Ranjan <ranjeetr@composewell.com> dateWed 11 Nov 2020, 21:42 (6 years ago) parent2842d50
3 files changed+83−3
src/Streamly/FileSystem/Handle.hs+1 src/Streamly/Internal/FileSystem/Handle.hs+26−3 test/Streamly/Test/FileSystem/Handle.hs+56
src/Streamly/FileSystem/Handle.hs+1
@@ -79,6 +79,7 @@ module Streamly.FileSystem.Handle
7979 , readWithBufferOf
8080 , readChunks
8181 , readChunksWithBufferOf
82+ , readChunksFromToWith
8283
8384 -- ** Writing
8485 -- | 'TextEncoding', 'NewLineMode', and 'Buffering' options of the
src/Streamly/Internal/FileSystem/Handle.hs+26−3
@@ -105,7 +105,7 @@ import Foreign.ForeignPtr (withForeignPtr)
105105import Foreign.Ptr (minusPtr, plusPtr)
106106import Foreign.Storable (Storable(..))
107107import GHC.ForeignPtr (mallocPlainForeignPtrBytes)
108−import System.IO (Handle, hGetBufSome, hPutBuf)
108+import System.IO (Handle, SeekMode(..), hGetBufSome, hPutBuf, hSeek)
109109import Prelude hiding (read)
110110
111111import Streamly.Internal.BaseCompat
@@ -257,9 +257,32 @@ readChunksWithBufferOf = Unfold step return
257257--
258258--
259259{-# INLINE_NORMAL readChunksFromToWith #-}
260−readChunksFromToWith :: -- MonadIO m =>
260+readChunksFromToWith :: MonadIO m =>
261261 Unfold m (Int, Int, Int, Handle) (Array Word8)
262−readChunksFromToWith = undefined
262+readChunksFromToWith = Unfold step inject
263+
264+ where
265+
266+ inject (from, to, buffSize, h) = do
267+ liftIO $ hSeek h AbsoluteSeek $ fromIntegral from
268+ return (to - from + 1, buffSize, h)
269+
270+ {-# INLINE_LATE step #-}
271+ step (remaining, buffSize, h) =
272+ if remaining <= 0
273+ then return D.Stop
274+ else
275+ do
276+ arr <- getChunk (min buffSize remaining) h
277+ return $
278+ case A.length arr of
279+ 0 -> D.Stop
280+ len ->
281+ if (remaining - len) >= 0
282+ then
283+ D.Yield arr (remaining - len, buffSize, h)
284+ else
285+ error "Bug: getChunk returned array length more than expected"
263286
264287-- XXX read 'Array a' instead of Word8
265288--
test/Streamly/Test/FileSystem/Handle.hs+56
@@ -61,6 +61,9 @@ testData = "This is the test data for FileSystem.Handle ??`!@#$%^&*~~))`]"
6161testDataLarge :: String
6262testDataLarge = concat $ replicate 6000 testData
6363
64+testBinData :: String
65+testBinData = "01234567890123456789012345678901234567890123456789"
66+
6467executor :: (Handle -> SerialT IO Char) -> IO (SerialT IO Char)
6568executor f =
6669 withSystemTempDirectory "fs_handle" $ \fp -> do
@@ -152,6 +155,53 @@ testWriteWithChunk =
152155 let arr = Array.fromList ls
153156 return (testDataLarge == utf8ToString arr)
154157
158+
159+testReadChunksFromToWith :: Int -> Int -> Int -> String -> Property
160+testReadChunksFromToWith from to buffSize expRes =
161+ monadicIO $ do
162+ res <- run go
163+ assert res
164+
165+ where
166+
167+ go =
168+ withSystemTempDirectory "fs_handle" $ \fp -> do
169+ let fpathRead = fp </> "tmp_read.txt"
170+ writeFile fpathRead testBinData
171+ h <- openFile fpathRead ReadMode
172+ ls <- Stream.toList $
173+ Stream.unfold
174+ Handle.readChunksFromToWith
175+ (from, to, buffSize, h)
176+ return ( expRes == show ls)
177+
178+-- Test for first byte
179+testReadChunksFromToWithFirstByte :: Property
180+testReadChunksFromToWithFirstByte = testReadChunksFromToWith 0 0 15 "[[48]]"
181+
182+-- Test for second byte
183+testReadChunksFromToWithSecondByte :: Property
184+testReadChunksFromToWithSecondByte = testReadChunksFromToWith 1 1 15 "[[49]]"
185+
186+-- Test for second to 10th bytes
187+testReadChunksFromToWithSecondToTenthBytes :: Property
188+testReadChunksFromToWithSecondToTenthBytes =
189+ testReadChunksFromToWith 1 10 15 "[[49,50,51,52,53,54,55,56,57,48]]"
190+
191+-- Test for offset of buffer size
192+testReadChunksFromToWithBuffSizeOffset :: Property
193+testReadChunksFromToWithBuffSizeOffset =
194+ testReadChunksFromToWith 15 25 15 "[[53,54,55,56,57,48,49,50,51,52,53]]"
195+
196+-- Test with multi buffer size
197+testReadChunksFromToWithMultiBuff :: Property
198+testReadChunksFromToWithMultiBuff =
199+ testReadChunksFromToWith
200+ 5 22 5 "[[53,54,55,56,57],[48,49,50,51,52],[53,54,55,56,57],[48,49,50]]"
201+
202+testReadChunksFromToWithRangeInvalid :: Property
203+testReadChunksFromToWithRangeInvalid = testReadChunksFromToWith 15 5 15 "[]"
204+
155205moduleName :: String
156206moduleName = "FileSystem.Handle"
157207
@@ -166,6 +216,12 @@ main =
166216 prop "readWithBufferOf" $ testRead readWithBufferFromHandle
167217 prop "readChunks" $ testRead readChunksFromHandle
168218 prop "readChunksWithBufferOf" $ testRead readChunksWithBuffer
219+ prop "readChunksFromToWithFirstByte" testReadChunksFromToWithFirstByte
220+ prop "readChunksFromToWithSecondByte" testReadChunksFromToWithSecondByte
221+ prop "readChunksFromToWithSecondToTenthBytes" testReadChunksFromToWithSecondToTenthBytes
222+ prop "readChunksFromToWithBuffSizeOffset" testReadChunksFromToWithBuffSizeOffset
223+ prop "readChunksFromToWithMultiBuff" testReadChunksFromToWithMultiBuff
224+ prop "readChunksFromToWithRangeInvalid" testReadChunksFromToWithRangeInvalid
169225 describe "Write To Handle" $ do
170226 prop "write" $ testWrite Handle.write
171227 prop "writeWithBufferOf" $ testWrite $ Handle.writeWithBufferOf 1024