Coverage Report

Created: 2023-12-12 06:10

/src/core/libntech/libutils/json.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
  Copyright 2023 Northern.tech AS
3
4
  This file is part of CFEngine 3 - written and maintained by Northern.tech AS.
5
6
  Licensed under the Apache License, Version 2.0 (the "License");
7
  you may not use this file except in compliance with the License.
8
  You may obtain a copy of the License at
9
10
      http://www.apache.org/licenses/LICENSE-2.0
11
12
  Unless required by applicable law or agreed to in writing, software
13
  distributed under the License is distributed on an "AS IS" BASIS,
14
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
  See the License for the specific language governing permissions and
16
  limitations under the License.
17
18
  To the extent this program is licensed as part of the Enterprise
19
  versions of CFEngine, the applicable Commercial Open Source License
20
  (COSL) may apply to this file if you as a licensee so wish it. See
21
  included file COSL.txt.
22
*/
23
24
#ifndef CFENGINE_JSON_H
25
#define CFENGINE_JSON_H
26
27
#include <writer.h>
28
#include <inttypes.h> // int64_t
29
#include <assert.h>
30
31
/**
32
  @brief JSON data-structure.
33
34
  This is a JSON Document Object Model (DOM). Clients deal only with the opaque
35
  JsonElement, which may be either a container or a primitive (client should
36
  probably not deal much with primitive elements). A JSON container may be
37
  either an object or an array. The JSON DOM currently supports copy semantics
38
  for primitive values, but not for container types. In practice, this means
39
  that clients always just free the parent element, but an element should just
40
  have a single parent, or none.
41
42
  JSON primitives as JsonElement are currently not well supported.
43
44
  JSON DOM is currently built upon Sequence.
45
  The JSON specification may be found at @link http://www.json.org @endlink.
46
47
  @see Sequence
48
*/
49
50
typedef enum
51
{
52
    JSON_ELEMENT_TYPE_CONTAINER = 1,
53
    JSON_ELEMENT_TYPE_PRIMITIVE = 2,
54
} JsonElementType;
55
56
typedef enum
57
{
58
    JSON_CONTAINER_TYPE_OBJECT = 3,
59
    JSON_CONTAINER_TYPE_ARRAY = 4,
60
} JsonContainerType;
61
62
typedef enum
63
{
64
    JSON_PRIMITIVE_TYPE_STRING = 5,
65
    JSON_PRIMITIVE_TYPE_INTEGER = 6,
66
    JSON_PRIMITIVE_TYPE_REAL = 7,
67
    JSON_PRIMITIVE_TYPE_BOOL = 8,
68
    JSON_PRIMITIVE_TYPE_NULL = 9,
69
} JsonPrimitiveType;
70
71
typedef enum
72
{
73
    JSON_TYPE_OBJECT = JSON_CONTAINER_TYPE_OBJECT,
74
    JSON_TYPE_ARRAY = JSON_CONTAINER_TYPE_ARRAY,
75
    JSON_TYPE_STRING = JSON_PRIMITIVE_TYPE_STRING,
76
    JSON_TYPE_INTEGER = JSON_PRIMITIVE_TYPE_INTEGER,
77
    JSON_TYPE_REAL = JSON_PRIMITIVE_TYPE_REAL,
78
    JSON_TYPE_BOOL = JSON_PRIMITIVE_TYPE_BOOL,
79
    JSON_TYPE_NULL = JSON_PRIMITIVE_TYPE_NULL,
80
} JsonType;
81
82
typedef enum
83
{
84
    JSON_PARSE_OK = 0,
85
86
    JSON_PARSE_ERROR_STRING_NO_DOUBLEQUOTE_START,
87
    JSON_PARSE_ERROR_STRING_NO_DOUBLEQUOTE_END,
88
89
    JSON_PARSE_ERROR_NUMBER_EXPONENT_NEGATIVE,
90
    JSON_PARSE_ERROR_NUMBER_EXPONENT_POSITIVE,
91
    JSON_PARSE_ERROR_NUMBER_DUPLICATE_ZERO,
92
    JSON_PARSE_ERROR_NUMBER_NO_DIGIT,
93
    JSON_PARSE_ERROR_NUMBER_MULTIPLE_DOTS,
94
    JSON_PARSE_ERROR_NUMBER_EXPONENT_DUPLICATE,
95
    JSON_PARSE_ERROR_NUMBER_EXPONENT_DIGIT,
96
    JSON_PARSE_ERROR_NUMBER_EXPONENT_FOLLOW_LEADING_ZERO,
97
    JSON_PARSE_ERROR_NUMBER_BAD_SYMBOL,
98
    JSON_PARSE_ERROR_NUMBER_DIGIT_END,
99
100
    JSON_PARSE_ERROR_ARRAY_START,
101
    JSON_PARSE_ERROR_ARRAY_END,
102
    JSON_PARSE_ERROR_ARRAY_COMMA,
103
104
    JSON_PARSE_ERROR_OBJECT_BAD_SYMBOL,
105
    JSON_PARSE_ERROR_OBJECT_START,
106
    JSON_PARSE_ERROR_OBJECT_END,
107
    JSON_PARSE_ERROR_OBJECT_COLON,
108
    JSON_PARSE_ERROR_OBJECT_COMMA,
109
    JSON_PARSE_ERROR_OBJECT_ARRAY_LVAL,
110
    JSON_PARSE_ERROR_OBJECT_OBJECT_LVAL,
111
    JSON_PARSE_ERROR_OBJECT_OPEN_LVAL,
112
113
    JSON_PARSE_ERROR_INVALID_START,
114
    JSON_PARSE_ERROR_INVALID_END,
115
    JSON_PARSE_ERROR_NO_LIBYAML,
116
    JSON_PARSE_ERROR_LIBYAML_FAILURE,
117
    JSON_PARSE_ERROR_NO_SUCH_FILE,
118
    JSON_PARSE_ERROR_NO_DATA,
119
    JSON_PARSE_ERROR_TRUNCATED,
120
121
    JSON_PARSE_ERROR_MAX
122
} JsonParseError;
123
124
typedef struct JsonElement_ JsonElement;
125
126
typedef struct
127
{
128
    const JsonElement *container;
129
    size_t index;
130
} JsonIterator;
131
132
133
//////////////////////////////////////////////////////////////////////////////
134
// String encoding (escaping)
135
//////////////////////////////////////////////////////////////////////////////
136
137
char *JsonDecodeString(const char *escaped_string);
138
char *JsonEncodeString(const char *const unescaped_string);
139
140
typedef struct _Slice
141
{
142
    // Slice is used to represent a section of memory which may or may not
143
    // contain NUL bytes. This is useful for storing the unescaped versions of
144
    // JSON(5) strings (which may have NUL bytes).
145
146
    void *data;  // Binary data here, not just ascii plain text
147
    size_t size; // Allocated size in bytes (or shorter if you shrink later)
148
} Slice;
149
150
char *Json5EscapeData(Slice unescaped_data);
151
152
// Not implemented yet:
153
// Slice Json5UnescapeString(const char *escaped_string);
154
155
//////////////////////////////////////////////////////////////////////////////
156
// Generic JSONElement functions
157
//////////////////////////////////////////////////////////////////////////////
158
159
JsonElement *JsonCopy(const JsonElement *json);
160
int JsonCompare(const JsonElement *a, const JsonElement *b);
161
JsonElement *JsonMerge(const JsonElement *a, const JsonElement *b);
162
163
/**
164
 * @brief Recursively merge one object into another
165
 *
166
 * @param base Object to merge data into
167
 * @param extra Object to merge data from
168
 * @return Pointer to base object (convenient for nested function calls)
169
 *
170
 * @note The function should not return NULL
171
 * @warning Side effects: The base object is modified in place. If this is not
172
 *          the intention, consider using JsonObjectMergeDeep
173
 */
