on master help sign in
Refactor and reformat readChunksFromToWith
932f7b2Harendra Kumar
src/Streamly/FileSystem/Handle.hs−1
@@ -79,7 +79,6 @@ module Streamly.FileSystem.Handle
79 , readWithBufferOf
79 , readWithBufferOf
80 , readChunks
80 , readChunks
81 , readChunksWithBufferOf
81 , readChunksWithBufferOf
82− , readChunksFromToWith
83
82
84 -- ** Writing
83 -- ** Writing
85 -- | 'TextEncoding', 'NewLineMode', and 'Buffering' options of the
84 -- | 'TextEncoding', 'NewLineMode', and 'Buffering' options of the
src/Streamly/Internal/FileSystem/Handle.hs+11−11
@@ -98,6 +98,7 @@ module Streamly.Internal.FileSystem.Handle
98 )
98 )
99where
99where
100
100
101+import Control.Exception (assert)
101import Control.Monad.IO.Class (MonadIO(..))
102import Control.Monad.IO.Class (MonadIO(..))
102import Data.Word (Word8)
103import Data.Word (Word8)
103import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
104import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
@@ -252,6 +253,8 @@ readChunksWithBufferOf = Unfold step return
252-- the array lengths and trim the last array to correct size.
253-- the array lengths and trim the last array to correct size.
253-- 2. Simply implement it from scratch like readChunksWithBufferOf.
254-- 2. Simply implement it from scratch like readChunksWithBufferOf.
254--
255--
256+-- XXX Change this to readChunksWithFromTo (bufferSize, from, to, h)?
257+--
255-- | The input to the unfold is @(from, to, bufferSize, handle)@. It starts
258-- | The input to the unfold is @(from, to, bufferSize, handle)@. It starts
256-- reading from the offset `from` in the file and reads up to the offset `to`.
259-- reading from the offset `from` in the file and reads up to the offset `to`.
257--
260--
@@ -263,26 +266,23 @@ readChunksFromToWith = Unfold step inject
263
266
264 where
267 where
265
268
266− inject (from, to, buffSize, h) = do
269+ inject (from, to, bufSize, h) = do
267 liftIO $ hSeek h AbsoluteSeek $ fromIntegral from
270 liftIO $ hSeek h AbsoluteSeek $ fromIntegral from
271+ -- XXX Use a strict Tuple?
268− return (to - from + 1, buffSize, h)
272+ return (to - from + 1, bufSize, h)
269
273
270 {-# INLINE_LATE step #-}
274 {-# INLINE_LATE step #-}
271− step (remaining, buffSize, h) =
275+ step (remaining, bufSize, h) =
272 if remaining <= 0
276 if remaining <= 0
273 then return D.Stop
277 then return D.Stop
274− else
278+ else do
275− do
276− arr <- getChunk (min buffSize remaining) h
279+ arr <- getChunk (min bufSize remaining) h
277 return $
280 return $
278 case A.length arr of
281 case A.length arr of
279 0 -> D.Stop
282 0 -> D.Stop
280 len ->
283 len ->
281− if (remaining - len) >= 0
284+ assert (len <= remaining)
282− then
283− D.Yield arr (remaining - len, buffSize, h)
285+ $ D.Yield arr (remaining - len, bufSize, h)
284− else
285− error "Bug: getChunk returned array length more than expected"
286
286
287-- XXX read 'Array a' instead of Word8
287-- XXX read 'Array a' instead of Word8
288--
288--
test/Streamly/Test/FileSystem/Handle.hs+34−31
@@ -27,7 +27,7 @@ import Test.QuickCheck (Property, forAll, Gen, vectorOf, choose)
27import Test.QuickCheck.Monadic (monadicIO, assert, run)
27import Test.QuickCheck.Monadic (monadicIO, assert, run)
28
28
29import qualified Streamly.Data.Fold as Fold
29import qualified Streamly.Data.Fold as Fold
30−import qualified Streamly.FileSystem.Handle as Handle
30+import qualified Streamly.Internal.FileSystem.Handle as Handle
31import qualified Streamly.Internal.Data.Stream.IsStream as Stream
31import qualified Streamly.Internal.Data.Stream.IsStream as Stream
32import qualified Streamly.Internal.Data.Array.Foreign as Array
32import qualified Streamly.Internal.Data.Array.Foreign as Array
33import qualified Streamly.Internal.Unicode.Stream as Unicode
33import qualified Streamly.Internal.Unicode.Stream as Unicode
@@ -155,52 +155,48 @@ testWriteWithChunk =
155 let arr = Array.fromList ls
155 let arr = Array.fromList ls
156 return (testDataLarge == utf8ToString arr)
156 return (testDataLarge == utf8ToString arr)
157
157
158+testReadChunksFromToWith :: Int -> Int -> Int -> [[Word8]] -> Property
159+testReadChunksFromToWith from to buffSize res = monadicIO $ run go
158
160
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
161+ where
166
162
167− go =
163+ go =
168− withSystemTempDirectory "fs_handle" $ \fp -> do
164+ withSystemTempDirectory "fs_handle" $ \fp -> do
169− let fpathRead = fp </> "tmp_read.txt"
165+ let fpathRead = fp </> "tmp_read.txt"
170− writeFile fpathRead testBinData
166+ writeFile fpathRead testBinData
171− h <- openFile fpathRead ReadMode
167+ h <- openFile fpathRead ReadMode
168+ ls <-
172− ls <- Stream.toList $
169+ Stream.toList
173− Stream.unfold
170+ $ Stream.unfold
174− Handle.readChunksFromToWith
171+ Handle.readChunksFromToWith (from, to, buffSize, h)
175− (from, to, buffSize, h)
172+ return (res `shouldBe` fmap Array.toList ls)
176− return ( expRes == show ls)
177
173
178-- Test for first byte
174-- Test for first byte
179testReadChunksFromToWithFirstByte :: Property
175testReadChunksFromToWithFirstByte :: Property
180−testReadChunksFromToWithFirstByte = testReadChunksFromToWith 0 0 15 "[[48]]"
176+testReadChunksFromToWithFirstByte = testReadChunksFromToWith 0 0 15 [[48]]
181
177
182-- Test for second byte
178-- Test for second byte
183testReadChunksFromToWithSecondByte :: Property
179testReadChunksFromToWithSecondByte :: Property
184−testReadChunksFromToWithSecondByte = testReadChunksFromToWith 1 1 15 "[[49]]"
180+testReadChunksFromToWithSecondByte = testReadChunksFromToWith 1 1 15 [[49]]
185
181
186-- Test for second to 10th bytes
182-- Test for second to 10th bytes
187testReadChunksFromToWithSecondToTenthBytes :: Property
183testReadChunksFromToWithSecondToTenthBytes :: Property
188testReadChunksFromToWithSecondToTenthBytes =
184testReadChunksFromToWithSecondToTenthBytes =
189− testReadChunksFromToWith 1 10 15 "[[49,50,51,52,53,54,55,56,57,48]]"
185+ testReadChunksFromToWith 1 10 15 [[49,50,51,52,53,54,55,56,57,48]]
190
186
191-- Test for offset of buffer size
187-- Test for offset of buffer size
192testReadChunksFromToWithBuffSizeOffset :: Property
188testReadChunksFromToWithBuffSizeOffset :: Property
193testReadChunksFromToWithBuffSizeOffset =
189testReadChunksFromToWithBuffSizeOffset =
194− testReadChunksFromToWith 15 25 15 "[[53,54,55,56,57,48,49,50,51,52,53]]"
190+ testReadChunksFromToWith 15 25 15 [[53,54,55,56,57,48,49,50,51,52,53]]
195
191
196-- Test with multi buffer size
192-- Test with multi buffer size
197testReadChunksFromToWithMultiBuff :: Property
193testReadChunksFromToWithMultiBuff :: Property
198testReadChunksFromToWithMultiBuff =
194testReadChunksFromToWithMultiBuff =
199 testReadChunksFromToWith
195 testReadChunksFromToWith
200− 5 22 5 "[[53,54,55,56,57],[48,49,50,51,52],[53,54,55,56,57],[48,49,50]]"
196+ 5 22 5 [[53,54,55,56,57],[48,49,50,51,52],[53,54,55,56,57],[48,49,50]]
201
197
202testReadChunksFromToWithRangeInvalid :: Property
198testReadChunksFromToWithRangeInvalid :: Property
203−testReadChunksFromToWithRangeInvalid = testReadChunksFromToWith 15 5 15 "[]"
199+testReadChunksFromToWithRangeInvalid = testReadChunksFromToWith 15 5 15 []
204
200
205moduleName :: String
201moduleName :: String
206moduleName = "FileSystem.Handle"
202moduleName = "FileSystem.Handle"
@@ -216,14 +212,21 @@ main =
216 prop "readWithBufferOf" $ testRead readWithBufferFromHandle
212 prop "readWithBufferOf" $ testRead readWithBufferFromHandle
217 prop "readChunks" $ testRead readChunksFromHandle
213 prop "readChunks" $ testRead readChunksFromHandle
218 prop "readChunksWithBufferOf" $ testRead readChunksWithBuffer
214 prop "readChunksWithBufferOf" $ testRead readChunksWithBuffer
215+ prop "readChunksFromToWith (0,0,n)"
219− prop "readChunksFromToWithFirstByte" testReadChunksFromToWithFirstByte
216+ testReadChunksFromToWithFirstByte
217+ prop "readChunksFromToWith (1,1,n)"
220− prop "readChunksFromToWithSecondByte" testReadChunksFromToWithSecondByte
218+ testReadChunksFromToWithSecondByte
219+ prop "readChunksFromToWith (1,10,n)"
221− prop "readChunksFromToWithSecondToTenthBytes" testReadChunksFromToWithSecondToTenthBytes
220+ testReadChunksFromToWithSecondToTenthBytes
221+ prop "readChunksFromToWith (n,<2n,n)"
222− prop "readChunksFromToWithBuffSizeOffset" testReadChunksFromToWithBuffSizeOffset
222+ testReadChunksFromToWithBuffSizeOffset
223+ prop "readChunksFromToWith (n,>2n,n)"
223− prop "readChunksFromToWithMultiBuff" testReadChunksFromToWithMultiBuff
224+ testReadChunksFromToWithMultiBuff
225+ prop "readChunksFromToWith (n,<n,n)"
224− prop "readChunksFromToWithRangeInvalid" testReadChunksFromToWithRangeInvalid
226+ testReadChunksFromToWithRangeInvalid
225 describe "Write To Handle" $ do
227 describe "Write To Handle" $ do
226 prop "write" $ testWrite Handle.write
228 prop "write" $ testWrite Handle.write
229+ prop "writeWithBufferOf"
227− prop "writeWithBufferOf" $ testWrite $ Handle.writeWithBufferOf 1024
230+ $ testWrite $ Handle.writeWithBufferOf 1024
228 -- XXX This test needs a lot of stack when built with -O0
231 -- XXX This test needs a lot of stack when built with -O0
229 prop "writeChunks" testWriteWithChunk
232 prop "writeChunks" testWriteWithChunk