peekNextTokenType
Seeks ahead in the input until the first byte of the next token (or the end of the input)
determines which type of token will be returned from the next next*() call.
This function is idempotent, only advancing past commas, colons, and inter-token whitespace.
Function parameters
Parameters
- self:*@This()
The tokens emitted by `std.json.Scanner` and `std.json.Reader` `.next*()` functions follow this grammar:
Types
- Token
- The tokens emitted by `std.json.Scanner` and `std.json.Reader` `.next*()` functions follow this grammar:
- TokenType
- This is only used in `peekNextTokenType()` and gives a categorization based on the first byte of the next token that will be emitted from a `next*()` call.
- Diagnostics
- To enable diagnostics, declare `var diagnostics = Diagnostics{};` then call `source.enableDiagnostics(&diagnostics);`
- AllocWhen
- See the documentation for `std.json.Token`.
- Reader
- All `next*()` methods here handle `error.BufferUnderrun` from `std.json.Scanner`, and then read from the reader.
The allocator is only used to track `[]` and `{}` nesting levels.
Functions
- initStreaming
- The allocator is only used to track `[]` and `{}` nesting levels.
- initCompleteInput
- Use this if your input is a single slice.
- feedInput
- Call this whenever you get `error.BufferUnderrun` from `next()`.
- endInput
- Call this when you will no longer call `feedInput()` anymore.
- nextAlloc
- Equivalent to `nextAllocMax(allocator, when, default_max_value_len);`
- nextAllocMax
- This function is only available after `endInput()` (or `initCompleteInput()`) has been called.
- allocNextIntoArrayList
- Equivalent to `allocNextIntoArrayListMax(value_list, when, default_max_value_len);`
- allocNextIntoArrayListMax
- The next token type must be either `.number` or `.string`.
- skipValue
- This function is only available after `endInput()` (or `initCompleteInput()`) has been called.
- skipUntilStackHeight
- Skip tokens until an `.object_end` or `.array_end` token results in a `stackHeight()` equal the given stack height.
- stackHeight
- The depth of `{}` or `[]` nesting levels at the current position.
- ensureTotalStackCapacity
- Pre allocate memory to hold the given number of nesting levels.
- next
- See `std.json.Token` for documentation of this function.
- peekNextTokenType
- Seeks ahead in the input until the first byte of the next token (or the end of the input)
- validate
- Scan the input and check for malformed JSON.
- isNumberFormattedLikeAnInteger
- For the slice you get from a `Token.number` or `Token.allocated_number`,
Error sets in this namespace
Error Sets
- Error
- The parsing errors are divided into two categories:
Used by `json.reader`.
Values
- default_buffer_size
- Used by `json.reader`.
- default_max_value_len
- For security, the maximum size allocated to store a single string or number value is limited to 4MiB by default.
Source
Implementation
pub fn peekNextTokenType(self: *@This()) PeekError!TokenType {
state_loop: while (true) {
switch (self.state) {
.value => {
switch (try self.skipWhitespaceExpectByte()) {
'{' => return .object_begin,
'[' => return .array_begin,
'"' => return .string,
'-', '0'...'9' => return .number,
't' => return .true,
'f' => return .false,
'n' => return .null,
else => return error.SyntaxError,
}
},
.post_value => {
if (try self.skipWhitespaceCheckEnd()) return .end_of_document;
const c = self.input[self.cursor];
if (self.string_is_object_key) {
self.string_is_object_key = false;
switch (c) {
':' => {
self.cursor += 1;
self.state = .value;
continue :state_loop;
},
else => return error.SyntaxError,
}
}
switch (c) {
'}' => return .object_end,
']' => return .array_end,
',' => {
switch (self.stack.peek()) {
OBJECT_MODE => {
self.state = .object_post_comma;
},
ARRAY_MODE => {
self.state = .value;
},
}
self.cursor += 1;
continue :state_loop;
},
else => return error.SyntaxError,
}
},
.object_start => {
switch (try self.skipWhitespaceExpectByte()) {
'"' => return .string,
'}' => return .object_end,
else => return error.SyntaxError,
}
},
.object_post_comma => {
switch (try self.skipWhitespaceExpectByte()) {
'"' => return .string,
else => return error.SyntaxError,
}
},
.array_start => {
switch (try self.skipWhitespaceExpectByte()) {
']' => return .array_end,
else => {
self.state = .value;
continue :state_loop;
},
}
},
.number_minus,
.number_leading_zero,
.number_int,
.number_post_dot,
.number_frac,
.number_post_e,
.number_post_e_sign,
.number_exp,
=> return .number,
.string,
.string_backslash,
.string_backslash_u,
.string_backslash_u_1,
.string_backslash_u_2,
.string_backslash_u_3,
.string_surrogate_half,
.string_surrogate_half_backslash,
.string_surrogate_half_backslash_u,
.string_surrogate_half_backslash_u_1,
.string_surrogate_half_backslash_u_2,
.string_surrogate_half_backslash_u_3,
=> return .string,
.string_utf8_last_byte,
.string_utf8_second_to_last_byte,
.string_utf8_second_to_last_byte_guard_against_overlong,
.string_utf8_second_to_last_byte_guard_against_surrogate_half,
.string_utf8_third_to_last_byte,
.string_utf8_third_to_last_byte_guard_against_overlong,
.string_utf8_third_to_last_byte_guard_against_too_large,
=> return .string,
.literal_t,
.literal_tr,
.literal_tru,
=> return .true,
.literal_f,
.literal_fa,
.literal_fal,
.literal_fals,
=> return .false,
.literal_n,
.literal_nu,
.literal_nul,
=> return .null,
}
unreachable;
}
}