BinaryParser

BinaryParser

class BinaryParser

Tool for reading bytes from a reader while supporting position tracking for error reporting purposes.

Constructors

<init>

constructor(reader: InputStream, fileName: String)

Parameters

Name Description
reader: InputStream
fileName: String

<init>

constructor(reader: InputStream, parseContext: ParseContext)

Tool for reading bytes from a reader while supporting position tracking for error reporting purposes.

Parameters

Name Description
reader: InputStream
parseContext: ParseContext

Methods

readByte

fun readByte(): Byte

Reads a single Byte from the reader.

From the docs:

Bytes encode themselves.


byte    ::= 0x00    => 0x00
0xFF    => 0xFF

ReturnValue

Name Description
Byte

readByteOrNull

fun readByteOrNull(): Byte?

Reads a single Byte from the reader, or returns null if the reader is empty.

ReturnValue

Name Description
Byte?

readFourBytes

fun readFourBytes(): Int

Reads the next four bytes from the reader as a little-endian-encoded Int.

ReturnValue

Name Description
Int

readEightBytes

fun readEightBytes(): Long

Reads the next eight bytes from the reader as a little-endian-encoded Long.

ReturnValue

Name Description
Long

readBytes

fun readBytes(size: Int): ByteArray

Reads size bytes from the reader into a new ByteArray.

Parameters

Name Description
size: Int

ReturnValue

Name Description
ByteArray

throwException

fun throwException(message: String, positionOffset: Int): Nothing

Throws a ParseException with the given message at the current position plus the provided positionOffset.

Parameters

Name Description
message: String
positionOffset: Int

ReturnValue

Name Description
Nothing

Extensions

readControlInstruction

fun BinaryParser.readControlInstruction(opcode: Int): ControlInstruction

From the docs:

Control instructions have varying encodings. For structured instructions, the instruction sequences forming nested blocks are terminated with explicit opcodes for end and else.

Block types are encoded in special compressed form, by either the byte 0x40 indicating the empty type, as a single value type, or as a type index encoded as a positive signed integer.


blocktype   ::= 0x40                                => ϵ
t:valtype                           => t
x:s33                               => x (if x >= 0)
instr       ::= 0x00                                => unreachable
0x01                                => nop
0x02 bt:blocktype (in:instr)* 0x0B  => block bt in* end
0x03 bt:blocktype (in:instr)* 0x0B  => loop bt in* end
0x04 bt:blocktype (in:instr)* 0x0B  => if bt in* else ϵ end
0x04 bt:blocktype (in1:instr)* 0x05 (in2:instr)* 0x0B
=> if bt in1 else in2 end
0x0C l:labelidx                     => br l
0x0D l:labelidx                     => br_if l
0x0E l*:vec(labelidx) l_N:labelidx  => br_table l* l_N
0x0F                                => return
0x10 x:funcidx                      => call x
0x11 x:typeidx 0x00                 => call_indirect x

Note The else opcode 0x05 in the encoding of an if instruction can be omitted if the following instruction sequence is empty.

Unlike any other occurrence, the type index in a block type is encoded as a positive signed integer, so that its signed LEB128 bit pattern cannot collide with the encoding of value types or the special code 0x40, which correspond to the LEB128 encoding of negative integers. To avoid any loss in the range of allowed indices, it is treated as a 33 bit signed integer.

In future versions of WebAssembly, the zero byte occurring in the encoding of the call_indirect instruction may be used to index additional tables.

Receiver

Name Description
BinaryParser

Parameters

Name Description
opcode: Int

ReturnValue

Name Description
ControlInstruction

readExpression

fun BinaryParser.readExpression(): Expression

From the docs:

Expressions are encoded by their instruction sequence terminated with an explicit 0x0B opcode for end.


expr ::= (in:instr)* 0x0B => in* end

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
Expression

readInstruction

fun BinaryParser.readInstruction(): Instruction?