174
JsonElement *JsonObjectMergeDeepInplace(JsonElement *base, const JsonElement *extra);
175
176
/**
177
 * @brief Recursively merge two objects into a new object
178
 *
179
 * @param base Object to copy and merge data into
180
 * @param extra Object to merge data from
181
 * @return Pointer to merged object
182
 *
183
 * @note The function should not return NULL
184
 * @warning Performance penalty: A new object is created. If this is not the
185
 *          intension, consider using JsonObjectMergeDeepInplace
186
 */
187
static inline JsonElement *JsonObjectMergeDeep(const JsonElement *const base, const JsonElement *const extra)
188
0
{
189
0
    assert(base != NULL);
190
0
    /* This could do a little better job by constructing the JsonElement while
191
0
     * merging base and extra. Not sure if it's worth the extra complexity,
192
0
     * though. */
193
0
    JsonElement *const copy = JsonCopy(base);
194
0
    return JsonObjectMergeDeepInplace(copy, extra);
195
0
}
196
197
/**
198
  @brief Destroy a JSON element
199
  @param element [in] The JSON element to destroy.
200
  */
201
void JsonDestroy(JsonElement *element);
202
203
/**
204
  @brief Destroy a JSON element if needed
205
  @param element [in] The JSON element to destroy.
206
  @param allocated [in] Whether the element was allocated and needs to be
207
                        destroyed.
208
  */
