@@ -136,18 +136,10 @@ fromFold (Fold.Fold fstep finitial fextract) =
136136fromParser :: forall m a b. (MonadIO m, Storable a) =>
137137 ParserD.Parser m a b -> Fold m a b
138138fromParser (ParserD.Parser step1 initial1 extract1) =
139− Fold (ParserD.Parser step initial extract1)
139+ Fold (ParserD.Parser step initial1 extract1)
140140
141141 where
142142
143− initial = do
144− res <- initial1
145− return
146− $ case res of
147− IPartial s1 -> IPartial s1
148− IDone b -> IDone b
149− IError err -> IError err
150−
151143 step s (Array fp@(ForeignPtr start _) end) = do
152144 if Ptr start >= end
153145 then return $ Continue 0 s
@@ -155,6 +147,13 @@ fromParser (ParserD.Parser step1 initial1 extract1) =
155147
156148 where
157149
150+ {-# INLINE partial #-}
151+ partial arrRem cur next elemSize st n fs1 = do
152+ let next1 = next `plusPtr` negate (n * elemSize)
153+ if next1 >= Ptr start && cur < end
154+ then goArray SPEC next1 fs1
155+ else return $ st (arrRem + n) fs1
156+
158157 goArray !_ !cur !fs = do
159158 x <- liftIO $ peek cur
160159 liftIO $ touchForeignPtr fp
@@ -165,16 +164,10 @@ fromParser (ParserD.Parser step1 initial1 extract1) =
165164 case res of
166165 ParserD.Done n b -> do
167166 return $ Done (arrRem + n) b
168− ParserD.Partial n fs1 -> do
169− let next1 = next `plusPtr` negate (n * elemSize)
170− if next1 >= Ptr start && cur < end
171− then goArray SPEC next1 fs1
172− else return $ Partial (arrRem + n) fs1
167+ ParserD.Partial n fs1 ->
168+ partial arrRem cur next elemSize Partial n fs1
173169 ParserD.Continue n fs1 -> do
174− let next1 = next `plusPtr` negate (n * elemSize)
175− if next1 >= Ptr start && cur < end
176− then goArray SPEC next1 fs1
177− else return $ Continue (arrRem + n) fs1
170+ partial arrRem cur next elemSize Continue n fs1
178171 Error err -> return $ Error err
179172
180173-- | Adapt an array stream fold.
@@ -309,20 +302,22 @@ take n (Fold (ParserD.Parser step1 initial1 extract1)) =
309302 IDone b -> return $ IDone b
310303 IError err -> return $ IError err
311304
305+ {-# INLINE partial #-}
306+ partial i1 st j s =
307+ let i2 = i1 + j
308+ in if i2 > 0
309+ then return $ st j (Tuple' i2 s)
310+ else Done 0 <$> extract1 s -- i2 == i1 == j == 0
311+
312312 step (Tuple' i r) arr = do
313313 let len = Array.length arr
314− if len <= i
314+ i1 = i - len
315+ if i1 >= 0
315316 then do
316317 res <- step1 r arr
317318 case res of
318− Partial j s ->
319− if (i + j - len) > 0
320− then return $ Partial j (Tuple' (i + j - len) s)
321− else Done j <$> extract1 s
322− Continue j s ->
323− if (i + j - len) > 0
324− then return $ Continue j (Tuple' (i + j - len) s)
325− else Done j <$> extract1 s
319+ Partial j s -> partial i1 Partial j s
320+ Continue j s -> partial i1 Continue j s
326321 Done j b -> return $ Done j b
327322 Error err -> return $ Error err
328323 else do
@@ -330,7 +325,7 @@ take n (Fold (ParserD.Parser step1 initial1 extract1)) =
330325 sz = sizeOf (undefined :: a)
331326 end = Ptr start `plusPtr` (i * sz)
332327 arr1 = Array (ForeignPtr start contents) end
333− remaining = len - i
328+ remaining = negate i1
334329 res <- step1 r arr1
335330 case res of
336331 Partial 0 s -> Done remaining <$> extract1 s