| slug | /model/core |
|---|---|
| title | Core reading patterns |
| sidebar_position | 2 |
This page records the core BinaryParsec helpers that were justified by the snippet milestones.
It is not generated API reference. It is a usage map for the contiguous parser surface.
If you are new to the library, start with Parse Your First Sized Message before using this page as a checklist.
- A
ContiguousParser<'T>is a parser value that knows how to read a'Tfrom contiguous bytes. - Parser bindings such as
let message = ...usually name the thing being parsed, not an already-parsed result. Contiguous.runexecutes the parser against an input span.ByteSliceis a zero-copy(offset, length)descriptor into the original input, not a copied payload array.open BinaryParsec.Syntaxis the recommended parser-writing style when you want the binary layout to stay visually dominant.
The most common control-flow pattern is:
- read one field
- use that field to decide the next read
For example, a 4-byte size prefix followed by that many payload bytes:
open BinaryParsec.Syntax
let message =
parse {
let! size = u32be
let! payload = takeSlice (int size)
return size, payload
}When the payload should be parsed immediately rather than kept as a slice, prefer parseExactly:
open BinaryParsec.Syntax
let payload =
parse {
let! command = ``byte``
let! argument = u16be
return command, argument
}
let message =
parse {
let! payloadLength = ``byte``
let! parsedPayload = parseExactly (int payloadLength) payload
return payloadLength, parsedPayload
}Contiguous.runRuns a parser fromParsePosition.originand returnsParseResult<'T>.Contiguous.runWithRuns a parser from an explicit starting position.Contiguous.positionReturns the currentParsePositionwithout consuming input.Contiguous.requireByteAlignedFails if the current cursor is not at a byte boundary.Contiguous.remainingBytesReturns the number of unread bytes from the current cursor.ParsePosition.originThe byte0, bit0starting position.ParsePosition.createCreates a validated explicit position.
Use these when parser control flow or diagnostics depend on the current cursor.
Contiguous.byteReads one byte.Contiguous.peekByteReads one byte without advancing.Contiguous.skipAdvances by a byte count.Contiguous.takeReturns a zero-copy slice of the nextcountbytes (aliased astakeSliceinSyntax).Contiguous.expectBytesMatches an exact byte sequence and returns its slice.Contiguous.takeRemainingMinusReturns all remaining bytes except a fixed trailing count.Contiguous.takeRemainingReturns all remaining unread bytes as one slice.ByteSlice.createCreates a validated zero-copy slice descriptor.ByteSlice.asSpanResolves aByteSliceback to aReadOnlySpan<byte>.
These helpers cover fixed signatures, bounded payload reads, framing bytes, and zero-copy payload exposure.
Contiguous.u16beContiguous.u16leContiguous.u32beContiguous.u32leContiguous.u64beContiguous.u64le
Use the endian-specific primitive that matches the format definition directly. Do not read raw bytes and reassemble them manually unless a measured hot path demands it.
Contiguous.bitReads one most-significant-bit-first flag.Contiguous.bitsReads1to32bits in most-significant-bit-first order.Contiguous.bitsLsbFirstReads1to32bits in least-significant-bit-first order.
Use bit and bits for register-style layouts such as controller headers. Use bitsLsbFirst for formats such as DEFLATE that define low-bit-first extraction.
Byte-oriented primitives still require byte alignment. Mixed byte and bit parsing should make alignment boundaries explicit in parser code using requireByteAligned.
Contiguous.varUInt64Reads one unsigned 64-bit varint.Contiguous.takeVarintPrefixedReads a varint length prefix followed by that many bytes as aByteSlice(aliased astakeVarintSliceinSyntax).
These helpers were added for Protocol Buffers wire-format style parsing, but they are also appropriate for other varint-length-prefixed binary layouts.
Contiguous.resultLifts a value into a parser without consuming input.Contiguous.failAtBuilds an explicit parse failure at a chosen cursor.Contiguous.failBuilds a failing parser at a chosen cursor.Contiguous.labelAttaches a label to a parser to improve error messages (aliased as<?>inSyntax).Contiguous.mapMaps a parser result without changing consumption.Contiguous.map2Combines two fixed-shape parsers without intermediate allocations.Contiguous.mergeSourcesReturns a struct tuple from two fixed-shape parsers.Contiguous.bindChooses the next parser from the previous value.Contiguous.zipSequences two parsers into a normal tuple.Contiguous.keepLeftRuns two parsers and keeps the left value.Contiguous.keepRightRuns two parsers and keeps the right value.Contiguous.choiceChooses between multiple parsers (aliased as<|>inSyntax).Contiguous.optionalAttempts to run a parser, returningNoneif it fails.Contiguous.many/Contiguous.many1Runs a parser zero/one or more times until it fails.Contiguous.sepBy/Contiguous.sepBy1Parses a sequence of items separated by a separator.Contiguous.betweenRuns a parser surrounded by open and close parsers.Contiguous.parseComputation-expression builder for parser composition.Contiguous.parseExactlyParses exactly the next bounded byte range as a nested payload.Contiguous.parseRemainingParses all remaining unread bytes as one bounded nested payload.
When BinaryParsec.Syntax is open, the following FParsec-style operators are available:
>>=:bind<!>:map|>>:map(piped).>>.:zip.>>:keepLeft>>.:keepRight<|>:choicebetween two parsers<?>:label
Contiguous.readAtRuns a parser at an absolute byte offset and then restores the original cursor.
Use this for dependent layouts such as ELF tables. Keep the offset calculation and validation in the caller so the jump stays visible and format-specific.