json_mlake ยท API

json.document

Structs

Document

struct Document

Owns the JSON input bytes and a packed tape of entries.

A Document is the storage unit produced by parsers. A Value view references a tape entry inside a Document by index; when a Value is mutated, the document is materialized into an owned tree (OwnedValue in value/owned.mojo).

Side pools:

  • key_pool stores unescaped object keys. Object KEY entries store a pool offset rather than an offset into input, so unescaped keys survive even when the original bytes are released.
  • string_pool stores unescaped STRING values that needed materialisation (e.g. escapes). Clean strings stay zero-copy as STRING (offset, length) entries into input.
  • float_pool stores Float64 values, since 64-bit IEEE 754 doesn't fit in 60 bits.
  • int_pool holds integers too wide for the 60-bit inline payload, both signed (TAPE_TAG_INT_POOL) and unsigned (TAPE_TAG_UINT, stored as a bit pattern).

Implements Copyable, Movable

Fields
input: String
tape: List[UInt64]
key_pool: List[String]
string_pool: List[String]
float_pool: List[Float64]
int_pool: List[Int64]

__init__

def __init__(out self)
def __init__(out self, var input: String)

copy

def copy(self) -> Self

append_null

def append_null(mut self) -> Int

append_bool

def append_bool(mut self, b: Bool) -> Int

append_int

def append_int(mut self, value: Int64) -> Int

Append an integer, inline when it fits and pooled when not.

The inline payload is 60 bits, so anything outside [-259, 259) has to spill. It used to be truncated instead, which turned 576460752303423488 into its negative -- no error, no warning, a different number.

append_uint

def append_uint(mut self, value: UInt64) -> Int

Append a magnitude above Int64.MAX.

Stored as a bit pattern in the same pool; the tag is what says to read it back unsigned.

append_float

def append_float(mut self, value: Float64) -> Int

append_string

def append_string(mut self, offset: Int, length: Int) -> Int

Append a STRING entry referencing bytes [offset:offset+length] of input.

append_key

def append_key(mut self, var key: String) -> Int

Intern a key into key_pool and append a KEY entry referencing it.

append_key_inline

def append_key_inline(mut self, offset: Int, length: Int) -> Int

Append a zero-copy KEY entry referencing input[offset:offset+length].

Used for the by-far-common case where the JSON key contains no escapes -- avoids the per-key heap allocation, memcpy, and key_pool append.

append_string_owned

def append_string_owned(mut self, var value: String) -> Int

Append a STRING_OWNED entry whose bytes live in string_pool.

Used for JSON strings that contain escapes (where a zero-copy slice into input would expose the escaped bytes). Clean strings stay on the zero-copy append_string path.

append_array

def append_array(mut self, count: Int, child_start_idx: Int) -> Int

append_object

def append_object(mut self, pair_count: Int, child_start_idx: Int) -> Int

get_tag

def get_tag(self, tape_idx: Int) -> UInt8

get_payload

def get_payload(self, tape_idx: Int) -> UInt64

get_bool

def get_bool(self, tape_idx: Int) -> Bool

get_int

def get_int(self, tape_idx: Int) -> Int64

Read an integer entry, inline or pooled.

get_uint

def get_uint(self, tape_idx: Int) -> UInt64

Read an entry as an unsigned magnitude.

A TAPE_TAG_UINT entry is one that only fits here; the signed tags are accepted too so a caller can ask this question of any non-negative integer without checking the tag first.

get_float

def get_float(self, tape_idx: Int) -> Float64

get_string_offset

def get_string_offset(self, tape_idx: Int) -> Int

get_string_length

def get_string_length(self, tape_idx: Int) -> Int

get_string

def get_string(self, tape_idx: Int) -> String

Materialize a STRING / STRING_OWNED entry as a fresh String.

  • For TAPE_TAG_STRING (clean / zero-copy), the returned string is a fresh copy of the slice of input referenced by the (offset, length) payload. Safe even if input is later consumed.
  • For TAPE_TAG_STRING_OWNED (had escapes at parse time), the string is read out of string_pool and returned as-is.

key_equals

def key_equals(self, tape_idx: Int, key: String) -> Bool

Whether a KEY entry spells key, without materializing it.

get_key

def get_key(self, tape_idx: Int) -> String

Return the unescaped key for a KEY / KEY_INLINE entry.

Dispatches on the tag: TAPE_TAG_KEY is a key_pool index (used when the key had escapes, or when an upstream source produced the key as an owned string); TAPE_TAG_KEY_INLINE is a zero-copy (offset, length) slice into input that we copy out on read.

get_count

def get_count(self, tape_idx: Int) -> Int

Element count for ARRAY, pair count for OBJECT.

get_child_start

def get_child_start(self, tape_idx: Int) -> Int

Tape index where this container's children start.

root

def root(self) -> Int

Tape index of the root entry. Defined as the LAST entry, since builders write children before their parent so the parent can record a backwards-pointing child_start_idx.

size

def size(self) -> Int

Functions

pack_tape_entry

def pack_tape_entry(tag: UInt8, payload: UInt64) -> UInt64

Pack a 4-bit tag with a 60-bit payload into one tape entry.

tape_tag

def tape_tag(entry: UInt64) -> UInt8

Extract the 4-bit type tag from a tape entry.

tape_payload

def tape_payload(entry: UInt64) -> UInt64

Extract the 60-bit payload from a tape entry.

pack_pair

def pack_pair(hi30: UInt64, lo30: UInt64) -> UInt64

Pack two 30-bit unsigned values into a 60-bit payload.

payload_hi30

def payload_hi30(payload: UInt64) -> Int

Return the high 30 bits of a payload as an Int.

payload_lo30

def payload_lo30(payload: UInt64) -> Int

Return the low 30 bits of a payload as an Int.

Aliases

comptime TAPE_TAG_NULL = UInt8(0)
comptime TAPE_TAG_BOOL = UInt8(1)
comptime TAPE_TAG_INT = UInt8(2)
comptime TAPE_TAG_FLOAT = UInt8(3)
comptime TAPE_TAG_STRING = UInt8(4)
comptime TAPE_TAG_ARRAY = UInt8(5)
comptime TAPE_TAG_OBJECT = UInt8(6)
comptime TAPE_TAG_KEY = UInt8(7)
comptime TAPE_TAG_STRING_OWNED = UInt8(8)
comptime TAPE_TAG_KEY_INLINE = UInt8(9)
comptime TAPE_TAG_INT_POOL = UInt8(10)
comptime TAPE_TAG_UINT = UInt8(11)