packages feed

pipes-binary (empty) → 0.1.0.0

raw patch · 8 files changed

+266/−0 lines, 8 filesdep +basedep +binarydep +bytestringsetup-changed

Dependencies added: base, binary, bytestring, pipes, pipes-parse

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2013, Renzo Carbonara++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Renzo Carbonara nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ NEWS view
@@ -0,0 +1,3 @@+# Version 0.1.0.0++* Initial version.
+ PEOPLE view
@@ -0,0 +1,5 @@+The following people have participated in creating this library, either+by directly contributing code or by providing thoughtful input in+discussions about the library design.++Renzo Carbonara
+ README.md view
@@ -0,0 +1,13 @@+# pipes-binary++Utilities to encode and decode binary streams using the **pipes** and+**binary** libraries.++Check the source or rendered Haddocks for extensive documentation.++This code is licensed under the terms of the so called **3-clause BSD+license**. Read the file named ``LICENSE`` found in this same directory+for details.++See the ``PEOPLE`` file to learn about the people involved in this+effort.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ pipes-binary.cabal view
@@ -0,0 +1,36 @@+name:               pipes-binary+version:            0.1.0.0+license:            BSD3+license-file:       LICENSE+copyright:          Copyright (c) Renzo Carbonara 2013+author:             Renzo Carbonara+maintainer:         renzocarbonaraλgmail.com+stability:          Experimental+tested-with:        GHC == 7.4.1+homepage:           https://github.com/k0001/pipes-binary+bug-reports:        https://github.com/k0001/pipes-binary/issues+category:           Pipes+build-type:         Simple+synopsis:           Encode and decode binary streams using the pipes and binary libraries.+cabal-version:      >=1.8+extra-source-files: README.md PEOPLE NEWS+description:+  Encode and decode binary streams using the @Pipes@ and @binary@ libraries.+  .+  See the @NEWS@ file in the source distribution to learn about any+  important changes between version.++source-repository head+    type: git+    location: git://github.com/k0001/pipes-binary.git++library+    hs-source-dirs:    src+    build-depends:     base           (==4.*)+                     , binary         (>=0.7 && <0.8)+                     , bytestring     (>=0.9.2.1)+                     , pipes          (>=3.3 && <3.4)+                     , pipes-parse    (>=1.0 && <1.1)+    exposed-modules:   Control.Proxy.Binary+    other-modules:     Control.Proxy.Binary.Internal+    ghc-options: -Wall -O2
+ src/Control/Proxy/Binary.hs view
@@ -0,0 +1,122 @@+-- | This module exports facilities that allows you to encode and decode+-- streams of 'Bin.Binary' values using the @pipes@ and @pipes-parse@ libraries.++module Control.Proxy.Binary+  ( -- * Decoding+    -- $decoding+    decode+  , decodeD+    -- * Encoding+    -- $encoding+  , encode+  , encodeD+   -- * Types+  , I.DecodingError(..)+  ) where++-------------------------------------------------------------------------------++import qualified Data.ByteString               as BS+import qualified Data.ByteString.Lazy.Internal as BLI+import           Control.Monad                 (unless)+import qualified Control.Proxy                 as P+import qualified Control.Proxy.Binary.Internal as I+import qualified Control.Proxy.Parse           as Pa+import qualified Control.Proxy.Trans.Either    as P+import qualified Control.Proxy.Trans.State     as P+import qualified Data.Binary                   as Bin+import           Data.Foldable                 (mapM_)+import           Data.Function                 (fix)+import           Prelude                       hiding (mapM_)++--------------------------------------------------------------------------------+-- $decoding+--+-- There are two different 'Bin.Binary' decoding facilities exported by this+-- module, and choosing between them is easy: If you need to interleave decoding+-- with other stream effects you must use 'decode', otherwise you may use the+-- simpler 'decodeD'.++-- | Decodes one 'Bin.Binary' instance flowing downstream.+--+-- * In case of decoding errors, a 'I.DecodingError' exception is thrown in the+-- 'Pe.EitherP' proxy transformer.+--+-- * Requests more input from upstream using 'Pa.draw' when needed.+--+-- * /Do not/ use this proxy if 'Control.Proxy.ByteString.isEndOfBytes' returns+-- 'True', otherwise you may get unexpected decoding errors.+decode+  :: (P.Proxy p, Monad m, Bin.Binary r)+  => P.EitherP I.DecodingError (P.StateP [BS.ByteString] p)+     () (Maybe BS.ByteString) y' y m r+decode = do+    (er, mlo) <- P.liftP (I.parseWith Pa.draw Bin.get)+    P.liftP (mapM_ Pa.unDraw mlo)+    either P.throw return er+{-# INLINABLE decode #-}+++-- | Decodes 'Bin.Binary' instances flowing downstream until end of input.+--+-- * In case of decoding errors, a 'I.DecodingError' exception is thrown in the+-- 'Pe.EitherP' proxy transformer.+--+-- * Requests more input from upstream using 'Pa.draw', when needed.+--+-- * Empty input chunks flowing downstream will be discarded.+decodeD+  :: (P.Proxy p, Monad m, Bin.Binary b)+  => ()+  -> P.Pipe (P.EitherP I.DecodingError (P.StateP [BS.ByteString] p))+     (Maybe BS.ByteString) b m ()+decodeD = \() -> loop where+    loop = do+        eof <- P.liftP isEndOfBytes+        unless eof $ decode >>= P.respond >> loop+{-# INLINABLE decodeD #-}++--------------------------------------------------------------------------------+-- $encoding+--+-- There are two different 'Bin.Binary' encoding facilities exported by this+-- module, and choosing between them is easy: If you need to interleave encoding+-- with other stream effects you must use 'encode', otherwise you may use the+-- simpler 'encodeD'.++-- | Encodes the given 'Bin.Binary' instance and sends it downstream in+-- 'BS.ByteString' chunks.+encode+  :: (P.Proxy p, Monad m, Bin.Binary x)+  => x -> p x' x () BS.ByteString m ()+encode = \x -> P.runIdentityP $ do+    BLI.foldrChunks (\e a -> P.respond e >> a) (return ()) (Bin.encode x)+{-# INLINABLE encode #-}+++-- | Encodes 'Bin.Binary' instances flowing downstream, each in possibly more+-- than one 'BS.ByteString' chunk.+encodeD+  :: (P.Proxy p, Monad m, Bin.Binary a)+  => () -> P.Pipe p a BS.ByteString m r+encodeD = P.pull P./>/ encode+{-# INLINABLE encodeD #-}+++--------------------------------------------------------------------------------+-- XXX: this function is here until pipes-bytestring exports it++-- | Like 'Pa.isEndOfInput', except it also consumes and discards leading+-- empty 'BS.ByteString' chunks.+isEndOfBytes+  :: (Monad m, P.Proxy p)+  => P.StateP [BS.ByteString] p () (Maybe BS.ByteString) y' y m Bool+isEndOfBytes = fix $ \loop -> do+    ma <- Pa.draw+    case ma of+      Just a+       | BS.null a -> loop+       | otherwise -> Pa.unDraw a >> return False+      Nothing      -> return True+{-# INLINABLE isEndOfBytes #-}+
+ src/Control/Proxy/Binary/Internal.hs view
@@ -0,0 +1,55 @@+{-# LANGUAGE DeriveDataTypeable #-}++-- | This module provides low-level integration with the @binary@ package and is+-- likely to be modified in backwards-incompatible ways in the future.+--+-- Use the "Control.Proxy.Binary" module instead.++module Control.Proxy.Binary.Internal+  ( DecodingError(..)+  , parseWith+  ) where++-------------------------------------------------------------------------------++import qualified Data.ByteString              as BS+import qualified Data.Binary                  as Bin+import qualified Data.Binary.Get              as Bin+import Control.Exception                      (Exception)+import Data.Data                              (Data, Typeable)++-------------------------------------------------------------------------------++data DecodingError = DecodingError+  { peConsumed :: Bin.ByteOffset -- ^Number of bytes consumed before the error.+  , peMessage  :: String         -- ^Error message.+  } deriving (Show, Eq, Data, Typeable)++instance Exception DecodingError++-------------------------------------------------------------------------------++-- | Run a parser drawing input from the given monadic action as needed.+parseWith+  :: (Monad m, Bin.Binary r)+  => m (Maybe BS.ByteString)+  -- ^An action that will be executed to provide the parser with more input+  -- as needed. If the action returns 'Nothing', then it's assumed no more+  -- input is available.+  -> Bin.Get r+  -- ^Parser to run on the given input.+  -> m (Either DecodingError r, Maybe BS.ByteString)+  -- ^Either a parser error or a parsed result, together with any leftover.+parseWith refill g = step $ Bin.runGetIncremental g+  where+    step (Bin.Partial k)   = step . k =<< refill+    step (Bin.Done lo _ r) = return (Right r, mayInput lo)+    step (Bin.Fail lo n m) = return (Left (DecodingError n m), mayInput lo)+{-# INLINABLE parseWith #-}++-- | Wrap @a@ in 'Just' if not-null. Otherwise, 'Nothing'.+mayInput :: BS.ByteString -> Maybe BS.ByteString+mayInput x | BS.null x = Nothing+           | otherwise = Just x+{-# INLINE mayInput #-}+