Parses an instruction given the opcode byte provided, or throws a ParseException if no instruction can be found for the provided opcode. Returns null if end was read.

From the docs:

Instructions are encoded by opcodes. Each opcode is represented by a single byte, and is followed by the instruction’s immediate arguments, where present. The only exception are structured control instructions, which consist of several opcodes bracketing their nested instruction sequences.

Note

Gaps in the byte code ranges for encoding instructions are reserved for future extensions.

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
Instruction?

readMemoryInstruction

fun BinaryParser.readMemoryInstruction(opcode: Int): Instruction

From the docs:

Each variant of memory instruction is encoded with a different byte code. Loads and stores are followed by the encoding of their memarg immediate.


memarg  ::=     a:u32 o:u32 => {align a, offset o}
instr   ::=     0x28 m:memarg => i32.load m
0x29 m:memarg => i64.load m
0x2A m:memarg => f32.load m
0x2B m:memarg => f64.load m
0x2C m:memarg => i32.load8_s m
0x2D m:memarg => i32.load8_u m
0x2E m:memarg => i32.load16_s m
0x2F m:memarg => i32.load16_u m
0x30 m:memarg => i64.load8_s m
0x31 m:memarg => i64.load8_u m
0x32 m:memarg => i64.load16_s m
0x33 m:memarg => i64.load16_u m
0x34 m:memarg => i64.load32_s m
0x35 m:memarg => i64.load32_u m
0x36 m:memarg => i32.store m
0x37 m:memarg => i64.store m
0x38 m:memarg => f32.store m
0x39 m:memarg => f64.store m
0x3A m:memarg => i32.store8 m
0x3B m:memarg => i32.store16 m
0x3C m:memarg => i64.store8 m
0x3D m:memarg => i64.store16 m
0x3E m:memarg => i64.store32 m
0x3F 0x00     => memory.size
0x40 0x00     => memory.grow

Note In future versions of WebAssembly, the additional zero bytes occurring in the encoding of the memory.size and memory.grow instructions may be used to index additional memories.

Receiver

Name Description
BinaryParser

Parameters

Name Description
opcode: Int

ReturnValue

Name Description
Instruction

readMemoryArg

fun BinaryParser.readMemoryArg(): MemArg

Reads a MemArg node from the binary stream.

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
MemArg

readNumericInstruction

fun BinaryParser.readNumericInstruction(opcode: Int): Instruction

From the docs :

All variants of numeric instructions are represented by separate byte codes.

The const instructions are followed by the respective literal.


instr   ::= 0x41 n:i32  =>  i32.const n
0x42 n:i64  =>  i64.const n
0x43 z:f32  =>  f32.const z
0x44 z:f64  =>  f64.const z

All other numeric instructions are plain opcodes without any immediates.


