module HaskellWorks.Data.Dsv.Lazy.Cursor.Strict
( snippet
, getRowListBetween
, getRowVectorBetween
, toListList
, toListVector
, toVectorVector
) where
import Data.Function
import HaskellWorks.Data.Dsv.Lazy.Cursor.Internal
import HaskellWorks.Data.Dsv.Lazy.Cursor.Type
import HaskellWorks.Data.RankSelect.Base.Rank1
import Prelude
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.List as L
import qualified Data.Vector as DV
snippet :: DsvCursor -> Int -> BS.ByteString -> BS.ByteString
snippet c offset bs = BS.take (len `max` 0) $ BS.drop posC $ bs
where d = nextField c
posC = fromIntegral (dsvCursorPosition c) - offset
posD = fromIntegral (dsvCursorPosition d) - offset
len = posD - posC
{-# INLINE snippet #-}
getRowListBetween :: DsvCursor -> DsvCursor -> Bool -> [BS.ByteString]
getRowListBetween c d dEnd = take fields (L.unfoldr go c)
where bsA = fromIntegral $ dsvCursorPosition c
bsZ = fromIntegral $ dsvCursorPosition d
bsT = dsvCursorText c
bs = LBS.toStrict $ LBS.take (bsZ - bsA) (LBS.drop bsA bsT)
cr = rank1 (dsvCursorMarkers c) (dsvCursorPosition c)
dr = rank1 (dsvCursorMarkers d) (dsvCursorPosition d)
c2d = fromIntegral (dr - cr)
fields = if dEnd then c2d +1 else c2d
go :: DsvCursor -> Maybe (BS.ByteString, DsvCursor)
go e = case nextField e of
f -> case nextPosition f of
g -> case snippet e (fromIntegral bsA) bs of
s -> Just (s, g)
{-# INLINE go #-}
{-# INLINE getRowListBetween #-}
getRowVectorBetween :: DsvCursor -> DsvCursor -> Bool -> DV.Vector BS.ByteString
getRowVectorBetween c d dEnd = DV.unfoldrN fields go c
where bsA = fromIntegral $ dsvCursorPosition c
bsZ = fromIntegral $ dsvCursorPosition d
bsT = dsvCursorText c
bs = LBS.toStrict $ LBS.take (bsZ - bsA) (LBS.drop bsA bsT)
cr = rank1 (dsvCursorMarkers c) (dsvCursorPosition c)
dr = rank1 (dsvCursorMarkers d) (dsvCursorPosition d)
c2d = fromIntegral (dr - cr)
fields = if dEnd then c2d +1 else c2d
go :: DsvCursor -> Maybe (BS.ByteString, DsvCursor)
go e = case nextField e of
f -> case nextPosition f of
g -> case snippet e (fromIntegral bsA) bs of
s -> Just (s, g)
{-# INLINE go #-}
{-# INLINE getRowVectorBetween #-}
toListList :: DsvCursor -> [[BS.ByteString]]
toListList c = if dsvCursorPosition d > dsvCursorPosition c && not (atEnd c)
then getRowListBetween c d dEnd:toListList (trim d)
else []
where nr = nextRow c
d = nextPosition nr
dEnd = atEnd nr
{-# INLINE toListList #-}
toListVector :: DsvCursor -> [DV.Vector BS.ByteString]
toListVector c = if dsvCursorPosition d > dsvCursorPosition c && not (atEnd c)
then getRowVectorBetween c d dEnd:toListVector (trim d)
else []
where nr = nextRow c
d = nextPosition nr
dEnd = atEnd nr
{-# INLINE toListVector #-}
toVectorVector :: DsvCursor -> DV.Vector (DV.Vector BS.ByteString)
toVectorVector = DV.fromList . toListVector
{-# INLINE toVectorVector #-}