[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