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