Mstdlib-1.24.0
m_json.h
1/* The MIT License (MIT)
2 *
3 * Copyright (c) 2015 Monetra Technologies, LLC.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23
24#ifndef __M_JSON_H__
25#define __M_JSON_H__
26
27/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
28
29#include <mstdlib/base/m_defs.h>
30#include <mstdlib/base/m_types.h>
31#include <mstdlib/base/m_list_str.h>
32#include <mstdlib/base/m_fs.h>
33
34/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
35
36__BEGIN_DECLS
37
38/*! \addtogroup m_json JSON
39 * \ingroup m_formats
40 *
41 * Mostly EMCA-404 compliant JSON manipulation.
42 *
43 * Number handling while writing:
44 * - Integrals are limited a range of -(2^53)+1 to (2^53)-1 for Java Script
45 * compatibility. Larger numbers will be encoded as a string.
46 * - Decimals are limited to 15 places for Java Script compatibility. Larger
47 * precision decimals will be encoded as strings.
48 * - Number to string compatibility conversion can be disabled with the
49 * M_JSON_WRITER_NUMBER_NOCOMPAT flag.
50 *
51 * Additional Features:
52 * - Comments (C/C++)
53 *
54 * Also supports most of Stefan Gössner's JSONPath for searching.
55 * Not supported are features considered redundant or potential
56 * security risks (script expressions).
57 *
58 * Example:
59 *
60 * \code{.c}
61 * M_json_node_t *j;
62 * M_json_node_t **n;
63 * size_t num_matches;
64 * size_t i;
65 * const char *s = "{ \"a\" :\n[1, \"abc\",2 ]\n}";
66 * char *out;
67 *
68 * j = M_json_read(s, M_str_len(s), M_JSON_READER_NONE, NULL, NULL, NULL, NULL);
69 * if (j == NULL) {
70 * M_printf("Could not parse json\n");
71 * return M_FALSE;
72 * }
73 *
74 * M_json_object_insert_string(j, "b", "string");
75 *
76 * n = M_json_jsonpath(j, "$.a[1::3]", &num_matches);
77 * for (i=0; i<num_matches; i++) {
78 * if (M_json_node_type(n[i]) == M_JSON_TYPE_STRING) {
79 * M_printf("%s\n", M_json_get_string(n);
80 * }
81 * }
82 * M_free(n);
83 *
84 * out = M_json_write(j, M_JSON_WRITER_PRETTYPRINT_SPACE, NULL);
85 * M_printf(out=\n%s\n", out);
86 * M_free(out);
87 *
88 * M_json_node_destroy(j);
89 * \endcode
90 *
91 * @{
92 */
93
94struct M_json_node;
95typedef struct M_json_node M_json_node_t;
96
97
98/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
99
100/*! Types of JSON nodes. */
101typedef enum {
102 M_JSON_TYPE_UNKNOWN = 0, /*!< An invalid node type. */
103 M_JSON_TYPE_OBJECT, /*!< Object (hashtable). */
104 M_JSON_TYPE_ARRAY, /*!< Array (list). */
105 M_JSON_TYPE_STRING, /*!< String. */
106 M_JSON_TYPE_INTEGER, /*!< Number. */
107 M_JSON_TYPE_DECIMAL, /*!< Floating point number. */
108 M_JSON_TYPE_BOOL, /*!< Boolean. */
109 M_JSON_TYPE_NULL /*!< JSON null type. */
111
112
113/*! Flags to control the behavior of the JSON reader. */
114typedef enum {
115 M_JSON_READER_NONE = 0, /*!< Normal operation. Treat decimal truncation as error and
116 ignore comments. */
117 M_JSON_READER_ALLOW_DECIMAL_TRUNCATION = 1 << 0, /*!< Allow decimal truncation. A decimal read and truncated will
118 not be treated as an error. */
119 M_JSON_READER_DISALLOW_COMMENTS = 1 << 1, /*!< Treat comments as an error. */
120 M_JSON_READER_OBJECT_UNIQUE_KEYS = 1 << 2, /*!< Return a parse error when an object has repeating keys. By
121 default the later key in the object will be the one used and
122 earlier keys ignored. This requires all keys in the object to
123 be unique. */
124 M_JSON_READER_DONT_DECODE_UNICODE = 1 << 3, /*!< By default unicode escapes will be decoded into their utf-8
125 byte sequence. Use this with care because "\u" will be put
126 in the string. Writing will produce "\\u" because the writer
127 will not understand this is a non-decoded unicode escape. */
128 M_JSON_READER_REPLACE_BAD_CHARS = 1 << 4 /*!< Replace bad characters (invalid utf-8 sequences with "?"). */
130
131
132/*! Flags to control the behavior of the JSON writer. */
133typedef enum {
134 M_JSON_WRITER_NONE = 0, /*!< No indent. All data on a single line. */
135 M_JSON_WRITER_PRETTYPRINT_SPACE = 1 << 0, /*!< 2 space indent. */
136 M_JSON_WRITER_PRETTYPRINT_TAB = 1 << 1, /*!< Tab indent. */
137 M_JSON_WRITER_PRETTYPRINT_WINLINEEND = 1 << 2, /*!< Windows line ending "\r\n" instead of Unix line ending "\n".
138 Requires space or tab pretty printing. */
139 M_JSON_WRITER_DONT_ENCODE_UNICODE = 1 << 3, /*!< By default utf-8 characters will be enocded into unicode
140 escapes. */
141 M_JSON_WRITER_REPLACE_BAD_CHARS = 1 << 4, /*!< Replace bad characters (invalid utf-8 sequences with "?"). */
142 M_JSON_WRITER_NUMBER_NOCOMPAT = 1 << 5 /*!< Write numbers as they are instead of limiting to Java Script
143 minimum and maximum sizes. */
145
146
147/*! Error codes. */
148typedef enum {
149 M_JSON_ERROR_SUCCESS = 0, /*!< success */
150 M_JSON_ERROR_GENERIC, /*!< generic error */
151 M_JSON_ERROR_MISUSE, /*!< API missuse */
152 M_JSON_ERROR_INVALID_START, /*!< expected Object or Array to start */
153 M_JSON_ERROR_EXPECTED_END, /*!< expected end but more data found */
154 M_JSON_ERROR_MISSING_COMMENT_CLOSE, /*!< close comment not found */
156 M_JSON_ERROR_INVALID_PAIR_START, /*!< expected string as first half of pair */
157 M_JSON_ERROR_DUPLICATE_KEY, /*!< duplicate key */
158 M_JSON_ERROR_MISSING_PAIR_SEPARATOR, /*!< expected ':' separator in pair */
159 M_JSON_ERROR_OBJECT_UNEXPECTED_CHAR, /*!< unexpected character in object */
160 M_JSON_ERROR_EXPECTED_VALUE, /*!< expected value after ',' */
161 M_JSON_ERROR_UNCLOSED_OBJECT, /*!< expected '}' to close object */
162 M_JSON_ERROR_ARRAY_UNEXPECTED_CHAR, /*!< unexpected character in array */
163 M_JSON_ERROR_UNCLOSED_ARRAY, /*!< expected ']' to close array */
164 M_JSON_ERROR_UNEXPECTED_NEWLINE, /*!< unexpected newline */
165 M_JSON_ERROR_UNEXPECTED_CONTROL_CHAR, /*!< unexpected control character */
166 M_JSON_ERROR_INVALID_UNICODE_ESACPE, /*!< invalid unicode escape */
167 M_JSON_ERROR_UNEXPECTED_ESCAPE, /*!< unexpected escape */
168 M_JSON_ERROR_UNCLOSED_STRING, /*!< unclosed string */
169 M_JSON_ERROR_INVALID_BOOL, /*!< invalid bool value */
170 M_JSON_ERROR_INVALID_NULL, /*!< invalid null value */
171 M_JSON_ERROR_INVALID_NUMBER, /*!< invalid number value */
172 M_JSON_ERROR_UNEXPECTED_TERMINATION, /*!< unexpected termination of string data. \0 in data. */
173 M_JSON_ERROR_INVALID_IDENTIFIER, /*!< invalid identifier */
174 M_JSON_ERROR_UNEXPECTED_END /*!< unexpected end of data */
176
177
178/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
179
180/*! Create a JSON node.
181 *
182 * \param[in] type The type of the node to create.
183 *
184 * \return A JSON node on success. NULL on failure (an invalid type was requested).
185 *
186 * \see M_json_node_destroy
187 */
189
190
191/*! Destory a JSON node.
192 *
193 * Destroying a node will destroy every node under it and remove it from it's parent node if it is a child.
194 *
195 * \param[in] node The node to destroy.
196 */
197M_API void M_json_node_destroy(M_json_node_t *node) M_FREE(1);
198
199
200/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
201
202/*! Parse a string into a JSON object.
203 *
204 * \param[in] data The data to parse.
205 * \param[in] data_len The length of the data to parse.
206 * \param[in] flags M_json_reader_flags_t flags to control the behavior of the reader.
207 * \param[out] processed_len Length of data processed. Useful if you could have multiple JSON documents
208 * in a stream. Optional pass NULL if not needed.
209 * \param[out] error On error this will be populated with an error reason. Optional, pass NULL if not needed.
210 * \param[out] error_line The line the error occurred. Optional, pass NULL if not needed.
211 * \param[out] error_pos The column the error occurred if error_line is not NULL, otherwise the position
212 * in the stream the error occurred. Optional, pass NULL if not needed.
213 *
214 * \return The root JSON node of the parsed data, or NULL on error.
215 */
216M_API M_json_node_t *M_json_read(const char *data, size_t data_len, M_uint32 flags, size_t *processed_len, M_json_error_t *error, size_t *error_line, size_t *error_pos) M_MALLOC;
217
218
219/*! Parse a file into a JSON object.
220 *
221 * \param[in] path The file to read.
222 * \param[in] flags M_json_reader_flags_t flags to control the behavior of the reader.
223 * \param[in] max_read The maximum number of bytes to read from the file. If the data in the file is
224 * larger than max_read an error will most likely result. Optional pass 0 to read all data.
225 * \param[out] error On error this will be populated with an error reason. Optional, pass NULL if not needed.
226 * \param[out] error_line The line the error occurred. Optional, pass NULL if not needed.
227 * \param[out] error_pos The column the error occurred if error_line is not NULL, otherwise the position
228 * in the stream the error occurred. Optional, pass NULL if not needed.
229 * \return The root JSON node of the parsed data, or NULL on error.
230 */
231M_API M_json_node_t *M_json_read_file(const char *path, M_uint32 flags, size_t max_read, M_json_error_t *error, size_t *error_line, size_t *error_pos) M_MALLOC;
232
233
234/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
235
236/*! Write JSON to a string.
237 *
238 * This writes nodes to a string. The string may not be directly usable by M_json_read.
239 * E.g. If you are only writing a string node.
240 *
241 * \param[in] node The node to write. This will write the node and any nodes under it.
242 * \param[in] flags M_json_writer_flags_t flags to control writing.
243 * \param[out] len The length of the string that was returned. Optional, pass NULL if not needed.
244 *
245 * \return A string with data or NULL on error.
246 */
247M_API char *M_json_write(const M_json_node_t *node, M_uint32 flags, size_t *len) M_WARN_UNUSED_RESULT M_MALLOC;
248
249
250/*! Write JSON to a file.
251 *
252 * This writes nodes to a string. The string may not be directly usable by M_json_read_file (for example)
253 * if you are only writing a string node (for example).
254 *
255 * \param[in] node The node to write. This will write the node and any nodes under it.
256 * \param[in] path The filename and path to write the data to.
257 * \param[in] flags M_json_writer_flags_t flags to control writing.
258 *
259 * \return Result.
260 */
261M_API M_fs_error_t M_json_write_file(const M_json_node_t *node, const char *path, M_uint32 flags);
262
263
264/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
265
266/*! Convert a JSON error code to a string.
267 *
268 * \param[in] err error code
269 * \return name of error code (not a description, just the enum name, like M_JSON_ERROR_SUCCESS)
270 */
272
273
274/*! Get the type of node.
275 *
276 * \param[in] node The node.
277 *
278 * \return The type.
279 */
281
282
283/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
284
285/*! Using JSONPath expressions, scan for matches.
286 *
287 * Note: that full JSONPath support does not yet exist.
288 *
289 * Search expressions must start with $. They can use . to refer to the first element
290 * or .. to search for the first matching element.
291 *
292 * Supports:
293 * - Patterns containing ".", "*", "..".
294 * - Array offsets using [*]/[]/[,]/[start:end:step].
295 * - Positive offsets [0], [0,2].
296 * - Negative offsets [-1] (last item). [-2] (second to last item).
297 * - Positive and negative steps. [0:4:2]. [4:0:-1].
298 * - When counting up start is inclusive and end is exclusive. [0:3] is equivalent to [0,1,2].
299 * - When counting down start is exclusive and end is inclusive. [3:0:-1] is equivalent to [2,1,0].
300 *
301 * Does not Support:
302 * - Braket notation ['x'].
303 * - Filter/script expressions. [?(exp)]/[(exp)].
304 *
305 * \param[in] node The node.
306 * \param[in] search search expression
307 * \param[out] num_matches Number of matches found
308 *
309 * \return array of M_json_node_t pointers on success (must free array, but not internal pointers), NULL on failure
310 *
311 * \see M_free
312 */
313M_API M_json_node_t **M_json_jsonpath(const M_json_node_t *node, const char *search, size_t *num_matches) M_MALLOC;
314
315
316/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
317
318/*! Get the parent node of a given node.
319 *
320 * \param[in] node The node.
321 *
322 * \return The parent node or NULL if there is no parent.
323 */
325
326
327/*! Take the node from the parent but does not destroy it.
328 *
329 * This allows a node to be moved between different parents.
330 *
331 * \param[in,out] node The node.
332 */
334
335
336/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
337
338/*! Get the value of an object node for a given key.
339 *
340 * The object still owns the returned node. You can use M_json_take_from_parent to remove the ownership.
341 * At which point you will need to either insert it into another object/array or destroy it.
342 *
343 * \param[in] node The node.
344 * \param[in] key The key.
345 *
346 * \return The node under key. Otherwise NULL if the key does not exist.
347 */
348M_API M_json_node_t *M_json_object_value(const M_json_node_t *node, const char *key);
349
350
351/*! Get the string value of an object node for a given key.
352 *
353 * \param[in] node The node.
354 * \param[in] key The key.
355 *
356 * \return The string value under the key. NULL if not a string or key does not exist.
357 */
358M_API const char *M_json_object_value_string(const M_json_node_t *node, const char *key);
359
360
361/*! Get the integer value of an object node for a given key.
362 *
363 * If the node is not an M_JSON_TYPE_INTEGER auto conversion will be attempted.
364 *
365 * \param[in] node The node.
366 * \param[in] key The key.
367 *
368 * \return The value. 0 on error. The only way to know if there was an error
369 * or the return is the value is to check the type.
370 */
371M_API M_int64 M_json_object_value_int(const M_json_node_t *node, const char *key);
372
373
374/*! Get the decimal value of an object node for a given key.
375 *
376 * \param[in] node The node.
377 * \param[in] key The key.
378 *
379 * \return The string value under the key. NULL if not a decimal or key does not exist.
380 */
381M_API const M_decimal_t *M_json_object_value_decimal(const M_json_node_t *node, const char *key);
382
383
384/*! Get the bool value of an object node for a given key.
385 *
386 * If the node is not a M_JSON_TYPE_BOOL auto conversion will be attempted.
387 *
388 * \param[in] node The node.
389 * \param[in] key The key.
390 *
391 * \return The value. M_FALSE on error. The only way to know if there was an error
392 * or the return is the value is to check the type.
393 */
394M_API M_bool M_json_object_value_bool(const M_json_node_t *node, const char *key);
395
396
397/*! Get a list of all keys for the object.
398 *
399 * \param[in] node The node.
400 *
401 * \return A list of keys.
402 */
404
405
406/*! Get the number of child nodes in this object.
407 *
408 * This corresponds to the number of gets.
409 *
410 * \param[in] node The node.
411 *
412 * \return Count of objects.
413 */
415
416
417/*! Insert a node into the object.
418 *
419 * The object node will take ownership of the value node.
420 *
421 * \param[in,out] node The node.
422 * \param[in] key The key. If the key already exists the existing node will be destroyed and replaced with the
423 * new value node.
424 * \param[in] value The node to add to the object.
425 *
426 * \return M_TRUE on success otherwise M_FALSE.
427 */
428M_API M_bool M_json_object_insert(M_json_node_t *node, const char *key, M_json_node_t *value);
429
430
431/*! Insert a string into the object.
432 *
433 * \param[in,out] node The node.
434 * \param[in] key The key. If the key already exists the existing node will be destroyed and replaced with the
435 * new value node.
436 * \param[in] value The string to add to the object.
437 *
438 * \return M_TRUE on success otherwise M_FALSE.
439 */
440M_API M_bool M_json_object_insert_string(M_json_node_t *node, const char *key, const char *value);
441
442
443/*! Insert an integer into the object.
444 *
445 * \param[in,out] node The node.
446 * \param[in] key The key. If the key already exists the existing node will be destroyed and replaced with the
447 * new value node.
448 * \param[in] value The integer to add to the object.
449 *
450 * \return M_TRUE on success otherwise M_FALSE.
451 */
452M_API M_bool M_json_object_insert_int(M_json_node_t *node, const char *key, M_int64 value);
453
454
455/*! Insert an decimal into the object.
456 *
457 * \param[in,out] node The node.
458 * \param[in] key The key. If the key already exists the existing node will be destroyed and replaced with the
459 * new value node.
460 * \param[in] value The decimal to add to the object.
461 *
462 * \return M_TRUE on success otherwise M_FALSE.
463 */
464M_API M_bool M_json_object_insert_decimal(M_json_node_t *node, const char *key, const M_decimal_t *value);
465
466
467/*! Insert an bool into the object.
468 *
469 * \param[in,out] node The node.
470 * \param[in] key The key. If the key already exists the existing node will be destroyed and replaced with the
471 * new value node.
472 * \param[in] value The bool to add to the object.
473 *
474 * \return M_TRUE on success otherwise M_FALSE.
475 */
476M_API M_bool M_json_object_insert_bool(M_json_node_t *node, const char *key, M_bool value);
477
478
479/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
480
481/*! Get the number of items in an array node.
482 *
483 * \param[in] node The node.
484 *
485 * \return The number of items in the array.
486 */
487M_API size_t M_json_array_len(const M_json_node_t *node);
488
489
490/*! Get the item in the array at a given index.
491 *
492 * The array still owns the returned node. You can use M_json_take_from_parent to remove the ownership.
493 * At which point you will need to either insert it into another object/array or destroy it.
494 *
495 * \param[in] node The node.
496 * \param[in] idx The index.
497 *
498 * \return The node at the given index or NULL if the index is invalid.
499 */
500M_API M_json_node_t *M_json_array_at(const M_json_node_t *node, size_t idx);
501
502
503/*! Get the string value of given index in an array.
504 *
505 * \param[in] node The node.
506 * \param[in] idx The index.
507 *
508 * \return The string value at the location. NULL if not a string or key does not exist.
509 */
510M_API const char *M_json_array_at_string(const M_json_node_t *node, size_t idx);
511
512
513/*! Get the integer value of given index in an array.
514 *
515 * If the node is not an M_JSON_TYPE_INTEGER auto conversion will be attempted.
516 *
517 * \param[in] node The node.
518 * \param[in] idx The index.
519 *
520 * \return The value. 0 on error. The only way to know if there was an error
521 * or the return is the value is to check the type.
522 */
523M_API M_int64 M_json_array_at_int(const M_json_node_t *node, size_t idx);
524
525
526/*! Get the decimal value of given index in an array.
527 *
528 * \param[in] node The node.
529 * \param[in] idx The index.
530 *
531 * \return The string value under the key. NULL if not a decimal or index does not exist.
532 */
533M_API const M_decimal_t *M_json_array_at_decimal(const M_json_node_t *node, size_t idx);
534
535
536/*! Get the string value of given index in an array.
537 *
538 * If the node is not a M_JSON_TYPE_BOOL auto conversion will be attempted.
539 *
540 * \param[in] node The node.
541 * \param[in] idx The index.
542 *
543 * \return The value. M_FALSE on error. The only way to know if there was an error
544 * or the return is the value is to check the type.
545 */
546M_API M_bool M_json_array_at_bool(const M_json_node_t *node, size_t idx);
547
548
549/*! Append a node into an array node.
550 *
551 * \param[in,out] node The node.
552 * \param[in] value The value node to append.
553 *
554 * \return M_TRUE if the value was appended otherwise M_FALSE.
555 */
557
558
559/*! Append a string into an array node.
560 *
561 * \param[in,out] node The node.
562 * \param[in] value The value to append.
563 *
564 * \return M_TRUE if the value was appended otherwise M_FALSE.
565 */
566M_API M_bool M_json_array_insert_string(M_json_node_t *node, const char *value);
567
568
569/*! Append a integer into an array node.
570 *
571 * \param[in,out] node The node.
572 * \param[in] value The value to append.
573 *
574 * \return M_TRUE if the value was appended otherwise M_FALSE.
575 */
576M_API M_bool M_json_array_insert_int(M_json_node_t *node, M_int64 value);
577
578
579/*! Append a decimal into an array node.
580 *
581 * \param[in,out] node The node.
582 * \param[in] value The value to append.
583 *
584 * \return M_TRUE if the value was appended otherwise M_FALSE.
585 */
586M_API M_bool M_json_array_insert_decimal(M_json_node_t *node, const M_decimal_t *value);
587
588
589/*! Append a bool into an array node.
590 *
591 * \param[in,out] node The node.
592 * \param[in] value The value to append.
593 *
594 * \return M_TRUE if the value was appended otherwise M_FALSE.
595 */
596M_API M_bool M_json_array_insert_bool(M_json_node_t *node, M_bool value);
597
598
599/*! Insert a node into an array node at a given index.
600 *
601 * \param[in,out] node The node.
602 * \param[in] value The value node to append.
603 * \param[in] idx The index to insert at.
604 *
605 * \return M_TRUE if the value was inserted otherwise M_FALSE.
606 */
607M_API M_bool M_json_array_insert_at(M_json_node_t *node, M_json_node_t *value, size_t idx);
608
609
610/*! Insert a string into an array node at a given index.
611 *
612 * \param[in,out] node The node.
613 * \param[in] value The value to append.
614 * \param[in] idx The index to insert at.
615 *
616 * \return M_TRUE if the value was inserted otherwise M_FALSE.
617 */
618M_API M_bool M_json_array_insert_at_string(M_json_node_t *node, const char *value, size_t idx);
619
620
621/*! Insert a integer into an array node at a given index.
622 *
623 * \param[in,out] node The node.
624 * \param[in] value The value to append.
625 * \param[in] idx The index to insert at.
626 *
627 * \return M_TRUE if the value was inserted otherwise M_FALSE.
628 */
629M_API M_bool M_json_array_insert_at_int(M_json_node_t *node, M_int64 value, size_t idx);
630
631
632/*! Insert a decimal into an array node at a given index.
633 *
634 * \param[in,out] node The node.
635 * \param[in] value The value to append.
636 * \param[in] idx The index to insert at.
637 *
638 * \return M_TRUE if the value was inserted otherwise M_FALSE.
639 */
640M_API M_bool M_json_array_insert_at_decimal(M_json_node_t *node, const M_decimal_t *value, size_t idx);
641
642
643/*! Insert a bool into an array node at a given index.
644 *
645 * \param[in,out] node The node.
646 * \param[in] value The value to append.
647 * \param[in] idx The index to insert at.
648 *
649 * \return M_TRUE if the value was inserted otherwise M_FALSE.
650 */
651M_API M_bool M_json_array_insert_at_bool(M_json_node_t *node, M_bool value, size_t idx);
652
653
654/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
655
656/*! Get the value from a string node.
657 *
658 * \param[in] node The node.
659 *
660 * \return The value.
661 */
662M_API const char *M_json_get_string(const M_json_node_t *node);
663
664
665/*! Make the node a string node and set the value.
666 *
667 * \param[in,out] node The node.
668 * \param[in] value The value to set.
669 *
670 * \return M_TRUE if the node updated.
671 */
672M_API M_bool M_json_set_string(M_json_node_t *node, const char *value);
673
674
675/*! Get the value from an integer node.
676 *
677 * If the node is not an M_JSON_TYPE_INTEGER auto conversion will be attempted.
678 *
679 * \param[in] node The node.
680 *
681 * \return The value. 0 on error. The only way to know if there was an error
682 * or the return is the value is to check the type.
683 */
684M_API M_int64 M_json_get_int(const M_json_node_t *node);
685
686
687/*! Make the node a integer node and set the value.
688 *
689 * \param[in,out] node The node.
690 * \param[in] value The value.
691 *
692 * \return M_TRUE if the node updated.
693 */
694M_API M_bool M_json_set_int(M_json_node_t *node, M_int64 value);
695
696
697/*! Get the value from a decimal node.
698 *
699 * \param[in] node The node.
700 *
701 * \return The value.
702 */
704
705
706/*! Make the node a decimal node and set the value.
707 *
708 * \param[in,out] node The node.
709 * \param[in] value The value.
710 *
711 * \return M_TRUE if the node updated.
712 */
713M_API M_bool M_json_set_decimal(M_json_node_t *node, const M_decimal_t *value);
714
715
716/*! Get the value from a bool node.
717 *
718 * If the node is not a M_JSON_TYPE_BOOL auto conversion will be attempted.
719 *
720 * \param[in] node The node.
721 *
722 * \return The value. M_FALSE on error. The only way to know if there was an error
723 * or the return is the value is to check the type.
724 *
725 * \see M_json_node_type
726 */
727M_API M_bool M_json_get_bool(const M_json_node_t *node);
728
729
730/*! Make the node a bool node and set the value.
731 *
732 * \param[in,out] node The node.
733 * \param[in] value The value.
734 *
735 * \return M_TRUE if the node updated.
736 */
737M_API M_bool M_json_set_bool(M_json_node_t *node, M_bool value);
738
739
740/*! Make the node a null node.
741 *
742 * \param[in] node The node.
743 *
744 * \return M_TRUE if the node updated.
745 */
746M_API M_bool M_json_set_null(M_json_node_t *node);
747
748
749/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
750
751/*! Get the node value as a string.
752 *
753 * This will only work on value type nodes (string, integer, decimal, book, null).
754 * Other node types (object, array) will fail.
755 *
756 * \param[in] node The node.
757 * \param[out] buf An allocated buffer to write the value as a string to. The result will be null terminated
758 * on success.
759 * \param[in] buf_len The length of the buffer.
760 *
761 * \return M_TRUE on success. Otherwise M_FALSE.
762 */
763M_API M_bool M_json_get_value(const M_json_node_t *node, char *buf, size_t buf_len);
764
765
766/*! Get the node value as a string.
767 *
768 * This will only work on value type nodes (string, integer, decimal, book, null).
769 * Other node types (object, array) will fail.
770 *
771 * \param[in] node The node.
772 *
773 * \return The value or NULL on error.
774 */
775M_API char *M_json_get_value_dup(const M_json_node_t *node);
776
777/*! @} */
778
779__END_DECLS
780
781#endif /* __M_JSON_H__ */
Definition: m_decimal.h:78
M_fs_error_t
Definition: m_fs.h:154
M_bool M_json_array_insert_string(M_json_node_t *node, const char *value)
M_bool M_json_array_insert(M_json_node_t *node, M_json_node_t *value)
void M_json_node_destroy(M_json_node_t *node) M_FREE(1)
M_bool M_json_set_decimal(M_json_node_t *node, const M_decimal_t *value)
char * M_json_get_value_dup(const M_json_node_t *node)
M_bool M_json_set_null(M_json_node_t *node)
M_bool M_json_object_insert(M_json_node_t *node, const char *key, M_json_node_t *value)
M_bool M_json_object_insert_bool(M_json_node_t *node, const char *key, M_bool value)
M_json_node_t * M_json_object_value(const M_json_node_t *node, const char *key)
M_bool M_json_object_value_bool(const M_json_node_t *node, const char *key)
const char * M_json_object_value_string(const M_json_node_t *node, const char *key)
M_bool M_json_set_bool(M_json_node_t *node, M_bool value)
M_int64 M_json_object_value_int(const M_json_node_t *node, const char *key)
M_int64 M_json_get_int(const M_json_node_t *node)
M_list_str_t * M_json_object_keys(const M_json_node_t *node)
M_bool M_json_object_insert_string(M_json_node_t *node, const char *key, const char *value)
M_bool M_json_get_bool(const M_json_node_t *node)
M_json_reader_flags_t
Definition: m_json.h:114
M_bool M_json_array_insert_at_int(M_json_node_t *node, M_int64 value, size_t idx)
M_json_node_t * M_json_array_at(const M_json_node_t *node, size_t idx)
size_t M_json_object_num_children(const M_json_node_t *node)
M_bool M_json_object_insert_decimal(M_json_node_t *node, const char *key, const M_decimal_t *value)
M_json_type_t
Definition: m_json.h:101
M_bool M_json_array_insert_at(M_json_node_t *node, M_json_node_t *value, size_t idx)
M_json_writer_flags_t
Definition: m_json.h:133
M_bool M_json_array_at_bool(const M_json_node_t *node, size_t idx)
M_json_node_t * M_json_read(const char *data, size_t data_len, M_uint32 flags, size_t *processed_len, M_json_error_t *error, size_t *error_line, size_t *error_pos) M_MALLOC
M_bool M_json_array_insert_decimal(M_json_node_t *node, const M_decimal_t *value)
M_json_node_t * M_json_get_parent(const M_json_node_t *node)
struct M_json_node M_json_node_t
Definition: m_json.h:95
M_bool M_json_array_insert_at_bool(M_json_node_t *node, M_bool value, size_t idx)
M_bool M_json_set_int(M_json_node_t *node, M_int64 value)
M_int64 M_json_array_at_int(const M_json_node_t *node, size_t idx)
M_bool M_json_array_insert_at_decimal(M_json_node_t *node, const M_decimal_t *value, size_t idx)
const char * M_json_get_string(const M_json_node_t *node)
M_bool M_json_array_insert_bool(M_json_node_t *node, M_bool value)
M_bool M_json_array_insert_at_string(M_json_node_t *node, const char *value, size_t idx)
M_json_node_t * M_json_read_file(const char *path, M_uint32 flags, size_t max_read, M_json_error_t *error, size_t *error_line, size_t *error_pos) M_MALLOC
M_json_error_t
Definition: m_json.h:148
M_json_node_t * M_json_node_create(M_json_type_t type) M_MALLOC
void M_json_take_from_parent(M_json_node_t *node)
const M_decimal_t * M_json_object_value_decimal(const M_json_node_t *node, const char *key)
const M_decimal_t * M_json_get_decimal(const M_json_node_t *node)
const char * M_json_array_at_string(const M_json_node_t *node, size_t idx)
const M_decimal_t * M_json_array_at_decimal(const M_json_node_t *node, size_t idx)
M_bool M_json_object_insert_int(M_json_node_t *node, const char *key, M_int64 value)
M_json_type_t M_json_node_type(const M_json_node_t *node)
size_t M_json_array_len(const M_json_node_t *node)
M_bool M_json_array_insert_int(M_json_node_t *node, M_int64 value)
M_fs_error_t M_json_write_file(const M_json_node_t *node, const char *path, M_uint32 flags)
M_bool M_json_get_value(const M_json_node_t *node, char *buf, size_t buf_len)
M_json_node_t ** M_json_jsonpath(const M_json_node_t *node, const char *search, size_t *num_matches) M_MALLOC
char * M_json_write(const M_json_node_t *node, M_uint32 flags, size_t *len) M_WARN_UNUSED_RESULT M_MALLOC
const char * M_json_errcode_to_str(M_json_error_t err)
M_bool M_json_set_string(M_json_node_t *node, const char *value)
@ M_JSON_READER_DISALLOW_COMMENTS
Definition: m_json.h:119
@ M_JSON_READER_ALLOW_DECIMAL_TRUNCATION
Definition: m_json.h:117
@ M_JSON_READER_REPLACE_BAD_CHARS
Definition: m_json.h:128
@ M_JSON_READER_DONT_DECODE_UNICODE
Definition: m_json.h:124
@ M_JSON_READER_OBJECT_UNIQUE_KEYS
Definition: m_json.h:120
@ M_JSON_READER_NONE
Definition: m_json.h:115
@ M_JSON_TYPE_OBJECT
Definition: m_json.h:103
@ M_JSON_TYPE_STRING
Definition: m_json.h:105
@ M_JSON_TYPE_BOOL
Definition: m_json.h:108
@ M_JSON_TYPE_DECIMAL
Definition: m_json.h:107
@ M_JSON_TYPE_UNKNOWN
Definition: m_json.h:102
@ M_JSON_TYPE_NULL
Definition: m_json.h:109
@ M_JSON_TYPE_ARRAY
Definition: m_json.h:104
@ M_JSON_TYPE_INTEGER
Definition: m_json.h:106
@ M_JSON_WRITER_PRETTYPRINT_TAB
Definition: m_json.h:136
@ M_JSON_WRITER_DONT_ENCODE_UNICODE
Definition: m_json.h:139
@ M_JSON_WRITER_PRETTYPRINT_WINLINEEND
Definition: m_json.h:137
@ M_JSON_WRITER_PRETTYPRINT_SPACE
Definition: m_json.h:135
@ M_JSON_WRITER_REPLACE_BAD_CHARS
Definition: m_json.h:141
@ M_JSON_WRITER_NUMBER_NOCOMPAT
Definition: m_json.h:142
@ M_JSON_WRITER_NONE
Definition: m_json.h:134
@ M_JSON_ERROR_INVALID_UNICODE_ESACPE
Definition: m_json.h:166
@ M_JSON_ERROR_UNCLOSED_STRING
Definition: m_json.h:168
@ M_JSON_ERROR_SUCCESS
Definition: m_json.h:149
@ M_JSON_ERROR_INVALID_IDENTIFIER
Definition: m_json.h:173
@ M_JSON_ERROR_EXPECTED_VALUE
Definition: m_json.h:160
@ M_JSON_ERROR_EXPECTED_END
Definition: m_json.h:153
@ M_JSON_ERROR_INVALID_START
Definition: m_json.h:152
@ M_JSON_ERROR_UNEXPECTED_END
Definition: m_json.h:174
@ M_JSON_ERROR_UNCLOSED_ARRAY
Definition: m_json.h:163
@ M_JSON_ERROR_INVALID_BOOL
Definition: m_json.h:169
@ M_JSON_ERROR_INVALID_PAIR_START
Definition: m_json.h:156
@ M_JSON_ERROR_UNEXPECTED_TERMINATION
Definition: m_json.h:172
@ M_JSON_ERROR_OBJECT_UNEXPECTED_CHAR
Definition: m_json.h:159
@ M_JSON_ERROR_MISSING_PAIR_SEPARATOR
Definition: m_json.h:158
@ M_JSON_ERROR_MISSING_COMMENT_CLOSE
Definition: m_json.h:154
@ M_JSON_ERROR_INVALID_NUMBER
Definition: m_json.h:171
@ M_JSON_ERROR_UNCLOSED_OBJECT
Definition: m_json.h:161
@ M_JSON_ERROR_INVALID_NULL
Definition: m_json.h:170
@ M_JSON_ERROR_MISUSE
Definition: m_json.h:151
@ M_JSON_ERROR_UNEXPECTED_CONTROL_CHAR
Definition: m_json.h:165
@ M_JSON_ERROR_UNEXPECTED_COMMENT_START
Definition: m_json.h:155
@ M_JSON_ERROR_UNEXPECTED_ESCAPE
Definition: m_json.h:167
@ M_JSON_ERROR_GENERIC
Definition: m_json.h:150
@ M_JSON_ERROR_DUPLICATE_KEY
Definition: m_json.h:157
@ M_JSON_ERROR_UNEXPECTED_NEWLINE
Definition: m_json.h:164
@ M_JSON_ERROR_ARRAY_UNEXPECTED_CHAR
Definition: m_json.h:162
struct M_list_str M_list_str_t
Definition: m_list_str.h:80