#bytebuilder

A buffer for building byte arrays.

A Builder collects bytes in emission order. Create one with newBuilder, append with the emit functions, and take the result with buildArray or buildBytes. Each emit function writes the byte order that byteparser's matching reader expects, so a value written here and read there comes back unchanged.

#The builder

#Builder

data Builder  -- abstract: the constructors are not exported

A byte buffer. Build one with newBuilder.

#newBuilder

newBuilder : Unit -> Builder

A new, empty builder. The backing block grows on the first emit.

#buildArray

buildArray : Builder -> Array Int

The bytes emitted so far, as an array.

#buildBytes

buildBytes : Builder -> Bytes

The bytes emitted so far, as a Bytes.

The packed counterpart of buildArray: the same bytes in the same order, one byte each rather than one boxed machine word each. The result is a copy, so emitting more afterwards does not reach it.

> let buf = newBuilder () in let _ = emitBytes (fromArrayAssumeByteDomain [|0, 128, 255|]) buf in debug (buildBytes buf)
"Bytes \"0080ff\""

#Emitting

#emitU8

emitU8 : U8 -> Builder -> Unit
emitU8 v _

Appends one byte.

#emitBytes

emitBytes : Bytes -> Builder -> Unit
emitBytes src _

Appends every byte of src, in order.

The backing block grows at most once per call, so appending n bytes costs O(n) whatever the builder's current capacity.

> let buf = newBuilder () in let _ = emitBytes (encodeUtf8 "hi") buf in let _ = emitBytes (encodeUtf8 "!") buf in debug (buildBytes buf)
"Bytes \"686921\""
> let buf = newBuilder () in let _ = emitBytes (encodeUtf8 "") buf in debug (buildBytes buf)
"Bytes \"\""

#builderParts

builderParts : Builder -> (MutBytes, Int)

The builder's backing block, and the number of bytes emitted so far, without copying.

The block is the builder's own, so it may be longer than the count, and bytes at or past the count are unwritten scratch. A later emit writes into that block or replaces it, so read the counted bytes before emitting again. It is a MutBytes rather than a Bytes because it changes under the builder: it cannot be compared, hashed or kept as a value. buildBytes is the copying form.

> let buf = newBuilder () in let _ = emitBytes (encodeUtf8 "hey") buf in let (_, n) = builderParts buf in n
3

#emitU16BE

emitU16BE : U16 -> Builder -> Unit
emitU16BE v buf

Appends a U16 as two bytes, most significant byte first. The inverse of byteparser.beU16.

#emitU24BE

emitU24BE : Int -> Builder -> Unit
emitU24BE v buf

Appends a three-byte unsigned integer, most significant byte first. The inverse of beUint 3.

#emitU32BE

emitU32BE : U32 -> Builder -> Unit
emitU32BE v buf

Appends a U32 as four bytes, most significant byte first. The inverse of byteparser.beU32.

#emitU64BE

emitU64BE : U64 -> Builder -> Unit
emitU64BE v buf

Appends a U64 as eight bytes, most significant byte first. The inverse of byteparser.beU64.

#emitU16LE

emitU16LE : U16 -> Builder -> Unit
emitU16LE v buf

Appends a U16 as two bytes, least significant byte first. The inverse of byteparser.leU16.

#emitU24LE

emitU24LE : Int -> Builder -> Unit
emitU24LE v buf

Appends a three-byte unsigned integer, least significant byte first. The inverse of leUint 3.

#emitU32LE

emitU32LE : U32 -> Builder -> Unit
emitU32LE v buf

Appends a U32 as four bytes, least significant byte first. The inverse of byteparser.leU32.

#emitU64LE

emitU64LE : U64 -> Builder -> Unit
emitU64LE v buf

Appends a U64 as eight bytes, least significant byte first. The inverse of byteparser.leU64.

#emitBeSint

emitBeSint : Int -> Int -> Builder -> Unit
emitBeSint nbytes v buf

Appends a signed integer as nbytes bytes in two's complement, most significant byte first. The inverse of beSint nbytes.

#emitBeUint

emitBeUint : Int -> Int -> Builder -> Unit
emitBeUint n v buf

Appends a non-negative integer as nbytes bytes, most significant byte first. The inverse of beUint nbytes.

#emitLeSint

emitLeSint : Int -> Int -> Builder -> Unit
emitLeSint nbytes v buf

Appends a signed integer as nbytes bytes in two's complement, least significant byte first. The inverse of leSint nbytes.

#emitLeUint

emitLeUint : Int -> Int -> Builder -> Unit
emitLeUint n v buf

Appends a non-negative integer as nbytes bytes, least significant byte first. The inverse of leUint nbytes.