instr   ::= 0x45    => i32.eqz
0x46    => i32.eq
0x47    => i32.ne
0x48    => i32.lt_s
0x49    => i32.lt_u
0x4A    => i32.gt_s
0x4B    => i32.gt_u
0x4C    => i32.le_s
0x4D    => i32.le_u
0x4E    => i32.ge_s
0x4F    => i32.ge_u

            0x50    => i64.eqz
            0x51    => i64.eq
            0x52    => i64.ne
            0x53    => i64.lt_s
            0x54    => i64.lt_u
            0x55    => i64.gt_s
            0x56    => i64.gt_u
            0x57    => i64.le_s
            0x58    => i64.le_u
            0x59    => i64.ge_s
            0x5A    => i64.ge_u

            0x5B    => f32.eq
            0x5C    => f32.ne
            0x5D    => f32.lt
            0x5E    => f32.gt
            0x5F    => f32.le
            0x60    => f32.ge

            0x61    => f64.eq
            0x62    => f64.ne
            0x63    => f64.lt
            0x64    => f64.gt
            0x65    => f64.le
            0x66    => f64.ge

            0x67    => i32.clz
            0x68    => i32.ctz
            0x69    => i32.popcnt
            0x6A    => i32.add
            0x6B    => i32.sub
            0x6C    => i32.mul
            0x6D    => i32.div_s
            0x6E    => i32.div_u
            0x6F    => i32.rem_s
            0x70    => i32.rem_u
            0x71    => i32.and
            0x72    => i32.or
            0x73    => i32.xor
            0x74    => i32.shl
            0x75    => i32.shr_s
            0x76    => i32.shr_u
            0x77    => i32.rotl
            0x78    => i32.rotr

            0x79    => i64.clz
            0x7A    => i64.ctz
            0x7B    => i64.popcnt
            0x7C    => i64.add
            0x7D    => i64.sub
            0x7E    => i64.mul
            0x7F    => i64.div_s
            0x80    => i64.div_u
            0x81    => i64.rem_s
            0x82    => i64.rem_u
            0x83    => i64.and
            0x84    => i64.or
            0x85    => i64.xor
            0x86    => i64.shl
            0x87    => i64.shr_s
            0x88    => i64.shr_u
            0x89    => i64.rotl
            0x8A    => i64.rotr

            0x8B    => f32.abs
            0x8C    => f32.neg
            0x8D    => f32.ceil
            0x8E    => f32.floor
            0x8F    => f32.trunc
            0x90    => f32.nearest
            0x91    => f32.sqrt
            0x92    => f32.add
            0x93    => f32.sub
            0x94    => f32.mul
            0x95    => f32.div
            0x96    => f32.min
            0x97    => f32.max
            0x98    => f32.copysign

            0x99    => f64.abs
            0x9A    => f64.neg
            0x9B    => f64.ceil
            0x9C    => f64.floor
            0x9D    => f64.trunc
            0x9E    => f64.nearest
            0x9F    => f64.sqrt
            0xA0    => f64.add
            0xA1    => f64.sub
            0xA2    => f64.mul
            0xA3    => f64.div
            0xA4    => f64.min
            0xA5    => f64.max
            0xA6    => f64.copysign

            0xA7    => i32.wrap_i64
            0xA8    => i32.trunc_f32_s
            0xA9    => i32.trunc_f32_u
            0xAA    => i32.trunc_f64_s
            0xAB    => i32.trunc_f64_u

            0xAC    => i64.extend_i32_s
            0xAD    => i64.extend_i32_u
            0xAE    => i64.trunc_f32_s
            0xAF    => i64.trunc_f32_u
            0xB0    => i64.trunc_f64_s
            0xB1    => i64.trunc_f64_u

            0xB2    => f32.convert_i32_s
            0xB3    => f32.convert_i32_u
            0xB4    => f32.convert_i64_s
            0xB5    => f32.convert_i64_u
            0xB6    => f32.demote_f64

            0xB7    => f64.convert_i32_s
            0xB8    => f64.convert_i32_u
            0xB9    => f64.convert_i64_s
            0xBA    => f64.convert_i64_u
            0xBB    => f64.promote_f32

            0xBC    => i32.reinterpret_f32
            0xBD    => i64.reinterpret_f64
            0xBE    => f32.reinterpret_i32
            0xBF    => f64.reinterpret_i64

            0xC0    => i32.extend8_s
            0xC1    => i32.extend16_s
            0xC2    => i64.extend8_s
            0xC3    => i64.extend16_s
            0xC4    => i64.extend32_s

The saturating truncation instructions all have a one byte prefix, whereas the actual opcode is encoded by a variable-length unsigned integer.


    instr   ::=     0xFC 0:u32  => i32.trunc_sat_f32_s
                    0xFC 1:u32  => i32.trunc_sat_f32_u
                    0xFC 2:u32  => i32.trunc_sat_f64_s
                    0xFC 3:u32  => i32.trunc_sat_f64_u
                    0xFC 4:u32  => i64.trunc_sat_f32_s
                    0xFC 5:u32  => i64.trunc_sat_f32_u
                    0xFC 6:u32  => i64.trunc_sat_f64_s
                    0xFC 7:u32  => i64.trunc_sat_f64_u

