packages feed

bits-conduit (empty) → 0.1.0.0

raw patch · 5 files changed

+158/−0 lines, 5 filesdep +HUnitdep +basedep +bits-conduitsetup-changed

Dependencies added: HUnit, base, bits-conduit, bytestring, conduit, hspec, mtl

Files

+ Data/Conduit/Bits.hs view
@@ -0,0 +1,42 @@+{-# LANGUAGE BangPatterns #-}
+
+module Data.Conduit.Bits (
+  -- * Conduits
+  decodeBits,
+  encodeBits,
+  ) where
+
+import Control.Monad
+import Data.Bits
+import qualified Data.ByteString as S
+import Data.Conduit
+import qualified Data.Conduit.Binary as CB
+import Data.Conduit.Internal
+
+-- | Bitstream decoder
+decodeBits :: Monad m => Conduit S.ByteString m Bool
+decodeBits = go where
+  go = do
+    mb <- sinkToPipe CB.head
+    case mb of
+      Nothing ->
+        return ()
+      Just b8 -> do
+        forM_ [0..7] $ \i -> yield $ testBit b8 i
+        go
+
+-- | Bitstream encoder
+encodeBits :: Monad m => Conduit Bool m S.ByteString
+encodeBits = go 0 0 where
+  go !acc 8 = do
+    yield $ S.singleton acc
+    go 0 0
+  go !acc !i = do
+    mb <- await
+    case mb of
+      Nothing ->
+        when (i > 0) $ yield $ S.singleton acc
+      Just b -> do
+        let n | b = acc `setBit` i
+              | otherwise = acc
+        go n (i+1)
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2012, Hideyuki Tanaka
+
+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 Hideyuki Tanaka 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.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple
+main = defaultMain
+ bits-conduit.cabal view
@@ -0,0 +1,38 @@+name:                bits-conduit
+version:             0.1.0.0
+synopsis:            Bitstream support for Conduit
+description:         Bitstream support for Conduit
+license:             BSD3
+license-file:        LICENSE
+author:              Hideyuki Tanaka
+maintainer:          Hideyuki Tanaka <tanaka.hideyuki@gmail.com>
+copyright:           (c) 2012, Hideyuki Tanaka
+category:            Data
+build-type:          Simple
+cabal-version:       >=1.8
+
+source-repository head
+  type:                git
+  location:            https://github.com/tanakh/bits-conduit.git
+
+library
+  exposed-modules:     Data.Conduit.Bits
+
+  build-depends:       base       ==4.5.*
+                     , mtl        >=2.1
+                     , bytestring >=0.9.2
+                     , conduit    >=0.4.2
+
+test-suite bits-conduit-test
+  type:                exitcode-stdio-1.0
+  hs-source-dirs:      dist
+  main-is:             ../test.hs
+
+  build-depends:       base
+                     , mtl
+                     , bytestring
+                     , conduit
+
+                     , hspec
+                     , HUnit
+                     , bits-conduit
+ test.hs view
@@ -0,0 +1,46 @@+{-# LANGUAGE OverloadedStrings, ViewPatterns #-}
+
+import Control.Monad.Identity
+import Data.Bits
+import qualified Data.ByteString as S
+import qualified Data.ByteString.Lazy as L
+import Data.Conduit
+import qualified Data.Conduit.Binary as CB
+import qualified Data.Conduit.List as CL
+import Data.Word
+import Test.Hspec.HUnit ()
+import Test.Hspec.QuickCheck
+import Test.Hspec.Monadic
+import Test.HUnit
+
+import Data.Conduit.Bits
+
+main :: IO ()
+main = hspecX $ do
+  describe "decoder" $ do
+    it "decodes empty sequence" $ do
+      a <- yield S.empty =$= decodeBits $$ CL.consume
+      [] @=? a
+
+    prop "decodes bits" $ \bs ->
+      let a = runIdentity $ yield (S.pack bs) =$= decodeBits $$ CL.consume
+      in decodeNaive bs == a
+
+  describe "encoder" $ do
+    it "encodes empty sequence" $ do
+      a <- CL.sourceNull =$= encodeBits $$ CB.take maxBound
+      L.empty @=? a
+
+    prop "encodes bits" $ \bs ->
+      let a = runIdentity $ CL.sourceList bs =$= encodeBits $$ CB.take maxBound
+      in L.pack (encodeNaive bs) == a
+
+decodeNaive :: [Word8] -> [Bool]
+decodeNaive = concatMap f where
+  f c = map (\i -> testBit c i) [0..7 :: Int]
+
+encodeNaive :: [Bool] -> [Word8]
+encodeNaive [] = []
+encodeNaive (splitAt 8 -> (cur, next)) =
+  let c = foldl (.|.) 0 (zipWith (\i b -> if b then bit i else 0) [0..] cur)
+  in c : encodeNaive next