209
void JsonDestroyMaybe(JsonElement *element, bool allocated);
210
211
/**
212
  @brief Get the length of a JsonElement. This is the number of elements or
213
  fields in an array or object respectively.
214
  @param element [in] The JSON element.
215
  */
216
size_t JsonLength(const JsonElement *element);
217
218
JsonElementType JsonGetElementType(const JsonElement *element);
219
JsonType JsonGetType(const JsonElement *element);
220
const char *JsonElementGetPropertyName(const JsonElement *element);
221
222
const char *JsonGetPropertyAsString(const JsonElement *element);
223
224
#define NULL_JSON(json) ((json == NULL) || (JsonGetType(json) == JSON_TYPE_NULL))
225
#define JSON_NOT_NULL(json) ((json != NULL) && (JsonGetType(json) != JSON_TYPE_NULL))
226
227
//////////////////////////////////////////////////////////////////////////////
228
// JSON Primitives
229
//////////////////////////////////////////////////////////////////////////////
230
231
const char *JsonPrimitiveTypeToString(JsonPrimitiveType type);
232
JsonPrimitiveType JsonGetPrimitiveType(const JsonElement *primitive);
233
const char *JsonPrimitiveGetAsString(const JsonElement *primitive);
234
char *JsonPrimitiveToString(const JsonElement *primitive);
235
bool JsonPrimitiveGetAsBool(const JsonElement *primitive);
236
long JsonPrimitiveGetAsInteger(const JsonElement *primitive);
237
int JsonPrimitiveGetAsInt64(const JsonElement *primitive, int64_t *value_out);
238
int64_t JsonPrimitiveGetAsInt64DefaultOnError(const JsonElement *primitive, int64_t default_return);
239
int64_t JsonPrimitiveGetAsInt64ExitOnError(const JsonElement *primitive);
240
double JsonPrimitiveGetAsReal(const JsonElement *primitive);
241
242
JsonElement *JsonStringCreate(const char *value);
243
JsonElement *JsonIntegerCreate(int value);
244
JsonElement *JsonIntegerCreate64(int64_t value);
245
JsonElement *JsonRealCreate(double value);
246
JsonElement *JsonBoolCreate(bool value);
247
JsonElement *JsonNullCreate();
248
249
250
//////////////////////////////////////////////////////////////////////////////
251
// JSON Containers (array or object)
252
//////////////////////////////////////////////////////////////////////////////
253
254
void JsonContainerReverse(JsonElement *array);
255
256
typedef int JsonComparator(
257
    const JsonElement *, const JsonElement *, void *user_data);
