module Data.Text.Internal.Lazy
(
Text(..)
, chunk
, empty
, foldrChunks
, foldlChunks
, strictInvariant
, lazyInvariant
, showStructure
, defaultChunkSize
, smallChunkSize
, chunkOverhead
, equal
) where
import Data.Bits (shiftL)
import Data.Text ()
import Data.Typeable (Typeable)
import Foreign.Storable (sizeOf)
import qualified Data.Text.Array as A
import qualified Data.Text.Internal as T
data Text = Empty
| Chunk !T.Text Text
deriving (Typeable)
strictInvariant :: Text -> Bool
strictInvariant Empty = True
strictInvariant x@(Chunk (T.Text _ _ len) cs)
| len > 0 = strictInvariant cs
| otherwise = error $ "Data.Text.Lazy: invariant violation: "
++ showStructure x
lazyInvariant :: Text -> Text
lazyInvariant Empty = Empty
lazyInvariant x@(Chunk c@(T.Text _ _ len) cs)
| len > 0 = Chunk c (lazyInvariant cs)
| otherwise = error $ "Data.Text.Lazy: invariant violation: "
++ showStructure x
showStructure :: Text -> String
showStructure Empty = "Empty"
showStructure (Chunk t Empty) = "Chunk " ++ show t ++ " Empty"
showStructure (Chunk t ts) =
"Chunk " ++ show t ++ " (" ++ showStructure ts ++ ")"
chunk :: T.Text -> Text -> Text
chunk t@(T.Text _ _ len) ts | len == 0 = ts
| otherwise = Chunk t ts
empty :: Text
empty = Empty
foldrChunks :: (T.Text -> a -> a) -> a -> Text -> a
foldrChunks f z = go
where go Empty = z
go (Chunk c cs) = f c (go cs)
foldlChunks :: (a -> T.Text -> a) -> a -> Text -> a
foldlChunks f z = go z
where go !a Empty = a
go !a (Chunk c cs) = go (f a c) cs
defaultChunkSize :: Int
defaultChunkSize = 16384 chunkOverhead
smallChunkSize :: Int
smallChunkSize = 128 chunkOverhead
chunkOverhead :: Int
chunkOverhead = sizeOf (undefined :: Int) `shiftL` 1
equal :: Text -> Text -> Bool
equal Empty Empty = True
equal Empty _ = False
equal _ Empty = False
equal (Chunk (T.Text arrA offA lenA) as) (Chunk (T.Text arrB offB lenB) bs) =
case compare lenA lenB of
LT -> A.equal arrA offA arrB offB lenA &&
as `equal` Chunk (T.Text arrB (offB + lenA) (lenB lenA)) bs
EQ -> A.equal arrA offA arrB offB lenA &&
as `equal` bs
GT -> A.equal arrA offA arrB offB lenB &&
Chunk (T.Text arrA (offA + lenB) (lenA lenB)) as `equal` bs