HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Modulecborg-0.2.10.0Haskell2010

Codec.CBOR.Decoding

High level API for decoding values that were encoded with the Codec.CBOR.Encoding module, using a Monad based interface.

  • 4 types
  • 70 values
  • Packagecborg-0.2.10.0
  • Exports74
  • LanguageHaskell2010
  • LicenceBSD-3-Clause
  • SourceDecoding.hs

Decode primitive operations

4 declarations
newtypenewtype Decoder s a
#

A continuation-based decoder, used for decoding values that were previously encoded using the Codec.CBOR.Encoding module. As Decoder has a Monad instance, you can easily write Decoders monadically for building your deserialisation logic.

Instances4Monad, Functor, MonadFail, Applicative
datadata DecodeAction s a
#

An action, representing a step for a decoder to taken and a continuation to invoke with the expected value.

Constructors

valueliftST :: ST s a -> Decoder s a
#

Lift an ST action into a Decoder. Useful for, e.g., leveraging in-place mutation to efficiently build a deserialised value.

Read input tokens

Decode a string of bytes as a ByteArray.

Also note that this will eagerly copy the content out of the input to ensure that the input does not leak in the event that the ByteArray is live but not forced.

Decode a textual string as UTF-8 encoded ByteArray. Note that the result is not validated to be well-formed UTF-8.

Also note that this will eagerly copy the content out of the input to ensure that the input does not leak in the event that the ByteArray is live but not forced.

Specialised Read input token operations

valuedecodeWordOf
  1. :: Word

    Expected value of the decoded word

  2. -> Decoder s ()
#

Attempt to decode a word with decodeWord, and ensure the word is exactly as expected, or fail.

Branching operations

Attempt to decode a token for the length of a finite, known list, or an indefinite list. If Nothing is returned, then an indefinite length list occurs afterwords. If Just x is returned, then a list of length x is encoded.

Attempt to decode a token for the length of a finite, known map, or an indefinite map. If Nothing is returned, then an indefinite length map occurs afterwords. If Just x is returned, then a map of length x is encoded.

Inspecting the token type

datadata TokenType
#
Instances5Bounded, Enum, Eq, Ord, Show

Special operations

valuepeekAvailable :: Decoder s Int
#

Peek and return the length of the current buffer that we're running our decoder on.

typetype ByteOffset = Int64
#

A 0-based offset within the overall byte sequence that makes up the input to the Decoder.

This is an Int64 since Decoder is incremental and can decode more data than fits in memory at once. This is also compatible with the result type of length.

Get the current ByteOffset in the input byte sequence of the Decoder.

The Decoder does not provide any facility to get at the input data directly (since that is tricky with an incremental decoder). The next best is this primitive which can be used to keep track of the offset within the input bytes that makes up the encoded form of a term.

By keeping track of the byte offsets before and after decoding a subterm (a pattern captured by decodeWithByteSpan) and if the overall input data is retained then this is enables later retrieving the span of bytes for the subterm.

Canonical CBOR

https://tools.ietf.org/html/rfc7049#section-3.9

In general in CBOR there can be multiple representations for the same value, for example the integer 0 can be represented in 8, 16, 32 or 64 bits. This library always encoded values in the shortest representation but on decoding allows any valid encoding. For some applications it is useful or important to only decode the canonical encoding. The decoder primitives here are to allow applications to implement canonical decoding.

It is important to note that achieving a canonical representation is not simply about using these primitives. For example consider a typical CBOR encoding of a Haskell Set data type. This will be encoded as a CBOR list of the set elements. A typical implementation might be:

encodeSet = encodeList . Set.toList
decodeSet = fmap Set.fromList . decodeList

This does not enforce a canonical encoding. The decoder above will allow set elements in any order. The use of Set.fromList forgets the order. To enforce that the decoder only accepts the canonical encoding it will have to check that the elements in the list are strictly increasing. Similar issues arise in many other data types, wherever there is redundancy in the external representation.

The decoder primitives in this section are not much more expensive than their normal counterparts. If checking the canonical encoding property is critical then a technique that is more expensive but easier to implement and test is to decode normally, re-encode and check the serialised bytes are the same.

Decode canonical representation of a textual string as UTF-8 encoded ByteArray. Note that the result is not validated to be well-formed UTF-8.

Also note that this will eagerly copy the content out of the input to ensure that the input does not leak in the event that the ByteArray is live but not forced.

Sequence operations

2 declarations