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