binary-ext 0.8.4.1 → 1.0
raw patch · 3 files changed
+8/−139 lines, 3 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- LICENSE +1/−0
- binary-ext.cabal +7/−14
- src/Data/Binary/Get/Ext.hs +0/−125
LICENSE view
@@ -1,3 +1,4 @@+Copyright (c) Warlock Copyright (c) Lennart Kolmodin All rights reserved.
binary-ext.cabal view
@@ -1,24 +1,17 @@ name: binary-ext-version: 0.8.4.1+version: 1.0 license: BSD3 license-file: LICENSE-author: Lennart Kolmodin <kolmodin@gmail.com>-maintainer: Lennart Kolmodin, Don Stewart <dons00@gmail.com>-homepage: https://github.com/kolmodin/binary-description: 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.-synopsis: Binary serialisation for Haskell values using lazy ByteStrings+author: Warlock <internalmike@gmail.com>+maintainer: Warlock <internalmike@gmail.com>+homepage: https://github.com/A1-Triard/binary-ext+description: An alternate with typed errors for Data.Binary.Get monad from 'binary' library. +synopsis: An alternate with typed errors for Data.Binary.Get monad from 'binary' library. category: Data, Parsing stability: provisional build-type: Simple cabal-version: >= 1.8-tested-with: GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3+tested-with: GHC == 8.0.1 extra-source-files: README.md
src/Data/Binary/Get/Ext.hs view
@@ -5,131 +5,6 @@ #include "MachDeps.h" #endif --------------------------------------------------------------------------------- |--- Module : Data.Binary.Get.Ext--- Copyright : Lennart Kolmodin--- License : BSD3-style (see LICENSE)------ Maintainer : Lennart Kolmodin <kolmodin@gmail.com>--- Stability : experimental--- Portability : portable to Hugs and GHC.------ 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 @Trade@s.------ @---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 ( -- * The Get monad