Receiver

Name Description
BinaryParser

Parameters

Name Description
opcode: Int

ReturnValue

Name Description
Instruction

readParametricInstruction

fun BinaryParser.readParametricInstruction(opcode: Int): ParametricInstruction

From the docs:

Parametric instructions are represented by single byte codes.


instr   ::= 0x1A => drop
0x1B => select

Receiver

Name Description
BinaryParser

Parameters

Name Description
opcode: Int

ReturnValue

Name Description
ParametricInstruction

readVariableInstruction

fun BinaryParser.readVariableInstruction(opcode: Int): VariableInstruction

From the docs:

Variable instructions are represented by byte codes followed by the encoding of the respective index.


instr ::=   0x20 x:localidx     => local.get x
0x21 x:localidx     => local.set x
0x22 x:localidx     => local.tee x
0x23 x:globalidx    => global.get x
0x24 x:globalidx    => global.set x

Receiver

Name Description
BinaryParser

Parameters

Name Description
opcode: Int

ReturnValue

Name Description
VariableInstruction

readCodeSection

fun BinaryParser.readCodeSection(): CodeSection

From the docs:

The code section has the id 10. It decodes into a vector of code entries that are pairs of value type vectors and expressions. They represent the locals and body field of the functions in the funcs component of a module. The type fields of the respective functions are encoded separately in the function section.

The encoding of each code entry consists of

  • the u32 size of the function code in bytes,
  • the actual function code, which in turn consists of
  • the declaration of locals,
  • the function body as an expression.

Local declarations are compressed into a vector whose entries consist of

  • a u32 count,
  • a value type, denoting count locals of the same value type.

codesec ::= code*:section_10(vec(code)) => code*
code    ::= size:u32 code:func          => code (if size = ||func||)
func    ::= (t*):vec(locals) e:expr    => concat((t)), e (if |concat((t*)*)| < 2^32)
locals  ::= n:u32 t:valtype             => t^n

Here, code ranges over pairs (valtype*, expr). The meta function concat((t*)*) concatenates all sequences t*_i in (t*)*. Any code for which the length of the resulting sequence is out of bounds of the maximum size of a vector is malformed.

Note

Like with sections, the code size is not needed for decoding, but can be used to skip functions when navigating through a binary. The module is malformed if a size does not match the length of the respective function code.

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
CodeSection

readCustomSection

fun BinaryParser.readCustomSection(totalSize: Int): CustomSection

From the docs:

Custom sections have the id 0. They are intended to be used for debugging information or third-party extensions, and are ignored by the WebAssembly semantics. Their contents consist of a name further identifying the custom section, followed by an uninterpreted sequence of bytes for custom use.


customsec   ::= section_0(custom)
custom      ::= name byte*

Note If an implementation interprets the data of a custom section, then errors in that data, or the placement of the section, must not invalidate the module.

Receiver

Name Description
BinaryParser

Parameters

Name Description
totalSize: Int

ReturnValue

Name Description
CustomSection

readDataSection

fun BinaryParser.readDataSection(): DataSection

From the docs:

The data section has the id 11. It decodes into a vector of data segments that represent the data component of a module.


datasec ::= seg*:section_11(vec(data))      => seg
data    ::= x:memidx e:expr b*:vec(byte)    => {data x, offset e, init b*}

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
DataSection

readElementSection

fun BinaryParser.readElementSection(): ElementSection

From the docs:

The element section has the id 9. It decodes into a vector of element segments that represent the elem component of a module.


elemsec ::= seg*:section_9(vec(elem))           => seg
elem    ::= x:tableidx e:expr y*:vec(funcidx)   => {table x, offset e, init y*}

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
ElementSection

