-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Binary serialisation for Haskell values using lazy ByteStrings -- -- Efficient, pure binary serialisation using lazy ByteStrings. Haskell -- values may be encoded to and from binary formats, written to disk as -- binary, or sent over the network. The format used can be automatically -- generated, or you can choose to implement a custom format if needed. -- Serialisation speeds of over 1 G/sec have been observed, so this -- library should be suitable for high performance scenarios. @package binary-ext @version 0.8.4.1 module Data.Binary.Get.Ext.Internal data Get e a runCont :: Get e a -> forall r. Int64 -> ByteString -> Success e a r -> Decoder e r -- | A decoder produced by running a Get monad. data Decoder e a -- | The decoder ran into an error. The decoder either used fail or -- was not provided enough input. Fail :: !ByteString -> (Either String e) -> Decoder e a -- | The decoder has consumed the available input and needs more to -- continue. Provide Just if more input is available and -- Nothing otherwise, and you will get a new Decoder. Partial :: (Maybe ByteString -> Decoder e a) -> Decoder e a -- | The decoder has successfully finished. Except for the output value you -- also get the unused input. Done :: !ByteString -> a -> Decoder e a -- | The decoder needs to know the current position in the input. Given the -- number of bytes remaning in the decoder, the outer decoder runner -- needs to calculate the position and resume the decoding. BytesRead :: {-# UNPACK #-} !Int64 -> (Int64 -> Decoder e a) -> Decoder e a -- | Run a Get monad. See Decoder for what to do next, like -- providing input, handling decoding errors and to get the output value. runGetIncremental :: Int64 -> Get e a -> Decoder e a -- | Return at least n bytes, maybe more. If not enough data is -- available the computation will escape with Partial. readN :: Int -> (ByteString -> a) -> Get () a -- | readNWith n f where f must be deterministic and not -- have side effects. readNWith :: Int -> (Ptr a -> IO a) -> Get () a -- | Get e the total number of bytes read to this point. bytesRead :: Get e Int64 -- | Get e the total number of bytes read to this point. totalBytesRead :: Get e Int64 -- | Isolate a decoder to operate with a fixed number of bytes, and fail if -- fewer bytes were consumed, or more bytes were attempted to be -- consumed. If the given decoder fails, isolate will also fail. -- Offset from bytesRead will be relative to the start of -- isolate, not the absolute of the input. isolate :: Int -> Get e a -> (Int -> e) -> Get e a withInputChunks :: s -> Consume s -> ([ByteString] -> b) -> ([ByteString] -> Get e b) -> Get e b type Consume s = s -> ByteString -> Either s (ByteString, ByteString) failOnEOF :: [ByteString] -> Get () a -- | Get e the current chunk. get :: Get e ByteString -- | Replace the current chunk. put :: ByteString -> Get e () -- | Ensure that there are at least n bytes available. If not, the -- computation will escape with Partial. ensureN :: Int -> Get () () -- | Test whether all input has been consumed, i.e. there are no remaining -- undecoded bytes. isEmpty :: Get e Bool failG :: e -> Get e a -- | Run the given decoder, but without consuming its input. If the given -- decoder fails, then so will this function. -- -- Since: 0.7.0.0 lookAhead :: Get e a -> Get e a -- | Run the given decoder, and only consume its input if it returns -- Just. If Nothing is returned, the input will be -- unconsumed. If the given decoder fails, then so will this function. -- -- Since: 0.7.0.0 lookAheadM :: Get e (Maybe a) -> Get e (Maybe a) -- | Run the given decoder, and only consume its input if it returns -- Right. If Left is returned, the input will be -- unconsumed. If the given decoder fails, then so will this function. lookAheadE :: Get e (Either a b) -> Get e (Either a b) label :: String -> Get String a -> Get String a -- | Convert decoder error. If the decoder fails, the given function will -- be applied to the error message. onError :: (e -> e') -> Get e a -> Get e' a -- | Set decoder error. If the decoder fails, the given error will be used -- as the error message. withError :: Get () a -> e -> Get e a -- | An efficient get method for strict ByteStrings. Fails if fewer than -- n bytes are left in the input. If n <= 0 then the -- empty string is returned. getByteString :: Int -> Get () ByteString instance GHC.Base.Monad (Data.Binary.Get.Ext.Internal.Get e) instance Control.Monad.Fail.MonadFail (Data.Binary.Get.Ext.Internal.Get e) instance GHC.Base.Applicative (Data.Binary.Get.Ext.Internal.Get e) instance GHC.Base.MonadPlus (Data.Binary.Get.Ext.Internal.Get e) instance GHC.Base.Functor (Data.Binary.Get.Ext.Internal.Get e) instance GHC.Base.Functor (Data.Binary.Get.Ext.Internal.Decoder e) instance (GHC.Show.Show e, GHC.Show.Show a) => GHC.Show.Show (Data.Binary.Get.Ext.Internal.Decoder e a) instance GHC.Base.Alternative (Data.Binary.Get.Ext.Internal.Get e) -- | The Get monad. A monad for efficiently building structures from -- encoded lazy ByteStrings. -- -- Primitives are available to decode words of various sizes, both big -- and little endian. -- -- Let's decode binary data representing illustrated here. In this -- example the values are in little endian. -- --
-- +------------------+--------------+-----------------+ -- | 32 bit timestamp | 32 bit price | 16 bit quantity | -- +------------------+--------------+-----------------+ ---- -- A corresponding Haskell value looks like this: -- --
-- data Trade = Trade
-- { timestamp :: !Word32
-- , price :: !Word32
-- , qty :: !Word16
-- } deriving (Show)
--
--
--
-- The fields in Trade are marked as strict (using !)
-- since we don't need laziness here. In practise, you would probably
-- consider using the UNPACK pragma as well.
-- http://www.haskell.org/ghc/docs/latest/html/users_guide/pragmas.html#unpack-pragma
--
-- Now, let's have a look at a decoder for this format.
--
-- -- getTrade :: Get Trade -- getTrade = do -- timestamp <- getWord32le -- price <- getWord32le -- quantity <- getWord16le -- return $! Trade timestamp price quantity -- ---- -- Or even simpler using applicative style: -- --
-- getTrade' :: Get Trade -- getTrade' = Trade <$> getWord32le <*> getWord32le <*> getWord16le -- ---- -- There are two kinds of ways to execute this decoder, the lazy input -- method and the incremental input method. Here we will use the lazy -- input method. -- -- Let's first define a function that decodes many Trades. -- --
-- getTrades :: Get [Trade] -- getTrades = do -- empty <- isEmpty -- if empty -- then return [] -- else do trade <- getTrade -- trades <- getTrades -- return (trade:trades) -- ---- -- Finally, we run the decoder: -- --
-- lazyIOExample :: IO [Trade] -- lazyIOExample = do -- input <- BL.readFile "trades.bin" -- return (runGet getTrades input) -- ---- -- This decoder has the downside that it will need to read all the input -- before it can return. On the other hand, it will not return anything -- until it knows it could decode without any decoder errors. -- -- You could also refactor to a left-fold, to decode in a more streaming -- fashion, and get the following decoder. It will start to return data -- without knowing that it can decode all input. -- --
-- incrementalExample :: BL.ByteString -> [Trade] -- incrementalExample input0 = go decoder input0 -- where -- decoder = runGetIncremental getTrade -- go :: Decoder Trade -> BL.ByteString -> [Trade] -- go (Done leftover _consumed trade) input = -- trade : go decoder (BL.chunk leftover input) -- go (Partial k) input = -- go (k . takeHeadChunk $ input) (dropHeadChunk input) -- go (Fail _leftover _consumed msg) _input = -- error msg -- -- takeHeadChunk :: BL.ByteString -> Maybe BS.ByteString -- takeHeadChunk lbs = -- case lbs of -- (BL.Chunk bs _) -> Just bs -- _ -> Nothing -- -- dropHeadChunk :: BL.ByteString -> BL.ByteString -- dropHeadChunk lbs = -- case lbs of -- (BL.Chunk _ lbs') -> lbs' -- _ -> BL.Empty -- ---- -- The lazyIOExample uses lazy I/O to read the file from the -- disk, which is not suitable in all applications, and certainly not if -- you need to read from a socket which has higher likelihood to fail. To -- address these needs, use the incremental input method like in -- incrementalExample. For an example of how to read -- incrementally from a Handle, see the implementation of -- decodeFileOrFail in Data.Binary. module Data.Binary.Get.Ext data Get e a -- | Run a Get monad and return Left on failure and -- Right on success. In both cases any unconsumed input and the -- number of bytes consumed is returned. In the case of failure, a -- human-readable error message is included as well. runGetOrFail :: ByteOffset -> Get e a -> ByteString -> Either (ByteString, ByteOffset, Either String e) (ByteString, ByteOffset, a) -- | An offset, counted in bytes. type ByteOffset = Int64 -- | A decoder procuced by running a Get monad. data Decoder e a -- | The decoder ran into an error. The decoder either used fail or -- was not provided enough input. Contains any unconsumed input and the -- number of bytes consumed. Fail :: !ByteString -> {-# UNPACK #-} !ByteOffset -> (Either String e) -> Decoder e a -- | The decoder has consumed the available input and needs more to -- continue. Provide Just if more input is available and -- Nothing otherwise, and you will get a new Decoder. Partial :: (Maybe ByteString -> Decoder e a) -> Decoder e a -- | The decoder has successfully finished. Except for the output value you -- also get any unused input as well as the number of bytes consumed. Done :: !ByteString -> {-# UNPACK #-} !ByteOffset -> a -> Decoder e a -- | Run a Get monad. See Decoder for what to do next, like -- providing input, handling decoder errors and to get the output value. -- Hint: Use the helper functions pushChunk, pushChunks and -- pushEndOfInput. runGetIncremental :: ByteOffset -> Get e a -> Decoder e a -- | Feed a Decoder with more input. If the Decoder is -- Done or Fail it will add the input to ByteString -- of unconsumed input. -- --
-- runGetIncremental myParser `pushChunk` myInput1 `pushChunk` myInput2 --pushChunk :: Decoder e a -> ByteString -> Decoder e a -- | Feed a Decoder with more input. If the Decoder is -- Done or Fail it will add the input to -- ByteString of unconsumed input. -- --
-- runGetIncremental myParser `pushChunks` myLazyByteString --pushChunks :: Decoder e a -> ByteString -> Decoder e a -- | Tell a Decoder that there is no more input. This passes -- Nothing to a Partial decoder, otherwise returns the -- decoder unchanged. pushEndOfInput :: Decoder e a -> Decoder e a -- | Skip ahead n bytes. Fails if fewer than n bytes are -- available. skip :: Int -> Get () () -- | Test whether all input has been consumed, i.e. there are no remaining -- undecoded bytes. isEmpty :: Get e Bool -- | Get e the total number of bytes read to this point. bytesRead :: Get e Int64 -- | Get e the total number of bytes read to this point. totalBytesRead :: Get e Int64 -- | Isolate a decoder to operate with a fixed number of bytes, and fail if -- fewer bytes were consumed, or more bytes were attempted to be -- consumed. If the given decoder fails, isolate will also fail. -- Offset from bytesRead will be relative to the start of -- isolate, not the absolute of the input. isolate :: Int -> Get e a -> (Int -> e) -> Get e a -- | Run the given decoder, but without consuming its input. If the given -- decoder fails, then so will this function. -- -- Since: 0.7.0.0 lookAhead :: Get e a -> Get e a -- | Run the given decoder, and only consume its input if it returns -- Just. If Nothing is returned, the input will be -- unconsumed. If the given decoder fails, then so will this function. -- -- Since: 0.7.0.0 lookAheadM :: Get e (Maybe a) -> Get e (Maybe a) -- | Run the given decoder, and only consume its input if it returns -- Right. If Left is returned, the input will be -- unconsumed. If the given decoder fails, then so will this function. lookAheadE :: Get e (Either a b) -> Get e (Either a b) label :: String -> Get String a -> Get String a -- | Convert decoder error. If the decoder fails, the given function will -- be applied to the error message. onError :: (e -> e') -> Get e a -> Get e' a -- | Set decoder error. If the decoder fails, the given error will be used -- as the error message. withError :: Get () a -> e -> Get e a failG :: e -> Get e a -- | An efficient get method for strict ByteStrings. Fails if fewer than -- n bytes are left in the input. If n <= 0 then the -- empty string is returned. getByteString :: Int -> Get () ByteString -- | An efficient get method for lazy ByteStrings. Fails if fewer than -- n bytes are left in the input. getLazyByteString :: Int64 -> Get () ByteString -- | Get a lazy ByteString that is terminated with a NUL byte. The returned -- string does not contain the NUL byte. Fails if it reaches the end of -- input without finding a NUL. getLazyByteStringNul :: Get () ByteString -- | Get the remaining bytes as a lazy ByteString. Note that this can be an -- expensive function to use as it forces reading all input and keeping -- the string in-memory. getRemainingLazyByteString :: Get e ByteString -- | Read a Word8 from the monad state getWord8 :: Get () Word8 -- | Read a Word16 in big endian format getWord16be :: Get () Word16 -- | Read a Word32 in big endian format getWord32be :: Get () Word32 -- | Read a Word64 in big endian format getWord64be :: Get () Word64 -- | Read a Word16 in little endian format getWord16le :: Get () Word16 -- | Read a Word32 in little endian format getWord32le :: Get () Word32 -- | Read a Word64 in little endian format getWord64le :: Get () Word64 -- | O(1). Read a single native machine word. The word is read in -- host order, host endian form, for the machine you're on. On a 64 bit -- machine the Word is an 8 byte value, on a 32 bit machine, 4 bytes. getWordhost :: Get () Word -- | O(1). Read a 2 byte Word16 in native host order and host -- endianness. getWord16host :: Get () Word16 -- | O(1). Read a Word32 in native host order and host endianness. getWord32host :: Get () Word32 -- | O(1). Read a Word64 in native host order and host endianess. getWord64host :: Get () Word64 -- | Read an Int8 from the monad state getInt8 :: Get () Int8 -- | Read an Int16 in big endian format. getInt16be :: Get () Int16 -- | Read an Int32 in big endian format. getInt32be :: Get () Int32 -- | Read an Int64 in big endian format. getInt64be :: Get () Int64 -- | Read an Int16 in little endian format. getInt16le :: Get () Int16 -- | Read an Int32 in little endian format. getInt32le :: Get () Int32 -- | Read an Int64 in little endian format. getInt64le :: Get () Int64 -- | O(1). Read a single native machine word in native host order. -- It works in the same way as getWordhost. getInthost :: Get () Int -- | O(1). Read a 2 byte Int16 in native host order and host -- endianness. getInt16host :: Get () Int16 -- | O(1). Read an Int32 in native host order and host endianness. getInt32host :: Get () Int32 -- | O(1). Read an Int64 in native host order and host endianess. getInt64host :: Get () Int64 -- | Read a Float in big endian IEEE-754 format. getFloatbe :: Get () Float -- | Read a Float in little endian IEEE-754 format. getFloatle :: Get () Float -- | Read a Float in IEEE-754 format and host endian. getFloathost :: Get () Float -- | Read a Double in big endian IEEE-754 format. getDoublebe :: Get () Double -- | Read a Double in little endian IEEE-754 format. getDoublele :: Get () Double -- | Read a Double in IEEE-754 format and host endian. getDoublehost :: Get () Double