@@ -49,6 +49,8 @@ module Streamly.Internal.Data.StreamK
49 , parseChunks
49 , parseChunks
50 , parseBreakSingular
50 , parseBreakSingular
51 , parseSingular
51 , parseSingular
52+ , parseBreakGenericChunks
53 -- ** Specialized Folds
55 -- ** Specialized Folds
@@ -143,6 +145,7 @@ import Streamly.Internal.Data.Unbox (sizeOf, Unbox)
144import qualified Control.Monad.Catch as MC
146import qualified Control.Monad.Catch as MC
145import qualified Streamly.Internal.Data.Array.Type as Array
147import qualified Streamly.Internal.Data.Array.Type as Array
148+import qualified Streamly.Internal.Data.Array.Generic as GenArr
146import qualified Streamly.Internal.Data.Fold.Type as FL
149import qualified Streamly.Internal.Data.Fold.Type as FL
147import qualified Streamly.Internal.Data.Parser as Parser
150import qualified Streamly.Internal.Data.Parser as Parser
148import qualified Streamly.Internal.Data.Parser.ParserD.Type as PR
151import qualified Streamly.Internal.Data.Parser.ParserD.Type as PR
@@ -1284,7 +1287,7 @@ parseD :: Monad m =>
1284parseD f = fmap fst . parseDBreak f
1287parseD f = fmap fst . parseDBreak f
1286-------------------------------------------------------------------------------
1289-------------------------------------------------------------------------------
1287−-- Chunked parsing using ParserK
1290+-- ParserK Chunked
1288-------------------------------------------------------------------------------
1291-------------------------------------------------------------------------------
1290-- The backracking buffer consists of arrays in the most-recent-first order. We
1293-- The backracking buffer consists of arrays in the most-recent-first order. We
@@ -1427,7 +1430,7 @@ parseChunks :: (Monad m, Unbox a) =>
1427parseChunks f = fmap fst . parseBreakChunks f
1430parseChunks f = fmap fst . parseBreakChunks f
1429-------------------------------------------------------------------------------
1432-------------------------------------------------------------------------------
1430−-- Parsing using ParserK.Generic
1433+-- ParserK Singular
1431-------------------------------------------------------------------------------
1434-------------------------------------------------------------------------------
1433{-# INLINE backTrackSingular #-}
1436{-# INLINE backTrackSingular #-}
@@ -1555,6 +1558,151 @@ parseSingular :: Monad m =>
1555 ParserK.ParserK a m b -> StreamK m a -> m (Either ParseError b)
1558 ParserK.ParserK a m b -> StreamK m a -> m (Either ParseError b)
1556parseSingular f = fmap fst . parseBreakSingular f
1559parseSingular f = fmap fst . parseBreakSingular f
1561+-------------------------------------------------------------------------------
1562+-- ParserK Chunked Generic
1563+-------------------------------------------------------------------------------
1565+{-# INLINE backTrackGenericChunks #-}
1566+backTrackGenericChunks ::
1568+ -> [GenArr.Array a]
1569+ -> StreamK m (GenArr.Array a)
1570+ -> (StreamK m (GenArr.Array a), [GenArr.Array a])
1571+backTrackGenericChunks = go
1575+ go _ [] stream = (stream, [])
1576+ go n xs stream | n <= 0 = (stream, xs)
1577+ go n (x:xs) stream =
1578+ let len = GenArr.length x
1580+ then go (n - len) xs (cons x stream)
1582+ then (cons x stream, xs)
1583+ else let arr1 = GenArr.getSliceUnsafe (len - n) n x
1584+ arr2 = GenArr.getSliceUnsafe 0 (len - n) x
1585+ in (cons arr1 stream, arr2:xs)
1587+-- | Similar to 'parseBreak' but works on generic arrays
1589+{-# INLINE_NORMAL parseBreakGenericChunks #-}
1590+parseBreakGenericChunks
1591+ :: forall m a b. Monad m
1592+ => ParserK.ParserK (GenArr.Array a) m b
1593+ -> StreamK m (GenArr.Array a)
1594+ -> m (Either ParseError b, StreamK m (GenArr.Array a))
1595+parseBreakGenericChunks parser input = do
1596+ let parserk = ParserK.runParser parser parserDone 0 0
1597+ in go [] parserk input
1601+ {-# INLINE goStop #-}
1603+ :: [GenArr.Array a]
1604+ -> (ParserK.Input (GenArr.Array a)
1605+ -> m (ParserK.Step (GenArr.Array a) m b))
1606+ -> m (Either ParseError b, StreamK m (GenArr.Array a))
1607+ goStop backBuf parserk = do
1608+ pRes <- parserk ParserK.None
1610+ -- If we stop in an alternative, it will try calling the next
1611+ -- parser, the next parser may call initial returning Partial and
1612+ -- then immediately we have to call extract on it.
1613+ ParserK.Partial 0 cont1 ->
1615+ ParserK.Partial n cont1 -> do
1617+ assertM(n1 >= 0 && n1 <= sum (Prelude.map GenArr.length backBuf))
1618+ let (s1, backBuf1) = backTrackGenericChunks n1 backBuf nil
1619+ in go backBuf1 cont1 s1
1620+ ParserK.Continue 0 cont1 ->
1621+ go backBuf cont1 nil
1622+ ParserK.Continue n cont1 -> do
1624+ assertM(n1 >= 0 && n1 <= sum (Prelude.map GenArr.length backBuf))
1625+ let (s1, backBuf1) = backTrackGenericChunks n1 backBuf nil
1626+ in go backBuf1 cont1 s1
1627+ ParserK.Done 0 b ->
1628+ return (Right b, nil)
1629+ ParserK.Done n b -> do
1631+ assertM(n1 >= 0 && n1 <= sum (Prelude.map GenArr.length backBuf))
1632+ let (s1, _) = backTrackGenericChunks n1 backBuf nil
1633+ in return (Right b, s1)
1634+ ParserK.Error _ err -> return (Left (ParseError err), nil)
1637+ error $ "parseBreak: Partial: forward seek not implemented n = "
1638+ ++ show n ++ " len = " ++ show len
1641+ :: [GenArr.Array a]
1642+ -> (ParserK.Input (GenArr.Array a)
1643+ -> m (ParserK.Step (GenArr.Array a) m b))
1645+ -> StreamK m (GenArr.Array a)
1646+ -> m (Either ParseError b, StreamK m (GenArr.Array a))
1647+ yieldk backBuf parserk arr stream = do
1648+ pRes <- parserk (ParserK.Chunk arr)
1649+ let len = GenArr.length arr
1651+ ParserK.Partial n cont1 ->
1652+ case compare n len of
1653+ EQ -> go [] cont1 stream
1656+ then yieldk [] cont1 arr stream
1659+ bufLen = sum (Prelude.map GenArr.length backBuf)
1660+ s = cons arr stream
1661+ assertM(n1 >= 0 && n1 <= bufLen)
1662+ let (s1, _) = backTrackGenericChunks n1 backBuf s
1664+ GT -> seekErr n len
1665+ ParserK.Continue n cont1 ->
1666+ case compare n len of
1667+ EQ -> go (arr:backBuf) cont1 stream
1670+ then yieldk backBuf cont1 arr stream
1673+ bufLen = sum (Prelude.map GenArr.length backBuf)
1674+ s = cons arr stream
1675+ assertM(n1 >= 0 && n1 <= bufLen)
1676+ let (s1, backBuf1) = backTrackGenericChunks n1 backBuf s
1677+ go backBuf1 cont1 s1
1678+ GT -> seekErr n len
1679+ ParserK.Done n b -> do
1681+ assertM(n1 <= sum (Prelude.map GenArr.length (arr:backBuf)))
1682+ let (s1, _) = backTrackGenericChunks n1 (arr:backBuf) stream
1683+ in return (Right b, s1)
1684+ ParserK.Error _ err -> return (Left (ParseError err), nil)
1687+ :: [GenArr.Array a]
1688+ -> (ParserK.Input (GenArr.Array a)
1689+ -> m (ParserK.Step (GenArr.Array a) m b))
1690+ -> StreamK m (GenArr.Array a)
1691+ -> m (Either ParseError b, StreamK m (GenArr.Array a))
1692+ go backBuf parserk stream = do
1693+ let stop = goStop backBuf parserk
1694+ single a = yieldk backBuf parserk a nil
1696+ defState (yieldk backBuf parserk) single stop stream
1698+{-# INLINE parseGenericChunks #-}
1699+parseGenericChunks ::
1701+ => ParserK.ParserK (GenArr.Array a) m b
1702+ -> StreamK m (GenArr.Array a)
1703+ -> m (Either ParseError b)
1704+parseGenericChunks f = fmap fst . parseBreakGenericChunks f
1558-------------------------------------------------------------------------------
1706-------------------------------------------------------------------------------
1559-- Sorting
1707-- Sorting
1560-------------------------------------------------------------------------------
1708-------------------------------------------------------------------------------