258
259
void JsonSort(
260
    const JsonElement *container, JsonComparator *Compare, void *user_data);
261
JsonElement *JsonAt(const JsonElement *container, size_t index);
262
JsonElement *JsonSelect(
263
    JsonElement *element, size_t num_indices, char **indices);
264
265
JsonContainerType JsonGetContainerType(const JsonElement *container);
266
267
268
//////////////////////////////////////////////////////////////////////////////
269
// JSON Object (dictionary)
270
//////////////////////////////////////////////////////////////////////////////
271
272
/**
273
  @brief Create a new JSON object
274
  @param initial_capacity [in] The number of fields to preallocate space for.
275
  @returns A pointer to the created object.
276
  */
277
JsonElement *JsonObjectCreate(size_t initial_capacity);
278
279
/**
280
  @brief Append a string field to an object.
281
  @param object [in] The JSON object parent.
282
  @param key [in] the key of the field.
283
  @param value [in] The value of the field.
284
  */
285
void JsonObjectAppendString(
286
    JsonElement *object, const char *key, const char *value);
287
288
/**
289
  @brief Append an integer field to an object.
290
  @param object [in] The JSON object parent.
291
  @param key [in] the key of the field.
292
  @param value [in] The value of the field.
293
  */
294
void JsonObjectAppendInteger(JsonElement *object, const char *key, int value);
295
296
/**
297
  @brief Append a 64-bit integer field to an object.
298
  @param object [in] The JSON object parent.
299
  @param key [in] the key of the field.
300
  @param value [in] The value of the field.
301
  */
302
void JsonObjectAppendInteger64(JsonElement *object, const char *key, int64_t value);
303
304
/**
305
  @brief Append an real number field to an object.
306
  @param object [in] The JSON object parent.
307
  @param key [in] the key of the field.
308
  @param value [in] The value of the field.
309
  */
310
void JsonObjectAppendReal(JsonElement *object, const char *key, double value);
311
312
/**
313
  @param object [in] The JSON object parent.
314
  @param key [in] the key of the field.
315
  @param value [in] The value of the field.
316
  */
317
void JsonObjectAppendBool(JsonElement *object, const char *key, _Bool value);
318
319
/**
320
  @brief Append null field to an object.
321
  @param object [in] The JSON object parent.
322
  @param key [in] the key of the field.
323
  */
324
void JsonObjectAppendNull(JsonElement *object, const char *key);
325
326
/**
327
  @brief Append an array field to an object.
328
  @param object [in] The JSON object parent.
329
  @param key [in] the key of the field.
330
  @param value [in] The value of the field.
331
  */
332
void JsonObjectAppendArray(
333
    JsonElement *object, const char *key, JsonElement *array);
334
335
/**
336
  @brief Append an object field to an object.
337
  @param object [in] The JSON object parent.
338
  @param key [in] the key of the field.
339
  @param value [in] The value of the field.
340
  */
341
void JsonObjectAppendObject(
342
    JsonElement *object, const char *key, JsonElement *childObject);
343
344
/**
345
  @brief Append any JSON element to an object.
346
  @param object [in] The JSON object parent.
347
  @param key [in] the key of the field.
348
  @param element [in] The element to append
349
*/
350
void JsonObjectAppendElement(
351
    JsonElement *object, const char *key, JsonElement *element);
352
353
/**
354
  @brief Get the value of a field in an object, as a string.
355
  @param object [in] The JSON object parent.
356
  @param key [in] the key of the field.
357
  @returns A pointer to the string value, or NULL if non-existent.
358
  */
