packages feed

io-streams 1.2.0.0 → 1.2.0.1

raw patch · 6 files changed

+55/−18 lines, 6 files

Files

changelog.md view
@@ -1,3 +1,12 @@+# Version 1.2.0.1++  - `System.IO.Streams.Attoparsec.parseFromStream`: export more information+    about the context of parse errors to the message returned via+    `ParseException`.++  - Improved documentation about stream flushing in the docstring for+    `handleToOutputStream`.+ # Version 1.2.0.0   - Fixed bug #27 (https://github.com/snapframework/io-streams/issues/27):     makeOutputStream now properly shuts down the stream upon receiving EOF. The
io-streams.cabal view
@@ -1,5 +1,5 @@ Name:                io-streams-Version:             1.2.0.0+Version:             1.2.0.1 License:             BSD3 License-file:        LICENSE Category:            Data, Network, IO-Streams
src/System/IO/Streams/Builder.hs view
@@ -10,7 +10,7 @@ -- -- (/N.B./: most of the @blaze-builder@ package has been moved into -- @bytestring@ in versions \>= 0.10; once two or three Haskell Platform--- editions have been released that contain @bytestring@ 0.10 or higher, the+-- editions have been released that contain @bytestring@ 0.10.2 or higher, the -- dependency on @blaze-builder@ will be dropped in favor of the native support -- for 'Builder' contained in the @bytestring@ package.) --@@ -43,8 +43,8 @@ -- As a convention, 'builderStream' will write the empty string to the wrapped -- 'OutputStream' upon a builder buffer flush. Output streams which receive -- 'ByteString' should either ignore the empty string or interpret it as a--- signal to flush their own buffers, as the "System.IO.Streams.Zlib" functions--- do.+-- signal to flush their own buffers, as the @handleToOutputStream@ and+-- "System.IO.Streams.Zlib" functions do. -- -- /Example/ --
src/System/IO/Streams/Handle.hs view
@@ -56,6 +56,11 @@ -- Note that the wrapped handle is /not/ closed when it receives end-of-stream; -- you can use 'System.IO.Streams.Combinators.atEndOfOutput' to close the -- handle if you would like this behaviour.+--+-- /Note/: to force the 'Handle' to be flushed, you can write a null string to+-- the returned 'OutputStream':+--+-- > Streams.write (Just "") os handleToOutputStream :: Handle -> IO (OutputStream ByteString) handleToOutputStream h = makeOutputStream f   where@@ -87,11 +92,12 @@ -- that the 'Handle' will be opened in non-buffering mode; if you buffer the -- 'OutputStream' using the 'Handle' buffering then @io-streams@ will copy the -- 'Handle' buffer when sending 'ByteString' values to the output, which might--- not be what you want. When the output buffer, if used, is flushed, an empty--- string is written to the output, as is conventional throughout the--- @io-streams@ library for 'ByteString' output buffers.+-- not be what you want. ----- Note: the 'OutputStream' passed into this function is wrapped in+-- When the output buffer, if used, is flushed (using 'System.IO.hFlush'), an+-- empty string is written to the provided 'OutputStream'.+--+-- /Note/: the 'OutputStream' passed into this function is wrapped in -- 'lockingOutputStream' to make it thread-safe. -- -- /Since: 1.0.2.0./
src/System/IO/Streams/Internal/Attoparsec.hs view
@@ -1,24 +1,30 @@ -- | This module provides support for parsing values from 'InputStream's using -- @attoparsec@. +{-# LANGUAGE BangPatterns       #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE OverloadedStrings  #-}  module System.IO.Streams.Internal.Attoparsec   ( -- * Parsing-    ParseException(..)-  , parseFromStream+    parseFromStream   , parseFromStreamInternal   , parserToInputStream++    -- * Parse Exceptions+  , ParseException(..)++  , eitherResult   ) where  ------------------------------------------------------------------------------ import           Control.Exception                (Exception, throwIO) import           Control.Monad                    (when)-import           Data.Attoparsec.ByteString.Char8 (Parser, Result, eitherResult, feed, parse)+import           Data.Attoparsec.ByteString.Char8 (Parser, Result, feed, parse) import           Data.Attoparsec.Types            (IResult (..)) import           Data.ByteString.Char8            (ByteString) import qualified Data.ByteString.Char8            as S+import           Data.List                        (intercalate) import           Data.Typeable                    (Typeable) import           Prelude                          hiding (read) ------------------------------------------------------------------------------@@ -36,14 +42,16 @@  instance Exception ParseException + ------------------------------------------------------------------------------ -- | Supplies an @attoparsec@ 'Parser' with an 'InputStream', returning the--- final parsed value or a 'ParseException' if parsing fails.+-- final parsed value or throwing a 'ParseException' if parsing fails. -- -- 'parseFromStream' consumes only as much input as necessary to satisfy the--- 'Parser' and unconsumed input is pushed back onto the 'InputStream'.+-- 'Parser': any unconsumed input is pushed back onto the 'InputStream'. ----- If the 'Parser' exhausts the 'InputStream', it receives an @EOF@.+-- If the 'Parser' exhausts the 'InputStream', the end-of-stream signal is sent+-- to attoparsec. -- -- Example: --@@ -85,8 +93,12 @@                     Partial _  -> err k'                -- should be impossible                     Done x r   -> leftover x >> return r -    err r = let (Left s) = eitherResult r in throwIO $ ParseException s+    err r = let (Left (!_,c,m)) = eitherResult r+            in throwIO $ ParseException (ctxMsg c ++ m) +    ctxMsg [] = ""+    ctxMsg xs = "[parsing " ++ intercalate "/" xs ++ "] "+     go r@(Fail x _ _) = leftover x >> err r     go (Done x r)     = leftover x >> return r     go r              = Streams.read is >>=@@ -128,3 +140,12 @@                     -> IO (InputStream r) parserToInputStream = (Streams.makeInputStream .) . parseFromStream {-# INLINE parserToInputStream #-}+++------------------------------------------------------------------------------+-- A replacement for attoparsec's 'eitherResult', which discards information+-- about the context of the failed parse.+eitherResult :: Result r -> Either (ByteString, [String], String) r+eitherResult (Done _ r)              = Right r+eitherResult (Fail residual ctx msg) = Left (residual, ctx, msg)+eitherResult _                       = Left ("", [], "Result: incomplete input")
test/System/IO/Streams/Tests/Attoparsec.hs view
@@ -4,7 +4,7 @@  ------------------------------------------------------------------------------ import           Control.Monad-import           Data.Attoparsec.ByteString.Char8+import           Data.Attoparsec.ByteString.Char8      hiding (eitherResult) import           Data.ByteString.Char8                 (ByteString) import           Prelude                               hiding (takeWhile) import           System.IO.Streams@@ -78,7 +78,7 @@     expectExceptionH $ fromList ["xxxxx"] >>= p    where-    p = parserToInputStream testParser2 >=> toList+    p = parserToInputStream ((testParser2 <?> "foo") <?> "bar") >=> toList   ------------------------------------------------------------------------------@@ -96,7 +96,8 @@ testTrivials :: Test testTrivials = testCase "attoparsec/trivials" $ do     coverTypeableInstance (undefined :: ParseException)-+    let (Right x) = eitherResult $ Done undefined (4 :: Int)+    assertEqual "eitherResult" 4 x  ------------------------------------------------------------------------------ testEmbeddedNull :: Test