readElementSegment

fun BinaryParser.readElementSegment(): ElementSegment

Reads an ElementSegment from a binary-encoded WebAssembly module's ElementSection.

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
ElementSegment

readExportSection

fun BinaryParser.readExportSection(): ExportSection

From the docs:

The export section has the id 7. It decodes into a vector of exports that represent the exports component of a module.


exportsec   ::= ex*:section_7(vec(export))  => ex*
export      ::= nm:name d:exportdesc        => {name nm, desc d}
exportdesc  ::= 0x00 x:funcidx              => func x
0x01 x:tableidx             => table x
0x02 x:memidx               => mem x
0x03 x:globalidx            => global x

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
ExportSection

readFunctionSection

fun BinaryParser.readFunctionSection(): FunctionSection

From the docs:

The function section has the id 3. It decodes into a vector of type indices that represent the type fields of the functions in the funcs component of a module. The locals and body fields of the respective functions are encoded separately in the code section.


funcsec ::= x*:section_3(vec(typeidx))  => x*

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
FunctionSection

readGlobalSection

fun BinaryParser.readGlobalSection(): GlobalSection

From the docs:

The global section has the id 6. It decodes into a vector of globals that represent the globals component of a module.


globalsec   ::= glob*:section_6(vec(global))    => glob*
global      ::= gt:globaltype e:expr            => {type gt, init e}

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
GlobalSection

readImportSection

fun BinaryParser.readImportSection(): ImportSection

From the docs:

The import section has the id 2. It decodes into a vector of imports that represent the imports component of a module.


importsec   ::= im*:section_2(vec(import))      => im*
import      ::= mod:name nm:name d:importdesc   => {module mod, name nm, desc d}
importdesc  ::= 0x00 x:typeidx                  => func x
0x01 tt:tabletype               => table tt
0x02 mt:memtype                 => mem mt
0x03 gt:globaltype              => global gt

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
ImportSection

readIndex

fun <T : Identifier> BinaryParser.readIndex(): Index<T>

From the docs:

All indices are encoded with their respective value.


typeidx     ::= x:u32 => x
funcidx     ::= x:u32 => x
tableidx    ::= x:u32 => x
memidx      ::= x:u32 => x
globalidx   ::= x:u32 => x
localidx    ::= x:u32 => x
labelidx    ::= l:u32 => l

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
Index<T>

readFuncLocals

fun BinaryParser.readFuncLocals(): List<Local>

From the code section docs:

Local declarations are compressed into a vector whose entries consist of

  • a u32 count,
  • a value type, denoting count locals of the same value type.

func    ::= (t*):vec(locals) e:expr    => concat((t)), e (if |concat((t*)*)| < 2^32)
locals  ::= n:u32 t:valtype             => tn

The meta function concat((t*)*) concatenates all sequences t*_i in (t*)*.

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
List<Local>

readMemorySection

fun BinaryParser.readMemorySection(): MemorySection

From the docs:

The memory section has the id 5. It decodes into a vector of memories that represent the mems component of a module.


memsec  ::= mem*:section_5(vec(mem))    => mem*
mem     ::= mt:memtype                  =>

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
MemorySection

readOffset

fun BinaryParser.readOffset(): Offset

Reads an Offset from a binary-encoded WebAssembly module.

Offsets are encoded as expressions.

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
Offset

readSection

fun BinaryParser.readSection(): Section?

From the docs:

Each section consists of

  • a one-byte section id,
  • theu32 size of the contents, in bytes,
  • the actual contents, whose structure is depended on the section id.

Every section is optional; an omitted section is equivalent to the section being present with empty contents.

The following parameterized grammar rule defines the generic structure of a section with id N and contents described by the grammar B.


section_N(B)    ::= N:byte size:u32 cont:B  => cont (if size = ||B||)
ϵ                       => ϵ