359
const char *JsonObjectGetAsString(const JsonElement *object, const char *key);
360
361
362
/**
363
  @brief Get the value of a field in an object, as a boolean.
364
  @param object [in] The JSON object parent.
365
  @param key [in] the key of the field.
366
  @returns The boolean value for the key or false if key is not available
367
  */
368
bool JsonObjectGetAsBool(const JsonElement *const object, const char *key);
369
370
/**
371
  @brief Get the value of a field in an object, as an object.
372
  @param object [in] The JSON object parent.
373
  @param key [in] the key of the field.
374
  @returns A pointer to the object value, or NULL if non-existent.
375
  */
376
JsonElement *JsonObjectGetAsObject(JsonElement *object, const char *key);
377
378
/**
379
  @brief Get the value of a field in an object, as an array.
380
  @param object [in] The JSON object parent.
381
  @param key [in] the key of the field.
382
  @returns A pointer to the array value, or NULL if non-existent.
383
  */
384
JsonElement *JsonObjectGetAsArray(JsonElement *object, const char *key);
385
386
JsonElement *JsonObjectGet(const JsonElement *object, const char *key);
387
388
/**
389
  @brief Remove key from the object
390
  @param object containing the key property
391
  @param property name to be removed
392
  @return True if key was removed
393
  */
394
bool JsonObjectRemoveKey(JsonElement *object, const char *key);
395
396
/**
397
  @brief Detach json element ownership from parent object;
398
  @param object containing the key property
399
  @param property name to be detached
400
  */
401
JsonElement *JsonObjectDetachKey(JsonElement *object, const char *key);
402
403
404
//////////////////////////////////////////////////////////////////////////////
405
// JSON Array (list)
406
//////////////////////////////////////////////////////////////////////////////
407
408
/**
409
  @brief Create a new JSON array
410
  @param initial_capacity [in] The number of fields to preallocate space for.
411
  @returns The pointer to the created array.
412
  */
413
JsonElement *JsonArrayCreate(size_t initialCapacity);
414
415
/**
416
  @brief Append a string to an array.
417
  @param array [in] The JSON array parent.
418
  @param value [in] The string value to append.
419
  */
420
void JsonArrayAppendString(JsonElement *array, const char *value);
421
422
void JsonArrayAppendBool(JsonElement *array, bool value);
423
424
/**
425
  @brief Append an integer to an array.
426
  @param array [in] The JSON array parent.
427
  @param value [in] The integer value to append.
428
  */
429
void JsonArrayAppendInteger(JsonElement *array, int value);
430
431
/**
432
  @brief Append an real to an array.
433
  @param array [in] The JSON array parent.
434
  @param value [in] The real value to append.
435
  */
436
void JsonArrayAppendReal(JsonElement *array, double value);
437
438
/**
439
  @brief Append null to an array.
440
  @param array [in] The JSON array parent.
441
  */
442
void JsonArrayAppendNull(JsonElement *array);
443
444
/**
445
  @brief Append an array to an array.
446
  @param array [in] The JSON array parent.
447
  @param child_array [in] The array value to append.
448
  */
449
void JsonArrayAppendArray(JsonElement *array, JsonElement *child_array);
450
451
/**
452
  @brief Append an object to an array.
453
  @param array [in] The JSON array parent.
454
  @param object [in] The object value to append.
455
  */
456
void JsonArrayAppendObject(JsonElement *array, JsonElement *object);
457
458
/**
459
  @brief Append any JSON element to an array.
460
  @param array [in] The JSON array parent.
461
  @param element [in] The object to append.
462
  */
463
void JsonArrayAppendElement(JsonElement *array, JsonElement *element);
464
465
/**
466
  * @brief Move elements from JSON array `b` to JSON array `a`.
467
  * @param a [in] The JSON array to move elements to.
468
  * @param b [in] The JSON array to move elements from.
469
  * @note JSON array `a` takes ownership of elements in JSON array `b`.
470
  *       JSON array `b` is freed from memory.
471
  */
