module Text.HTML.Tagchup.Parser.Stream where import Control.Monad.Trans.State (StateT(StateT), gets, put, ) import Control.Monad (guard, mzero, ) import qualified Data.List.HT as L import qualified Data.ByteString.Char8 as BS import qualified Data.ByteString.Lazy.Char8 as BL import qualified Prelude as P import Prelude hiding (Char, getChar, ) class C stream where getChar :: StateT stream Maybe P.Char class Char char where toChar :: char -> P.Char instance Char P.Char where toChar :: Char -> Char toChar = forall a. a -> a id instance Char char => C [char] where getChar :: StateT [char] Maybe Char getChar = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap forall char. Char char => char -> Char toChar forall a b. (a -> b) -> a -> b $ forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a StateT forall a. [a] -> Maybe (a, [a]) L.viewL instance C BS.ByteString where getChar :: StateT ByteString Maybe Char getChar = forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a StateT ByteString -> Maybe (Char, ByteString) BS.uncons instance C BL.ByteString where getChar :: StateT ByteString Maybe Char getChar = forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a StateT ByteString -> Maybe (Char, ByteString) BL.uncons data PointerStrict = PointerStrict {PointerStrict -> ByteString psSource :: !BS.ByteString, PointerStrict -> Int psIndex :: !Int} pointerFromByteStringStrict :: BS.ByteString -> PointerStrict pointerFromByteStringStrict :: ByteString -> PointerStrict pointerFromByteStringStrict ByteString str = ByteString -> Int -> PointerStrict PointerStrict ByteString str Int 0 instance C PointerStrict where getChar :: StateT PointerStrict Maybe Char getChar = do ByteString s <- forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a gets PointerStrict -> ByteString psSource Int i <- forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a gets PointerStrict -> Int psIndex forall (f :: * -> *). Alternative f => Bool -> f () guard (Int i forall a. Ord a => a -> a -> Bool < ByteString -> Int BS.length ByteString s) forall (m :: * -> *) s. Monad m => s -> StateT s m () put forall a b. (a -> b) -> a -> b $ ByteString -> Int -> PointerStrict PointerStrict ByteString s (Int iforall a. Num a => a -> a -> a +Int 1) forall (m :: * -> *) a. Monad m => a -> m a return (ByteString -> Int -> Char BS.index ByteString s Int i) data PointerLazy = PointerLazy {PointerLazy -> [ByteString] plSource :: ![BS.ByteString], PointerLazy -> Int plIndex :: !Int} pointerFromByteStringLazy :: BL.ByteString -> PointerLazy pointerFromByteStringLazy :: ByteString -> PointerLazy pointerFromByteStringLazy ByteString str = [ByteString] -> Int -> PointerLazy PointerLazy (ByteString -> [ByteString] BL.toChunks ByteString str) Int 0 instance C PointerLazy where getChar :: StateT PointerLazy Maybe Char getChar = do [ByteString] s <- forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a gets PointerLazy -> [ByteString] plSource Int i <- forall (m :: * -> *) s a. Monad m => (s -> a) -> StateT s m a gets PointerLazy -> Int plIndex case [ByteString] s of [] -> forall (m :: * -> *) a. MonadPlus m => m a mzero (ByteString c:[ByteString] cs) -> if Int i forall a. Ord a => a -> a -> Bool < ByteString -> Int BS.length ByteString c then forall (m :: * -> *) s. Monad m => s -> StateT s m () put ([ByteString] -> Int -> PointerLazy PointerLazy [ByteString] s (Int iforall a. Num a => a -> a -> a +Int 1)) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> forall (m :: * -> *) a. Monad m => a -> m a return (ByteString -> Int -> Char BS.index ByteString c Int i) else forall (m :: * -> *) s. Monad m => s -> StateT s m () put ([ByteString] -> Int -> PointerLazy PointerLazy [ByteString] cs (Int i forall a. Num a => a -> a -> a - ByteString -> Int BS.length ByteString c)) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b >> forall stream. C stream => StateT stream Maybe Char getChar