Note Other than for unknown custom sections, the size is not required for decoding, but can be used to skip sections when navigating through a binary. The module is malformed if the size does not match the length of the binary contents B.

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
Section?

readStartSection

fun BinaryParser.readStartSection(): StartSection

From the docs:

The start section has the id 8. It decodes into an optional start function that represents the start component of a module.


startsec    ::= st?:section_8(start)    => st?
start       ::= x:funcidx               =>

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
StartSection

readTableSection

fun BinaryParser.readTableSection(): TableSection

From the docs:

The table section has the id 4. It decodes into a vector of tables that represent the tables component of a module.


tablesec    ::= tab*:section_4(vec(table))  => tab*
table       ::= tt:tabletype                =>

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
TableSection

readTypeSection

fun BinaryParser.readTypeSection(): TypeSection

From the docs:

The type section has the id 1. It decodes into a vector of function types that represent the 𝗍𝗒𝗉𝖾𝗌 component of a module.


typesec ::= ft*:section_1(vec(functype)) => ft*

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
TypeSection

readModule

fun BinaryParser.readModule(): WasmModule

From the docs:

The encoding of a module starts with a preamble containing a 4-byte magic number (the string ‘∖0asm’) and a version field. The current version of the WebAssembly binary format is 1.

The preamble is followed by a sequence of sections. Custom sections may be inserted at any place in this sequence, while other sections must occur at most once and in the prescribed order. All sections can be empty.

The lengths of vectors produced by the (possibly empty) function and code section must match up.


magic   ::= 0x00 0x61 0x73 0x6D
version ::= 0x01 0x00 0x00 0x00
module  ::= magic
version
customsec*
functype*:typesec
customsec*
import*:importsec
customsec*
typeidx^n:funcsec
customsec*
table*:tablesec
customsec*
mem*:memsec
customsec*
global*:globalsec
customsec*
export*:exportsec
customsec*
start?:startsec
customsec*
elem*:elemsec
customsec*
code^n:codesec
customsec*
data*:datasec
customsec*          => {types functype*,
funcs func^n,
tables table*,
mems mem*,
globals global*,
elem elem*,
data data*,
start start?,
imports import*,
exports export*}

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
WasmModule

readFunctionType

fun BinaryParser.readFunctionType(): FunctionType

From the docs:

Function types are encoded by the byte 0x60 followed by the respective vectors of parameter and result types.


functype    ::= 0x60 rt1:resulttype rt2:resulttype  =>  rt1 → rt2

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
FunctionType

readGlobalType

fun BinaryParser.readGlobalType(): GlobalType

From the docs:

Global types are encoded by their value type and a flag for their mutability.


globaltype  ::= t:valtype m:mut => m
tmut        ::= 0x00            => const
0x01            => var

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
GlobalType

readLimits

fun BinaryParser.readLimits(): Limits

From the docs:

Limits are encoded with a preceding flag indicating whether a maximum is present.


limits  ::=     0x00 n:u32          => {min n, max ϵ}
0x01 n:u32 m:u32    => {min n, max m}

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
Limits

readMemoryType

fun BinaryParser.readMemoryType(): MemoryType

From the docs:

Memory types are encoded with their limits.


memtype ::=     lim:limits  =>  lim

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
MemoryType

readResultType

fun BinaryParser.readResultType(): ResultType

From the docs:

