{-# LANGUAGE ExplicitForAll   #-}
{-# LANGUAGE FlexibleContexts #-}

module HaskellWorks.Data.Dsv.Lazy.Cursor.Internal
  ( nextField
  , nextPosition
  , atEnd
  , nextRow
  , trim
  , advanceField
  ) where

import HaskellWorks.Data.Dsv.Lazy.Cursor.Type
import HaskellWorks.Data.Positioning
import HaskellWorks.Data.RankSelect.Base.Rank1
import HaskellWorks.Data.RankSelect.Base.Select1
import Prelude

import qualified Data.ByteString.Lazy as LBS

advanceField :: Count -> DsvCursor -> DsvCursor
advanceField :: Count -> DsvCursor -> DsvCursor
advanceField Count
n DsvCursor
cursor = DsvCursor
cursor
  { dsvCursorPosition :: Count
dsvCursorPosition = Count
newPos
  }
  where currentRank :: Count
currentRank = [Vector Count] -> Count -> Count
forall v. Rank1 v => v -> Count -> Count
rank1   (DsvCursor -> [Vector Count]
dsvCursorMarkers DsvCursor
cursor) (DsvCursor -> Count
dsvCursorPosition DsvCursor
cursor)
        newPos :: Count
newPos      = [Vector Count] -> Count -> Count
forall v. Select1 v => v -> Count -> Count
select1 (DsvCursor -> [Vector Count]
dsvCursorMarkers DsvCursor
cursor) (Count
currentRank Count -> Count -> Count
forall a. Num a => a -> a -> a
+ Count
n) Count -> Count -> Count
forall a. Num a => a -> a -> a
- Count
1
{-# INLINE advanceField #-}

nextField :: DsvCursor -> DsvCursor
nextField :: DsvCursor -> DsvCursor
nextField DsvCursor
cursor = DsvCursor
cursor
  { dsvCursorPosition :: Count
dsvCursorPosition = Count
newPos
  }
  where currentRank :: Count
currentRank = [Vector Count] -> Count -> Count
forall v. Rank1 v => v -> Count -> Count
rank1   (DsvCursor -> [Vector Count]
dsvCursorMarkers DsvCursor
cursor) (DsvCursor -> Count
dsvCursorPosition DsvCursor
cursor)
        newPos :: Count
newPos      = [Vector Count] -> Count -> Count
forall v. Select1 v => v -> Count -> Count
select1 (DsvCursor -> [Vector Count]
dsvCursorMarkers DsvCursor
cursor) (Count
currentRank Count -> Count -> Count
forall a. Num a => a -> a -> a
+ Count
1) Count -> Count -> Count
forall a. Num a => a -> a -> a
- Count
1
{-# INLINE nextField #-}

nextPosition :: DsvCursor -> DsvCursor
nextPosition :: DsvCursor -> DsvCursor
nextPosition DsvCursor
cursor = DsvCursor
cursor
    { dsvCursorPosition :: Count
dsvCursorPosition = if ByteString -> Bool
LBS.null (Int64 -> ByteString -> ByteString
LBS.drop (Count -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Count
newPos) (DsvCursor -> ByteString
dsvCursorText DsvCursor
cursor))
                            then Int64 -> Count
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int64
LBS.length (DsvCursor -> ByteString
dsvCursorText DsvCursor
cursor))
                            else Count
newPos
    }
  where newPos :: Count
newPos  = DsvCursor -> Count
dsvCursorPosition DsvCursor
cursor Count -> Count -> Count
forall a. Num a => a -> a -> a
+ Count
1
{-# INLINE nextPosition #-}

atEnd :: DsvCursor -> Bool
atEnd :: DsvCursor -> Bool
atEnd DsvCursor
c = ByteString -> Bool
LBS.null (Int64 -> ByteString -> ByteString
LBS.drop (Count -> Int64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (DsvCursor -> Count
dsvCursorPosition DsvCursor
c)) (DsvCursor -> ByteString
dsvCursorText DsvCursor
c))
{-# INLINE atEnd #-}

nextRow :: DsvCursor -> DsvCursor
nextRow :: DsvCursor -> DsvCursor
nextRow DsvCursor
cursor = DsvCursor
cursor
  { dsvCursorPosition :: Count
dsvCursorPosition = if Count
newPos Count -> Count -> Bool
forall a. Ord a => a -> a -> Bool
> DsvCursor -> Count
dsvCursorPosition DsvCursor
cursor
                          then Count
newPos
                          else Int64 -> Count
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int64
LBS.length (DsvCursor -> ByteString
dsvCursorText DsvCursor
cursor))

  }
  where currentRank :: Count
currentRank = [Vector Count] -> Count -> Count
forall v. Rank1 v => v -> Count -> Count
rank1   (DsvCursor -> [Vector Count]
dsvCursorNewlines DsvCursor
cursor) (DsvCursor -> Count
dsvCursorPosition DsvCursor
cursor)
        newPos :: Count
newPos      = [Vector Count] -> Count -> Count
forall v. Select1 v => v -> Count -> Count
select1 (DsvCursor -> [Vector Count]
dsvCursorNewlines DsvCursor
cursor) (Count
currentRank Count -> Count -> Count
forall a. Num a => a -> a -> a
+ Count
1) Count -> Count -> Count
forall a. Num a => a -> a -> a
- Count
1
{-# INLINE nextRow #-}

trim :: DsvCursor -> DsvCursor
trim :: DsvCursor -> DsvCursor
trim DsvCursor
c = if DsvCursor -> Count
dsvCursorPosition DsvCursor
c Count -> Count -> Bool
forall a. Ord a => a -> a -> Bool
>= Count
512
  then DsvCursor -> DsvCursor
trim DsvCursor
c
    { dsvCursorText :: ByteString
dsvCursorText     = Int64 -> ByteString -> ByteString
LBS.drop Int64
512 (DsvCursor -> ByteString
dsvCursorText DsvCursor
c)
    , dsvCursorMarkers :: [Vector Count]
dsvCursorMarkers  = Int -> [Vector Count] -> [Vector Count]
forall a. Int -> [a] -> [a]
drop Int
1 (DsvCursor -> [Vector Count]
dsvCursorMarkers DsvCursor
c)
    , dsvCursorNewlines :: [Vector Count]
dsvCursorNewlines = Int -> [Vector Count] -> [Vector Count]
forall a. Int -> [a] -> [a]
drop Int
1 (DsvCursor -> [Vector Count]
dsvCursorNewlines DsvCursor
c)
    , dsvCursorPosition :: Count
dsvCursorPosition = DsvCursor -> Count
dsvCursorPosition DsvCursor
c Count -> Count -> Count
forall a. Num a => a -> a -> a
- Count
512
    }
  else DsvCursor
c
{-# INLINE trim #-}