1 JSON Encoder 2 ============ 3 4 Approach 5 -------- 6 7 The JSON encoder exists to support qlog implementation. There is no intention to 8 implement a decoder at this time. The encoder is intended to support automation 9 using immediate calls without the use of an intermediate syntax tree 10 representation and is expected to be zero-allocation in most cases. This enables 11 highly efficient serialization when called from QUIC code without dynamic memory 12 allocation. 13 14 An example usage is as follows: 15 16 ```c 17 int 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 52 The zero-allocation, immediate-output design means that most API calls 53 correspond directly to immediately generated output; however there is some 54 minimal state tracking. The API guarantees that it will never generate invalid 55 JSON, 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 60 Since the JSON encoder is for internal use only, its structure is defined in 61 headers and can be incorporated into other objects without a heap allocation. 62 The JSON encoder maintains an internal write buffer and a small state tracking 63 stack (1 bit per level of depth in a JSON hierarchy). 64 65 JSON-SEQ 66 -------- 67 68 The encoder supports JSON-SEQ (RFC 7464), as this is an optimal format for 69 outputting qlog for our purposes. 70 71 Number Handling 72 --------------- 73 74 It is an unfortunate reality that many JSON implementations are not able to 75 handle integers outside `[-2**53 + 1, 2**53 - 1]`. This leads to the I-JSON 76 specification, RFC 7493, which recommends that values outside these ranges are 77 encoded as strings. 78 79 An optional I-JSON mode is offered, in which case integers outside these ranges 80 are automatically serialized as strings instead. 81 82 Error Handling 83 -------------- 84 85 Error handling is deferred to improve ergonomics. If any call to a JSON encoder 86 fails, all future calls also fail and the caller is expected to ascertain that 87 the encoding process failed by calling `ossl_json_get_error_flag`. 88 89 API 90 --- 91 92 The API is documented in `include/internal/json_enc.h`. 93