[commit: packages/binary] master: Implement `isolate` for reading fixed-size blocks. (4ecce94)

git at git.haskell.org git at git.haskell.org
Sun Dec 14 17:53:58 UTC 2014


Repository : ssh://git@git.haskell.org/binary

On branch  : master
Link       : http://git.haskell.org/packages/binary.git/commitdiff/4ecce94041b3f8e5b7e9e2f1e7d0b57280659916

>---------------------------------------------------------------

commit 4ecce94041b3f8e5b7e9e2f1e7d0b57280659916
Author: Stephen Paul Weber <singpolyma at singpolyma.net>
Date:   Tue Sep 10 18:14:05 2013 -0500

    Implement `isolate` for reading fixed-size blocks.
    
    Closes #32


>---------------------------------------------------------------

4ecce94041b3f8e5b7e9e2f1e7d0b57280659916
 src/Data/Binary/Get.hs          |  1 +
 src/Data/Binary/Get/Internal.hs | 22 ++++++++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/src/Data/Binary/Get.hs b/src/Data/Binary/Get.hs
index 656b712..1487447 100644
--- a/src/Data/Binary/Get.hs
+++ b/src/Data/Binary/Get.hs
@@ -144,6 +144,7 @@ module Data.Binary.Get (
     , skip
     , isEmpty
     , bytesRead
+    , isolate
     , lookAhead
     , lookAheadM
     , lookAheadE
diff --git a/src/Data/Binary/Get/Internal.hs b/src/Data/Binary/Get/Internal.hs
index 7dac47d..91f8ed7 100644
--- a/src/Data/Binary/Get/Internal.hs
+++ b/src/Data/Binary/Get/Internal.hs
@@ -18,6 +18,7 @@ module Data.Binary.Get.Internal (
     -- * Parsing
     , skip
     , bytesRead
+    , isolate
     
     , get
     , put
@@ -179,6 +180,27 @@ prompt inp kf ks =
 bytesRead :: Get Int64
 bytesRead = C $ \inp k -> BytesRead (fromIntegral $ B.length inp) (k inp)
 
+-- | Isolate an action to operating within a fixed block of bytes.
+isolate :: Int      -- ^ The action much consume this many bytes
+           -> Bool  -- ^ Optionally discard bytes that are left unconsumed
+           -> Get a -- ^ The action to isolate
+           -> Get a
+isolate n discard (C go)
+  | n < 0 = fail "isolate: negative n"
+  | otherwise = do
+    ensureN n
+    C (\inp k -> isolate' n discard inp k (go (B.unsafeTake n inp) Done))
+
+isolate' :: Int -> Bool -> B.ByteString -> Success a r -> Decoder a -> Decoder r
+isolate' n discard inp k = go
+  where
+  go (Done left x)
+    | B.null left || discard = k (B.unsafeDrop n inp) x
+    | otherwise = Fail inp "isolate: action read less than block size"
+  go (Partial resume) = go (resume Nothing)
+  go (Fail bs err) = Fail bs err
+  go (BytesRead r resume) = go (resume (fromIntegral n - r))
+
 -- | Demand more input. If none available, fail.
 demandInput :: Get ()
 demandInput = C $ \inp ks ->



More information about the ghc-commits mailing list