afb-apiset: Fix start of apis
[src/app-framework-binder.git] / src / wrap-json.md
1 WRAP-JSON facility
2 ==================
3
4 The facility wrap-json is based on the pack/unpack API on the
5 library jansson. The two chapters below are copied from the
6 documentation of jansson library copyrighted by Petri Lehtinen
7 (see at end).
8
9 Building Values
10 ---------------
11
12 This section describes functions that help to create, or *pack*, complex
13 JSON values, especially nested objects and arrays. Value building is
14 based on a *format string* that is used to tell the functions about the
15 expected arguments.
16
17 For example, the format string `"i"` specifies a single integer value,
18 while the format string `"[ssb]"` or the equivalent `"[s, s, b]"`
19 specifies an array value with two strings and a boolean as its items:
20
21     /* Create the JSON integer 42 */
22     wrap_json_pack(&result, "i", 42);
23
24     /* Create the JSON array ["foo", "bar", true] */
25     wrap_json_pack(&result, "[ssb]", "foo", "bar", 1);
26
27 Here's the full list of format specifiers. The type in parentheses
28 denotes the resulting JSON type, and the type in brackets (if any)
29 denotes the C type that is expected as the corresponding argument or
30 arguments.
31
32 `s` (string) \[const char \*\]
33
34 :   Convert a null terminated UTF-8 string to a JSON string.
35
36 `s?` (string) \[const char \*\]
37
38 :   Like `s`, but if the argument is *NULL*, output a JSON null value.
39
40 `s*` (string) \[const char \*\]
41
42 :   Like `s`, but if the argument is *NULL*, do not output any value.
43     This format can only be used inside an object or an array. If used
44     inside an object, the corresponding key is additionally suppressed
45     when the value is omitted. See below for an example.
46
47 `s#` (string) \[const char \*, int\]
48
49 :   Convert a UTF-8 buffer of a given length to a JSON string.
50
51 `s%` (string) \[const char \*, size\_t\]
52
53 :   Like `s#` but the length argument is of type size\_t.
54
55 `+` \[const char \*\]
56
57 :   Like `s`, but concatenate to the previous string. Only valid after
58     `s`, `s#`, `+` or `+#`.
59
60 `+#` \[const char \*, int\]
61
62 :   Like `s#`, but concatenate to the previous string. Only valid after
63     `s`, `s#`, `+` or `+#`.
64
65 `+%` (string) \[const char \*, size\_t\]
66
67 :   Like `+#` but the length argument is of type size\_t.
68
69 `y` (byte array) \[const uint8_t \*, size\_t\]
70
71 :   Convert the byte array whose length is given to
72     its base64url string representation.
73
74 `Y` (byte array) \[const uint8_t \*, size\_t\]
75
76 :   Like 'y' but output is base64.
77
78 `y?`, `Y?` (byte array or null) \[const uint8_t \*, size\_t\]
79
80 :   Like 'y' or 'Y' but allows to output a JSON null value
81     either when the buffer is *NULL* or when the size is *0*.
82
83 `y*`, `y*` (optional byte array) \[const uint8_t \*, size\_t\]
84
85 :   Like 'y' or 'Y' but do not put JSON value
86     either when the buffer is *NULL* or when the size is *0*.
87     This format can only be used inside an object or an array. If used
88     inside an object, the corresponding key is additionally suppressed
89     when the value is omitted. See below for an example.
90
91 `n` (null)
92
93 :   Output a JSON null value. No argument is consumed.
94
95 `b` (boolean) \[int\]
96
97 :   Convert a C int to JSON boolean value. Zero is converted to `false`
98     and non-zero to `true`.
99
100 `i` (integer) \[int\]
101
102 :   Convert a C int to JSON integer.
103
104 `I` (integer) \[json\_int\_t\]
105
106 :   Convert a C json\_int\_t to JSON integer.
107
108 `f` (real) \[double\]
109
110 :   Convert a C double to JSON real.
111
112 `o` (any value) \[json\_t \*\]
113
114 :   Output any given JSON value as-is. If the value is added to an array
115     or object, the reference to the value passed to `o` is stolen by the
116     container.
117
118 `O` (any value) \[json\_t \*\]
119
120 :   Like `o`, but the argument's reference count is incremented. This is
121     useful if you pack into an array or object and want to keep the
122     reference for the JSON value consumed by `O` to yourself.
123
124 `o?`, `O?` (any value) \[json\_t \*\]
125
126 :   Like `o` and `O`, respectively, but if the argument is *NULL*,
127     output a JSON null value.
128
129 `o*`, `O*` (any value) \[json\_t \*\]
130
131 :   Like `o` and `O`, respectively, but if the argument is *NULL*, do
132     not output any value. This format can only be used inside an object
133     or an array. If used inside an object, the corresponding key is
134     additionally suppressed. See below for an example.
135
136 `[fmt]` (array)
137
138 :   Build an array with contents from the inner format string. `fmt` may
139     contain objects and arrays, i.e. recursive value building is
140     supported.
141
142 `{fmt}` (object)
143
144 :   Build an object with contents from the inner format string `fmt`.
145     The first, third, etc. format specifier represent a key, and must be
146     a string (see `s`, `s#`, `+` and `+#` above), as object keys are
147     always strings. The second, fourth, etc. format specifier represent
148     a value. Any value may be an object or array, i.e. recursive value
149     building is supported.
150
151 Whitespace, `:` and `,` are ignored.
152
153 More examples:
154
155     /* Build an empty JSON object */
156     wrap_json_pack(&result, "{}");
157
158     /* Build the JSON object {"foo": 42, "bar": 7} */
159     wrap_json_pack(&result, "{sisi}", "foo", 42, "bar", 7);
160
161     /* Like above, ':', ',' and whitespace are ignored */
162     wrap_json_pack(&result, "{s:i, s:i}", "foo", 42, "bar", 7);
163
164     /* Build the JSON array [[1, 2], {"cool": true}] */
165     wrap_json_pack(&result, "[[i,i],{s:b}]", 1, 2, "cool", 1);
166
167     /* Build a string from a non-null terminated buffer */
168     char buffer[4] = {'t', 'e', 's', 't'};
169     wrap_json_pack(&result, "s#", buffer, 4);
170
171     /* Concatenate strings together to build the JSON string "foobarbaz" */
172     wrap_json_pack(&result, "s++", "foo", "bar", "baz");
173
174     /* Create an empty object or array when optional members are missing */
175     wrap_json_pack(&result, "{s:s*,s:o*,s:O*}", "foo", NULL, "bar", NULL, "baz", NULL);
176     wrap_json_pack(&result, "[s*,o*,O*]", NULL, NULL, NULL);
177
178 Parsing and Validating Values
179 -----------------------------
180
181 This section describes functions that help to validate complex values
182 and extract, or *unpack*, data from them. Like building values
183 <apiref-pack>, this is also based on format strings.
184
185 While a JSON value is unpacked, the type specified in the format string
186 is checked to match that of the JSON value. This is the validation part
187 of the process. In addition to this, the unpacking functions can also
188 check that all items of arrays and objects are unpacked. This check be
189 enabled with the format specifier `!` or by using the flag
190 `JSON_STRICT`. See below for details.
191
192 Here's the full list of format specifiers. The type in parentheses
193 denotes the JSON type, and the type in brackets (if any) denotes the C
194 type whose address should be passed.
195
196 `s` (string) \[const char \*\]
197
198 :   Convert a JSON string to a pointer to a null terminated UTF-8
199     string. The resulting string is extracted by using
200     json\_string\_value() internally, so it exists as long as there are
201     still references to the corresponding JSON string.
202
203 `s%` (string) \[const char \*, size\_t \*\]
204
205 :   Convert a JSON string to a pointer to a null terminated UTF-8 string
206     and its length.
207
208 `y` (byte array) \[uint8_t \*\*, size\_t \*\]
209
210 :   Convert an input string base64url encoded to its
211     byte array representation. The result and its length
212     are stored. The returned buffer must be freed by the caller.
213
214 `Y` (byte array) \[uint8_t \*\*, size\_t \*\]
215
216 :   Like 'y' but input is base64.
217
218 `n` (null)
219
220 :   Expect a JSON null value. Nothing is extracted.
221
222 `b` (boolean) \[int\]
223
224 :   Convert a JSON boolean value to a C int, so that `true` is converted
225     to 1 and `false` to 0.
226
227 `i` (integer) \[int\]
228
229 :   Convert a JSON integer to C int.
230
231 `I` (integer) \[json\_int\_t\]
232
233 :   Convert a JSON integer to C json\_int\_t.
234
235 `f` (real) \[double\]
236
237 :   Convert a JSON real to C double.
238
239 `F` (integer or real) \[double\]
240
241 :   Convert a JSON number (integer or real) to C double.
242
243 `o` (any value) \[json\_t \*\]
244
245 :   Store a JSON value with no conversion to a json\_t pointer.
246
247 `O` (any value) \[json\_t \*\]
248
249 :   Like `O`, but the JSON value's reference count is incremented.
250
251 `[fmt]` (array)
252
253 :   Convert each item in the JSON array according to the inner format
254     string. `fmt` may contain objects and arrays, i.e. recursive value
255     extraction is supported.
256
257 `{fmt}` (object)
258
259 :   Convert each item in the JSON object according to the inner format
260     string `fmt`. The first, third, etc. format specifier represent a
261     key, and must be `s`. The corresponding argument to unpack functions
262     is read as the object key. The second fourth, etc. format specifier
263     represent a value and is written to the address given as the
264     corresponding argument. **Note** that every other argument is read
265     from and every other is written to.
266
267     `fmt` may contain objects and arrays as values, i.e. recursive value
268     extraction is supported.
269
270 `!`
271
272 :   This special format specifier is used to enable the check that all
273     object and array items are accessed, on a per-value basis. It must
274     appear inside an array or object as the last format specifier before
275     the closing bracket or brace.
276
277 `*`
278
279 :   This special format specifier is the opposite of `!`. This is the default.
280     It must appear inside an array or object as the last format specifier
281     before the closing bracket or brace.
282
283 Whitespace, `:` and `,` are ignored.
284
285 Examples:
286
287     /* root is the JSON integer 42 */
288     int myint;
289     wrap_json_unpack(root, "i", &myint);
290     assert(myint == 42);
291
292     /* root is the JSON object {"foo": "bar", "quux": true} */
293     const char *str;
294     int boolean;
295     wrap_json_unpack(root, "{s:s, s:b}", "foo", &str, "quux", &boolean);
296     assert(strcmp(str, "bar") == 0 && boolean == 1);
297
298     /* root is the JSON array [[1, 2], {"baz": null} */
299     wrap_json_check(root, "[[i,i], {s:n}]", "baz");
300     /* returns 0 for validation success, nothing is extracted */
301
302     /* root is the JSON array [1, 2, 3, 4, 5] */
303     int myint1, myint2;
304     wrap_json_unpack(root, "[ii!]", &myint1, &myint2);
305     /* returns -1 for failed validation */
306
307     /* root is an empty JSON object */
308     int myint = 0, myint2 = 0, myint3 = 0;
309     wrap_json_unpack(root, "{s?i, s?[ii]}",
310                 "foo", &myint1,
311                 "bar", &myint2, &myint3);
312     /* myint1, myint2 or myint3 is no touched as "foo" and "bar" don't exist */
313
314 Copyright
315 ---------
316
317 Copyright (c) 2009-2016 Petri Lehtinen <petri@digip.org>
318
319 Permission is hereby granted, free of charge, to any person obtaining a copy
320 of this software and associated documentation files (the "Software"), to deal
321 in the Software without restriction, including without limitation the rights
322 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
323 copies of the Software, and to permit persons to whom the Software is
324 furnished to do so, subject to the following conditions:
325
326 The above copyright notice and this permission notice shall be included in
327 all copies or substantial portions of the Software.
328
329 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
330 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
331 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
332 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
333 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
334 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
335 THE SOFTWARE.