packages feed

bytesmith 0.3.7.0 → 0.3.8.0

raw patch · 10 files changed

+238/−116 lines, 10 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Data.Bytes.Parser.Latin: peek :: Parser e s (Maybe Char)
+ Data.Bytes.Parser.Latin: peek' :: e -> Parser e s Char
+ Data.Bytes.Parser.Rebindable: instance Data.Bytes.Parser.Rebindable.Bind 'GHC.Types.WordRep 'GHC.Types.LiftedRep
+ Data.Bytes.Parser.Unsafe: uneffectful :: (Bytes -> Result e a) -> Parser e s a

Files

CHANGELOG.md view
@@ -1,5 +1,13 @@ # Revision history for bytesmith +## 0.3.8.0 -- 2021-10-11++* Add `peek` and `peek'` to `Data.Bytes.Parser.Latin`.+* Add inline pragmas to most functions to prevent cost centers.+* Add support for WordRep-to-LiftedRep in Rebindable module.+* Allow building with newer Contiguous.+* Export `uneffectful`.+ ## 0.3.7.0 -- 2020-07-27  * Add `Data.Bytes.Parser.Base128` module for Base-128 encoding.
bytesmith.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: bytesmith-version: 0.3.7.0+version: 0.3.8.0 synopsis: Nonresumable byte parser description:   Parse bytes as fast as possible. This is a nonresumable parser@@ -35,7 +35,7 @@     , base >=4.12 && <5     , bytestring >=0.10.8 && <0.11     , byteslice >=0.1.4 && <0.3-    , contiguous >= 0.4 && < 0.6+    , contiguous >= 0.4 && < 0.7     , primitive >=0.7 && <0.8     , text-short >=0.1.3 && <0.2     , run-st >=0.1 && <0.2
src/Data/Bytes/Parser.hs view
@@ -100,7 +100,7 @@  import Prelude hiding (length,any,fail,takeWhile,take,replicate) -import Data.Bytes.Parser.Internal (InternalResult(..),Parser(..),ST#,unboxBytes)+import Data.Bytes.Parser.Internal (Parser(..),ST#,unboxBytes) import Data.Bytes.Parser.Internal (boxBytes,Result#,uneffectful,fail) import Data.Bytes.Parser.Internal (uneffectful#,uneffectfulInt#) import Data.Bytes.Parser.Types (Result(Failure,Success),Slice(Slice))@@ -114,6 +114,7 @@ import Data.Primitive.Contiguous (Contiguous,Element)  import qualified Data.Bytes as B+import qualified Data.Bytes.Parser.Internal as Internal import qualified Data.Primitive as PM import qualified Data.Primitive.Contiguous as C import qualified GHC.Exts as Exts@@ -121,6 +122,7 @@ -- | Parse a byte sequence. This can succeed even if the -- entire slice was not consumed by the parser. parseBytes :: forall e a. (forall s. Parser e s a) -> Bytes -> Result e a+{-# inline parseBytes #-} parseBytes p !b = runResultST action   where   action :: forall s. ST# s (Result# e a)@@ -131,6 +133,7 @@ -- Just like 'parseBytesEither', this does not impose any checks on the length -- of the remaining input. parseBytesMaybe :: forall e a. (forall s. Parser e s a) -> Bytes -> Maybe a+{-# inline parseBytesMaybe #-} parseBytesMaybe p !b = runMaybeST action   where   action :: forall s. ST# s (Result# e a)@@ -141,6 +144,7 @@ -- remaining length. This does not, however, require the remaining -- length to be zero. Use 'endOfInput' to accomplish that. parseBytesEither :: forall e a. (forall s. Parser e s a) -> Bytes -> Either e a+{-# inline parseBytesEither #-} parseBytesEither p !b = runEitherST action   where   action :: forall s. ST# s (Result# e a)@@ -149,12 +153,14 @@  -- Similar to runResultST runMaybeST :: (forall s. ST# s (Result# e x)) -> Maybe x+{-# inline runMaybeST #-} runMaybeST f = case (runRW# (\s0 -> case f s0 of { (# _, r #) -> r })) of   (# _ | #) -> Nothing   (# | (# x, _, _ #) #) -> Just x  -- Similar to runResultST runEitherST :: (forall s. ST# s (Result# e x)) -> Either e x+{-# inline runEitherST #-} runEitherST f = case (runRW# (\s0 -> case f s0 of { (# _, r #) -> r })) of   (# e | #) -> Left e   (# | (# x, _, _ #) #) -> Right x@@ -165,18 +171,21 @@ -- it avoids the additional boxing that the Success data -- constructor would normally cause. runResultST :: (forall s. ST# s (Result# e x)) -> Result e x+{-# inline runResultST #-} runResultST f = case (runRW# (\s0 -> case f s0 of { (# _, r #) -> r })) of   (# e | #) -> Failure e   (# | (# x, off, len #) #) -> Success (Slice (I# off) (I# len) x)  -- | Variant of 'parseBytes' that accepts an unsliced 'ByteArray'. parseByteArray :: (forall s. Parser e s a) -> ByteArray -> Result e a+{-# inline parseByteArray #-} parseByteArray p b =   parseBytes p (Bytes b 0 (PM.sizeofByteArray b))  -- | Variant of 'parseBytes' that allows the parser to be run -- as part of an existing effectful context. parseBytesEffectfully :: Parser e s a -> Bytes -> ST s (Result e a)+{-# inline parseBytesEffectfully #-} parseBytesEffectfully (Parser f) !b = ST   (\s0 -> case f (unboxBytes b) s0 of     (# s1, r #) -> (# s1, boxPublicResult r #)@@ -184,12 +193,14 @@  -- | Lift an effectful computation into a parser. effect :: ST s a -> Parser e s a+{-# inline effect #-} effect (ST f) = Parser   ( \(# _, off, len #) s0 -> case f s0 of     (# s1, a #) -> (# s1, (# | (# a, off, len #) #) #)   )  byteArray :: e -> ByteArray -> Parser e s ()+{-# inline byteArray #-} byteArray e !expected = bytes e (B.fromByteArray expected)  -- | Consume input matching the byte sequence.@@ -235,8 +246,8 @@ any e = uneffectful $ \chunk -> if length chunk > 0   then     let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8-     in InternalSuccess w (offset chunk + 1) (length chunk - 1)-  else InternalFailure e+     in Internal.Success w (offset chunk + 1) (length chunk - 1)+  else Internal.Failure e  -- | Match any byte, to perform lookahead. Returns 'Nothing' if --   end of input has been reached. Does not consume any input.@@ -246,18 +257,20 @@ --   because such parsers loop until a failure occurs. Careless --   use will thus result in an infinite loop. peek :: Parser e s (Maybe Word8)+{-# inline peek #-} peek = uneffectful $ \chunk ->   let v = if length chunk > 0         then Just (B.unsafeIndex chunk 0)         else Nothing-  in InternalSuccess v (offset chunk) (length chunk)+  in Internal.Success v (offset chunk) (length chunk)  -- | Match any byte, to perform lookahead. Does not consume any --   input, but will fail if end of input has been reached. peek' :: e -> Parser e s Word8+{-# inline peek' #-} peek' e = uneffectful $ \chunk -> if length chunk > 0-  then InternalSuccess (B.unsafeIndex chunk 0) (offset chunk) (length chunk)-  else InternalFailure e+  then Internal.Success (B.unsafeIndex chunk 0) (offset chunk) (length chunk)+  else Internal.Failure e  -- | A stateful scanner. The predicate consumes and transforms a --   state argument, and each transformed state is passed to@@ -271,6 +284,7 @@ --   combinators such a 'many', because such parsers loop until a --   failure occurs. Careless use will thus result in an infinite loop. scan :: state -> (state -> Word8 -> Maybe state) -> Parser e s state+{-# inline scan #-} scan s0 t = do   let go s = do         mw <- peek@@ -288,13 +302,14 @@ {-# inline anyUnsafe #-} anyUnsafe = uneffectful $ \chunk ->   let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8-   in InternalSuccess w (offset chunk + 1) (length chunk - 1)+   in Internal.Success w (offset chunk + 1) (length chunk - 1) --- | Take while the predicate is matched. This is always inlined.+-- | Take while the predicate is matched. This is always inlined. This+-- always succeeds. takeWhile :: (Word8 -> Bool) -> Parser e s Bytes {-# inline takeWhile #-} takeWhile f = uneffectful $ \chunk -> case B.takeWhile f chunk of-  bs -> InternalSuccess bs (offset chunk + length bs) (length chunk - length bs)+  bs -> Internal.Success bs (offset chunk + length bs) (length chunk - length bs)  -- | Take bytes until the specified byte is encountered. Consumes -- the matched byte as well. Fails if the byte is not present.@@ -315,6 +330,7 @@ -- | Skip all characters until the character from the is encountered -- and then consume the matching byte as well. skipTrailedBy :: e -> Word8 -> Parser e s ()+{-# inline skipTrailedBy #-} skipTrailedBy e !w = uneffectful# (\c -> skipUntilConsumeByteLoop e w c)  skipUntilConsumeByteLoop ::@@ -337,6 +353,7 @@   -> Word8 -- ^ First trailer, @False@ indicates that this was encountered   -> Word8 -- ^ Second trailer, @True@ indicates that this was encountered   -> Parser e s Bool+{-# inline skipTrailedBy2 #-} skipTrailedBy2 e !wa !wb = boxBool (skipTrailedBy2# e wa wb)  skipTrailedBy2# ::@@ -344,6 +361,7 @@   -> Word8 -- ^ First trailer, 0 indicates that this was encountered   -> Word8 -- ^ Second trailer, 1 indicates that this was encountered   -> Parser e s Int#+{-# inline skipTrailedBy2# #-} skipTrailedBy2# e !wa !wb =   uneffectfulInt# (\c -> skipUntilConsumeByteEitherLoop e wa wb c) @@ -353,6 +371,7 @@   -> Word8 -- ^ Second trailer, 1 indicates that this was encountered   -> Word8 -- ^ Third trailer, 2 indicates that this was encountered   -> Parser e s Int#+{-# inline skipTrailedBy3# #-} skipTrailedBy3# e !wa !wb !wc =   uneffectfulInt# (\c -> skipUntilConsumeByte3Loop e wa wb wc c) @@ -390,20 +409,20 @@ {-# inline take #-} take e n = uneffectful $ \chunk -> if n <= B.length chunk   then case B.unsafeTake n chunk of-    bs -> InternalSuccess bs (offset chunk + n) (length chunk - n)-  else InternalFailure e+    bs -> Internal.Success bs (offset chunk + n) (length chunk - n)+  else Internal.Failure e  -- | Consume all remaining bytes in the input. remaining :: Parser e s Bytes {-# inline remaining #-} remaining = uneffectful $ \chunk ->-  InternalSuccess chunk (offset chunk + length chunk) 0+  Internal.Success chunk (offset chunk + length chunk) 0  -- | Return all remaining bytes in the input without consuming them. peekRemaining :: Parser e s Bytes {-# inline peekRemaining #-} peekRemaining = uneffectful $ \b@(Bytes _ off len) ->-  InternalSuccess b off len+  Internal.Success b off len  -- | Skip while the predicate is matched. This is always inlined. skipWhile :: (Word8 -> Bool) -> Parser e s ()@@ -428,35 +447,38 @@ --   if the predicate @p@ returns 'True' on the transformed value. --   The parser returns the transformed byte that was parsed. satisfyWith :: e -> (Word8 -> a) -> (a -> Bool) -> Parser e s a+{-# inline satisfyWith #-} satisfyWith e f p = uneffectful $ \chunk -> if length chunk > 1   then case B.unsafeIndex chunk 1 of     w ->       let v = f w       in if p v-        then InternalSuccess v (offset chunk + 1) (length chunk - 1)-        else InternalFailure e-  else InternalFailure e+        then Internal.Success v (offset chunk + 1) (length chunk - 1)+        else Internal.Failure e+  else Internal.Failure e  -- | Fails if there is still more input remaining. endOfInput :: e -> Parser e s ()--- GHC should decide to inline this after optimization.+{-# inline endOfInput #-} endOfInput e = uneffectful $ \chunk -> if length chunk == 0-  then InternalSuccess () (offset chunk) 0-  else InternalFailure e+  then Internal.Success () (offset chunk) 0+  else Internal.Failure e  -- | Returns true if there are no more bytes in the input. Returns -- false otherwise. Always succeeds. isEndOfInput :: Parser e s Bool--- GHC should decide to inline this after optimization.+{-# inline isEndOfInput #-} isEndOfInput = uneffectful $ \chunk ->-  InternalSuccess (length chunk == 0) (offset chunk) (length chunk)+  Internal.Success (length chunk == 0) (offset chunk) (length chunk)  boxPublicResult :: Result# e a -> Result e a+{-# inline boxPublicResult #-} boxPublicResult (# | (# a, b, c #) #) = Success (Slice (I# b) (I# c) a) boxPublicResult (# e | #) = Failure e  -- | Convert a 'Word32' parser to a 'Word#' parser. unboxWord32 :: Parser e s Word32 -> Parser e s Word#+{-# inline unboxWord32 #-} unboxWord32 (Parser f) = Parser   (\x s0 -> case f x s0 of     (# s1, r #) -> case r of@@ -466,6 +488,7 @@  -- | Convert a @(Int,Int)@ parser to a @(# Int#, Int# #)@ parser. unboxIntPair :: Parser e s (Int,Int) -> Parser e s (# Int#, Int# #)+{-# inline unboxIntPair #-} unboxIntPair (Parser f) = Parser   (\x s0 -> case f x s0 of     (# s1, r #) -> case r of@@ -476,6 +499,7 @@ -- | Convert a 'Word#' parser to a 'Word32' parser. Precondition: -- the argument parser only returns words less than 4294967296. boxWord32 :: Parser e s Word# -> Parser e s Word32+{-# inline boxWord32 #-} boxWord32 (Parser f) = Parser   (\x s0 -> case f x s0 of     (# s1, r #) -> case r of@@ -505,6 +529,7 @@  -- | Convert a @(# Int#, Int# #)@ parser to a @(Int,Int)@ parser. boxIntPair :: Parser e s (# Int#, Int# #) -> Parser e s (Int,Int)+{-# inline boxIntPair #-} boxIntPair (Parser f) = Parser   (\x s0 -> case f x s0 of     (# s1, r #) -> case r of@@ -664,6 +689,7 @@   -> Int -- ^ Exact number of bytes delimited parser is expected to consume   -> Parser e s a -- ^ Parser to execute in delimited context   -> Parser e s a+{-# inline delimit #-} delimit esz eleftovers (I# n) (Parser f) = Parser   ( \(# arr, off, len #) s0 -> case len >=# n of     1# -> case f (# arr, off, n #) s0 of@@ -696,4 +722,5 @@   go 0  unI :: Int -> Int#+{-# inline unI #-} unI (I# w) = w
src/Data/Bytes/Parser/Ascii.hs view
@@ -57,7 +57,7 @@ import Data.Bits (clearBit) import Data.Bytes.Types (Bytes(..)) import Data.Bytes.Parser.Internal (Parser(..),uneffectful,Result#,uneffectful#)-import Data.Bytes.Parser.Internal (InternalResult(..),indexLatinCharArray,upcastUnitSuccess)+import Data.Bytes.Parser.Internal (Result(..),indexLatinCharArray,upcastUnitSuccess) import Data.Char (ord) import Data.Word (Word8) import Data.Text.Short (ShortText)@@ -79,11 +79,12 @@ -- Precondition: The argument must be a letter (@[a-zA-Z]@). Behavior is -- undefined if it is not. charInsensitive :: e -> Char -> Parser e s ()+{-# inline charInsensitive #-} charInsensitive e !c = uneffectful $ \chunk -> if length chunk > 0   then if clearBit (PM.indexByteArray (array chunk) (offset chunk) :: Word8) 5 == w-    then InternalSuccess () (offset chunk + 1) (length chunk - 1)-    else InternalFailure e-  else InternalFailure e+    then Success () (offset chunk + 1) (length chunk - 1)+    else Failure e+  else Failure e   where   w = clearBit (fromIntegral @Int @Word8 (ord c)) 5 @@ -91,6 +92,7 @@ -- the trailer as well. This fails if the trailer is not -- found or if any non-ASCII characters are encountered. skipTrailedBy :: e -> Char -> Parser e s ()+{-# inline skipTrailedBy #-} skipTrailedBy e !c = do   let go = do         !d <- any e@@ -142,13 +144,14 @@  -- | Consumes and returns the next character in the input. any :: e -> Parser e s Char+{-# inline any #-} any e = uneffectful $ \chunk -> if length chunk > 0   then     let c = indexLatinCharArray (array chunk) (offset chunk)      in if c < '\128'-          then InternalSuccess c (offset chunk + 1) (length chunk - 1)-          else InternalFailure e-  else InternalFailure e+          then Success c (offset chunk + 1) (length chunk - 1)+          else Failure e+  else Failure e  -- | Variant of 'any' with unboxed result. any# :: e -> Parser e s Char#@@ -164,22 +167,24 @@   )  unI :: Int -> Int#+{-# inline unI #-} unI (I# w) = w  -- | Examine the next byte without consuming it, interpret it as an -- ASCII-encoded character. This fails if the byte is above @0x7F@ or -- if the end of input has been reached. peek :: e -> Parser e s Char+{-# inline peek #-} peek e = uneffectful $ \chunk -> if length chunk > 0   then     let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8      in if w < 128-          then InternalSuccess+          then Success                  (C# (chr# (unI (fromIntegral w))))                  (offset chunk)                  (length chunk)-          else InternalFailure e-  else InternalFailure e+          else Failure e+  else Failure e  -- | Consume the next byte, interpreting it as an ASCII-encoded character. -- Fails if the byte is above @0x7F@. Returns @Nothing@ if the@@ -190,12 +195,12 @@   then     let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8      in if w < 128-          then InternalSuccess+          then Success                  (Just (C# (chr# (unI (fromIntegral w)))))                  (offset chunk + 1)                  (length chunk - 1)-          else InternalFailure e-  else InternalSuccess Nothing (offset chunk) (length chunk)+          else Failure e+  else Success Nothing (offset chunk) (length chunk)  -- | Consume characters matching the predicate. The stops when it -- encounters a non-matching character or when it encounters a byte@@ -218,18 +223,21 @@ -- | Skip uppercase and lowercase letters until a non-alpha -- character is encountered. skipAlpha :: Parser e s ()+{-# inline skipAlpha #-} skipAlpha = uneffectful# $ \c ->   upcastUnitSuccess (skipAlphaAsciiLoop c)  -- | Skip uppercase and lowercase letters until a non-alpha -- character is encountered. skipAlpha1 :: e -> Parser e s ()+{-# inline skipAlpha1 #-} skipAlpha1 e = uneffectful# $ \c ->   skipAlphaAsciiLoop1Start e c  skipAlphaAsciiLoop ::      Bytes -- Chunk   -> (# Int#, Int# #)+{-# inline skipAlphaAsciiLoop #-} skipAlphaAsciiLoop !c = if length c > 0   then     let w = indexLatinCharArray (array c) (offset c)@@ -242,6 +250,7 @@      e   -> Bytes -- chunk   -> Result# e ()+{-# inline skipAlphaAsciiLoop1Start #-} skipAlphaAsciiLoop1Start e !c = if length c > 0   then      let w = indexLatinCharArray (array c) (offset c)@@ -251,5 +260,5 @@   else (# e | #)  byteArrayToShortByteString :: PM.ByteArray -> BSS.ShortByteString+{-# inline byteArrayToShortByteString #-} byteArrayToShortByteString (PM.ByteArray x) = BSS.SBS x-
src/Data/Bytes/Parser/BigEndian.hs view
@@ -45,7 +45,7 @@ import Data.Bits ((.|.),unsafeShiftL) import Data.Bytes.Types (Bytes(..)) import Data.Bytes.Parser.Internal (Parser,uneffectful)-import Data.Bytes.Parser.Internal (InternalResult(..))+import Data.Bytes.Parser.Internal (Result(..)) import Data.Bytes.Parser.Internal (swapArray16,swapArray32,swapArray64,swapArray256) import Data.Bytes.Parser.Internal (swapArray128) import Data.Word (Word8,Word16,Word32,Word64)@@ -146,10 +146,10 @@   then     let wa = PM.indexByteArray (array chunk) (offset chunk) :: Word8         wb = PM.indexByteArray (array chunk) (offset chunk + 1) :: Word8-     in InternalSuccess+     in Success           (fromIntegral @Word @Word16 (unsafeShiftL (fromIntegral wa) 8 .|. fromIntegral wb))           (offset chunk + 2) (length chunk - 2)-  else InternalFailure e+  else Failure e  -- | Unsigned 32-bit word. word32 :: e -> Parser e s Word32@@ -159,7 +159,7 @@         wb = PM.indexByteArray (array chunk) (offset chunk + 1) :: Word8         wc = PM.indexByteArray (array chunk) (offset chunk + 2) :: Word8         wd = PM.indexByteArray (array chunk) (offset chunk + 3) :: Word8-     in InternalSuccess+     in Success           (fromIntegral @Word @Word32             ( unsafeShiftL (fromIntegral wa) 24 .|.               unsafeShiftL (fromIntegral wb) 16 .|.@@ -168,7 +168,7 @@             )           )           (offset chunk + 4) (length chunk - 4)-  else InternalFailure e+  else Failure e  -- | Unsigned 64-bit word. word64 :: e -> Parser e s Word64@@ -182,7 +182,7 @@         wf = PM.indexByteArray (array chunk) (offset chunk + 5) :: Word8         wg = PM.indexByteArray (array chunk) (offset chunk + 6) :: Word8         wh = PM.indexByteArray (array chunk) (offset chunk + 7) :: Word8-     in InternalSuccess+     in Success           ( unsafeShiftL (fromIntegral wa) 56 .|.             unsafeShiftL (fromIntegral wb) 48 .|.             unsafeShiftL (fromIntegral wc) 40 .|.@@ -193,7 +193,7 @@             fromIntegral wh           )           (offset chunk + 8) (length chunk - 8)-  else InternalFailure e+  else Failure e  -- | Unsigned 128-bit word. word128 :: e -> Parser e s Word128
src/Data/Bytes/Parser/Internal.hs view
@@ -19,7 +19,7 @@  module Data.Bytes.Parser.Internal   ( Parser(..)-  , InternalResult(..)+  , Result(..)   , InternalStep(..)   , Bytes#   , ST#@@ -63,16 +63,16 @@     { runParser :: (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a) } -> Parser e s a  -- The result of running a parser. Used internally.-data InternalResult e a-  = InternalFailure e+data Result e a+  = Failure e     -- An error message indicating what went wrong.-  | InternalSuccess !a !Int !Int+  | Success !a !Int !Int     -- The parsed value, the offset after the last consumed byte, and the     -- number of bytes remaining in parsed slice.  data InternalStep a = InternalStep !a !Int !Int -uneffectful :: (Bytes -> InternalResult e a) -> Parser e s a+uneffectful :: (Bytes -> Result e a) -> Parser e s a {-# inline uneffectful #-} uneffectful f = Parser   ( \b s0 -> (# s0, unboxResult (f (boxBytes b)) #) )@@ -98,9 +98,10 @@   (# e   | (# a, Int#, Int# #) #) -- ints are offset and length -unboxResult :: InternalResult e a -> Result# e a-unboxResult (InternalSuccess a (I# b) (I# c)) = (# | (# a, b, c #) #)-unboxResult (InternalFailure e) = (# e | #)+unboxResult :: Result e a -> Result# e a+{-# inline unboxResult #-}+unboxResult (Success a (I# b) (I# c)) = (# | (# a, b, c #) #)+unboxResult (Failure e) = (# e | #)  -- | Combines the error messages using '<>' when both -- parsers fail.@@ -122,7 +123,8 @@ fail ::      e -- ^ Error message   -> Parser e s a-fail e = uneffectful $ \_ -> InternalFailure e+{-# inline fail #-}+fail e = uneffectful $ \_ -> Failure e  instance Applicative (Parser e s) where   pure = pureParser
src/Data/Bytes/Parser/Latin.hs view
@@ -43,6 +43,9 @@   , opt#     -- * Many Characters   , takeTrailedBy+    -- * Lookahead+  , peek+  , peek'     -- * Skip   , skipDigits   , skipDigits1@@ -94,7 +97,7 @@ import Data.Bytes.Types (Bytes(..)) import Data.Bytes.Parser.Internal (InternalStep(..),unfailing) import Data.Bytes.Parser.Internal (Parser(..),ST#,uneffectful,Result#,uneffectful#)-import Data.Bytes.Parser.Internal (InternalResult(..),indexLatinCharArray,upcastUnitSuccess)+import Data.Bytes.Parser.Internal (Result(..),indexLatinCharArray,upcastUnitSuccess) import Data.Bytes.Parser.Internal (boxBytes) import Data.Bytes.Parser (bindFromLiftedToInt,isEndOfInput,endOfInput) import Data.Bytes.Parser.Unsafe (expose,cursor,unconsume)@@ -116,10 +119,10 @@ -- of the input has been reached. This never fails. trySatisfy :: (Char -> Bool) -> Parser e s Bool trySatisfy f = uneffectful $ \chunk -> case length chunk of-  0 -> InternalSuccess False (offset chunk) (length chunk)+  0 -> Success False (offset chunk) (length chunk)   _ -> case f (indexLatinCharArray (array chunk) (offset chunk)) of-    True -> InternalSuccess True (offset chunk + 1) (length chunk - 1)-    False -> InternalSuccess False (offset chunk) (length chunk)+    True -> Success True (offset chunk + 1) (length chunk - 1)+    False -> Success False (offset chunk) (length chunk)  -- | Runs the function on the next character in the input. If the -- function returns @Just@, this consumes the character and then@@ -144,58 +147,59 @@ -- | Consume the next character, failing if it does not -- match the expected value or if there is no more input. char :: e -> Char -> Parser e s ()--- GHC should decide to inline this after optimization.+{-# inline char #-} char e !c = uneffectful $ \chunk -> if length chunk > 0   then if indexLatinCharArray (array chunk) (offset chunk) == c-    then InternalSuccess () (offset chunk + 1) (length chunk - 1)-    else InternalFailure e-  else InternalFailure e+    then Success () (offset chunk + 1) (length chunk - 1)+    else Failure e+  else Failure e  -- | Consume the next two characters, failing if they do -- not match the expected values. -- -- > char2 e a b === char e a *> char e b char2 :: e -> Char -> Char -> Parser e s ()--- GHC should decide to inline this after optimization.+{-# inline char2 #-} char2 e !c0 !c1 = uneffectful $ \chunk ->   if | length chunk > 1      , indexLatinCharArray (array chunk) (offset chunk) == c0      , indexLatinCharArray (array chunk) (offset chunk + 1) == c1-         -> InternalSuccess () (offset chunk + 2) (length chunk - 2)-     | otherwise -> InternalFailure e+         -> Success () (offset chunk + 2) (length chunk - 2)+     | otherwise -> Failure e  -- | Consume three characters, failing if they do -- not match the expected values. -- -- > char3 e a b c === char e a *> char e b *> char e c char3 :: e -> Char -> Char -> Char -> Parser e s ()--- GHC should decide to inline this after optimization.+{-# inline char3 #-} char3 e !c0 !c1 !c2 = uneffectful $ \chunk ->   if | length chunk > 2      , indexLatinCharArray (array chunk) (offset chunk) == c0      , indexLatinCharArray (array chunk) (offset chunk + 1) == c1      , indexLatinCharArray (array chunk) (offset chunk + 2) == c2-         -> InternalSuccess () (offset chunk + 3) (length chunk - 3)-     | otherwise -> InternalFailure e+         -> Success () (offset chunk + 3) (length chunk - 3)+     | otherwise -> Failure e  -- | Consume four characters, failing if they do -- not match the expected values. -- -- > char4 e a b c d === char e a *> char e b *> char e c *> char e d char4 :: e -> Char -> Char -> Char -> Char -> Parser e s ()--- GHC should decide to inline this after optimization.+{-# inline char4 #-} char4 e !c0 !c1 !c2 !c3 = uneffectful $ \chunk ->   if | length chunk > 3      , indexLatinCharArray (array chunk) (offset chunk) == c0      , indexLatinCharArray (array chunk) (offset chunk + 1) == c1      , indexLatinCharArray (array chunk) (offset chunk + 2) == c2      , indexLatinCharArray (array chunk) (offset chunk + 3) == c3-         -> InternalSuccess () (offset chunk + 4) (length chunk - 4)-     | otherwise -> InternalFailure e+         -> Success () (offset chunk + 4) (length chunk - 4)+     | otherwise -> Failure e  -- | Consume five characters, failing if they do -- not match the expected values. char5 :: e -> Char -> Char -> Char -> Char -> Char -> Parser e s ()+{-# inline char5 #-} char5 e !c0 !c1 !c2 !c3 !c4 = uneffectful $ \chunk ->   if | length chunk > 4      , indexLatinCharArray (array chunk) (offset chunk) == c0@@ -203,12 +207,13 @@      , indexLatinCharArray (array chunk) (offset chunk + 2) == c2      , indexLatinCharArray (array chunk) (offset chunk + 3) == c3      , indexLatinCharArray (array chunk) (offset chunk + 4) == c4-         -> InternalSuccess () (offset chunk + 5) (length chunk - 5)-     | otherwise -> InternalFailure e+         -> Success () (offset chunk + 5) (length chunk - 5)+     | otherwise -> Failure e  -- | Consume six characters, failing if they do -- not match the expected values. char6 :: e -> Char -> Char -> Char -> Char -> Char -> Char -> Parser e s ()+{-# inline char6 #-} char6 e !c0 !c1 !c2 !c3 !c4 !c5 = uneffectful $ \chunk ->   if | length chunk > 5      , indexLatinCharArray (array chunk) (offset chunk) == c0@@ -217,12 +222,13 @@      , indexLatinCharArray (array chunk) (offset chunk + 3) == c3      , indexLatinCharArray (array chunk) (offset chunk + 4) == c4      , indexLatinCharArray (array chunk) (offset chunk + 5) == c5-         -> InternalSuccess () (offset chunk + 6) (length chunk - 6)-     | otherwise -> InternalFailure e+         -> Success () (offset chunk + 6) (length chunk - 6)+     | otherwise -> Failure e  -- | Consume seven characters, failing if they do -- not match the expected values. char7 :: e -> Char -> Char -> Char -> Char -> Char -> Char -> Char -> Parser e s ()+{-# inline char7 #-} char7 e !c0 !c1 !c2 !c3 !c4 !c5 !c6 = uneffectful $ \chunk ->   if | length chunk > 6      , indexLatinCharArray (array chunk) (offset chunk) == c0@@ -232,12 +238,13 @@      , indexLatinCharArray (array chunk) (offset chunk + 4) == c4      , indexLatinCharArray (array chunk) (offset chunk + 5) == c5      , indexLatinCharArray (array chunk) (offset chunk + 6) == c6-         -> InternalSuccess () (offset chunk + 7) (length chunk - 7)-     | otherwise -> InternalFailure e+         -> Success () (offset chunk + 7) (length chunk - 7)+     | otherwise -> Failure e  -- | Consume eight characters, failing if they do -- not match the expected values. char8 :: e -> Char -> Char -> Char -> Char -> Char -> Char -> Char -> Char -> Parser e s ()+{-# inline char8 #-} char8 e !c0 !c1 !c2 !c3 !c4 !c5 !c6 !c7 = uneffectful $ \chunk ->   if | length chunk > 7      , indexLatinCharArray (array chunk) (offset chunk) == c0@@ -248,13 +255,14 @@      , indexLatinCharArray (array chunk) (offset chunk + 5) == c5      , indexLatinCharArray (array chunk) (offset chunk + 6) == c6      , indexLatinCharArray (array chunk) (offset chunk + 7) == c7-         -> InternalSuccess () (offset chunk + 8) (length chunk - 8)-     | otherwise -> InternalFailure e+         -> Success () (offset chunk + 8) (length chunk - 8)+     | otherwise -> Failure e  -- | Consume nine characters, failing if they do -- not match the expected values. char9 :: e -> Char -> Char -> Char -> Char   -> Char -> Char -> Char -> Char -> Char -> Parser e s ()+{-# inline char9 #-} char9 e !c0 !c1 !c2 !c3 !c4 !c5 !c6 !c7 !c8 = uneffectful $ \chunk ->   if | length chunk > 8      , indexLatinCharArray (array chunk) (offset chunk) == c0@@ -266,13 +274,14 @@      , indexLatinCharArray (array chunk) (offset chunk + 6) == c6      , indexLatinCharArray (array chunk) (offset chunk + 7) == c7      , indexLatinCharArray (array chunk) (offset chunk + 8) == c8-         -> InternalSuccess () (offset chunk + 9) (length chunk - 9)-     | otherwise -> InternalFailure e+         -> Success () (offset chunk + 9) (length chunk - 9)+     | otherwise -> Failure e  -- | Consume ten characters, failing if they do -- not match the expected values. char10 :: e -> Char -> Char -> Char -> Char -> Char   -> Char -> Char -> Char -> Char -> Char -> Parser e s ()+{-# inline char10 #-} char10 e !c0 !c1 !c2 !c3 !c4 !c5 !c6 !c7 !c8 !c9 = uneffectful $ \chunk ->   if | length chunk > 9      , indexLatinCharArray (array chunk) (offset chunk) == c0@@ -285,13 +294,14 @@      , indexLatinCharArray (array chunk) (offset chunk + 7) == c7      , indexLatinCharArray (array chunk) (offset chunk + 8) == c8      , indexLatinCharArray (array chunk) (offset chunk + 9) == c9-         -> InternalSuccess () (offset chunk + 10) (length chunk - 10)-     | otherwise -> InternalFailure e+         -> Success () (offset chunk + 10) (length chunk - 10)+     | otherwise -> Failure e  -- | Consume eleven characters, failing if they do -- not match the expected values. char11 :: e -> Char -> Char -> Char -> Char -> Char -> Char   -> Char -> Char -> Char -> Char -> Char -> Parser e s ()+{-# inline char11 #-} char11 e !c0 !c1 !c2 !c3 !c4 !c5 !c6 !c7 !c8 !c9 !c10 = uneffectful $ \chunk ->   if | length chunk > 10      , indexLatinCharArray (array chunk) (offset chunk) == c0@@ -305,13 +315,14 @@      , indexLatinCharArray (array chunk) (offset chunk + 8) == c8      , indexLatinCharArray (array chunk) (offset chunk + 9) == c9      , indexLatinCharArray (array chunk) (offset chunk + 10) == c10-         -> InternalSuccess () (offset chunk + 11) (length chunk - 11)-     | otherwise -> InternalFailure e+         -> Success () (offset chunk + 11) (length chunk - 11)+     | otherwise -> Failure e  -- | Consume twelve characters, failing if they do -- not match the expected values. char12 :: e -> Char -> Char -> Char -> Char -> Char -> Char   -> Char -> Char -> Char -> Char -> Char -> Char -> Parser e s ()+{-# inline char12 #-} char12 e !c0 !c1 !c2 !c3 !c4 !c5 !c6 !c7 !c8 !c9 !c10 !c11 = uneffectful $ \chunk ->   if | length chunk > 11      , indexLatinCharArray (array chunk) (offset chunk) == c0@@ -326,24 +337,26 @@      , indexLatinCharArray (array chunk) (offset chunk + 9) == c9      , indexLatinCharArray (array chunk) (offset chunk + 10) == c10      , indexLatinCharArray (array chunk) (offset chunk + 11) == c11-         -> InternalSuccess () (offset chunk + 12) (length chunk - 12)-     | otherwise -> InternalFailure e+         -> Success () (offset chunk + 12) (length chunk - 12)+     | otherwise -> Failure e  -- | Consumes and returns the next character in the input. any :: e -> Parser e s Char+{-# inline any #-} any e = uneffectful $ \chunk -> if length chunk > 0   then     let c = indexLatinCharArray (array chunk) (offset chunk)-     in InternalSuccess c (offset chunk + 1) (length chunk - 1)-  else InternalFailure e+     in Success c (offset chunk + 1) (length chunk - 1)+  else Failure e  -- | Consume a character from the input or return @Nothing@ if -- end of the stream has been reached. Since ISO 8859-1 maps every -- bytes to a character, this parser never fails. opt :: Parser e s (Maybe Char)+{-# inline opt #-} opt = uneffectful $ \chunk -> case length chunk of-  0 -> InternalSuccess Nothing (offset chunk) (length chunk)-  _ -> InternalSuccess+  0 -> Success Nothing (offset chunk) (length chunk)+  _ -> Success     (Just (indexLatinCharArray (array chunk) (offset chunk)))     (offset chunk + 1) (length chunk - 1) @@ -382,6 +395,7 @@ -- | Variant of 'skipDigits' that requires at least one digit -- to be present. skipDigits1 :: e -> Parser e s ()+{-# inline skipDigits1 #-} skipDigits1 e = uneffectful# $ \c ->   skipDigitsAscii1LoopStart e c @@ -397,12 +411,14 @@ -- | Skip the character any number of times. This succeeds -- even if the character was not present. skipChar :: Char -> Parser e s ()+{-# inline skipChar #-} skipChar !w = uneffectful# $ \c ->   upcastUnitSuccess (skipLoop w c)  -- | Skip the character any number of times. It must occur -- at least once or else this will fail. skipChar1 :: e -> Char -> Parser e s ()+{-# inline skipChar1 #-} skipChar1 e !w = uneffectful# $ \c ->   skipLoop1Start e w c @@ -539,11 +555,13 @@   !len@(I# len# ) = length chunk0  upcastWordResult :: Result# e Word# -> Result# e Word+{-# inline upcastWordResult #-} upcastWordResult (# e | #) = (# e | #) upcastWordResult (# | (# a, b, c #) #) = (# | (# W# a, b, c #) #)  -- This only works on 64-bit platforms. upcastWord64Result :: Result# e Word# -> Result# e Word64+{-# inline upcastWord64Result #-} upcastWord64Result (# e | #) = (# e | #) upcastWord64Result (# | (# a, b, c #) #) = (# | (# W64# a, b, c #) #) @@ -599,16 +617,19 @@  -- Precondition: the word is small enough upcastWord16Result :: Result# e Word# -> Result# e Word16+{-# inline upcastWord16Result #-} upcastWord16Result (# e | #) = (# e | #) upcastWord16Result (# | (# a, b, c #) #) = (# | (# W16# a, b, c #) #)  -- Precondition: the word is small enough upcastWord32Result :: Result# e Word# -> Result# e Word32+{-# inline upcastWord32Result #-} upcastWord32Result (# e | #) = (# e | #) upcastWord32Result (# | (# a, b, c #) #) = (# | (# W32# a, b, c #) #)  -- Precondition: the word is small enough upcastWord8Result :: Result# e Word# -> Result# e Word8+{-# inline upcastWord8Result #-} upcastWord8Result (# e | #) = (# e | #) upcastWord8Result (# | (# a, b, c #) #) = (# | (# W8# a, b, c #) #) @@ -1076,25 +1097,25 @@ -- @[a-f0-9]@. hexNibbleLower :: e -> Parser e s Word hexNibbleLower e = uneffectful $ \chunk -> case length chunk of-  0 -> InternalFailure e+  0 -> Failure e   _ ->     let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8 in-    if | w >= 48 && w < 58 -> InternalSuccess (fromIntegral w - 48) (offset chunk + 1) (length chunk - 1)-       | w >= 97 && w < 103 -> InternalSuccess (fromIntegral w - 87) (offset chunk + 1) (length chunk - 1)-       | otherwise -> InternalFailure e+    if | w >= 48 && w < 58 -> Success (fromIntegral w - 48) (offset chunk + 1) (length chunk - 1)+       | w >= 97 && w < 103 -> Success (fromIntegral w - 87) (offset chunk + 1) (length chunk - 1)+       | otherwise -> Failure e  -- | Consume a single character that is the case-insensitive hexadecimal -- encoding of a 4-bit word. Fails if the character is not in the class -- @[a-fA-F0-9]@. hexNibble :: e -> Parser e s Word hexNibble e = uneffectful $ \chunk -> case length chunk of-  0 -> InternalFailure e+  0 -> Failure e   _ ->     let w = PM.indexByteArray (array chunk) (offset chunk) :: Word8 in-    if | w >= 48 && w < 58 -> InternalSuccess (fromIntegral w - 48) (offset chunk + 1) (length chunk - 1)-       | w >= 65 && w < 71 -> InternalSuccess (fromIntegral w - 55) (offset chunk + 1) (length chunk - 1)-       | w >= 97 && w < 103 -> InternalSuccess (fromIntegral w - 87) (offset chunk + 1) (length chunk - 1)-       | otherwise -> InternalFailure e+    if | w >= 48 && w < 58 -> Success (fromIntegral w - 48) (offset chunk + 1) (length chunk - 1)+       | w >= 65 && w < 71 -> Success (fromIntegral w - 55) (offset chunk + 1) (length chunk - 1)+       | w >= 97 && w < 103 -> Success (fromIntegral w - 87) (offset chunk + 1) (length chunk - 1)+       | otherwise -> Failure e  -- | Consume a single character that is the lowercase hexadecimal -- encoding of a 4-bit word. Returns @Nothing@ without consuming@@ -1126,6 +1147,7 @@ -- Returns the maximum machine word if the argument is not -- the ASCII encoding of a hexadecimal digit. oneHex :: Word8 -> Word+{-# inline oneHex #-} oneHex w   | w >= 48 && w < 58 = (fromIntegral w - 48)   | w >= 65 && w < 71 = (fromIntegral w - 55)@@ -1141,6 +1163,7 @@   | otherwise = Nothing  uneffectfulWord# :: (Bytes -> Result# e Word#) -> Parser e s Word#+{-# inline uneffectfulWord# #-} uneffectfulWord# f = Parser   ( \b s0 -> (# s0, (f (boxBytes b)) #) ) @@ -1149,6 +1172,7 @@ -- Postcondition: when overflow is false, the resulting -- word is less than or equal to the upper bound positivePushBase10 :: Word -> Word -> Word -> (Bool,Word)+{-# inline positivePushBase10 #-} positivePushBase10 (W# a) (W# b) (W# upper) =    let !(# ca, r0 #) = Exts.timesWord2# a 10##       !r1 = Exts.plusWord# r0 b@@ -1158,6 +1182,7 @@    in (case c of { 0## -> False; _ -> True }, W# r1)  unsignedPushBase10 :: Word -> Word -> (Bool,Word)+{-# inline unsignedPushBase10 #-} unsignedPushBase10 (W# a) (W# b) =    let !(# ca, r0 #) = Exts.timesWord2# a 10##       !r1 = Exts.plusWord# r0 b@@ -1184,8 +1209,32 @@ {-# inline anyUnsafe #-} anyUnsafe = uneffectful $ \chunk ->   let w = indexCharArray (array chunk) (offset chunk) :: Char-   in InternalSuccess w (offset chunk + 1) (length chunk - 1)+   in Success w (offset chunk + 1) (length chunk - 1)  -- Reads one byte and interprets it as Latin1-encoded character. indexCharArray :: PM.ByteArray -> Int -> Char+{-# inline indexCharArray #-} indexCharArray (PM.ByteArray x) (I# i) = C# (indexCharArray# x i)++-- | Match any character, to perform lookahead. Returns 'Nothing' if+--   end of input has been reached. Does not consume any input.+--+--   /Note/: Because this parser does not fail, do not use it+--   with combinators such as 'many', because such as 'many',+--   because such parsers loop until a failure occurs. Careless+--   use will thus result in an infinite loop.+peek :: Parser e s (Maybe Char)+{-# inline peek #-}+peek = uneffectful $ \(Bytes arr off len) ->+  let v = if len > 0+        then Just (indexCharArray arr off)+        else Nothing+  in Success v off len++-- | Match any byte, to perform lookahead. Does not consume any+--   input, but will fail if end of input has been reached.+peek' :: e -> Parser e s Char+{-# inline peek' #-}+peek' e = uneffectful $ \(Bytes arr off len) -> if len > 0+  then Success (indexCharArray arr off) off len+  else Failure e
src/Data/Bytes/Parser/LittleEndian.hs view
@@ -49,7 +49,7 @@ import Data.Primitive (ByteArray(..),PrimArray(..)) import Data.Bytes.Types (Bytes(..)) import Data.Bytes.Parser.Internal (Parser,uneffectful)-import Data.Bytes.Parser.Internal (InternalResult(..))+import Data.Bytes.Parser.Internal (Result(..)) import Data.Bytes.Parser.Internal (swapArray16,swapArray32) import Data.Bytes.Parser.Internal (swapArray64,swapArray128,swapArray256) import Data.Word (Word8,Word16,Word32,Word64)@@ -158,10 +158,10 @@   then     let wa = PM.indexByteArray (array chunk) (offset chunk) :: Word8         wb = PM.indexByteArray (array chunk) (offset chunk + 1) :: Word8-     in InternalSuccess+     in Success           (fromIntegral @Word @Word16 (unsafeShiftL (fromIntegral wb) 8 .|. fromIntegral wa))           (offset chunk + 2) (length chunk - 2)-  else InternalFailure e+  else Failure e  -- | Unsigned 32-bit word. word32 :: e -> Parser e s Word32@@ -171,7 +171,7 @@         wb = PM.indexByteArray (array chunk) (offset chunk + 1) :: Word8         wc = PM.indexByteArray (array chunk) (offset chunk + 2) :: Word8         wd = PM.indexByteArray (array chunk) (offset chunk + 3) :: Word8-     in InternalSuccess+     in Success           (fromIntegral @Word @Word32             ( unsafeShiftL (fromIntegral wd) 24 .|.               unsafeShiftL (fromIntegral wc) 16 .|.@@ -180,7 +180,7 @@             )           )           (offset chunk + 4) (length chunk - 4)-  else InternalFailure e+  else Failure e  -- | Unsigned 64-bit word. word64 :: e -> Parser e s Word64@@ -194,7 +194,7 @@         wf = PM.indexByteArray (array chunk) (offset chunk + 5) :: Word8         wg = PM.indexByteArray (array chunk) (offset chunk + 6) :: Word8         wh = PM.indexByteArray (array chunk) (offset chunk + 7) :: Word8-     in InternalSuccess+     in Success           ( unsafeShiftL (fromIntegral wh) 56 .|.             unsafeShiftL (fromIntegral wg) 48 .|.             unsafeShiftL (fromIntegral wf) 40 .|.@@ -205,7 +205,7 @@             fromIntegral wa           )           (offset chunk + 8) (length chunk - 8)-  else InternalFailure e+  else Failure e  -- | Unsigned 256-bit word. word256 :: e -> Parser e s Word256
src/Data/Bytes/Parser/Rebindable.hs view
@@ -75,6 +75,17 @@         runParser (g y) (# arr, b, c #) s1   ) +bindWordParser :: forall (a :: TYPE 'WordRep) e s b.+  Parser e s a -> (a -> Parser e s b) -> Parser e s b+{-# inline bindWordParser #-}+bindWordParser (Parser f) g = Parser+  (\x@(# arr, _, _ #) s0 -> case f x s0 of+    (# s1, r0 #) -> case r0 of+      (# e | #) -> (# s1, (# e | #) #)+      (# | (# y, b, c #) #) ->+        runParser (g y) (# arr, b, c #) s1+  )+ sequenceIntParser :: forall (a :: TYPE 'IntRep) e s b.   Parser e s a -> Parser e s b -> Parser e s b {-# inline sequenceIntParser #-}@@ -85,6 +96,16 @@       (# | (# _, b, c #) #) -> g (# arr, b, c #) s1   ) +sequenceWordParser :: forall (a :: TYPE 'WordRep) e s b.+  Parser e s a -> Parser e s b -> Parser e s b+{-# inline sequenceWordParser #-}+sequenceWordParser (Parser f) (Parser g) = Parser+  (\x@(# arr, _, _ #) s0 -> case f x s0 of+    (# s1, r0 #) -> case r0 of+      (# e | #) -> (# s1, (# e | #) #)+      (# | (# _, b, c #) #) -> g (# arr, b, c #) s1+  )+ pureIntPairParser :: forall (a :: TYPE ('TupleRep '[ 'IntRep, 'IntRep])) e s.   a -> Parser e s a {-# inline pureIntPairParser #-}@@ -171,6 +192,12 @@   {-# inline (>>) #-}   (>>=) = bindParser   (>>) = sequenceParser++instance Bind 'WordRep 'LiftedRep where+  {-# inline (>>=) #-}+  {-# inline (>>) #-}+  (>>=) = bindWordParser+  (>>) = sequenceWordParser  instance Bind 'IntRep 'LiftedRep where   {-# inline (>>=) #-}
src/Data/Bytes/Parser/Unsafe.hs view
@@ -29,23 +29,24 @@   , expose   , unconsume   , jump+  , uneffectful   ) where  import Prelude hiding (length) -import Data.Primitive (ByteArray)-import Data.Bytes.Types (Bytes(..)) import Data.Bytes.Parser.Internal (Parser(..),uneffectful,uneffectfulInt#)-import Data.Bytes.Parser.Internal (InternalResult(..))-+import Data.Bytes.Parser.Internal (Result(..))+import Data.Bytes.Types (Bytes(..))+import Data.Primitive (ByteArray) import GHC.Exts (Int#,Int(I#)) + -- | Get the current offset into the chunk. Using this makes -- it possible to observe the internal difference between 'Bytes' -- that refer to equivalent slices. Be careful. cursor :: Parser e s Int cursor = uneffectful $ \Bytes{offset,length} ->-  InternalSuccess offset offset length+  Success offset offset length  -- | Variant of 'cursor' with unboxed result. cursor# :: Parser e s Int#@@ -57,18 +58,17 @@ -- use this is you know what you're doing. expose :: Parser e s ByteArray expose = uneffectful $ \Bytes{length,offset,array} ->-  InternalSuccess array offset length+  Success array offset length  -- | Move the cursor back by @n@ bytes. Precondition: you -- must have previously consumed at least @n@ bytes. unconsume :: Int -> Parser e s () unconsume n = uneffectful $ \Bytes{length,offset} ->-  InternalSuccess () (offset - n) (length + n)+  Success () (offset - n) (length + n)  -- | Set the position to the given index. Precondition: the index -- must be valid. It should be the result of an earlier call to -- 'cursor'. jump :: Int -> Parser e s () jump ix = uneffectful $ \(Bytes{length,offset}) ->-  InternalSuccess () ix (length + (offset - ix))-+  Success () ix (length + (offset - ix))