472
void JsonArrayExtend(JsonElement *a, JsonElement *b);
473
474
/**
475
  @brief Remove an inclusive range from a JSON array.
476
  @see SequenceRemoveRange
477
  @param array [in] The JSON array parent.
478
  @param start [in] Index of the first element to remove.
479
  @param end [in] Index of the last element to remove.
480
  */
481
void JsonArrayRemoveRange(JsonElement *array, size_t start, size_t end);
482
483
/**
484
  @brief Get a string value from an array
485
  @param array [in] The JSON array parent
486
  @param index [in] Position of the value to get
487
  @returns A pointer to the string value, or NULL if non-existent.
488
  */
489
const char *JsonArrayGetAsString(JsonElement *array, size_t index);
490
491
/**
492
  @brief Get an object value from an array
493
  @param array [in] The JSON array parent
494
  @param index [in] Position of the value to get
495
  @returns A pointer to the object value, or NULL if non-existent.
496
  */
497
JsonElement *JsonArrayGetAsObject(JsonElement *array, size_t index);
498
499
JsonElement *JsonArrayGet(const JsonElement *array, size_t index);
500
501
/**
502
  @brief Check if an array contains only primitives
503
  @param array [in] The JSON array parent
504
  @returns true if the array contains only primitives, false otherwise
505
  */
506
bool JsonArrayContainsOnlyPrimitives(JsonElement *array);
507
508
509
//////////////////////////////////////////////////////////////////////////////
510
// JSON Iterator
511
//////////////////////////////////////////////////////////////////////////////
512
513
JsonIterator JsonIteratorInit(const JsonElement *container);
514
const char *JsonIteratorNextKey(JsonIterator *iter);
515
JsonElement *JsonIteratorNextValue(JsonIterator *iter);
516
JsonElement *JsonIteratorNextValueByType(
517
    JsonIterator *iter, JsonElementType type, bool skip_null);
518
const char *JsonIteratorCurrentKey(const JsonIterator *iter);
519
JsonElement *JsonIteratorCurrentValue(const JsonIterator *iter);
520
JsonElementType JsonIteratorCurrentElementType(const JsonIterator *iter);
521
JsonContainerType JsonIteratorCurrentContainerType(const JsonIterator *iter);
522
JsonPrimitiveType JsonIteratorCurrentPrimitiveType(const JsonIterator *iter);
523
bool JsonIteratorHasMore(const JsonIterator *iter);
524
525
526
/**
527
 * @param element current element being visited
528
 * @param data    arbitrary data passed to JsonWalk()
529
 * @return        whether the recursive walk should continue or not
530
 */
531
typedef bool JsonElementVisitor(JsonElement *element, void *data);
532
533
/**
534
 * Recursively walk over the JSON element.
535
 *
536
 * @param element           JSON element to start with
537
 * @param object_visitor    function to call on child objects
538
 * @param array_visitor     function to call on child arrays
539
 * @param primitive_visitor function to call on child primitives
540
 * @param data              arbitrary data passed to visitor functions
541
 * @return                  whether the recursive walk finished or was stopped (see #JsonElementVisitor)
542
 *
543
 * The function starts with the given JSON element #element and recursively
544
 * visits its child elements (if any), calling respective visitor functions on
545
 * each of the child elements.
546
 *
547
 * @note Each parent element is visited before its child elements.
548
 * @note Every element in the given JSON is visited unless one of the visitor functions returns
549
 *       #false.
550
 * @note Every element is visited at most once.
551
 * @warning Modifications of the visited elements must be done with extreme caution and good
552
 *          understanding of the implementation of the #JsonElement and #JsonIterator internals.
553
 */
554
bool JsonWalk(JsonElement *element,
555
              JsonElementVisitor object_visitor,
556
              JsonElementVisitor array_visitor,
557
              JsonElementVisitor primitive_visitor,
558
              void *data);