Result types are encoded by the respective vectors of value types `.


resulttype   ::= t*:vec(valtype) =>  [t*]

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
ResultType

readTableType

fun BinaryParser.readTableType(): TableType

From the docs:

Table types are encoded with their limits and a constant byte indicating their element type.


tabletype   ::=     et:elemtype lim:limits  => lim et
elemtype    ::=     0x70                    => funcref

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
TableType

readValueType

fun BinaryParser.readValueType(): ValueType

From the docs:

Value types are encoded by a single byte.


valtype ::= 0x7F    =>  i32
0x7E    =>  i64
0x7D    =>  f32
0x7C    =>  f64

Note

Value types can occur in contexts where type indices are also allowed, such as in the case of block types. Thus, the binary format for types corresponds to the signed LEB128 encoding of small negative sN values, so that they can coexist with (positive) type indices in the future.

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
ValueType

readFloat

fun BinaryParser.readFloat(): Float

From the docs:

Floating-point values are encoded directly by their IEEE 754-2019 (Section 3.4) bit pattern in little endian byte order:


fN  ::= b∗:byte^N/8     =>  bytes^−1_fN(b∗)

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
Float

readDouble

fun BinaryParser.readDouble(): Double

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
Double

readUInt

fun BinaryParser.readUInt(): Int

From the docs:

All integers are encoded using the LEB128 variable-length integer encoding, in either unsigned or signed variant.

Unsigned integers are encoded in unsigned LEB128 format. As an additional constraint, the total number of bytes encoding a value of type uN must not exceed ceil(N/7) bytes.


uN  ::= n:byte              => n                    (if n < 2^7 and n < 2^N)
n:byte  m:u(N−7)    => 2^7 * m + (n - 2^7)  (if n >= 2^7 and N > 7)

Signed integers are encoded in signed LEB128 format, which uses a two’s complement representation. As an additional constraint, the total number of bytes encoding a value of type sN must not exceed ceil(N/7) bytes.


sN  ::= n:byte              => n                    (if n<26 and n < 2^(N−1))
n:byte              => n - 2^7              (if 26 <= n < 27 and n >= 2^7 - 2^(N−1))
n:byte  m:s(N−7)    => 2^7 * m + (n - 2^7)  (if n >= 27 and N > 7)

Uninterpreted integers are encoded as signed integers.
    iN  ::= n:sN                => i                    (if n = signed_iN(i))


**Note**

The side conditions `N > 7` in the productions for non-terminal bytes of the `u` and `s`
encodings restrict the encoding’s length. However, “trailing zeros” are still allowed within
these bounds. For example, `0x03` and `0x83 0x00` are both well-formed encodings for the value
`3` as a u8. Similarly, either of `0x7e` and `0xFE 0x7F` and `0xFE 0xFF 0x7F` are well-formed
encodings of the value `−2` as a `s16`.

The side conditions on the value `n` of terminal bytes further enforce that any unused bits in
these bytes must be `0` for positive values and 1 for negative ones. For example, `0x83 0x10` is
malformed as a `u8` encoding. Similarly, both `0x83 0x3E` and `0xFF 0x7B` are malformed as s8
encodings.

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
Int

readInt

fun BinaryParser.readInt(): Int

See BinaryParser.readUInt.

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
Int

readULong

fun BinaryParser.readULong(): Long

See BinaryParser.readUInt.

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
Long

readLong

fun BinaryParser.readLong(): Long

See BinaryParser.readUInt.

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
Long

readName

fun BinaryParser.readName(): String

From the docs:

Names are encoded as a vector of bytes containing the Unicode (Section 3.9) UTF-8 encoding of the name’s character sequence.


name    ::= b∗:vec(byte)    =>  name (if utf8(name)=b∗)

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
String

readVector

fun BinaryParser.readVector(): List<Byte>

From the docs:

Vectors are encoded with their u32 length followed by the encoding of their element sequence.


vec(B)  ::= n:u32 (x:B)n   =>  x^n

Receiver

Name Description
BinaryParser

ReturnValue

Name Description
List<Byte>

readVector

fun <T> BinaryParser.readVector(block: BinaryParser.()->T): List<T>

From the docs:

Vectors are encoded with their u32 length followed by the encoding of their element sequence.


vec(B)  ::= n:u32 (x:B)n   =>  x^n

Receiver

Name Description
BinaryParser

Parameters

Name Description
block: BinaryParser.()->T

ReturnValue

Name Description
List<T>