1JSON Encoder
2============
3
4Approach
5--------
6
7The JSON encoder exists to support qlog implementation. There is no intention to
8implement a decoder at this time. The encoder is intended to support automation
9using immediate calls without the use of an intermediate syntax tree
10representation and is expected to be zero-allocation in most cases. This enables
11highly efficient serialization when called from QUIC code without dynamic memory
12allocation.
13
14An example usage is as follows:
15
16```c
17int generate_json(BIO *b)
18{
19    int ret = 1;
20    JSON_ENC z;
21
22    if (!ossl_json_init(&z, b, 0))
23        return 0;
24
25    ossl_json_object_begin(&z);
26    {
27        ossl_json_key(&z, "key");
28        ossl_json_str(&z, "value");
29
30        ossl_json_key(&z, "key2");
31        ossl_json_u64(&z, 42);
32
33        ossl_json_key(&z, "key3");
34        ossl_json_array_begin(&z);
35        {
36            ossl_json_null(&z);
37            ossl_json_f64(&z, 42.0);
38            ossl_json_str(&z, "string");
39        }
40        ossl_json_array_end(&z);
41    }
42    ossl_json_object_end(&z);
43
44    if (ossl_json_get_error_flag(&z))
45        ret = 0;
46
47    ossl_json_cleanup(&z);
48    return ret;
49}
50```
51
52The zero-allocation, immediate-output design means that most API calls
53correspond directly to immediately generated output; however there is some
54minimal state tracking. The API guarantees that it will never generate invalid
55JSON, with two exceptions:
56
57- it is the caller's responsibility to avoid generating duplicate keys;
58- it is the caller's responsibility to provide valid UTF-8 strings.
59
60Since the JSON encoder is for internal use only, its structure is defined in
61headers and can be incorporated into other objects without a heap allocation.
62The JSON encoder maintains an internal write buffer and a small state tracking
63stack (1 bit per level of depth in a JSON hierarchy).
64
65JSON-SEQ
66--------
67
68The encoder supports JSON-SEQ (RFC 7464), as this is an optimal format for
69outputting qlog for our purposes.
70
71Number Handling
72---------------
73
74It is an unfortunate reality that many JSON implementations are not able to
75handle integers outside `[-2**53 + 1, 2**53 - 1]`. This leads to the I-JSON
76specification, RFC 7493, which recommends that values outside these ranges are
77encoded as strings.
78
79An optional I-JSON mode is offered, in which case integers outside these ranges
80are automatically serialized as strings instead.
81
82Error Handling
83--------------
84
85Error handling is deferred to improve ergonomics. If any call to a JSON encoder
86fails, all future calls also fail and the caller is expected to ascertain that
87the encoding process failed by calling `ossl_json_get_error_flag`.
88
89API
90---
91
92The API is documented in `include/internal/json_enc.h`.
93