559
560
/**
561
 * Visitor that just stops the walk on any element.
562
 *
563
 * Can be used as one of the visitor functions for JsonWalk() to detect
564
 * undesired child elements.
565
 */
566
bool JsonErrorVisitor(JsonElement *element, void *data);
567
568
//////////////////////////////////////////////////////////////////////////////
569
// JSON Parsing
570
//////////////////////////////////////////////////////////////////////////////
571
572
typedef JsonElement *JsonLookup(void *ctx, const char **data);
573
574
/**
575
  @brief Parse a string to create a JsonElement
576
  @param data [in] Pointer to the string to parse
577
  @param json_out Resulting JSON object
578
  @returns See JsonParseError and JsonParseErrorToString
579
  */
580
JsonParseError JsonParse(const char **data, JsonElement **json_out);
581
582
/**
583
  @brief Parse the whole string to create a JsonElement
584
  @param data [in] Pointer to the string to parse
585
  @param json_out Resulting JSON object
586
  @note In contrast to JsonParse(), this function will return
587
        JSON_PARSE_ERROR_INVALID_END if there are trailing non-whitespace
588
        characters after termination of the JsonElement in the remainder of
589
        the string.
590
  @returns See JsonParseError and JsonParseErrorToString
591
  */
592
JsonParseError JsonParseAll(const char **data, JsonElement **json_out);
593
594
/**
595
  @brief Parse a string to create a JsonElement
596
  @param lookup_data [in] Evaluation context for variable lookups
597
  @param lookup_function [in] Callback function for variable lookups
598
  @param data [in] Pointer to the string to parse
599
  @param json_out Resulting JSON object
600
  @returns See JsonParseError and JsonParseErrorToString
601
602
  The lookup_context type is void so we don't have to include
603
  eval_context.h from libpromises into libutil
604
  */
605
JsonParseError JsonParseWithLookup(
606
    void *lookup_data,
607
    JsonLookup *lookup_function,
608
    const char **data,
609
    JsonElement **json_out);
610
611
/**
612
 * @brief Convenience function to parse JSON or YAML from a file
613
 * @param path Path to the file
614
 * @param size_max Maximum size to read in memory
615
 * @param json_out Resulting JSON object
616
 * @param yaml_format Whether or not the file is in yaml format
617
 * @return See JsonParseError and JsonParseErrorToString
618
 */
619
JsonParseError JsonParseAnyFile(
620
    const char *path,
621
    size_t size_max,
622
    JsonElement **json_out,
623
    bool yaml_format);
624
625
/**
626
 * @brief Convenience function to parse JSON from a file.
627
 * @param path Path to the file
628
 * @param size_max Maximum size to read in memory
629
 * @param json_out Resulting JSON object
630
 * @return See JsonParseError and JsonParseErrorToString
631
 */
632
JsonParseError JsonParseFile(
633
    const char *path, size_t size_max, JsonElement **json_out);
634
635
const char *JsonParseErrorToString(JsonParseError error);
636
637
638
//////////////////////////////////////////////////////////////////////////////
639
// JSON Serialization (Write)
640
//////////////////////////////////////////////////////////////////////////////
641
642
/**
643
  @brief Pretty-print a JsonElement recursively into a Writer.  If it's a
644
  JsonObject, its children will be sorted to produce canonical JSON output, but
645
  the object's contents are not modified so it's still a const.
646
  @see Writer
647
  @param writer [in] The Writer object to use as a buffer.
648
  @param element [in] The JSON element to print.
649
  @param indent_level [in] The nesting level with which the printing should be
650
  done. This is mainly to allow the function to be called recursively. Clients
651
  will normally want to set this to 0.
652
  */
653
void JsonWrite(
654
    Writer *writer, const JsonElement *element, size_t indent_level);
655
656
void JsonWriteCompact(Writer *w, const JsonElement *element);
657
658
void JsonEncodeStringWriter(const char *const unescaped_string, Writer *const writer);
659
660
#endif