Parse one complete value
Flyology JSON has no default profile or capacity. This complete strict scalar example sets each value explicitly, initializes the parser, and checks complete-document acceptance.
declare
Quick_Profile : constant Profiles.Parser_Profile :=
(Syntax => (Family => Profiles.RFC_8259, Version => 1),
Unicode => (Family => Profiles.Unicode_Scalars, Version => 1),
Compatibility => (Family => Profiles.No_Extensions, Version => 1),
BOM => Profiles.Reject_BOM,
Duplicates => Profiles.Reject_Duplicates,
Top_Level => Profiles.Accept_Any_Value);
Quick_Parser : Parsing.Parser
(Maximum_Depth => 0,
Name_Octet_Capacity => 0,
Name_Capacity => 0);
Input : constant Ada.Streams.Stream_Element_Array :=
[Character'Pos ('n'), Character'Pos ('u'), Character'Pos ('l'), Character'Pos ('l')];
Quick_Events : Parsing.Event_Array (1 .. 4);
Quick_Result : Parsing.Drain_Result;
Quick_Diagnostic : Errors.Diagnostic;
begin
Parsing.Initialize (Quick_Parser, Quick_Profile, Quick_Diagnostic);
if Quick_Diagnostic.Code /= Errors.No_Error then
raise Program_Error with "parser initialization failed";
end if;
Parsing.Drain
(Self => Quick_Parser,
Input => Input,
End_Of_Input => True,
Events => Quick_Events,
Result => Quick_Result);
if Quick_Result.Stop /= Parsing.Drain_Document_Complete then
raise Program_Error with "JSON document was not accepted";
end if;
end;
Run the complete examples with ./scripts/test-examples.sh. The maintained streaming_parser.adb source contains the complete arbitrary-chunk loop.
Choose a static duplicate policy
Instantiate Flyology_JSON.Parsing with one explicit duplicate policy. The generic has no default.
Reject_Duplicates compares decoded UTF-8 names without normalization. It uses caller-backed name storage and a bounded crit-bit index. Detection occurs when the later name ends, and the diagnostic blames its opening quote.
Preserve_Unchecked emits every member in source order. It stores no duplicate-name state and does not choose a first or last value.
Duplicate JSON names and application aliases are different checks.
An application adapter still detects two different names that map to one application field.
Configure physical storage
A Parser takes three discriminants. They are capacities, not compatibility policy, and the library supplies no defaults.
| Capacity | Exact unit |
|---|---|
Maximum_Depth | Simultaneously open objects and arrays. A root container is depth one. |
Name_Octet_Capacity | Decoded UTF-8 octets retained across all open strict objects plus the active candidate. |
Name_Capacity | Strict duplicate-index leaves and internal nodes retained across open objects. |
Preserve mode ignores both name capacities, so an application can set them to zero. A scalar root needs depth zero.
Drive one event or a batch
Step returns one event, a request for input, complete-document acceptance, or a failure. Drain uses the same engine and fills an arbitrary-bound caller event array.
Input'First.Need_Input consumes the complete supplied chunk. A nonnull Output_Full result fills the complete event array. A null event array is a nonmutating capacity stop.
When a call admits End_Of_Input = True, later calls for that document must keep it true. Retraction fails without consuming input.
Read the closed event grammar
The Event_Kind sequence is balanced and JSON-specific. Objects and arrays do not report lengths. Names, strings, and numbers use begin, fragment, and end events.
- Number fragments preserve exact source octets and have no token-storage length ceiling, subject to coordinate exhaustion.
- Decoded name and string fragments end at Unicode scalar boundaries.
- An escape or surrogate pair can produce an inline decoded scalar with complete source provenance.
- A copied event retains coordinates and inline scalar bytes, but never an input reference.
Null and Boolean events expose the complete raw literal only when that literal fits in the producing input window. A split literal remains valid without such a slice.
Resolve a raw range in the producing call
Resolve_Raw_Range maps absolute source coordinates into the current input window. It validates coordinate containment only. It cannot authenticate an Ada array's identity or unchanged contents.
Use the exact unchanged input actual from the call that produced the event. If a consumer must retain a range, copy it before the producing call returns. Do not attach an event to a later chunk that happens to have the same bounds.
All public offsets are zero-based octet coordinates.
Consumed, produced, and raw-slice positions are counts from the corresponding array's first bound.
Accept only after document completion
Every event is a provisional observation. The parser accepts the complete document only when a call returns Document_Complete after Document_End.
A consumer can commit its private candidate at that gate. On malformed input or resource failure, the consumer aborts its candidate and then resets or discards the parser.
Abort_Document ends a clean active operation without raising. A retained primary failure remains primary. Reset starts a new operation at byte zero only from a terminal state and revalidates the complete profile.