packages feed

quiver-bytestring (empty) → 0.0.0.1

raw patch · 4 files changed

+174/−0 lines, 4 filesdep +basedep +bytestringdep +quiversetup-changed

Dependencies added: base, bytestring, quiver

Files

+ LICENSE view
@@ -0,0 +1,28 @@++  Quiver combinators for bytestring streaming+  ===========================================++    Copyright © 2015 Patryk Zadarnowski «pat@jantar.org».+    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. ➂ The name of any+  author may not be used to endorse or promote products derived from this+  software without their specific prior written permission.++  THIS SOFTWARE IS PROVIDED “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 AUTHORS 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.+
+ Setup.hs view
@@ -0,0 +1,3 @@+#! /usr/bin/env runhaskell+import Distribution.Simple+main = defaultMain
+ quiver-bytestring.cabal view
@@ -0,0 +1,43 @@+name:           quiver-bytestring+version:        0.0.0.1+synopsis:       Quiver combinators for bytestring streaming+homepage:       https://github.com/zadarnowski/quiver-bytestring+category:       Control+stability:      alpha++author:         Patryk Zadarnowski+maintainer:     Patryk Zadarnowski <pat@jantar.org>++copyright:      Copyright (c) 2015 Patryk Zadarnowski++description:++    This library provides a set of combinators for efficient+    streaming of bytestring data in the Quiver framework.++cabal-version:  >= 1.18+build-type:     Simple+license:        BSD3+license-file:   LICENSE++source-repository head+  type:         git+  location:     https://github.com/zadarnowski/quiver-bytestring.git++source-repository this+  type:         git+  location:     https://github.com/zadarnowski/quiver-bytestring.git+  tag:          0.0.0.1++library+  hs-source-dirs:   src+  default-language: Haskell2010+  ghc-options:      -Wall -fno-warn-unused-do-bind -fno-warn-missing-signatures++  exposed-modules:+    Control.Quiver.ByteString++  build-depends:+    base                    >= 4.8 && < 5,+    bytestring              >= 0.10.6.0,+    quiver                  >= 0.0.0.6
+ src/Control/Quiver/ByteString.lhs view
@@ -0,0 +1,100 @@+> -- | Module:    Control.Quiver.ByteString+> -- Description: Chunked streams of lazy bytestrings+> -- Copyright:   © 2015 Patryk Zadarnowski <pat@jantar.org>+> -- License:     BSD3+> -- Maintainer:  pat@jantar.org+> -- Stability:   experimental+> -- Portability: portable+> --+> -- When binary data is streamed through a Quiver processor, it's often+> -- partitioned arbitrarily into /packets/ with no semantic significance,+> -- beyond facilitation of processing in constant space. This is similar+> -- to the chunking mechanism within lazy bytestrings, and, accordingly,+> -- it's often convenient to unify the two mechanisms, by converting+> -- between processors over lazy bytestrings and processors over strict+> -- chunks of these bytestrings. This module provides efficient+> -- implementations of these conversions.++> {-# LANGUAGE RankNTypes #-}++> module Control.Quiver.ByteString (+>   toChunks, fromChunks+> ) where++> import Data.ByteString (ByteString)+> import Data.Int+> import Data.Functor+> import Control.Quiver++> import qualified Data.ByteString as ByteString+> import qualified Data.ByteString.Lazy as Lazy++> -- | A processors that converts a stream of lazy bytestrings+> --   into a stream of their chunks.++> toChunks :: Functor f => SP Lazy.ByteString ByteString f [ByteString]+> toChunks = snd <$> (qpure_ Lazy.toChunks >->> qconcat_)++> -- | A processors that converts a stream of strict bytestring chunks+> --   into a stream of lazy bytestrings with the specified minimum+> --   and maximum size, without copying any data.++> fromChunks :: Functor f => Int64 -> Int64 -> SP ByteString Lazy.ByteString f [ByteString]+> fromChunks m n+>   | (m > n || n <= 0) = error ("fromChunks: invalid string size range: [" ++ show m ++ ".." ++ show n ++ "]")+>   | (m <= 0) = fromMaxChunks n+>   | (n >= fromIntegral (maxBound::Int)) = fromMinChunks m+>   | (m == n) = fromExactChunks n+>   | otherwise = loop0+>  where+>   loop0 = loop1 m n []+>   loop1 rm rn cs = consume () (loop2 rm rn cs) (deliver (reverse cs))+>   loop2 rm rn cs c = loop3 rm rn cs c (fromIntegral (ByteString.length c))+>   loop3 rm rn cs c cl+>     | (cl <=  0) = loop1 rm rn cs -- skip empty chunks+>     | (cl <  rm) = loop1 (rm - cl) (rn - cl) (c:cs)+>     | (cl <= rn) = let xs = reverse (c:cs)+>                    in produce (Lazy.fromChunks xs) (const loop0) (deliver xs)+>     | otherwise  = let (c1, c2) = ByteString.splitAt (fromIntegral rn) c+>                    in produce (Lazy.fromChunks (reverse (c1:cs))) (const $ loop3 m n [] c2 (cl - rn)) (deliver (reverse (c:cs)))++> fromMaxChunks :: Functor f => Int64 -> SP ByteString Lazy.ByteString f [ByteString]+> fromMaxChunks n+>   | (n <= 0) = error ("fromChunks: invalid maximum chunk size: " ++ show n)+>   | (n >= fromIntegral (maxBound::Int)) = qpure_ Lazy.fromStrict $> []+>   | otherwise = loop0+>  where+>   loop0 = consume () loop1 (deliver [])+>   loop1 c = loop2 c (fromIntegral (ByteString.length c))+>   loop2 c cl+>     | (cl <= n) = produce (Lazy.fromStrict c) (const loop0) (deliver [c])+>     | otherwise = let (c1, c2) = ByteString.splitAt n' c+>                   in produce (Lazy.fromStrict c1) (const $ loop2 c2 (cl - n)) (deliver [c])+>   n' = fromIntegral n++> fromMinChunks :: Functor f => Int64 -> SP ByteString Lazy.ByteString f [ByteString]+> fromMinChunks n+>   | (n > 0) = loop0 n []+>   | otherwise = qpure_ Lazy.fromStrict $> []+>  where+>   loop0 r cs = consume () (loop1 r cs) (deliver (reverse cs))+>   loop1 r cs c = loop2 r cs c (fromIntegral (ByteString.length c))+>   loop2 r cs c cl+>     | (cl <= 0) = loop0 r cs -- skip empty chunks+>     | (cl <  r) = loop0 (r - cl) (c:cs)+>     | otherwise = let xs = reverse (c:cs) in produce (Lazy.fromChunks xs) (const $ loop0 n []) (deliver xs)++> fromExactChunks :: Int64 -> SP ByteString Lazy.ByteString f [ByteString]+> fromExactChunks n+>   | (n > 0) = loop0 n []+>   | otherwise = error ("Pipes.fromChunks: invalid chunk size: " ++ show n)+>  where+>   loop0 r cs = consume () (loop1 r cs) (deliver (reverse cs))+>   loop1 r cs c = loop2 r cs c (fromIntegral (ByteString.length c))+>   loop2 r cs c cl+>     | (cl <= 0) = loop0 r cs -- skip empty chunks+>     | otherwise = case compare cl r of+>                     LT -> loop0 (r - cl) (c:cs)+>                     EQ -> let xs = reverse (c:cs) in produce (Lazy.fromChunks xs) (const $ loop0 0 []) (deliver xs)+>                     GT -> let (c1, c2) = ByteString.splitAt (fromIntegral r) c+>                           in produce (Lazy.fromChunks (reverse (c1:cs))) (const $ loop2 n [] c2 (cl - r)) (deliver (reverse (c:cs)))