uniform-io 1.1.0.0 → 1.1.1.0
raw patch · 3 files changed
+91/−49 lines, 3 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ System.IO.Uniform.Streamline: Finished :: IOScannerState a
+ System.IO.Uniform.Streamline: LastPass :: a -> IOScannerState a
+ System.IO.Uniform.Streamline: Running :: a -> IOScannerState a
+ System.IO.Uniform.Streamline: textScanner :: [Word8] -> (IOScanner [[Word8]])
+ System.IO.Uniform.Streamline.Scanner: Finished :: IOScannerState a
+ System.IO.Uniform.Streamline.Scanner: LastPass :: a -> IOScannerState a
+ System.IO.Uniform.Streamline.Scanner: Running :: a -> IOScannerState a
+ System.IO.Uniform.Streamline.Scanner: anyScanner :: Default a => [IOScanner a] -> IOScanner [a]
+ System.IO.Uniform.Streamline.Scanner: data IOScannerState a
+ System.IO.Uniform.Streamline.Scanner: instance Applicative IOScannerState
+ System.IO.Uniform.Streamline.Scanner: instance Functor IOScannerState
+ System.IO.Uniform.Streamline.Scanner: instance Monad IOScannerState
+ System.IO.Uniform.Streamline.Scanner: textScanner :: [Word8] -> (IOScanner [[Word8]])
+ System.IO.Uniform.Streamline.Scanner: type IOScanner a = a -> Word8 -> IOScannerState a
- System.IO.Uniform.Streamline: runScanner :: MonadIO m => s -> (s -> Word8 -> IOScannerState s) -> Streamline m (ByteString, s)
+ System.IO.Uniform.Streamline: runScanner :: MonadIO m => s -> IOScanner s -> Streamline m (ByteString, s)
- System.IO.Uniform.Streamline: runScanner' :: MonadIO m => s -> (s -> Word8 -> IOScannerState s) -> Streamline m (ByteString, s)
+ System.IO.Uniform.Streamline: runScanner' :: MonadIO m => s -> IOScanner s -> Streamline m (ByteString, s)
- System.IO.Uniform.Streamline: scan :: MonadIO m => s -> (s -> Word8 -> IOScannerState s) -> Streamline m ByteString
+ System.IO.Uniform.Streamline: scan :: MonadIO m => s -> IOScanner s -> Streamline m ByteString
- System.IO.Uniform.Streamline: scan' :: MonadIO m => s -> (s -> Word8 -> IOScannerState s) -> Streamline m ByteString
+ System.IO.Uniform.Streamline: scan' :: MonadIO m => s -> IOScanner s -> Streamline m ByteString
Files
- src/System/IO/Uniform/Streamline.hs +11/−46
- src/System/IO/Uniform/Streamline/Scanner.hs +76/−0
- uniform-io.cabal +4/−3
src/System/IO/Uniform/Streamline.hs view
@@ -5,7 +5,7 @@ -- character tream IO using high performance block IO. module System.IO.Uniform.Streamline ( Streamline,- IOScannerState,+ IOScannerState(..), withClient, withServer, withTarget,@@ -28,12 +28,14 @@ runScanner, runScanner', scan,- scan'+ scan',+ textScanner ) where import qualified System.IO.Uniform as S import qualified System.IO.Uniform.Network as N import System.IO.Uniform (UniformIO, SomeIO(..), TlsSettings)+import System.IO.Uniform.Streamline.Scanner import Control.Monad.Trans.Class import Control.Applicative@@ -144,25 +146,9 @@ mapM (writeF cl) dd return ((), cl) --- | State of an IO scanner.--- Differently from a parser scanner, an IO scanner--- must deal with blocking behavior.-data IOScannerState a =- -- | A scanner returns Finished when the current input is not- -- part of the result, and the scanning must stop before this- -- input.- Finished |- -- | A scanner returns LastPass when the current input is the- -- last one of the result, and the scanning must stop before- -- after this input, without consuming more data.- LastPass a |- -- | A scanner returns Running when the current input is part- -- of the result, and the scanning must continue.- Running a- -- | Equivalent to runScanner', but returns a strict, completely -- evaluated ByteString.-runScanner :: MonadIO m => s -> (s -> Word8 -> IOScannerState s) -> Streamline m (ByteString, s)+runScanner :: MonadIO m => s -> IOScanner s -> Streamline m (ByteString, s) runScanner state scanner = do (rt, st) <- runScanner' state scanner return (LBS.toStrict rt, st)@@ -179,7 +165,7 @@ Returns the scanned ByteString. -} -runScanner' :: MonadIO m => s -> (s -> Word8 -> IOScannerState s) -> Streamline m (LBS.ByteString, s)+runScanner' :: MonadIO m => s -> IOScanner s -> Streamline m (LBS.ByteString, s) runScanner' state scanner = Streamline $ \d -> do (tx, st, d') <- in_scan d state@@ -212,11 +198,11 @@ -- | Equivalent to runScanner, but dischards the final state-scan :: MonadIO m => s -> (s -> Word8 -> IOScannerState s) -> Streamline m ByteString+scan :: MonadIO m => s -> IOScanner s -> Streamline m ByteString scan state scanner = fst <$> runScanner state scanner -- | Equivalent to runScanner', but dischards the final state-scan' :: MonadIO m => s -> (s -> Word8 -> IOScannerState s) -> Streamline m LBS.ByteString+scan' :: MonadIO m => s -> IOScanner s -> Streamline m LBS.ByteString scan' state scanner = fst <$> runScanner' state scanner -- | Recieves data untill the next end of line (\n or \r\n)@@ -383,32 +369,11 @@ r <- A.takeByteString return (l, r) +eofError :: MonadIO m => String -> m a+eofError msg = liftIO . ioError $ mkIOError eofErrorType msg Nothing Nothing+ lineScanner :: Bool -> Word8 -> Maybe Bool lineScanner False c | c == (fromIntegral . C.ord $ '\n') = Just True | otherwise = Just False lineScanner True _ = Nothing--eofError :: MonadIO m => String -> m a-eofError msg = liftIO . ioError $ mkIOError eofErrorType msg Nothing Nothing--textScanner :: [Word8] -> ([[Word8]] -> Word8 -> IOScannerState [[Word8]])-textScanner [] = \_ _ -> Finished-textScanner t@(c:_) = scanner- where- scanner st c'- | c == c' = popStacks c' $ t:st- | otherwise = popStacks c' st- popStacks :: Word8 -> [[Word8]] -> IOScannerState [[Word8]]- popStacks _ [] = Running []- popStacks _ ([]:_) = Finished- popStacks h ((h':hh):ss)- | h == h' && null hh = case popStacks h ss of- Finished -> Finished- LastPass ss' -> LastPass $ ss'- Running ss' -> LastPass $ ss'- | h == h' = case popStacks h ss of- Finished -> Finished- LastPass ss' -> LastPass $ hh:ss'- Running ss' -> Running $ hh:ss'- | otherwise = popStacks h ss
+ src/System/IO/Uniform/Streamline/Scanner.hs view
@@ -0,0 +1,76 @@+module System.IO.Uniform.Streamline.Scanner where++import Control.Applicative+import Data.Default.Class+import Data.Word8 (Word8)++-- | State of an IO scanner.+-- Differently from a parser scanner, an IO scanner+-- must deal with blocking behavior.+data IOScannerState a =+ -- | A scanner returns Finished when the current input is not+ -- part of the result, and the scanning must stop before this+ -- input.+ Finished |+ -- | A scanner returns LastPass when the current input is the+ -- last one of the result, and the scanning must stop before+ -- after this input, without consuming more data.+ LastPass a |+ -- | A scanner returns Running when the current input is part+ -- of the result, and the scanning must continue.+ Running a++instance Functor IOScannerState where+ fmap _ Finished = Finished+ fmap f (LastPass x) = LastPass $ f x+ fmap f (Running x) = Running $ f x+instance Applicative IOScannerState where+ pure a = Running a+ Finished <*> _ = Finished+ _ <*> Finished = Finished+ (LastPass f) <*> (LastPass x) = LastPass $ f x+ (LastPass f) <*> (Running x) = LastPass $ f x+ (Running f) <*> (LastPass x) = LastPass $ f x+ (Running f) <*> (Running x) = Running $ f x+instance Monad IOScannerState where+ return = pure+ Finished >>= _ = Finished+ (LastPass x) >>= f = case f x of+ Finished -> Finished+ LastPass y -> LastPass y+ Running y -> LastPass y+ (Running x) >>= f = f x++type IOScanner a = a -> Word8 -> IOScannerState a++anyScanner :: Default a => [IOScanner a] -> IOScanner [a]+anyScanner scanners = scan+ where+ --scan :: IOScanner [a]+ scan st c = sequence $ apScanner scanners st c+ --apScanner :: [IOScanner a] -> [a] -> Word8 -> [IOScannerState a]+ apScanner [] _ _ = []+ apScanner (s:ss) [] h = s def h : apScanner ss [] h+ apScanner (s:ss) (t:tt) h = s t h : apScanner ss tt h+++textScanner :: [Word8] -> (IOScanner [[Word8]])+textScanner [] = \_ _ -> Finished+textScanner t@(c:_) = scanner+ where+ scanner st c'+ | c == c' = popStacks (t:st) c'+ | otherwise = popStacks st c'+ popStacks :: IOScanner [[Word8]]+ popStacks [] _ = Running []+ popStacks ([]:_) _ = Finished+ popStacks ((h':hh):ss) h+ | h == h' && null hh = case popStacks ss h of+ Finished -> Finished+ LastPass ss' -> LastPass $ ss'+ Running ss' -> LastPass $ ss'+ | h == h' = case popStacks ss h of+ Finished -> Finished+ LastPass ss' -> LastPass $ hh:ss'+ Running ss' -> Running $ hh:ss'+ | otherwise = popStacks ss h
uniform-io.cabal view
@@ -10,7 +10,7 @@ -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 1.1.0.0+version: 1.1.1.0 -- A short (one-line) description of the package. synopsis: Uniform IO over files, network, anything.@@ -70,7 +70,7 @@ source-repository this type: git location: https://sealgram.com/git/haskell/uniform-io- tag: 1.1.0.0+ tag: 1.1.1.0 library -- Modules exported by the library.@@ -80,7 +80,8 @@ System.IO.Uniform.File, System.IO.Uniform.Std, System.IO.Uniform.ByteString,- System.IO.Uniform.Streamline+ System.IO.Uniform.Streamline,+ System.IO.Uniform.Streamline.Scanner ghc-options: -Wall -fno-warn-unused-do-bind -fwarn-incomplete-patterns -fno-warn-orphans