Pharos 0.7.23
Modern Web Framework & Web App Hosting Service.
Loading...
Searching...
No Matches
yyjson.h
Go to the documentation of this file.
1/*==============================================================================
2 Copyright (c) 2020 YaoYuan <ibireme@gmail.com>
3
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 SOFTWARE.
21 *============================================================================*/
22
23/**
24 @file yyjson.h
25 @date 2019-03-09
26 @author YaoYuan
27 */
28
29#ifndef YYJSON_H
30#define YYJSON_H
31
32
33
34/*==============================================================================
35 * MARK: - Compile-time Options
36 *============================================================================*/
37
38/* Define as 1 to disable JSON reader at compile-time.
39 This disables functions with "read" in their name.
40 Reduces binary size by about 60%. */
41#ifndef YYJSON_DISABLE_READER
42#define YYJSON_DISABLE_READER 0
43#endif
44
45/* Define as 1 to disable JSON writer at compile-time.
46 This disables functions with "write" in their name.
47 Reduces binary size by about 30%. */
48#ifndef YYJSON_DISABLE_WRITER
49#define YYJSON_DISABLE_WRITER 0
50#endif
51
52/* Define as 1 to disable JSON incremental reader at compile-time.
53 This disables functions with "incr" in their name. */
54#ifndef YYJSON_DISABLE_INCR_READER
55#define YYJSON_DISABLE_INCR_READER 0
56#endif
57
58/* Define as 1 to disable file/fp read and write APIs. */
59#ifndef YYJSON_DISABLE_FILE
60#define YYJSON_DISABLE_FILE 0
61#endif
62
63/* Define as 1 to disable JSON Pointer, JSON Patch and JSON Merge Patch.
64 This disables functions with "ptr" or "patch" in their name. */
65#ifndef YYJSON_DISABLE_UTILS
66#define YYJSON_DISABLE_UTILS 0
67#endif
68
69/* Define as 1 to disable the fast floating-point number conversion in yyjson.
70 Libc's `strtod/snprintf` will be used instead.
71
72 This reduces binary size by about 30%, but significantly slows down the
73 floating-point read/write speed. */
74#ifndef YYJSON_DISABLE_FAST_FP_CONV
75#define YYJSON_DISABLE_FAST_FP_CONV 0
76#endif
77
78/* Define as 1 to disable non-standard JSON features support at compile-time,
79 such as YYJSON_READ_ALLOW_XXX and YYJSON_WRITE_ALLOW_XXX.
80
81 This reduces binary size by about 10%, and slightly improves performance. */
82#ifndef YYJSON_DISABLE_NON_STANDARD
83#define YYJSON_DISABLE_NON_STANDARD 0
84#endif
85
86/* Define as 1 to disable UTF-8 validation at compile-time.
87
88 Use this if all input strings are guaranteed to be valid UTF-8
89 (e.g. language-level String types are already validated).
90
91 Disabling UTF-8 validation improves performance for non-ASCII strings by
92 about 3% to 7%.
93
94 Note: If this flag is enabled while passing illegal UTF-8 strings,
95 the following errors may occur:
96 - Escaped characters may be ignored when parsing JSON strings.
97 - Ending quotes may be ignored when parsing JSON strings, causing the
98 string to merge with the next value.
99 - When serializing with `yyjson_mut_val`, the string's end may be accessed
100 out of bounds, potentially causing a segmentation fault. */
101#ifndef YYJSON_DISABLE_UTF8_VALIDATION
102#define YYJSON_DISABLE_UTF8_VALIDATION 0
103#endif
104
105/* Define as 1 to improve performance on architectures that do not support
106 unaligned memory access.
107
108 Normally, this does not need to be set manually. */
109#ifndef YYJSON_DISABLE_UNALIGNED_MEMORY_ACCESS
110/* auto detected in yyjson.c */
111#endif
112
113/* Define to an integer to set a depth limit for containers (arrays/objects). */
114#ifndef YYJSON_READER_DEPTH_LIMIT
115#define YYJSON_READER_DEPTH_LIMIT 0
116#endif
117
118/* Define as 1 to build without libc (stdlib, string, math, stdio).
119 Inline fallbacks for memcpy/memmove/memset/memcmp/strlen are provided.
120 Optional `YYJSON_FREESTANDING_HEADER` for custom replacements.
121
122 `malloc`/`free` are unavailable; pass `yyjson_alc` per call or define
123 `YYJSON_CUSTOM_ALC`. Also disables file/fp APIs. Cannot be used with
124 `YYJSON_DISABLE_FAST_FP_CONV`. */
125#ifndef YYJSON_FREESTANDING
126#define YYJSON_FREESTANDING 0
127#endif
128
129/* Define as 1 to export symbols when building this library as a Windows DLL. */
130#ifndef YYJSON_EXPORTS
131#endif
132
133/* Define as 1 to import symbols when using this library as a Windows DLL. */
134#ifndef YYJSON_IMPORTS
135#endif
136
137/* Define as 1 to include <stdint.h> for compilers without C99 support. */
138#ifndef YYJSON_HAS_STDINT_H
139#endif
140
141/* Define as 1 to include <stdbool.h> for compilers without C99 support. */
142#ifndef YYJSON_HAS_STDBOOL_H
143#endif
144
145
146
147/*==============================================================================
148 * MARK: - Compiler Macros
149 *============================================================================*/
150
151/** compiler version (MSVC) */
152#ifdef _MSC_VER
153# define YYJSON_MSC_VER _MSC_VER
154#else
155# define YYJSON_MSC_VER 0
156#endif
157
158/** compiler version (GCC) */
159#ifdef __GNUC__
160# define YYJSON_GCC_VER __GNUC__
161# if defined(__GNUC_PATCHLEVEL__)
162# define yyjson_gcc_available(major, minor, patch) \
163 ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) \
164 >= (major * 10000 + minor * 100 + patch))
165# else
166# define yyjson_gcc_available(major, minor, patch) \
167 ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100) \
168 >= (major * 10000 + minor * 100 + patch))
169# endif
170#else
171# define YYJSON_GCC_VER 0
172# define yyjson_gcc_available(major, minor, patch) 0
173#endif
174
175/** real gcc check */
176#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \
177 !defined(__clang__) && !defined(__llvm__) && \
178 !defined(__INTEL_COMPILER) && !defined(__ICC) && \
179 !defined(__NVCC__) && !defined(__PGI) && !defined(__TINYC__)
180# define YYJSON_IS_REAL_GCC 1
181#else
182# define YYJSON_IS_REAL_GCC 0
183#endif
184
185/** C version (STDC) */
186#if defined(__STDC__) && (__STDC__ >= 1) && defined(__STDC_VERSION__)
187# define YYJSON_STDC_VER __STDC_VERSION__
188#else
189# define YYJSON_STDC_VER 0
190#endif
191
192/** C++ version */
193#if defined(__cplusplus)
194# define YYJSON_CPP_VER __cplusplus
195#else
196# define YYJSON_CPP_VER 0
197#endif
198
199/** compiler builtin check (since gcc 10.0, clang 2.6, icc 2021) */
200#ifndef yyjson_has_builtin
201# ifdef __has_builtin
202# define yyjson_has_builtin(x) __has_builtin(x)
203# else
204# define yyjson_has_builtin(x) 0
205# endif
206#endif
207
208/** compiler attribute check (since gcc 5.0, clang 2.9, icc 17) */
209#ifndef yyjson_has_attribute
210# ifdef __has_attribute
211# define yyjson_has_attribute(x) __has_attribute(x)
212# else
213# define yyjson_has_attribute(x) 0
214# endif
215#endif
216
217/** compiler feature check (since clang 2.6, icc 17) */
218#ifndef yyjson_has_feature
219# ifdef __has_feature
220# define yyjson_has_feature(x) __has_feature(x)
221# else
222# define yyjson_has_feature(x) 0
223# endif
224#endif
225
226/** include check (since gcc 5.0, clang 2.7, icc 16, msvc 2017 15.3) */
227#ifndef yyjson_has_include
228# ifdef __has_include
229# define yyjson_has_include(x) __has_include(x)
230# else
231# define yyjson_has_include(x) 0
232# endif
233#endif
234
235/** inline for compiler */
236#ifndef yyjson_inline
237# if YYJSON_MSC_VER >= 1200
238# define yyjson_inline __forceinline
239# elif defined(_MSC_VER)
240# define yyjson_inline __inline
241# elif yyjson_has_attribute(always_inline) || YYJSON_GCC_VER >= 4
242# define yyjson_inline __inline__ __attribute__((always_inline))
243# elif defined(__clang__) || defined(__GNUC__)
244# define yyjson_inline __inline__
245# elif defined(__cplusplus) || YYJSON_STDC_VER >= 199901L
246# define yyjson_inline inline
247# else
248# define yyjson_inline
249# endif
250#endif
251
252/** noinline for compiler */
253#ifndef yyjson_noinline
254# if YYJSON_MSC_VER >= 1400
255# define yyjson_noinline __declspec(noinline)
256# elif yyjson_has_attribute(noinline) || YYJSON_GCC_VER >= 4
257# define yyjson_noinline __attribute__((noinline))
258# else
259# define yyjson_noinline
260# endif
261#endif
262
263/** align for compiler */
264#ifndef yyjson_align
265# if YYJSON_MSC_VER >= 1300
266# define yyjson_align(x) __declspec(align(x))
267# elif yyjson_has_attribute(aligned) || defined(__GNUC__)
268# define yyjson_align(x) __attribute__((aligned(x)))
269# elif YYJSON_CPP_VER >= 201103L
270# define yyjson_align(x) alignas(x)
271# else
272# define yyjson_align(x)
273# endif
274#endif
275
276/** likely for compiler */
277#ifndef yyjson_likely
278# if yyjson_has_builtin(__builtin_expect) || \
279 (YYJSON_GCC_VER >= 4 && YYJSON_GCC_VER != 5)
280# define yyjson_likely(expr) __builtin_expect(!!(expr), 1)
281# else
282# define yyjson_likely(expr) (expr)
283# endif
284#endif
285
286/** unlikely for compiler */
287#ifndef yyjson_unlikely
288# if yyjson_has_builtin(__builtin_expect) || \
289 (YYJSON_GCC_VER >= 4 && YYJSON_GCC_VER != 5)
290# define yyjson_unlikely(expr) __builtin_expect(!!(expr), 0)
291# else
292# define yyjson_unlikely(expr) (expr)
293# endif
294#endif
295
296/** assume for compiler */
297#undef yyjson_assume
298#if yyjson_has_builtin(__builtin_unreachable) || yyjson_gcc_available(4, 5, 0)
299# define yyjson_assume(expr) ((expr) ? (void)0 : __builtin_unreachable())
300#elif YYJSON_MSC_VER >= 1300
301# define yyjson_assume(expr) __assume(expr)
302#else
303# define yyjson_assume(expr) ((void)0)
304#endif
305
306/** compile-time constant check for compiler */
307#ifndef yyjson_constant_p
308# if yyjson_has_builtin(__builtin_constant_p) || (YYJSON_GCC_VER >= 3)
309# define YYJSON_HAS_CONSTANT_P 1
310# define yyjson_constant_p(value) __builtin_constant_p(value)
311# else
312# define YYJSON_HAS_CONSTANT_P 0
313# define yyjson_constant_p(value) 0
314# endif
315#endif
316
317/** deprecate warning */
318#ifndef yyjson_deprecated
319# if YYJSON_MSC_VER >= 1400
320# define yyjson_deprecated(msg) __declspec(deprecated(msg))
321# elif yyjson_has_feature(attribute_deprecated_with_message) || \
322 (YYJSON_GCC_VER > 4 || (YYJSON_GCC_VER == 4 && __GNUC_MINOR__ >= 5))
323# define yyjson_deprecated(msg) __attribute__((deprecated(msg)))
324# elif YYJSON_GCC_VER >= 3
325# define yyjson_deprecated(msg) __attribute__((deprecated))
326# else
327# define yyjson_deprecated(msg)
328# endif
329#endif
330
331/** function export */
332#ifndef yyjson_api
333# if defined(_WIN32)
334# if defined(YYJSON_EXPORTS) && YYJSON_EXPORTS
335# define yyjson_api __declspec(dllexport)
336# elif defined(YYJSON_IMPORTS) && YYJSON_IMPORTS
337# define yyjson_api __declspec(dllimport)
338# else
339# define yyjson_api
340# endif
341# elif yyjson_has_attribute(visibility) || YYJSON_GCC_VER >= 4
342# define yyjson_api __attribute__((visibility("default")))
343# else
344# define yyjson_api
345# endif
346#endif
347
348/** inline function export */
349#ifndef yyjson_api_inline
350# define yyjson_api_inline static yyjson_inline
351#endif
352
353/** Used to cast away (remove) const qualifier. */
354#ifndef yyjson_constcast
355# define yyjson_constcast(type) (type)(void *)(size_t)(const void *)
356#endif
357
358/** Microsoft Visual C++ 6.0 doesn't support converting number from u64 to f64:
359 error C2520: conversion from unsigned __int64 to double not implemented. */
360#ifndef YYJSON_U64_TO_F64_NO_IMPL
361# if (0 < YYJSON_MSC_VER) && (YYJSON_MSC_VER <= 1200)
362# define YYJSON_U64_TO_F64_NO_IMPL 1
363# else
364# define YYJSON_U64_TO_F64_NO_IMPL 0
365# endif
366#endif
367
368
369
370/*==============================================================================
371 * MARK: - Header Files
372 *============================================================================*/
373
374#include <stddef.h> /* for size_t, NULL */
375#include <limits.h> /* for CHAR_BIT, *_MAX */
376#include <float.h> /* for floating-point limit macros */
377
378/** freestanding */
379#if !YYJSON_FREESTANDING && !YYJSON_DISABLE_FILE
380#include <stdio.h> /* for FILE, fopen, fread, fwrite, sprintf */
381#endif
382#if !YYJSON_FREESTANDING
383#include <stdlib.h> /* for malloc, realloc, free, strtod */
384#include <string.h> /* for memcpy, memmove, memset, memcmp, strlen */
385#include <math.h> /* for HUGE_VAL, INFINITY, NAN (no libm required) */
386#elif defined(YYJSON_FREESTANDING_HEADER)
387# include YYJSON_FREESTANDING_HEADER /* custom replacement for string.h */
388#else
389# ifndef memcpy
390# define memcpy(d,s,n) yyjson_memcpy(d,s,n)
391# endif
392# ifndef memmove
393# define memmove(d,s,n) yyjson_memmove(d,s,n)
394# endif
395# ifndef memset
396# define memset(d,v,n) yyjson_memset(d,v,n)
397# endif
398# ifndef memcmp
399# define memcmp(a,b,n) yyjson_memcmp(a,b,n)
400# endif
401# ifndef strlen
402# define strlen(s) yyjson_strlen(s)
403# endif
404yyjson_api_inline void *yyjson_memcpy(void *d, const void *s, size_t n) {
405 char *p = (char *)d; const char *q = (const char *)s;
406 while (n--) *p++ = *q++; return d;
407}
408yyjson_api_inline void *yyjson_memmove(void *d, const void *s, size_t n) {
409 char *p = (char *)d; const char *q = (const char *)s;
410 if (p == q || !n) return d;
411 if (p < q) { while (n--) *p++ = *q++; }
412 else { p += n; q += n; while (n--) *--p = *--q; }
413 return d;
414}
415yyjson_api_inline void *yyjson_memset(void *d, int v, size_t n) {
416 char *p = (char *)d, x = (char)v;
417 while (n--) *p++ = x; return d;
418}
419yyjson_api_inline int yyjson_memcmp(const void *a, const void *b, size_t n) {
420 const unsigned char *p = (const unsigned char *)a;
421 const unsigned char *q = (const unsigned char *)b;
422 while (n--) { if (*p != *q) return (int)(*p - *q); p++; q++; } return 0;
423}
424yyjson_api_inline size_t yyjson_strlen(const char *s) {
425 const char *p = s; while (*p) p++; return (size_t)(p - s);
426}
427#endif
428
429/** stdint (C89 compatible) */
430#if (defined(YYJSON_HAS_STDINT_H) && YYJSON_HAS_STDINT_H) || \
431 YYJSON_MSC_VER >= 1600 || YYJSON_STDC_VER >= 199901L || \
432 defined(_STDINT_H) || defined(_STDINT_H_) || \
433 defined(__CLANG_STDINT_H) || defined(_STDINT_H_INCLUDED) || \
434 yyjson_has_include(<stdint.h>)
435# include <stdint.h>
436#elif defined(_MSC_VER)
437# if _MSC_VER < 1300
438 typedef signed char int8_t;
439 typedef signed short int16_t;
440 typedef signed int int32_t;
441 typedef unsigned char uint8_t;
442 typedef unsigned short uint16_t;
443 typedef unsigned int uint32_t;
444 typedef signed __int64 int64_t;
445 typedef unsigned __int64 uint64_t;
446# else
447 typedef signed __int8 int8_t;
448 typedef signed __int16 int16_t;
449 typedef signed __int32 int32_t;
450 typedef unsigned __int8 uint8_t;
451 typedef unsigned __int16 uint16_t;
452 typedef unsigned __int32 uint32_t;
453 typedef signed __int64 int64_t;
454 typedef unsigned __int64 uint64_t;
455# endif
456#else
457# if UCHAR_MAX == 0xFFU
458 typedef signed char int8_t;
459 typedef unsigned char uint8_t;
460# else
461# error cannot find 8-bit integer type
462# endif
463# if USHRT_MAX == 0xFFFFU
464 typedef unsigned short uint16_t;
465 typedef signed short int16_t;
466# elif UINT_MAX == 0xFFFFU
467 typedef unsigned int uint16_t;
468 typedef signed int int16_t;
469# else
470# error cannot find 16-bit integer type
471# endif
472# if UINT_MAX == 0xFFFFFFFFUL
473 typedef unsigned int uint32_t;
474 typedef signed int int32_t;
475# elif ULONG_MAX == 0xFFFFFFFFUL
476 typedef unsigned long uint32_t;
477 typedef signed long int32_t;
478# elif USHRT_MAX == 0xFFFFFFFFUL
479 typedef unsigned short uint32_t;
480 typedef signed short int32_t;
481# else
482# error cannot find 32-bit integer type
483# endif
484# if defined(__INT64_TYPE__) && defined(__UINT64_TYPE__)
485 typedef __INT64_TYPE__ int64_t;
486 typedef __UINT64_TYPE__ uint64_t;
487# elif defined(__GNUC__) || defined(__clang__)
488# if !defined(_SYS_TYPES_H) && !defined(__int8_t_defined)
489 __extension__ typedef long long int64_t;
490# endif
491 __extension__ typedef unsigned long long uint64_t;
492# elif defined(_LONG_LONG) || defined(__MWERKS__) || defined(_CRAYC) || \
493 defined(__SUNPRO_C) || defined(__SUNPRO_CC)
494 typedef long long int64_t;
495 typedef unsigned long long uint64_t;
496# elif (defined(__BORLANDC__) && __BORLANDC__ > 0x460) || \
497 defined(__WATCOM_INT64__) || defined (__alpha) || defined (__DECC)
498 typedef __int64 int64_t;
499 typedef unsigned __int64 uint64_t;
500# else
501# error cannot find 64-bit integer type
502# endif
503#endif
504
505/** stdbool (C89 compatible) */
506#if (defined(YYJSON_HAS_STDBOOL_H) && YYJSON_HAS_STDBOOL_H) || \
507 YYJSON_MSC_VER >= 1800 || YYJSON_STDC_VER >= 199901L || \
508 (yyjson_has_include(<stdbool.h>) && !defined(__STRICT_ANSI__))
509# include <stdbool.h>
510#elif !defined(__bool_true_false_are_defined)
511# define __bool_true_false_are_defined 1
512# if defined(__cplusplus)
513# if defined(__GNUC__) && !defined(__STRICT_ANSI__)
514# define _Bool bool
515# if __cplusplus < 201103L
516# define bool bool
517# define false false
518# define true true
519# endif
520# endif
521# else
522# define bool unsigned char
523# define true 1
524# define false 0
525# endif
526#endif
527
528/** char bit check */
529#if defined(CHAR_BIT)
530# if CHAR_BIT != 8
531# error non 8-bit char is not supported
532# endif
533#endif
534
535
536
537/*==============================================================================
538 * MARK: - Compile Hint Begin
539 *============================================================================*/
540
541/* extern "C" begin */
542#ifdef __cplusplus
543extern "C" {
544#endif
545
546/* warning suppress begin */
547#if defined(__clang__)
548# pragma clang diagnostic push
549# pragma clang diagnostic ignored "-Wunused-function"
550# pragma clang diagnostic ignored "-Wunused-parameter"
551#elif YYJSON_IS_REAL_GCC
552# if yyjson_gcc_available(4, 6, 0)
553# pragma GCC diagnostic push
554# endif
555# if yyjson_gcc_available(4, 2, 0)
556# pragma GCC diagnostic ignored "-Wunused-function"
557# pragma GCC diagnostic ignored "-Wunused-parameter"
558# endif
559#elif defined(_MSC_VER)
560# pragma warning(push)
561# pragma warning(disable:4800) /* 'int': forcing value to 'true' or 'false' */
562#endif
563
564
565
566/*==============================================================================
567 * MARK: - Version
568 *============================================================================*/
569
570/** The major version of yyjson. */
571#define YYJSON_VERSION_MAJOR 0
572
573/** The minor version of yyjson. */
574#define YYJSON_VERSION_MINOR 12
575
576/** The patch version of yyjson. */
577#define YYJSON_VERSION_PATCH 0
578
579/** The version of yyjson in hex: `(major << 16) | (minor << 8) | (patch)`. */
580#define YYJSON_VERSION_HEX 0x000C00
581
582/** The version string of yyjson. */
583#define YYJSON_VERSION_STRING "0.12.0"
584
585/** The version of yyjson in hex, same as `YYJSON_VERSION_HEX`. */
586yyjson_api uint32_t yyjson_version(void);
587
588
589
590/*==============================================================================
591 * MARK: - JSON Types
592 *============================================================================*/
593
594/** Type of a JSON value (3 bit). */
595typedef uint8_t yyjson_type;
596/** No type, invalid. */
597#define YYJSON_TYPE_NONE ((uint8_t)0) /* _____000 */
598/** Raw string type, no subtype. */
599#define YYJSON_TYPE_RAW ((uint8_t)1) /* _____001 */
600/** Null type: `null` literal, no subtype. */
601#define YYJSON_TYPE_NULL ((uint8_t)2) /* _____010 */
602/** Boolean type, subtype: TRUE, FALSE. */
603#define YYJSON_TYPE_BOOL ((uint8_t)3) /* _____011 */
604/** Number type, subtype: UINT, SINT, REAL. */
605#define YYJSON_TYPE_NUM ((uint8_t)4) /* _____100 */
606/** String type, subtype: NONE, NOESC. */
607#define YYJSON_TYPE_STR ((uint8_t)5) /* _____101 */
608/** Array type, no subtype. */
609#define YYJSON_TYPE_ARR ((uint8_t)6) /* _____110 */
610/** Object type, no subtype. */
611#define YYJSON_TYPE_OBJ ((uint8_t)7) /* _____111 */
612
613/** Subtype of a JSON value (2 bit). */
614typedef uint8_t yyjson_subtype;
615/** No subtype. */
616#define YYJSON_SUBTYPE_NONE ((uint8_t)(0 << 3)) /* ___00___ */
617/** False subtype: `false` literal. */
618#define YYJSON_SUBTYPE_FALSE ((uint8_t)(0 << 3)) /* ___00___ */
619/** True subtype: `true` literal. */
620#define YYJSON_SUBTYPE_TRUE ((uint8_t)(1 << 3)) /* ___01___ */
621/** Unsigned integer subtype: `uint64_t`. */
622#define YYJSON_SUBTYPE_UINT ((uint8_t)(0 << 3)) /* ___00___ */
623/** Signed integer subtype: `int64_t`. */
624#define YYJSON_SUBTYPE_SINT ((uint8_t)(1 << 3)) /* ___01___ */
625/** Real number subtype: `double`. */
626#define YYJSON_SUBTYPE_REAL ((uint8_t)(2 << 3)) /* ___10___ */
627/** String that does not need to be escaped for writing (internal use). */
628#define YYJSON_SUBTYPE_NOESC ((uint8_t)(1 << 3)) /* ___01___ */
629
630/** The mask used to extract the type of a JSON value. */
631#define YYJSON_TYPE_MASK ((uint8_t)0x07) /* _____111 */
632/** The number of bits used by the type. */
633#define YYJSON_TYPE_BIT ((uint8_t)3)
634/** The mask used to extract the subtype of a JSON value. */
635#define YYJSON_SUBTYPE_MASK ((uint8_t)0x18) /* ___11___ */
636/** The number of bits used by the subtype. */
637#define YYJSON_SUBTYPE_BIT ((uint8_t)2)
638/** The mask used to extract the reserved bits of a JSON value. */
639#define YYJSON_RESERVED_MASK ((uint8_t)0xE0) /* 111_____ */
640/** The number of reserved bits. */
641#define YYJSON_RESERVED_BIT ((uint8_t)3)
642/** The mask used to extract the tag of a JSON value. */
643#define YYJSON_TAG_MASK ((uint8_t)0xFF) /* 11111111 */
644/** The number of bits used by the tag. */
645#define YYJSON_TAG_BIT ((uint8_t)8)
646
647/** Padding size for JSON reader. */
648#define YYJSON_PADDING_SIZE 4
649
650
651
652/*==============================================================================
653 * MARK: - Allocator
654 *============================================================================*/
655
656/**
657 A memory allocator.
658
659 Typically you don't need to use it, unless you want to customize your own
660 memory allocator.
661 */
662typedef struct yyjson_alc {
663 /** Same as libc's malloc(size), should not be NULL. */
664 void *(*malloc)(void *ctx, size_t size);
665 /** Same as libc's realloc(ptr, size), should not be NULL. */
666 void *(*realloc)(void *ctx, void *ptr, size_t old_size, size_t size);
667 /** Same as libc's free(ptr), should not be NULL. */
668 void (*free)(void *ctx, void *ptr);
669 /** A context for malloc/realloc/free, can be NULL. */
670 void *ctx;
672
673/**
674 A pool allocator uses fixed length pre-allocated memory.
675
676 This allocator may be used to avoid malloc/realloc calls. The pre-allocated
677 memory should be held by the caller. The maximum amount of memory required to
678 read a JSON can be calculated using the `yyjson_read_max_memory_usage()`
679 function, but the amount of memory required to write a JSON cannot be directly
680 calculated.
681
682 This is not a general-purpose allocator. It is designed to handle a single JSON
683 document at a time. If it is used for overly complex memory tasks, such as
684 parsing multiple JSON documents using the same allocator but releasing only a
685 few of them, it may cause memory fragmentation, resulting in performance
686 degradation and memory waste.
687
688 @param alc The allocator to be initialized.
689 If `alc` is NULL, returns false.
690 If `buf` or `size` is invalid, this will be set to an empty allocator.
691 @param buf The buffer memory for this allocator.
692 If `buf` is NULL, returns false.
693 @param size The size of `buf`, in bytes.
694 If `size` is less than 8 words (32/64 bytes on 32/64-bit OS),
695 returns false.
696 @return true if the `alc` has been successfully initialized.
697
698 @b Example
699 @code
700 // parse JSON with stack memory
701 char buf[1024];
702 yyjson_alc alc;
703 yyjson_alc_pool_init(&alc, buf, 1024);
704
705 const char *json = "{\"name\":\"Helvetica\",\"size\":16}";
706 yyjson_doc *doc = yyjson_read_opts(json, strlen(json), 0, &alc, NULL);
707 // the memory of `doc` is on the stack
708 @endcode
709
710 @warning This Allocator is not thread-safe.
711 */
712yyjson_api bool yyjson_alc_pool_init(yyjson_alc *alc, void *buf, size_t size);
713
714/**
715 A dynamic allocator.
716
717 This allocator has a similar usage to the pool allocator above. However, when
718 there is not enough memory, this allocator will dynamically request more memory
719 using libc's `malloc` function, and frees it all at once when it is destroyed.
720
721 @return A new dynamic allocator, or NULL if memory allocation failed.
722 @note The returned value should be freed with `yyjson_alc_dyn_free()`.
723
724 @warning This Allocator is not thread-safe.
725 */
727
728/**
729 Free a dynamic allocator which is created by `yyjson_alc_dyn_new()`.
730 @param alc The dynamic allocator to be destroyed.
731 */
733
734
735
736/*==============================================================================
737 * MARK: - Text Locating
738 *============================================================================*/
739
740/**
741 Locate the line and column number for a byte position in a string.
742 This can be used to get better description for error position.
743
744 @param str The input string.
745 @param len The byte length of the input string.
746 @param pos The byte position within the input string.
747 @param line A pointer to receive the line number, starting from 1.
748 @param col A pointer to receive the column number, starting from 1.
749 @param chr A pointer to receive the character index, starting from 0.
750 @return true on success, false if `str` is NULL or `pos` is out of bounds.
751 @note Line/column/character are calculated based on Unicode characters for
752 compatibility with text editors. For multi-byte UTF-8 characters,
753 the returned value may not directly correspond to the byte position.
754 */
755yyjson_api bool yyjson_locate_pos(const char *str, size_t len, size_t pos,
756 size_t *line, size_t *col, size_t *chr);
757
758
759
760/*==============================================================================
761 * MARK: - JSON Structure
762 *============================================================================*/
763
764/**
765 An immutable document for reading JSON.
766 This document holds memory for all its JSON values and strings. When it is no
767 longer used, the user should call `yyjson_doc_free()` to free its memory.
768 */
769typedef struct yyjson_doc yyjson_doc;
770
771/**
772 An immutable value for reading JSON.
773 A JSON Value has the same lifetime as its document. The memory is held by its
774 document and cannot be freed alone.
775 */
776typedef struct yyjson_val yyjson_val;
777
778/**
779 A mutable document for building JSON.
780 This document holds memory for all its JSON values and strings. When it is no
781 longer used, the user should call `yyjson_mut_doc_free()` to free its memory.
782 */
784
785/**
786 A mutable value for building JSON.
787 A JSON Value has the same lifetime as its document. The memory is held by its
788 document and cannot be freed alone.
789 */
791
792
793
794/*==============================================================================
795 * MARK: - JSON Reader API
796 *============================================================================*/
797
798/** Run-time options for JSON reader. */
799typedef uint32_t yyjson_read_flag;
800
801/** Default option (RFC 8259 compliant):
802 - Read positive integer as uint64_t.
803 - Read negative integer as int64_t.
804 - Read floating-point number as double with round-to-nearest mode.
805 - Read integer which cannot fit in uint64_t or int64_t as double.
806 - Report error if double number is infinity.
807 - Report error if string contains invalid UTF-8 character or BOM.
808 - Report error on trailing commas, comments, inf and nan literals. */
810
811/** Read the input data in-situ.
812 This option allows the reader to modify and use input data to store string
813 values, which can increase reading speed slightly.
814 The caller should hold the input data before freeing the document.
815 The input data must be padded by at least `YYJSON_PADDING_SIZE` bytes.
816 For example: `[1,2]` should be `[1,2]\0\0\0\0`, input length should be 5. */
818
819/** Stop when done instead of issuing an error if there's additional content
820 after a JSON document. This option may be used to parse small pieces of JSON
821 in larger data, such as `NDJSON`. */
823
824/** Allow single trailing comma at the end of an object or array,
825 such as `[1,2,3,]`, `{"a":1,"b":2,}` (non-standard). */
827
828/** Allow C-style single-line and multi-line comments (non-standard). */
830
831/** Allow inf/nan number and literal, case-insensitive,
832 such as 1e999, NaN, inf, -Infinity (non-standard). */
834
835/** Read all numbers as raw strings (value with `YYJSON_TYPE_RAW` type),
836 inf/nan literal is also read as raw with `ALLOW_INF_AND_NAN` flag. */
838
839/** Allow reading invalid unicode when parsing string values (non-standard).
840 Invalid characters will be allowed to appear in the string values, but
841 invalid escape sequences will still be reported as errors.
842 This flag does not affect the performance of correctly encoded strings.
843
844 @warning Strings in JSON values may contain incorrect encoding when this
845 option is used, you need to handle these strings carefully to avoid security
846 risks. */
848
849/** Read big numbers as raw strings. These big numbers include integers that
850 cannot be represented by `int64_t` and `uint64_t`, and floating-point
851 numbers that cannot be represented by finite `double`.
852 The flag will be overridden by `YYJSON_READ_NUMBER_AS_RAW` flag. */
854
855/** Allow UTF-8 BOM and skip it before parsing if any (non-standard). */
857
858/** Allow extended number formats (non-standard):
859 - Hexadecimal numbers, such as `0x7B`.
860 - Numbers with leading or trailing decimal point, such as `.123`, `123.`.
861 - Numbers with a leading plus sign, such as `+123`. */
863
864/** Allow extended escape sequences in strings (non-standard):
865 - Additional escapes: `\a`, `\e`, `\v`, ``\'``, `\?`, `\0`.
866 - Hex escapes: `\xNN`, such as `\x7B`.
867 - Line continuation: backslash followed by line terminator sequences.
868 - Unknown escape: if backslash is followed by an unsupported character,
869 the backslash will be removed and the character will be kept as-is.
870 However, `\1`-`\9` will still trigger an error. */
872
873/** Allow extended whitespace characters (non-standard):
874 - Vertical tab `\v` and form feed `\f`.
875 - Line separator `\u2028` and paragraph separator `\u2029`.
876 - Non-breaking space `\xA0`.
877 - Byte order mark: `\uFEFF`.
878 - Other Unicode characters in the Zs (Separator, space) category. */
880
881/** Allow strings enclosed in single quotes (non-standard), such as ``'ab'``. */
883
884/** Allow object keys without quotes (non-standard), such as `{a:1,b:2}`.
885 This extends the ECMAScript IdentifierName rule by allowing any
886 non-whitespace character with code point above `U+007F`. */
888
889/** Allow JSON5 format, see: [https://json5.org].
890 This flag supports all JSON5 features with some additional extensions:
891 - Accepts more escape sequences than JSON5 (e.g. `\a`, `\e`).
892 - Unquoted keys are not limited to ECMAScript IdentifierName.
893 - Allow case-insensitive `NaN`, `Inf` and `Infinity` literals. */
895 (1 << 2) | /* YYJSON_READ_ALLOW_TRAILING_COMMAS */
896 (1 << 3) | /* YYJSON_READ_ALLOW_COMMENTS */
897 (1 << 4) | /* YYJSON_READ_ALLOW_INF_AND_NAN */
898 (1 << 9) | /* YYJSON_READ_ALLOW_EXT_NUMBER */
899 (1 << 10) | /* YYJSON_READ_ALLOW_EXT_ESCAPE */
900 (1 << 11) | /* YYJSON_READ_ALLOW_EXT_WHITESPACE */
901 (1 << 12) | /* YYJSON_READ_ALLOW_SINGLE_QUOTED_STR */
902 (1 << 13); /* YYJSON_READ_ALLOW_UNQUOTED_KEY */
903
904
905
906/** Result code for JSON reader. */
907typedef uint32_t yyjson_read_code;
908
909/** Success, no error. */
911
912/** Invalid parameter, such as NULL input string or 0 input length. */
914
915/** Memory allocation failed. */
917
918/** Input JSON string is empty. */
920
921/** Unexpected content after document, such as `[123]abc`. */
923
924/** Unexpected end of input, the parsed part is valid, such as `[123`. */
926
927/** Unexpected character inside the document, such as `[abc]`. */
929
930/** Invalid JSON structure, such as `[1,]`. */
932
933/** Invalid comment, deprecated, use `UNEXPECTED_END` for unclosed comment. */
935
936/** Invalid number, such as `123.e12`, `000`. */
938
939/** Invalid string, such as invalid escaped character inside a string. */
941
942/** Invalid JSON literal, such as `truu`. */
944
945/** Failed to open a file. */
947
948/** Failed to read a file. */
950
951/** Incomplete input during incremental parsing; parsing state is preserved. */
953
954/** Read depth limit exceeded. */
956
957/** Error information for JSON reader. */
958typedef struct yyjson_read_err {
959 /** Error code, see `yyjson_read_code` for all possible values. */
961 /** Error message, constant, no need to free (NULL if success). */
962 const char *msg;
963 /** Error byte position for input data (0 if success). */
964 size_t pos;
966
967
968
969#if !defined(YYJSON_DISABLE_READER) || !YYJSON_DISABLE_READER
970
971/**
972 Read JSON with options.
973
974 This function is thread-safe when:
975 1. The `dat` is not modified by other threads.
976 2. The `alc` is thread-safe or NULL.
977
978 @param dat The JSON data (UTF-8 without BOM), null-terminator is not required.
979 If `dat` is NULL, returns NULL.
980 The `dat` will not be modified without the flag `YYJSON_READ_INSITU`, so you
981 can pass a `const char *` string and cast it to `char *` if you don't use
982 the `YYJSON_READ_INSITU` flag.
983 @param len The length of JSON data in bytes.
984 If `len` is 0, returns NULL.
985 @param flg The JSON read options.
986 Multiple options can be combined with `|` operator. 0 means no options.
987 @param alc The memory allocator used by JSON reader.
988 Pass NULL to use the libc's default allocator.
989 @param err A pointer to receive error information.
990 Pass NULL if you don't need error information.
991 @return A new JSON document, or NULL if an error occurs.
992 When it's no longer needed, it should be freed with `yyjson_doc_free()`.
993 */
995 size_t len,
997 const yyjson_alc *alc,
998 yyjson_read_err *err);
999
1000#if !YYJSON_FREESTANDING && !YYJSON_DISABLE_FILE
1001
1002/**
1003 Read a JSON file.
1004
1005 This function is thread-safe when:
1006 1. The file is not modified by other threads.
1007 2. The `alc` is thread-safe or NULL.
1008
1009 @param path The JSON file's path.
1010 This should be a null-terminated string using the system's native encoding.
1011 If `path` is NULL or invalid, returns NULL.
1012 @param flg The JSON read options.
1013 Multiple options can be combined with `|` operator. 0 means no options.
1014 @param alc The memory allocator used by JSON reader.
1015 Pass NULL to use the libc's default allocator.
1016 @param err A pointer to receive error information.
1017 Pass NULL if you don't need error information.
1018 @return A new JSON document, or NULL if an error occurs.
1019 When it's no longer needed, it should be freed with `yyjson_doc_free()`.
1020
1021 @warning On 32-bit operating system, files larger than 2GB may fail to read.
1022 */
1023yyjson_api yyjson_doc *yyjson_read_file(const char *path,
1024 yyjson_read_flag flg,
1025 const yyjson_alc *alc,
1026 yyjson_read_err *err);
1027
1028/**
1029 Read JSON from a file pointer.
1030
1031 @param fp The file pointer.
1032 The data will be read from the current position of the FILE to the end.
1033 If `fp` is NULL or invalid, returns NULL.
1034 @param flg The JSON read options.
1035 Multiple options can be combined with `|` operator. 0 means no options.
1036 @param alc The memory allocator used by JSON reader.
1037 Pass NULL to use the libc's default allocator.
1038 @param err A pointer to receive error information.
1039 Pass NULL if you don't need error information.
1040 @return A new JSON document, or NULL if an error occurs.
1041 When it's no longer needed, it should be freed with `yyjson_doc_free()`.
1042
1043 @warning On 32-bit operating system, files larger than 2GB may fail to read.
1044 */
1046 yyjson_read_flag flg,
1047 const yyjson_alc *alc,
1048 yyjson_read_err *err);
1049
1050#endif /* !YYJSON_FREESTANDING && !YYJSON_DISABLE_FILE */
1051
1052/**
1053 Read a JSON string.
1054
1055 This function is thread-safe.
1056
1057 @param dat The JSON data (UTF-8 without BOM), null-terminator is not required.
1058 If `dat` is NULL, returns NULL.
1059 @param len The length of JSON data in bytes.
1060 If `len` is 0, returns NULL.
1061 @param flg The JSON read options.
1062 Multiple options can be combined with `|` operator. 0 means no options.
1063 @return A new JSON document, or NULL if an error occurs.
1064 When it's no longer needed, it should be freed with `yyjson_doc_free()`.
1065 */
1067 size_t len,
1068 yyjson_read_flag flg) {
1069 flg &= ~YYJSON_READ_INSITU; /* const string cannot be modified */
1070 return yyjson_read_opts((char *)(void *)(size_t)(const void *)dat,
1071 len, flg, NULL, NULL);
1072}
1073
1074
1075
1076#if !defined(YYJSON_DISABLE_INCR_READER) || !YYJSON_DISABLE_INCR_READER
1077
1078/** Opaque state for incremental JSON reader. */
1080
1081/**
1082 Initialize state for incremental read.
1083
1084 To read a large JSON document incrementally:
1085 1. Call `yyjson_incr_new()` to create the state for incremental reading.
1086 2. Call `yyjson_incr_read()` repeatedly.
1087 3. Call `yyjson_incr_free()` to free the state.
1088
1089 Note: The incremental JSON reader only supports standard JSON.
1090 Flags for non-standard features (e.g. comments, trailing commas) are ignored.
1091
1092 @param buf The JSON data, null-terminator is not required.
1093 If `buf` is NULL, returns NULL.
1094 @param buf_len The length of the JSON data in `buf`.
1095 If using `YYJSON_READ_INSITU`, buf_len should not include the padding size.
1096 @param flg The JSON read options.
1097 Multiple options can be combined with `|` operator.
1098 @param alc The memory allocator used by JSON reader.
1099 Pass NULL to use the libc's default allocator.
1100 @return A state for incremental reading.
1101 It should be freed with `yyjson_incr_free()`.
1102 NULL is returned if memory allocation fails.
1103*/
1106 const yyjson_alc *alc);
1107
1108/**
1109 Performs incremental read of up to `len` bytes.
1110
1111 If NULL is returned and `err->code` is set to `YYJSON_READ_ERROR_MORE`, it
1112 indicates that more data is required to continue parsing. Then, call this
1113 function again with incremented `len`. Continue until a document is returned or
1114 an error other than `YYJSON_READ_ERROR_MORE` is returned.
1115
1116 Note: Parsing in very small increments is not efficient. An increment of
1117 several kilobytes or megabytes is recommended.
1118
1119 @param state The state for incremental reading, created using
1120 `yyjson_incr_new()`.
1121 @param len The number of bytes of JSON data available to parse.
1122 If `len` is 0, returns NULL.
1123 @param err A pointer to receive error information.
1124 @return A new JSON document, or NULL if an error occurs.
1125 When the document is no longer needed, it should be freed with
1126 `yyjson_doc_free()`.
1127*/
1129 yyjson_read_err *err);
1130
1131/** Release the incremental read state and free the memory. */
1133
1134#endif /* YYJSON_DISABLE_INCR_READER */
1135
1136/**
1137 Returns the maximum memory usage to read a JSON document.
1138
1139 You may use this value to avoid malloc() or calloc() call inside the reader
1140 to get better performance, or read multiple JSON with one piece of memory.
1141
1142 @param len The length of JSON data in bytes.
1143 @param flg The JSON read options.
1144 @return The maximum memory size to read this JSON, or 0 if overflow.
1145
1146 @b Example
1147 @code
1148 // read multiple JSON with same pre-allocated memory
1149
1150 char *dat1, *dat2, *dat3; // JSON data
1151 size_t len1, len2, len3; // JSON length
1152 size_t max_len = MAX(len1, MAX(len2, len3));
1153 yyjson_doc *doc;
1154
1155 // use one allocator for multiple JSON
1156 size_t size = yyjson_read_max_memory_usage(max_len, 0);
1157 void *buf = malloc(size);
1158 yyjson_alc alc;
1159 yyjson_alc_pool_init(&alc, buf, size);
1160
1161 // no more malloc() or realloc() call during reading
1162 doc = yyjson_read_opts(dat1, len1, 0, &alc, NULL);
1163 yyjson_doc_free(doc);
1164 doc = yyjson_read_opts(dat2, len2, 0, &alc, NULL);
1165 yyjson_doc_free(doc);
1166 doc = yyjson_read_opts(dat3, len3, 0, &alc, NULL);
1167 yyjson_doc_free(doc);
1168
1169 free(buf);
1170 @endcode
1171 @see yyjson_alc_pool_init()
1172 */
1175 /*
1176 1. The max value count is (json_size / 2 + 1),
1177 for example: "[1,2,3,4]" size is 9, value count is 5.
1178 2. Some broken JSON may cost more memory during reading, but fail at end,
1179 for example: "[[[[[[[[".
1180 3. yyjson uses 16 bytes per value, see struct yyjson_val.
1181 4. yyjson use dynamic memory with a growth factor of 1.5.
1182
1183 The max memory size is (json_size / 2 * 16 * 1.5 + padding).
1184 */
1185 size_t mul = (size_t)12 + !(flg & YYJSON_READ_INSITU);
1186 size_t pad = 256;
1187 size_t max = (size_t)(~(size_t)0);
1188 if (flg & YYJSON_READ_STOP_WHEN_DONE) len = len < 256 ? 256 : len;
1189 if (len >= (max - pad - mul) / mul) return 0;
1190 return len * mul + pad;
1191}
1192
1193/**
1194 Read a JSON number.
1195
1196 This function is thread-safe when data is not modified by other threads.
1197
1198 @param dat The JSON data (UTF-8 without BOM), null-terminator is required.
1199 If `dat` is NULL, returns NULL.
1200 @param val The output value where result is stored.
1201 If `val` is NULL, returns NULL.
1202 The value will hold either UINT or SINT or REAL number;
1203 @param flg The JSON read options.
1204 Multiple options can be combined with `|` operator. 0 means no options.
1205 Supports `YYJSON_READ_NUMBER_AS_RAW` and `YYJSON_READ_ALLOW_INF_AND_NAN`.
1206 @param alc The memory allocator used for long number.
1207 It is only used when the built-in floating point reader is disabled.
1208 Pass NULL to use the libc's default allocator.
1209 @param err A pointer to receive error information.
1210 Pass NULL if you don't need error information.
1211 @return If successful, a pointer to the character after the last character
1212 used in the conversion, NULL if an error occurs.
1213 */
1214yyjson_api const char *yyjson_read_number(const char *dat,
1215 yyjson_val *val,
1217 const yyjson_alc *alc,
1218 yyjson_read_err *err);
1219
1220/** Same as `yyjson_read_number()`. */
1221yyjson_api_inline const char *yyjson_mut_read_number(const char *dat,
1224 const yyjson_alc *alc,
1225 yyjson_read_err *err) {
1226 return yyjson_read_number(dat, (yyjson_val *)val, flg, alc, err);
1227}
1228
1229#endif /* YYJSON_DISABLE_READER) */
1230
1231
1232
1233/*==============================================================================
1234 * MARK: - JSON Writer API
1235 *============================================================================*/
1236
1237/** Run-time options for JSON writer. */
1238typedef uint32_t yyjson_write_flag;
1239
1240/** Default option:
1241 - Write JSON minify.
1242 - Report error on inf or nan number.
1243 - Report error on invalid UTF-8 string.
1244 - Do not escape unicode or slash. */
1246
1247/** Write JSON pretty with 4 space indent. */
1249
1250/** Escape unicode as `uXXXX`, make the output ASCII only. */
1252
1253/** Escape '/' as '\/'. */
1255
1256/** Write inf and nan number as 'Infinity' and 'NaN' literal (non-standard). */
1258
1259/** Write inf and nan number as null literal.
1260 This flag will override `YYJSON_WRITE_ALLOW_INF_AND_NAN` flag. */
1262
1263/** Allow invalid unicode when encoding string values (non-standard).
1264 Invalid characters in string value will be copied byte by byte.
1265 If `YYJSON_WRITE_ESCAPE_UNICODE` flag is also set, invalid character will be
1266 escaped as `U+FFFD` (replacement character).
1267 This flag does not affect the performance of correctly encoded strings. */
1269
1270/** Write JSON pretty with 2 space indent.
1271 This flag will override `YYJSON_WRITE_PRETTY` flag. */
1273
1274/** Adds a newline character `\n` at the end of the JSON.
1275 This can be helpful for text editors or NDJSON. */
1277
1278/** Use lowercase hex digits in `\uXXXX` escape sequences instead of the default
1279 uppercase. Only effective when `YYJSON_WRITE_ESCAPE_UNICODE` is also set. */
1281
1282
1283
1284/** The highest 8 bits of `yyjson_write_flag` and real number value's `tag`
1285 are reserved for controlling the output format of floating-point numbers. */
1286#define YYJSON_WRITE_FP_FLAG_BITS 8
1287
1288/** The highest 4 bits of flag are reserved for precision value. */
1289#define YYJSON_WRITE_FP_PREC_BITS 4
1290
1291/** Write floating-point number using fixed-point notation.
1292 - This is similar to ECMAScript `Number.prototype.toFixed(prec)`,
1293 but with trailing zeros removed. The `prec` ranges from 1 to 15.
1294 - This will produce shorter output but may lose some precision. */
1295#define YYJSON_WRITE_FP_TO_FIXED(prec) ((yyjson_write_flag)( \
1296 (uint32_t)((uint32_t)(prec)) << (32 - 4) ))
1297
1298/** Write floating-point numbers using single-precision (float).
1299 - This casts `double` to `float` before serialization.
1300 - This will produce shorter output, but may lose some precision.
1301 - This flag is ignored if `YYJSON_WRITE_FP_TO_FIXED(prec)` is also used. */
1302#define YYJSON_WRITE_FP_TO_FLOAT ((yyjson_write_flag)(1 << (32 - 5)))
1303
1304
1305
1306/** Result code for JSON writer */
1307typedef uint32_t yyjson_write_code;
1308
1309/** Success, no error. */
1311
1312/** Invalid parameter, such as NULL document. */
1314
1315/** Memory allocation failed. */
1317
1318/** Invalid value type in JSON document. */
1320
1321/** NaN or Infinity number occurs. */
1323
1324/** Failed to open a file. */
1326
1327/** Failed to write a file. */
1329
1330/** Invalid unicode in string. */
1332
1333/** Error information for JSON writer. */
1334typedef struct yyjson_write_err {
1335 /** Error code, see `yyjson_write_code` for all possible values. */
1337 /** Error message, constant, no need to free (NULL if success). */
1338 const char *msg;
1340
1341
1342
1343#if !defined(YYJSON_DISABLE_WRITER) || !YYJSON_DISABLE_WRITER
1344
1345/*==============================================================================
1346 * MARK: - JSON Document Writer API
1347 *============================================================================*/
1348
1349/**
1350 Write a document to JSON string with options.
1351
1352 This function is thread-safe when:
1353 The `alc` is thread-safe or NULL.
1354
1355 @param doc The JSON document.
1356 If `doc` is NULL or has no root, returns NULL.
1357 @param flg The JSON write options.
1358 Multiple options can be combined with `|` operator. 0 means no options.
1359 @param alc The memory allocator used by JSON writer.
1360 Pass NULL to use the libc's default allocator.
1361 @param len A pointer to receive output length in bytes (not including the
1362 null-terminator). Pass NULL if you don't need length information.
1363 @param err A pointer to receive error information.
1364 Pass NULL if you don't need error information.
1365 @return A new JSON string, or NULL if an error occurs.
1366 This string is encoded as UTF-8 with a null-terminator.
1367 When it's no longer needed, it should be freed with free() or alc->free().
1368 */
1369yyjson_api char *yyjson_write_opts(const yyjson_doc *doc,
1371 const yyjson_alc *alc,
1372 size_t *len,
1373 yyjson_write_err *err);
1374
1375#if !YYJSON_FREESTANDING && !YYJSON_DISABLE_FILE
1376
1377/**
1378 Write a document to JSON file with options.
1379
1380 This function is thread-safe when:
1381 1. The file is not accessed by other threads.
1382 2. The `alc` is thread-safe or NULL.
1383
1384 @param path The JSON file's path.
1385 This should be a null-terminated string using the system's native encoding.
1386 If `path` is NULL or invalid, returns false.
1387 If the file is not empty, its content is discarded.
1388 @param doc The JSON document.
1389 If `doc` is NULL or has no root, returns false.
1390 @param flg The JSON write options.
1391 Multiple options can be combined with `|` operator. 0 means no options.
1392 @param alc The memory allocator used by JSON writer.
1393 Pass NULL to use the libc's default allocator.
1394 @param err A pointer to receive error information.
1395 Pass NULL if you don't need error information.
1396 @return true if successful, false if an error occurs.
1397
1398 @warning On 32-bit operating system, files larger than 2GB may fail to write.
1399 */
1400yyjson_api bool yyjson_write_file(const char *path,
1401 const yyjson_doc *doc,
1403 const yyjson_alc *alc,
1404 yyjson_write_err *err);
1405
1406/**
1407 Write a document to file pointer with options.
1408
1409 @param fp The file pointer.
1410 The data will be written to the current position of the file.
1411 If `fp` is NULL or invalid, returns false.
1412 @param doc The JSON document.
1413 If `doc` is NULL or has no root, returns false.
1414 @param flg The JSON write options.
1415 Multiple options can be combined with `|` operator. 0 means no options.
1416 @param alc The memory allocator used by JSON writer.
1417 Pass NULL to use the libc's default allocator.
1418 @param err A pointer to receive error information.
1419 Pass NULL if you don't need error information.
1420 @return true if successful, false if an error occurs.
1421
1422 @warning On 32-bit operating system, files larger than 2GB may fail to write.
1423 */
1424yyjson_api bool yyjson_write_fp(FILE *fp,
1425 const yyjson_doc *doc,
1427 const yyjson_alc *alc,
1428 yyjson_write_err *err);
1429
1430#endif /* !YYJSON_FREESTANDING && !YYJSON_DISABLE_FILE */
1431
1432/**
1433 Write a document into a buffer.
1434
1435 This function does not allocate memory, but the buffer must be larger than the
1436 final JSON size to allow temporary space. See `API.md` for details.
1437
1438 @param buf The output buffer.
1439 If `buf` is NULL, returns 0.
1440 @param buf_len The buffer length.
1441 If `buf_len` is too small, returns 0.
1442 @param doc The JSON document.
1443 If `doc` is NULL or has no root, returns 0.
1444 @param flg The JSON write options.
1445 Multiple options can be combined with `|` operator. 0 means no options.
1446 @param err A pointer to receive error information.
1447 Pass NULL if you don't need error information.
1448 @return The number of bytes written (excluding the null terminator),
1449 or 0 on failure.
1450 */
1451yyjson_api size_t yyjson_write_buf(char *buf, size_t buf_len,
1452 const yyjson_doc *doc,
1454 yyjson_write_err *err);
1455
1456/**
1457 Write a document to JSON string.
1458
1459 This function is thread-safe.
1460
1461 @param doc The JSON document.
1462 If `doc` is NULL or has no root, returns NULL.
1463 @param flg The JSON write options.
1464 Multiple options can be combined with `|` operator. 0 means no options.
1465 @param len A pointer to receive output length in bytes (not including the
1466 null-terminator). Pass NULL if you don't need length information.
1467 @return A new JSON string, or NULL if an error occurs.
1468 This string is encoded as UTF-8 with a null-terminator.
1469 When it's no longer needed, it should be freed with free().
1470 */
1473 size_t *len) {
1474 return yyjson_write_opts(doc, flg, NULL, len, NULL);
1475}
1476
1477
1478
1479/**
1480 Write a document to JSON string with options.
1481
1482 This function is thread-safe when:
1483 1. The `doc` is not modified by other threads.
1484 2. The `alc` is thread-safe or NULL.
1485
1486 @param doc The mutable JSON document.
1487 If `doc` is NULL or has no root, returns NULL.
1488 @param flg The JSON write options.
1489 Multiple options can be combined with `|` operator. 0 means no options.
1490 @param alc The memory allocator used by JSON writer.
1491 Pass NULL to use the libc's default allocator.
1492 @param len A pointer to receive output length in bytes (not including the
1493 null-terminator). Pass NULL if you don't need length information.
1494 @param err A pointer to receive error information.
1495 Pass NULL if you don't need error information.
1496 @return A new JSON string, or NULL if an error occurs.
1497 This string is encoded as UTF-8 with a null-terminator.
1498 When it's no longer needed, it should be freed with free() or alc->free().
1499 */
1502 const yyjson_alc *alc,
1503 size_t *len,
1504 yyjson_write_err *err);
1505
1506#if !YYJSON_FREESTANDING && !YYJSON_DISABLE_FILE
1507
1508/**
1509 Write a document to JSON file with options.
1510
1511 This function is thread-safe when:
1512 1. The file is not accessed by other threads.
1513 2. The `doc` is not modified by other threads.
1514 3. The `alc` is thread-safe or NULL.
1515
1516 @param path The JSON file's path.
1517 This should be a null-terminated string using the system's native encoding.
1518 If `path` is NULL or invalid, returns false.
1519 If the file is not empty, its content is discarded.
1520 @param doc The mutable JSON document.
1521 If `doc` is NULL or has no root, returns false.
1522 @param flg The JSON write options.
1523 Multiple options can be combined with `|` operator. 0 means no options.
1524 @param alc The memory allocator used by JSON writer.
1525 Pass NULL to use the libc's default allocator.
1526 @param err A pointer to receive error information.
1527 Pass NULL if you don't need error information.
1528 @return true if successful, false if an error occurs.
1529
1530 @warning On 32-bit operating system, files larger than 2GB may fail to write.
1531 */
1532yyjson_api bool yyjson_mut_write_file(const char *path,
1533 const yyjson_mut_doc *doc,
1535 const yyjson_alc *alc,
1536 yyjson_write_err *err);
1537
1538/**
1539 Write a document to file pointer with options.
1540
1541 @param fp The file pointer.
1542 The data will be written to the current position of the file.
1543 If `fp` is NULL or invalid, returns false.
1544 @param doc The mutable JSON document.
1545 If `doc` is NULL or has no root, returns false.
1546 @param flg The JSON write options.
1547 Multiple options can be combined with `|` operator. 0 means no options.
1548 @param alc The memory allocator used by JSON writer.
1549 Pass NULL to use the libc's default allocator.
1550 @param err A pointer to receive error information.
1551 Pass NULL if you don't need error information.
1552 @return true if successful, false if an error occurs.
1553
1554 @warning On 32-bit operating system, files larger than 2GB may fail to write.
1555 */
1556yyjson_api bool yyjson_mut_write_fp(FILE *fp,
1557 const yyjson_mut_doc *doc,
1559 const yyjson_alc *alc,
1560 yyjson_write_err *err);
1561
1562#endif /* !YYJSON_FREESTANDING && !YYJSON_DISABLE_FILE */
1563
1564/**
1565 Write a document into a buffer.
1566
1567 This function does not allocate memory, but the buffer must be larger than the
1568 final JSON size to allow temporary space. See `API.md` for details.
1569
1570 @param buf The output buffer.
1571 If `buf` is NULL, returns 0.
1572 @param buf_len The buffer length.
1573 If `buf_len` is too small, returns 0.
1574 @param doc The JSON document.
1575 If `doc` is NULL or has no root, returns 0.
1576 @param flg The JSON write options.
1577 Multiple options can be combined with `|` operator. 0 means no options.
1578 @param err A pointer to receive error information.
1579 Pass NULL if you don't need error information.
1580 @return The number of bytes written (excluding the null terminator),
1581 or 0 on failure.
1582 */
1583yyjson_api size_t yyjson_mut_write_buf(char *buf, size_t buf_len,
1584 const yyjson_mut_doc *doc,
1586 yyjson_write_err *err);
1587
1588/**
1589 Write a document to JSON string.
1590
1591 This function is thread-safe when:
1592 The `doc` is not modified by other threads.
1593
1594 @param doc The JSON document.
1595 If `doc` is NULL or has no root, returns NULL.
1596 @param flg The JSON write options.
1597 Multiple options can be combined with `|` operator. 0 means no options.
1598 @param len A pointer to receive output length in bytes (not including the
1599 null-terminator). Pass NULL if you don't need length information.
1600 @return A new JSON string, or NULL if an error occurs.
1601 This string is encoded as UTF-8 with a null-terminator.
1602 When it's no longer needed, it should be freed with free().
1603 */
1606 size_t *len) {
1607 return yyjson_mut_write_opts(doc, flg, NULL, len, NULL);
1608}
1609
1610
1611
1612/*==============================================================================
1613 * MARK: - JSON Value Writer API
1614 *============================================================================*/
1615
1616/**
1617 Write a value to JSON string with options.
1618
1619 This function is thread-safe when:
1620 The `alc` is thread-safe or NULL.
1621
1622 @param val The JSON root value.
1623 If `val` is NULL, returns NULL.
1624 @param flg The JSON write options.
1625 Multiple options can be combined with `|` operator. 0 means no options.
1626 @param alc The memory allocator used by JSON writer.
1627 Pass NULL to use the libc's default allocator.
1628 @param len A pointer to receive output length in bytes (not including the
1629 null-terminator). Pass NULL if you don't need length information.
1630 @param err A pointer to receive error information.
1631 Pass NULL if you don't need error information.
1632 @return A new JSON string, or NULL if an error occurs.
1633 This string is encoded as UTF-8 with a null-terminator.
1634 When it's no longer needed, it should be freed with free() or alc->free().
1635 */
1638 const yyjson_alc *alc,
1639 size_t *len,
1640 yyjson_write_err *err);
1641
1642#if !YYJSON_FREESTANDING && !YYJSON_DISABLE_FILE
1643
1644/**
1645 Write a value to JSON file with options.
1646
1647 This function is thread-safe when:
1648 1. The file is not accessed by other threads.
1649 2. The `alc` is thread-safe or NULL.
1650
1651 @param path The JSON file's path.
1652 This should be a null-terminated string using the system's native encoding.
1653 If `path` is NULL or invalid, returns false.
1654 If the file is not empty, its content is discarded.
1655 @param val The JSON root value.
1656 If `val` is NULL, returns false.
1657 @param flg The JSON write options.
1658 Multiple options can be combined with `|` operator. 0 means no options.
1659 @param alc The memory allocator used by JSON writer.
1660 Pass NULL to use the libc's default allocator.
1661 @param err A pointer to receive error information.
1662 Pass NULL if you don't need error information.
1663 @return true if successful, false if an error occurs.
1664
1665 @warning On 32-bit operating system, files larger than 2GB may fail to write.
1666 */
1667yyjson_api bool yyjson_val_write_file(const char *path,
1668 const yyjson_val *val,
1670 const yyjson_alc *alc,
1671 yyjson_write_err *err);
1672
1673/**
1674 Write a value to file pointer with options.
1675
1676 @param fp The file pointer.
1677 The data will be written to the current position of the file.
1678 If `fp` is NULL or invalid, returns false.
1679 @param val The JSON root value.
1680 If `val` is NULL, returns false.
1681 @param flg The JSON write options.
1682 Multiple options can be combined with `|` operator. 0 means no options.
1683 @param alc The memory allocator used by JSON writer.
1684 Pass NULL to use the libc's default allocator.
1685 @param err A pointer to receive error information.
1686 Pass NULL if you don't need error information.
1687 @return true if successful, false if an error occurs.
1688
1689 @warning On 32-bit operating system, files larger than 2GB may fail to write.
1690 */
1691yyjson_api bool yyjson_val_write_fp(FILE *fp,
1692 const yyjson_val *val,
1694 const yyjson_alc *alc,
1695 yyjson_write_err *err);
1696
1697#endif /* !YYJSON_FREESTANDING && !YYJSON_DISABLE_FILE */
1698
1699/**
1700 Write a value into a buffer.
1701
1702 This function does not allocate memory, but the buffer must be larger than the
1703 final JSON size to allow temporary space. See `API.md` for details.
1704
1705 @param buf The output buffer.
1706 If `buf` is NULL, returns 0.
1707 @param buf_len The buffer length.
1708 If `buf_len` is too small, returns 0.
1709 @param val The JSON root value.
1710 If `val` is NULL, returns 0.
1711 @param flg The JSON write options.
1712 Multiple options can be combined with `|` operator. 0 means no options.
1713 @param err A pointer to receive error information.
1714 Pass NULL if you don't need error information.
1715 @return The number of bytes written (excluding the null terminator),
1716 or 0 on failure.
1717 */
1718yyjson_api size_t yyjson_val_write_buf(char *buf, size_t buf_len,
1719 const yyjson_val *val,
1721 yyjson_write_err *err);
1722
1723/**
1724 Write a value to JSON string.
1725
1726 This function is thread-safe.
1727
1728 @param val The JSON root value.
1729 If `val` is NULL, returns NULL.
1730 @param flg The JSON write options.
1731 Multiple options can be combined with `|` operator. 0 means no options.
1732 @param len A pointer to receive output length in bytes (not including the
1733 null-terminator). Pass NULL if you don't need length information.
1734 @return A new JSON string, or NULL if an error occurs.
1735 This string is encoded as UTF-8 with a null-terminator.
1736 When it's no longer needed, it should be freed with free().
1737 */
1740 size_t *len) {
1741 return yyjson_val_write_opts(val, flg, NULL, len, NULL);
1742}
1743
1744/**
1745 Write a value to JSON string with options.
1746
1747 This function is thread-safe when:
1748 1. The `val` is not modified by other threads.
1749 2. The `alc` is thread-safe or NULL.
1750
1751 @param val The mutable JSON root value.
1752 If `val` is NULL, returns NULL.
1753 @param flg The JSON write options.
1754 Multiple options can be combined with `|` operator. 0 means no options.
1755 @param alc The memory allocator used by JSON writer.
1756 Pass NULL to use the libc's default allocator.
1757 @param len A pointer to receive output length in bytes (not including the
1758 null-terminator). Pass NULL if you don't need length information.
1759 @param err A pointer to receive error information.
1760 Pass NULL if you don't need error information.
1761 @return A new JSON string, or NULL if an error occurs.
1762 This string is encoded as UTF-8 with a null-terminator.
1763 When it's no longer needed, it should be freed with free() or alc->free().
1764 */
1767 const yyjson_alc *alc,
1768 size_t *len,
1769 yyjson_write_err *err);
1770
1771#if !YYJSON_FREESTANDING && !YYJSON_DISABLE_FILE
1772
1773/**
1774 Write a value to JSON file with options.
1775
1776 This function is thread-safe when:
1777 1. The file is not accessed by other threads.
1778 2. The `val` is not modified by other threads.
1779 3. The `alc` is thread-safe or NULL.
1780
1781 @param path The JSON file's path.
1782 This should be a null-terminated string using the system's native encoding.
1783 If `path` is NULL or invalid, returns false.
1784 If the file is not empty, its content is discarded.
1785 @param val The mutable JSON root value.
1786 If `val` is NULL, returns false.
1787 @param flg The JSON write options.
1788 Multiple options can be combined with `|` operator. 0 means no options.
1789 @param alc The memory allocator used by JSON writer.
1790 Pass NULL to use the libc's default allocator.
1791 @param err A pointer to receive error information.
1792 Pass NULL if you don't need error information.
1793 @return true if successful, false if an error occurs.
1794
1795 @warning On 32-bit operating system, files larger than 2GB may fail to write.
1796 */
1797yyjson_api bool yyjson_mut_val_write_file(const char *path,
1798 const yyjson_mut_val *val,
1800 const yyjson_alc *alc,
1801 yyjson_write_err *err);
1802
1803/**
1804 Write a value to file pointer with options.
1805
1806 @param fp The file pointer.
1807 The data will be written to the current position of the file.
1808 If `fp` is NULL or invalid, returns false.
1809 @param val The mutable JSON root value.
1810 If `val` is NULL, returns false.
1811 @param flg The JSON write options.
1812 Multiple options can be combined with `|` operator. 0 means no options.
1813 @param alc The memory allocator used by JSON writer.
1814 Pass NULL to use the libc's default allocator.
1815 @param err A pointer to receive error information.
1816 Pass NULL if you don't need error information.
1817 @return true if successful, false if an error occurs.
1818
1819 @warning On 32-bit operating system, files larger than 2GB may fail to write.
1820 */
1822 const yyjson_mut_val *val,
1824 const yyjson_alc *alc,
1825 yyjson_write_err *err);
1826
1827#endif /* !YYJSON_FREESTANDING && !YYJSON_DISABLE_FILE */
1828
1829/**
1830 Write a value into a buffer.
1831
1832 This function does not allocate memory, but the buffer must be larger than the
1833 final JSON size to allow temporary space. See `API.md` for details.
1834
1835 @param buf The output buffer.
1836 If `buf` is NULL, returns 0.
1837 @param buf_len The buffer length.
1838 If `buf_len` is too small, returns 0.
1839 @param val The JSON root value.
1840 If `val` is NULL, returns 0.
1841 @param flg The JSON write options.
1842 Multiple options can be combined with `|` operator. 0 means no options.
1843 @param err A pointer to receive error information.
1844 Pass NULL if you don't need error information.
1845 @return The number of bytes written (excluding the null terminator),
1846 or 0 on failure.
1847 */
1848yyjson_api size_t yyjson_mut_val_write_buf(char *buf, size_t buf_len,
1849 const yyjson_mut_val *val,
1851 yyjson_write_err *err);
1852
1853/**
1854 Write a value to JSON string.
1855
1856 This function is thread-safe when:
1857 The `val` is not modified by other threads.
1858
1859 @param val The JSON root value.
1860 If `val` is NULL, returns NULL.
1861 @param flg The JSON write options.
1862 Multiple options can be combined with `|` operator. 0 means no options.
1863 @param len A pointer to receive output length in bytes (not including the
1864 null-terminator). Pass NULL if you don't need length information.
1865 @return A new JSON string, or NULL if an error occurs.
1866 This string is encoded as UTF-8 with a null-terminator.
1867 When it's no longer needed, it should be freed with free().
1868 */
1871 size_t *len) {
1872 return yyjson_mut_val_write_opts(val, flg, NULL, len, NULL);
1873}
1874
1875/**
1876 Write a JSON number.
1877
1878 @param val A JSON number value to be converted to a string.
1879 If `val` is invalid, returns NULL.
1880 @param buf A buffer to store the resulting null-terminated string.
1881 If `buf` is NULL, returns NULL.
1882 For integer values, the buffer must be at least 21 bytes.
1883 For floating-point values, the buffer must be at least 40 bytes.
1884 @return On success, returns a pointer to the character after the last
1885 written character. On failure, returns NULL.
1886 @note
1887 - This function is thread-safe and does not allocate memory
1888 (when `YYJSON_DISABLE_FAST_FP_CONV` is not defined).
1889 - This function will fail and return NULL only in the following cases:
1890 1) `val` or `buf` is NULL;
1891 2) `val` is not a number type;
1892 3) `val` is `inf` or `nan`, and non-standard JSON is explicitly disabled
1893 via the `YYJSON_DISABLE_NON_STANDARD` flag.
1894 */
1895yyjson_api char *yyjson_write_number(const yyjson_val *val, char *buf);
1896
1897/** Same as `yyjson_write_number()`. */
1899 char *buf) {
1900 return yyjson_write_number((const yyjson_val *)val, buf);
1901}
1902
1903#endif /* YYJSON_DISABLE_WRITER */
1904
1905
1906
1907/*==============================================================================
1908 * MARK: - JSON Document API
1909 *============================================================================*/
1910
1911/** Returns the root value of this JSON document.
1912 Returns NULL if `doc` is NULL. */
1914
1915/** Returns read size of input JSON data.
1916 Returns 0 if `doc` is NULL.
1917 For example: the read size of `[1,2,3]` is 7 bytes. */
1919
1920/** Returns total value count in this JSON document.
1921 Returns 0 if `doc` is NULL.
1922 For example: the value count of `[1,2,3]` is 4. */
1924
1925/** Release the JSON document and free the memory.
1926 After calling this function, the `doc` and all values from the `doc` are no
1927 longer available. This function will do nothing if the `doc` is NULL. */
1929
1930
1931
1932/*==============================================================================
1933 * MARK: - JSON Value Type API
1934 *============================================================================*/
1935
1936/** Returns whether the JSON value is raw.
1937 Returns false if `val` is NULL. */
1939
1940/** Returns whether the JSON value is `null`.
1941 Returns false if `val` is NULL. */
1943
1944/** Returns whether the JSON value is `true`.
1945 Returns false if `val` is NULL. */
1947
1948/** Returns whether the JSON value is `false`.
1949 Returns false if `val` is NULL. */
1951
1952/** Returns whether the JSON value is bool (true/false).
1953 Returns false if `val` is NULL. */
1955
1956/** Returns whether the JSON value is unsigned integer (uint64_t).
1957 Returns false if `val` is NULL. */
1959
1960/** Returns whether the JSON value is signed integer (int64_t).
1961 Returns false if `val` is NULL. */
1963
1964/** Returns whether the JSON value is integer (uint64_t/int64_t).
1965 Returns false if `val` is NULL. */
1967
1968/** Returns whether the JSON value is real number (double).
1969 Returns false if `val` is NULL. */
1971
1972/** Returns whether the JSON value is number (uint64_t/int64_t/double).
1973 Returns false if `val` is NULL. */
1975
1976/** Returns whether the JSON value is string.
1977 Returns false if `val` is NULL. */
1979
1980/** Returns whether the JSON value is array.
1981 Returns false if `val` is NULL. */
1983
1984/** Returns whether the JSON value is object.
1985 Returns false if `val` is NULL. */
1987
1988/** Returns whether the JSON value is container (array/object).
1989 Returns false if `val` is NULL. */
1991
1992
1993
1994/*==============================================================================
1995 * MARK: - JSON Value Content API
1996 *============================================================================*/
1997
1998/** Returns the JSON value's type.
1999 Returns YYJSON_TYPE_NONE if `val` is NULL. */
2001
2002/** Returns the JSON value's subtype.
2003 Returns YYJSON_SUBTYPE_NONE if `val` is NULL. */
2005
2006/** Returns the JSON value's tag.
2007 Returns 0 if `val` is NULL. */
2008yyjson_api_inline uint8_t yyjson_get_tag(const yyjson_val *val);
2009
2010/** Returns the JSON value's type description.
2011 The return value should be one of these strings: "raw", "null", "string",
2012 "array", "object", "true", "false", "uint", "sint", "real", "unknown". */
2013yyjson_api_inline const char *yyjson_get_type_desc(const yyjson_val *val);
2014
2015/** Returns the content if the value is raw.
2016 Returns NULL if `val` is NULL or type is not raw. */
2017yyjson_api_inline const char *yyjson_get_raw(const yyjson_val *val);
2018
2019/** Returns the content if the value is bool.
2020 Returns false if `val` is NULL or type is not bool. */
2022
2023/** Returns the content cast to uint64_t.
2024 Returns 0 if `val` is NULL or type is not integer(sint/uint). */
2025yyjson_api_inline uint64_t yyjson_get_uint(const yyjson_val *val);
2026
2027/** Returns the content cast to int64_t.
2028 Returns 0 if `val` is NULL or type is not integer(sint/uint). */
2029yyjson_api_inline int64_t yyjson_get_sint(const yyjson_val *val);
2030
2031/** Returns the content cast to int (may overflow).
2032 Returns 0 if `val` is NULL or type is not integer(sint/uint). */
2034
2035/** Returns the content if the value is real number, or 0.0 on error.
2036 Returns 0.0 if `val` is NULL or type is not real(double). */
2038
2039/** Returns the content cast to `double` if the value is a number.
2040 Returns 0.0 if `val` is NULL or type is not number(uint/sint/real). */
2042
2043/** Returns the content if the value is string.
2044 Returns NULL if `val` is NULL or type is not string. */
2045yyjson_api_inline const char *yyjson_get_str(const yyjson_val *val);
2046
2047/** Returns the content length (string length, array size, object size).
2048 Returns 0 if `val` is NULL or type is not string/array/object. */
2050
2051/** Returns whether the JSON value is equal to a string.
2052 Returns false if `val` is NULL or type is not string. */
2054 const char *str);
2055
2056/** Returns whether the JSON value is equal to a string.
2057 The `str` should be a UTF-8 string, null-terminator is not required.
2058 Returns false if `val` is NULL or type is not string. */
2060 const char *str, size_t len);
2061
2062/** Returns whether two JSON values are equal (deep compare).
2063 Returns false if `lhs` or `rhs` is NULL.
2064 @note the result may be inaccurate if object has duplicate keys.
2065 @warning This function is recursive and may cause a stack overflow
2066 if the object level is too deep. */
2068 const yyjson_val *rhs);
2069
2070/** Set the value to raw.
2071 Returns false if `val` is NULL or is object or array.
2072 @warning This will modify the `immutable` value, use with caution. */
2074 const char *raw, size_t len);
2075
2076/** Set the value to null.
2077 Returns false if `val` is NULL or is object or array.
2078 @warning This will modify the `immutable` value, use with caution. */
2080
2081/** Set the value to bool.
2082 Returns false if `val` is NULL or is object or array.
2083 @warning This will modify the `immutable` value, use with caution. */
2084yyjson_api_inline bool yyjson_set_bool(yyjson_val *val, bool num);
2085
2086/** Set the value to uint.
2087 Returns false if `val` is NULL or is object or array.
2088 @warning This will modify the `immutable` value, use with caution. */
2089yyjson_api_inline bool yyjson_set_uint(yyjson_val *val, uint64_t num);
2090
2091/** Set the value to sint.
2092 Returns false if `val` is NULL or is object or array.
2093 @warning This will modify the `immutable` value, use with caution. */
2094yyjson_api_inline bool yyjson_set_sint(yyjson_val *val, int64_t num);
2095
2096/** Set the value to int.
2097 Returns false if `val` is NULL or is object or array.
2098 @warning This will modify the `immutable` value, use with caution. */
2099yyjson_api_inline bool yyjson_set_int(yyjson_val *val, int64_t num);
2100
2101/** Set the value to float.
2102 Returns false if `val` is NULL or is object or array.
2103 @warning This will modify the `immutable` value, use with caution. */
2104yyjson_api_inline bool yyjson_set_float(yyjson_val *val, float num);
2105
2106/** Set the value to double.
2107 Returns false if `val` is NULL or is object or array.
2108 @warning This will modify the `immutable` value, use with caution. */
2109yyjson_api_inline bool yyjson_set_double(yyjson_val *val, double num);
2110
2111/** Set the value to real.
2112 Returns false if `val` is NULL or is object or array.
2113 @warning This will modify the `immutable` value, use with caution. */
2114yyjson_api_inline bool yyjson_set_real(yyjson_val *val, double num);
2115
2116/** Set the floating-point number's output format to fixed-point notation.
2117 Returns false if `val` is NULL or is not real type.
2118 @see YYJSON_WRITE_FP_TO_FIXED flag.
2119 @warning This will modify the `immutable` value, use with caution. */
2121
2122/** Set the floating-point number's output format to single-precision.
2123 Returns false if `val` is NULL or is not real type.
2124 @see YYJSON_WRITE_FP_TO_FLOAT flag.
2125 @warning This will modify the `immutable` value, use with caution. */
2127
2128/** Set the value to string (null-terminated).
2129 Returns false if `val` is NULL or is object or array.
2130 @warning This will modify the `immutable` value, use with caution. */
2131yyjson_api_inline bool yyjson_set_str(yyjson_val *val, const char *str);
2132
2133/** Set the value to string (with length).
2134 Returns false if `val` is NULL or is object or array.
2135 @warning This will modify the `immutable` value, use with caution. */
2137 const char *str, size_t len);
2138
2139/** Marks this string as not needing to be escaped during JSON writing.
2140 This can be used to avoid the overhead of escaping if the string contains
2141 only characters that do not require escaping.
2142 Returns false if `val` is NULL or is not string.
2143 @see YYJSON_SUBTYPE_NOESC subtype.
2144 @warning This will modify the `immutable` value, use with caution. */
2146
2147
2148
2149/*==============================================================================
2150 * MARK: - JSON Array API
2151 *============================================================================*/
2152
2153/** Returns the number of elements in this array.
2154 Returns 0 if `arr` is NULL or type is not array. */
2156
2157/** Returns the element at the specified position in this array.
2158 Returns NULL if array is NULL/empty or the index is out of bounds.
2159 @warning This function takes a linear search time if array is not flat.
2160 For example: `[1,{},3]` is flat, `[1,[2],3]` is not flat. */
2161yyjson_api_inline yyjson_val *yyjson_arr_get(const yyjson_val *arr, size_t idx);
2162
2163/** Returns the first element of this array.
2164 Returns NULL if `arr` is NULL/empty or type is not array. */
2166
2167/** Returns the last element of this array.
2168 Returns NULL if `arr` is NULL/empty or type is not array.
2169 @warning This function takes a linear search time if array is not flat.
2170 For example: `[1,{},3]` is flat, `[1,[2],3]` is not flat.*/
2172
2173
2174
2175/*==============================================================================
2176 * MARK: - JSON Array Iterator API
2177 *============================================================================*/
2178
2179/**
2180 A JSON array iterator.
2181
2182 @b Example
2183 @code
2184 yyjson_val *val;
2185 yyjson_arr_iter iter = yyjson_arr_iter_with(arr);
2186 while ((val = yyjson_arr_iter_next(&iter))) {
2187 your_func(val);
2188 }
2189 @endcode
2190 */
2191typedef struct yyjson_arr_iter {
2192 size_t idx; /**< next value's index */
2193 size_t max; /**< maximum index (arr.size) */
2194 yyjson_val *cur; /**< next value */
2196
2197/**
2198 Initialize an iterator for this array.
2199
2200 @param arr The array to be iterated over.
2201 If `arr` is NULL or not an array, `iter` is cleared.
2202 @param iter The iterator to be initialized.
2203 If `iter` is NULL, returns false.
2204 @return true if the `iter` has been successfully initialized.
2205
2206 @note The iterator does not need to be destroyed.
2207 */
2209 yyjson_arr_iter *iter);
2210
2211/**
2212 Create an iterator with an array, same as `yyjson_arr_iter_init()`.
2213
2214 @param arr The array to be iterated over.
2215 If `arr` is NULL or not an array, returns an empty iterator.
2216 @return A new iterator for the array.
2217
2218 @note The iterator does not need to be destroyed.
2219 */
2221
2222/**
2223 Returns whether the iteration has more elements.
2224 If `iter` is NULL, returns false.
2225 */
2227
2228/**
2229 Returns the next element in the iteration, or NULL on end.
2230 If `iter` is NULL, returns NULL.
2231 */
2233
2234/**
2235 Macro for iterating over an array.
2236 It works like iterator, but with a more intuitive API.
2237
2238 @b Example
2239 @code
2240 size_t idx, max;
2241 yyjson_val *val;
2242 yyjson_arr_foreach(arr, idx, max, val) {
2243 your_func(idx, val);
2244 }
2245 @endcode
2246 */
2247#define yyjson_arr_foreach(arr, idx, max, val) \
2248 for ((idx) = 0, \
2249 (max) = yyjson_arr_size(arr), \
2250 (val) = yyjson_arr_get_first(arr); \
2251 (idx) < (max); \
2252 (idx)++, \
2253 (val) = unsafe_yyjson_get_next(val))
2254
2255
2256
2257/*==============================================================================
2258 * MARK: - JSON Object API
2259 *============================================================================*/
2260
2261/** Returns the number of key-value pairs in this object.
2262 Returns 0 if `obj` is NULL or type is not object. */
2264
2265/** Returns the value to which the specified key is mapped.
2266 Returns NULL if this object contains no mapping for the key.
2267 Returns NULL if `obj/key` is NULL, or type is not object.
2268
2269 The `key` should be a null-terminated UTF-8 string.
2270
2271 @warning This function takes a linear search time. */
2273 const char *key);
2274
2275/** Returns the value to which the specified key is mapped.
2276 Returns NULL if this object contains no mapping for the key.
2277 Returns NULL if `obj/key` is NULL, or type is not object.
2278
2279 The `key` should be a UTF-8 string, null-terminator is not required.
2280 The `key_len` should be the length of the key, in bytes.
2281
2282 @warning This function takes a linear search time. */
2284 const char *key, size_t key_len);
2285
2286
2287
2288/*==============================================================================
2289 * MARK: - JSON Object Iterator API
2290 *============================================================================*/
2291
2292/**
2293 A JSON object iterator.
2294
2295 @b Example
2296 @code
2297 yyjson_val *key, *val;
2298 yyjson_obj_iter iter = yyjson_obj_iter_with(obj);
2299 while ((key = yyjson_obj_iter_next(&iter))) {
2300 val = yyjson_obj_iter_get_val(key);
2301 your_func(key, val);
2302 }
2303 @endcode
2304
2305 If the ordering of the keys is known at compile-time, you can use this method
2306 to speed up value lookups:
2307 @code
2308 // {"k1":1, "k2": 3, "k3": 3}
2309 yyjson_val *key, *val;
2310 yyjson_obj_iter iter = yyjson_obj_iter_with(obj);
2311 yyjson_val *v1 = yyjson_obj_iter_get(&iter, "k1");
2312 yyjson_val *v3 = yyjson_obj_iter_get(&iter, "k3");
2313 @endcode
2314 @see yyjson_obj_iter_get() and yyjson_obj_iter_getn()
2315 */
2316typedef struct yyjson_obj_iter {
2317 size_t idx; /**< next key's index */
2318 size_t max; /**< maximum key index (obj.size) */
2319 yyjson_val *cur; /**< next key */
2320 yyjson_val *obj; /**< the object being iterated */
2322
2323/**
2324 Initialize an iterator for this object.
2325
2326 @param obj The object to be iterated over.
2327 If `obj` is NULL or not an object, `iter` is cleared.
2328 @param iter The iterator to be initialized.
2329 If `iter` is NULL, returns false.
2330 @return true if the `iter` has been successfully initialized.
2331
2332 @note The iterator does not need to be destroyed.
2333 */
2335 yyjson_obj_iter *iter);
2336
2337/**
2338 Create an iterator with an object, same as `yyjson_obj_iter_init()`.
2339
2340 @param obj The object to be iterated over.
2341 If `obj` is NULL or not an object, returns an empty iterator.
2342 @return A new iterator for the object.
2343
2344 @note The iterator does not need to be destroyed.
2345 */
2347
2348/**
2349 Returns whether the iteration has more elements.
2350 If `iter` is NULL, returns false.
2351 */
2353
2354/**
2355 Returns the next key in the iteration, or NULL on end.
2356 If `iter` is NULL, returns NULL.
2357 */
2359
2360/**
2361 Returns the value for key inside the iteration.
2362 If `iter` is NULL, returns NULL.
2363 */
2365
2366/**
2367 Iterates to a specified key and returns the value.
2368
2369 This function does the same thing as `yyjson_obj_get()`, but is much faster
2370 if the ordering of the keys is known at compile-time and you are using the same
2371 order to look up the values. If the key exists in this object, then the
2372 iterator will stop at the next key, otherwise the iterator will not change and
2373 NULL is returned.
2374
2375 @param iter The object iterator, should not be NULL.
2376 @param key The key, should be a UTF-8 string with null-terminator.
2377 @return The value to which the specified key is mapped.
2378 NULL if the key is not found or arguments are invalid.
2379
2380 @warning This function takes a linear search time if the key is not nearby.
2381 */
2383 const char *key);
2384
2385/**
2386 Iterates to a specified key and returns the value.
2387
2388 This function does the same thing as `yyjson_obj_getn()`, but is much faster
2389 if the ordering of the keys is known at compile-time and you are using the same
2390 order to look up the values. If the key exists in this object, then the
2391 iterator will stop at the next key, otherwise the iterator will not change and
2392 NULL is returned.
2393
2394 @param iter The object iterator, should not be NULL.
2395 @param key The key, should be a UTF-8 string, null-terminator is not required.
2396 @param key_len The length of `key`, in bytes.
2397 @return The value to which the specified key is mapped.
2398 NULL if the key is not found or arguments are invalid.
2399
2400 @warning This function takes a linear search time if the key is not nearby.
2401 */
2403 const char *key,
2404 size_t key_len);
2405
2406/**
2407 Macro for iterating over an object.
2408 It works like iterator, but with a more intuitive API.
2409
2410 @b Example
2411 @code
2412 size_t idx, max;
2413 yyjson_val *key, *val;
2414 yyjson_obj_foreach(obj, idx, max, key, val) {
2415 your_func(key, val);
2416 }
2417 @endcode
2418 */
2419#define yyjson_obj_foreach(obj, idx, max, key, val) \
2420 for ((idx) = 0, \
2421 (max) = yyjson_obj_size(obj), \
2422 (key) = (obj) ? unsafe_yyjson_get_first(obj) : NULL, \
2423 (val) = (key) + 1; \
2424 (idx) < (max); \
2425 (idx)++, \
2426 (key) = unsafe_yyjson_get_next(val), \
2427 (val) = (key) + 1)
2428
2429
2430
2431/*==============================================================================
2432 * MARK: - Mutable JSON Document API
2433 *============================================================================*/
2434
2435/** Returns the root value of this JSON document.
2436 Returns NULL if `doc` is NULL. */
2438
2439/** Sets the root value of this JSON document.
2440 Pass NULL to clear root value of the document. */
2442 yyjson_mut_val *root);
2443
2444/**
2445 Set the string pool size for a mutable document.
2446 This function does not allocate memory immediately, but uses the size when
2447 the next memory allocation is needed.
2448
2449 If the caller knows the approximate bytes of strings that the document needs to
2450 store (e.g. copy string with `yyjson_mut_strcpy` function), setting a larger
2451 size can avoid multiple memory allocations and improve performance.
2452
2453 @param doc The mutable document.
2454 @param len The desired string pool size in bytes (total string length).
2455 @return true if successful, false if size is 0 or overflow.
2456 */
2458 size_t len);
2459
2460/**
2461 Set the value pool size for a mutable document.
2462 This function does not allocate memory immediately, but uses the size when
2463 the next memory allocation is needed.
2464
2465 If the caller knows the approximate number of values that the document needs to
2466 store (e.g. create new value with `yyjson_mut_xxx` functions), setting a larger
2467 size can avoid multiple memory allocations and improve performance.
2468
2469 @param doc The mutable document.
2470 @param count The desired value pool size (number of `yyjson_mut_val`).
2471 @return true if successful, false if size is 0 or overflow.
2472 */
2474 size_t count);
2475
2476/** Release the JSON document and free the memory.
2477 After calling this function, the `doc` and all values from the `doc` are no
2478 longer available. This function will do nothing if the `doc` is NULL. */
2480
2481/** Creates and returns a new mutable JSON document, returns NULL on error.
2482 If allocator is NULL, the default allocator will be used. */
2484
2485/** Copies and returns a new mutable document from input, returns NULL on error.
2486 This makes a `deep-copy` on the immutable document.
2487 If allocator is NULL, the default allocator will be used.
2488 @note `imut_doc` -> `mut_doc`. */
2490 const yyjson_alc *alc);
2491
2492/** Copies and returns a new mutable document from input, returns NULL on error.
2493 This makes a `deep-copy` on the mutable document.
2494 If allocator is NULL, the default allocator will be used.
2495 @note `mut_doc` -> `mut_doc`. */
2497 const yyjson_alc *alc);
2498
2499/** Copies and returns a new mutable value from input, returns NULL on error.
2500 This makes a `deep-copy` on the immutable value.
2501 The memory is managed by the mutable document.
2502 @note `imut_val` -> `mut_val`. */
2504 const yyjson_val *val);
2505
2506/** Copies and returns a new mutable value from input, returns NULL on error.
2507 This makes a `deep-copy` on the mutable value.
2508 The memory is managed by the mutable document.
2509 @note `mut_val` -> `mut_val`.
2510 @warning This function is recursive and may cause a stack overflow
2511 if the object level is too deep. */
2513 const yyjson_mut_val *val);
2514
2515/** Copies and returns a new immutable document from input,
2516 returns NULL on error. This makes a `deep-copy` on the mutable document.
2517 The returned document should be freed with `yyjson_doc_free()`.
2518 @note `mut_doc` -> `imut_doc`.
2519 @warning This function is recursive and may cause a stack overflow
2520 if the object level is too deep. */
2522 const yyjson_alc *alc);
2523
2524/** Copies and returns a new immutable document from input,
2525 returns NULL on error. This makes a `deep-copy` on the mutable value.
2526 The returned document should be freed with `yyjson_doc_free()`.
2527 @note `mut_val` -> `imut_doc`.
2528 @warning This function is recursive and may cause a stack overflow
2529 if the object level is too deep. */
2531 const yyjson_alc *alc);
2532
2533
2534
2535/*==============================================================================
2536 * MARK: - Mutable JSON Value Type API
2537 *============================================================================*/
2538
2539/** Returns whether the JSON value is raw.
2540 Returns false if `val` is NULL. */
2542
2543/** Returns whether the JSON value is `null`.
2544 Returns false if `val` is NULL. */
2546
2547/** Returns whether the JSON value is `true`.
2548 Returns false if `val` is NULL. */
2550
2551/** Returns whether the JSON value is `false`.
2552 Returns false if `val` is NULL. */
2554
2555/** Returns whether the JSON value is bool (true/false).
2556 Returns false if `val` is NULL. */
2558
2559/** Returns whether the JSON value is unsigned integer (uint64_t).
2560 Returns false if `val` is NULL. */
2562
2563/** Returns whether the JSON value is signed integer (int64_t).
2564 Returns false if `val` is NULL. */
2566
2567/** Returns whether the JSON value is integer (uint64_t/int64_t).
2568 Returns false if `val` is NULL. */
2570
2571/** Returns whether the JSON value is real number (double).
2572 Returns false if `val` is NULL. */
2574
2575/** Returns whether the JSON value is number (uint/sint/real).
2576 Returns false if `val` is NULL. */
2578
2579/** Returns whether the JSON value is string.
2580 Returns false if `val` is NULL. */
2582
2583/** Returns whether the JSON value is array.
2584 Returns false if `val` is NULL. */
2586
2587/** Returns whether the JSON value is object.
2588 Returns false if `val` is NULL. */
2590
2591/** Returns whether the JSON value is container (array/object).
2592 Returns false if `val` is NULL. */
2594
2595
2596
2597/*==============================================================================
2598 * MARK: - Mutable JSON Value Content API
2599 *============================================================================*/
2600
2601/** Returns the JSON value's type.
2602 Returns `YYJSON_TYPE_NONE` if `val` is NULL. */
2604
2605/** Returns the JSON value's subtype.
2606 Returns `YYJSON_SUBTYPE_NONE` if `val` is NULL. */
2608 const yyjson_mut_val *val);
2609
2610/** Returns the JSON value's tag.
2611 Returns 0 if `val` is NULL. */
2613
2614/** Returns the JSON value's type description.
2615 The return value should be one of these strings: "raw", "null", "string",
2616 "array", "object", "true", "false", "uint", "sint", "real", "unknown". */
2618 const yyjson_mut_val *val);
2619
2620/** Returns the content if the value is raw.
2621 Returns NULL if `val` is NULL or type is not raw. */
2623
2624/** Returns the content if the value is bool.
2625 Returns NULL if `val` is NULL or type is not bool. */
2627
2628/** Returns the content and cast to uint64_t.
2629 Returns 0 if `val` is NULL or type is not integer(sint/uint). */
2631
2632/** Returns the content and cast to int64_t.
2633 Returns 0 if `val` is NULL or type is not integer(sint/uint). */
2635
2636/** Returns the content and cast to int.
2637 Returns 0 if `val` is NULL or type is not integer(sint/uint). */
2639
2640/** Returns the content if the value is real number.
2641 Returns 0.0 if `val` is NULL or type is not real(double). */
2643
2644/** Returns the content cast to `double` if the value is a number.
2645 Returns 0.0 if `val` is NULL or type is not number(uint/sint/real). */
2647
2648/** Returns the content if the value is string.
2649 Returns NULL if `val` is NULL or type is not string. */
2651
2652/** Returns the content length (string length, array size, object size).
2653 Returns 0 if `val` is NULL or type is not string/array/object. */
2655
2656/** Returns whether the JSON value is equal to a string.
2657 The `str` should be a null-terminated UTF-8 string.
2658 Returns false if `val` is NULL or type is not string. */
2660 const char *str);
2661
2662/** Returns whether the JSON value is equal to a string.
2663 The `str` should be a UTF-8 string, null-terminator is not required.
2664 Returns false if `val` is NULL or type is not string. */
2666 const char *str, size_t len);
2667
2668/** Returns whether two JSON values are equal (deep compare).
2669 Returns false if `lhs` or `rhs` is NULL.
2670 @note the result may be inaccurate if object has duplicate keys.
2671 @warning This function is recursive and may cause a stack overflow
2672 if the object level is too deep. */
2674 const yyjson_mut_val *rhs);
2675
2676/** Set the value to raw.
2677 Returns false if `val` is NULL.
2678 @warning This function should not be used on an existing object or array. */
2680 const char *raw, size_t len);
2681
2682/** Set the value to null.
2683 Returns false if `val` is NULL.
2684 @warning This function should not be used on an existing object or array. */
2686
2687/** Set the value to bool.
2688 Returns false if `val` is NULL.
2689 @warning This function should not be used on an existing object or array. */
2691
2692/** Set the value to uint.
2693 Returns false if `val` is NULL.
2694 @warning This function should not be used on an existing object or array. */
2696
2697/** Set the value to sint.
2698 Returns false if `val` is NULL.
2699 @warning This function should not be used on an existing object or array. */
2701
2702/** Set the value to int.
2703 Returns false if `val` is NULL.
2704 @warning This function should not be used on an existing object or array. */
2706
2707/** Set the value to float.
2708 Returns false if `val` is NULL.
2709 @warning This function should not be used on an existing object or array. */
2711
2712/** Set the value to double.
2713 Returns false if `val` is NULL.
2714 @warning This function should not be used on an existing object or array. */
2716
2717/** Set the value to real.
2718 Returns false if `val` is NULL.
2719 @warning This function should not be used on an existing object or array. */
2721
2722/** Set the floating-point number's output format to fixed-point notation.
2723 Returns false if `val` is NULL or is not real type.
2724 @see YYJSON_WRITE_FP_TO_FIXED flag.
2725 @warning This will modify the `mutable` value, use with caution. */
2727 int prec);
2728
2729/** Set the floating-point number's output format to single-precision.
2730 Returns false if `val` is NULL or is not real type.
2731 @see YYJSON_WRITE_FP_TO_FLOAT flag.
2732 @warning This will modify the `mutable` value, use with caution. */
2734 bool flt);
2735
2736/** Set the value to string (null-terminated).
2737 Returns false if `val` is NULL.
2738 @warning This function should not be used on an existing object or array. */
2739yyjson_api_inline bool yyjson_mut_set_str(yyjson_mut_val *val, const char *str);
2740
2741/** Set the value to string (with length).
2742 Returns false if `val` is NULL.
2743 @warning This function should not be used on an existing object or array. */
2745 const char *str, size_t len);
2746
2747/** Marks this string as not needing to be escaped during JSON writing.
2748 This can be used to avoid the overhead of escaping if the string contains
2749 only characters that do not require escaping.
2750 Returns false if `val` is NULL or is not string.
2751 @see YYJSON_SUBTYPE_NOESC subtype.
2752 @warning This will modify the `mutable` value, use with caution. */
2754 bool noesc);
2755
2756/** Set the value to array.
2757 Returns false if `val` is NULL.
2758 @warning This function should not be used on an existing object or array. */
2760
2761/** Set the value to object.
2762 Returns false if `val` is NULL.
2763 @warning This function should not be used on an existing object or array. */
2765
2766
2767
2768/*==============================================================================
2769 * MARK: - Mutable JSON Value Creation API
2770 *============================================================================*/
2771
2772/** Creates and returns a raw value, returns NULL on error.
2773 The `str` should be a null-terminated UTF-8 string.
2774
2775 @warning The input string is not copied, you should keep this string
2776 unmodified for the lifetime of this JSON document. */
2778 const char *str);
2779
2780/** Creates and returns a raw value, returns NULL on error.
2781 The `str` should be a UTF-8 string, null-terminator is not required.
2782
2783 @warning The input string is not copied, you should keep this string
2784 unmodified for the lifetime of this JSON document. */
2786 const char *str,
2787 size_t len);
2788
2789/** Creates and returns a raw value, returns NULL on error.
2790 The `str` should be a null-terminated UTF-8 string.
2791 The input string is copied and held by the document. */
2793 const char *str);
2794
2795/** Creates and returns a raw value, returns NULL on error.
2796 The `str` should be a UTF-8 string, null-terminator is not required.
2797 The input string is copied and held by the document. */
2799 const char *str,
2800 size_t len);
2801
2802/** Creates and returns a null value, returns NULL on error. */
2804
2805/** Creates and returns a true value, returns NULL on error. */
2807
2808/** Creates and returns a false value, returns NULL on error. */
2810
2811/** Creates and returns a bool value, returns NULL on error. */
2813 bool val);
2814
2815/** Creates and returns an unsigned integer value, returns NULL on error. */
2817 uint64_t num);
2818
2819/** Creates and returns a signed integer value, returns NULL on error. */
2821 int64_t num);
2822
2823/** Creates and returns a signed integer value, returns NULL on error. */
2825 int64_t num);
2826
2827/** Creates and returns a float number value, returns NULL on error. */
2829 float num);
2830
2831/** Creates and returns a double number value, returns NULL on error. */
2833 double num);
2834
2835/** Creates and returns a real number value, returns NULL on error. */
2837 double num);
2838
2839/** Creates and returns a string value, returns NULL on error.
2840 The `str` should be a null-terminated UTF-8 string.
2841 @warning The input string is not copied, you should keep this string
2842 unmodified for the lifetime of this JSON document. */
2844 const char *str);
2845
2846/** Creates and returns a string value, returns NULL on error.
2847 The `str` should be a UTF-8 string, null-terminator is not required.
2848 @warning The input string is not copied, you should keep this string
2849 unmodified for the lifetime of this JSON document. */
2851 const char *str,
2852 size_t len);
2853
2854/** Creates and returns a string value, returns NULL on error.
2855 The `str` should be a null-terminated UTF-8 string.
2856 The input string is copied and held by the document. */
2858 const char *str);
2859
2860/** Creates and returns a string value, returns NULL on error.
2861 The `str` should be a UTF-8 string, null-terminator is not required.
2862 The input string is copied and held by the document. */
2864 const char *str,
2865 size_t len);
2866
2867
2868
2869/*==============================================================================
2870 * MARK: - Mutable JSON Array API
2871 *============================================================================*/
2872
2873/** Returns the number of elements in this array.
2874 Returns 0 if `arr` is NULL or type is not array. */
2876
2877/** Returns the element at the specified position in this array.
2878 Returns NULL if array is NULL/empty or the index is out of bounds.
2879 @warning This function takes a linear search time. */
2881 size_t idx);
2882
2883/** Returns the first element of this array.
2884 Returns NULL if `arr` is NULL/empty or type is not array. */
2886 const yyjson_mut_val *arr);
2887
2888/** Returns the last element of this array.
2889 Returns NULL if `arr` is NULL/empty or type is not array. */
2891 const yyjson_mut_val *arr);
2892
2893
2894
2895/*==============================================================================
2896 * MARK: - Mutable JSON Array Iterator API
2897 *============================================================================*/
2898
2899/**
2900 A mutable JSON array iterator.
2901
2902 @warning You should not modify the array while iterating over it, but you can
2903 use `yyjson_mut_arr_iter_remove()` to remove current value.
2904
2905 @b Example
2906 @code
2907 yyjson_mut_val *val;
2908 yyjson_mut_arr_iter iter = yyjson_mut_arr_iter_with(arr);
2909 while ((val = yyjson_mut_arr_iter_next(&iter))) {
2910 your_func(val);
2911 if (your_val_is_unused(val)) {
2912 yyjson_mut_arr_iter_remove(&iter);
2913 }
2914 }
2915 @endcode
2916 */
2917typedef struct yyjson_mut_arr_iter {
2918 size_t idx; /**< next value's index */
2919 size_t max; /**< maximum index (arr.size) */
2920 yyjson_mut_val *cur; /**< current value */
2921 yyjson_mut_val *pre; /**< previous value */
2922 yyjson_mut_val *arr; /**< the array being iterated */
2924
2925/**
2926 Initialize an iterator for this array.
2927
2928 @param arr The array to be iterated over.
2929 If `arr` is NULL or not an array, `iter` is cleared.
2930 @param iter The iterator to be initialized.
2931 If `iter` is NULL, returns false.
2932 @return true if the `iter` has been successfully initialized.
2933
2934 @note The iterator does not need to be destroyed.
2935 */
2937 yyjson_mut_arr_iter *iter);
2938
2939/**
2940 Create an iterator with an array, same as `yyjson_mut_arr_iter_init()`.
2941
2942 @param arr The array to be iterated over.
2943 If `arr` is NULL or not an array, returns an empty iterator.
2944 @return A new iterator for the array.
2945
2946 @note The iterator does not need to be destroyed.
2947 */
2949 yyjson_mut_val *arr);
2950
2951/**
2952 Returns whether the iteration has more elements.
2953 If `iter` is NULL, returns false.
2954 */
2956 yyjson_mut_arr_iter *iter);
2957
2958/**
2959 Returns the next element in the iteration, or NULL on end.
2960 If `iter` is NULL, returns NULL.
2961 */
2963 yyjson_mut_arr_iter *iter);
2964
2965/**
2966 Removes and returns current element in the iteration.
2967 If `iter` is NULL, returns NULL.
2968 */
2970 yyjson_mut_arr_iter *iter);
2971
2972/**
2973 Macro for iterating over an array.
2974 It works like iterator, but with a more intuitive API.
2975
2976 @warning You should not modify the array while iterating over it.
2977
2978 @b Example
2979 @code
2980 size_t idx, max;
2981 yyjson_mut_val *val;
2982 yyjson_mut_arr_foreach(arr, idx, max, val) {
2983 your_func(idx, val);
2984 }
2985 @endcode
2986 */
2987#define yyjson_mut_arr_foreach(arr, idx, max, val) \
2988 for ((idx) = 0, \
2989 (max) = yyjson_mut_arr_size(arr), \
2990 (val) = yyjson_mut_arr_get_first(arr); \
2991 (idx) < (max); \
2992 (idx)++, \
2993 (val) = (val)->next)
2994
2995
2996
2997/*==============================================================================
2998 * MARK: - Mutable JSON Array Creation API
2999 *============================================================================*/
3000
3001/**
3002 Creates and returns an empty mutable array.
3003 @param doc A mutable document, used for memory allocation only.
3004 @return The new array. NULL if `doc` is NULL or allocation fails.
3005 */
3007
3008/**
3009 Creates and returns a new mutable array with the given boolean values.
3010
3011 @param doc A mutable document, used for memory allocation only.
3012 If `doc` is NULL, returns NULL.
3013 @param vals A C array of boolean values.
3014 @param count The value count. If this value is 0, an empty array is returned.
3015 @return The new array. NULL if arguments are invalid or allocation fails.
3016
3017 @b Example
3018 @code
3019 const bool vals[3] = { true, false, true };
3020 yyjson_mut_val *arr = yyjson_mut_arr_with_bool(doc, vals, 3);
3021 @endcode
3022 */
3024 yyjson_mut_doc *doc, const bool *vals, size_t count);
3025
3026/**
3027 Creates and returns a new mutable array with the given sint numbers.
3028
3029 @param doc A mutable document, used for memory allocation only.
3030 If `doc` is NULL, returns NULL.
3031 @param vals A C array of sint numbers.
3032 @param count The number count. If this value is 0, an empty array is returned.
3033 @return The new array. NULL if arguments are invalid or allocation fails.
3034
3035 @b Example
3036 @code
3037 const int64_t vals[3] = { -1, 0, 1 };
3038 yyjson_mut_val *arr = yyjson_mut_arr_with_sint64(doc, vals, 3);
3039 @endcode
3040 */
3042 yyjson_mut_doc *doc, const int64_t *vals, size_t count);
3043
3044/**
3045 Creates and returns a new mutable array with the given uint numbers.
3046
3047 @param doc A mutable document, used for memory allocation only.
3048 If `doc` is NULL, returns NULL.
3049 @param vals A C array of uint numbers.
3050 @param count The number count. If this value is 0, an empty array is returned.
3051 @return The new array. NULL if arguments are invalid or allocation fails.
3052
3053 @b Example
3054 @code
3055 const uint64_t vals[3] = { 0, 1, 0 };
3056 yyjson_mut_val *arr = yyjson_mut_arr_with_uint(doc, vals, 3);
3057 @endcode
3058 */
3060 yyjson_mut_doc *doc, const uint64_t *vals, size_t count);
3061
3062/**
3063 Creates and returns a new mutable array with the given real numbers.
3064
3065 @param doc A mutable document, used for memory allocation only.
3066 If `doc` is NULL, returns NULL.
3067 @param vals A C array of real numbers.
3068 @param count The number count. If this value is 0, an empty array is returned.
3069 @return The new array. NULL if arguments are invalid or allocation fails.
3070
3071 @b Example
3072 @code
3073 const double vals[3] = { 0.1, 0.2, 0.3 };
3074 yyjson_mut_val *arr = yyjson_mut_arr_with_real(doc, vals, 3);
3075 @endcode
3076 */
3078 yyjson_mut_doc *doc, const double *vals, size_t count);
3079
3080/**
3081 Creates and returns a new mutable array with the given int8 numbers.
3082
3083 @param doc A mutable document, used for memory allocation only.
3084 If `doc` is NULL, returns NULL.
3085 @param vals A C array of int8 numbers.
3086 @param count The number count. If this value is 0, an empty array is returned.
3087 @return The new array. NULL if arguments are invalid or allocation fails.
3088
3089 @b Example
3090 @code
3091 const int8_t vals[3] = { -1, 0, 1 };
3092 yyjson_mut_val *arr = yyjson_mut_arr_with_sint8(doc, vals, 3);
3093 @endcode
3094 */
3096 yyjson_mut_doc *doc, const int8_t *vals, size_t count);
3097
3098/**
3099 Creates and returns a new mutable array with the given int16 numbers.
3100
3101 @param doc A mutable document, used for memory allocation only.
3102 If `doc` is NULL, returns NULL.
3103 @param vals A C array of int16 numbers.
3104 @param count The number count. If this value is 0, an empty array is returned.
3105 @return The new array. NULL if arguments are invalid or allocation fails.
3106
3107 @b Example
3108 @code
3109 const int16_t vals[3] = { -1, 0, 1 };
3110 yyjson_mut_val *arr = yyjson_mut_arr_with_sint16(doc, vals, 3);
3111 @endcode
3112 */
3114 yyjson_mut_doc *doc, const int16_t *vals, size_t count);
3115
3116/**
3117 Creates and returns a new mutable array with the given int32 numbers.
3118
3119 @param doc A mutable document, used for memory allocation only.
3120 If `doc` is NULL, returns NULL.
3121 @param vals A C array of int32 numbers.
3122 @param count The number count. If this value is 0, an empty array is returned.
3123 @return The new array. NULL if arguments are invalid or allocation fails.
3124
3125 @b Example
3126 @code
3127 const int32_t vals[3] = { -1, 0, 1 };
3128 yyjson_mut_val *arr = yyjson_mut_arr_with_sint32(doc, vals, 3);
3129 @endcode
3130 */
3132 yyjson_mut_doc *doc, const int32_t *vals, size_t count);
3133
3134/**
3135 Creates and returns a new mutable array with the given int64 numbers.
3136
3137 @param doc A mutable document, used for memory allocation only.
3138 If `doc` is NULL, returns NULL.
3139 @param vals A C array of int64 numbers.
3140 @param count The number count. If this value is 0, an empty array is returned.
3141 @return The new array. NULL if arguments are invalid or allocation fails.
3142
3143 @b Example
3144 @code
3145 const int64_t vals[3] = { -1, 0, 1 };
3146 yyjson_mut_val *arr = yyjson_mut_arr_with_sint64(doc, vals, 3);
3147 @endcode
3148 */
3150 yyjson_mut_doc *doc, const int64_t *vals, size_t count);
3151
3152/**
3153 Creates and returns a new mutable array with the given uint8 numbers.
3154
3155 @param doc A mutable document, used for memory allocation only.
3156 If `doc` is NULL, returns NULL.
3157 @param vals A C array of uint8 numbers.
3158 @param count The number count. If this value is 0, an empty array is returned.
3159 @return The new array. NULL if arguments are invalid or allocation fails.
3160
3161 @b Example
3162 @code
3163 const uint8_t vals[3] = { 0, 1, 0 };
3164 yyjson_mut_val *arr = yyjson_mut_arr_with_uint8(doc, vals, 3);
3165 @endcode
3166 */
3168 yyjson_mut_doc *doc, const uint8_t *vals, size_t count);
3169
3170/**
3171 Creates and returns a new mutable array with the given uint16 numbers.
3172
3173 @param doc A mutable document, used for memory allocation only.
3174 If `doc` is NULL, returns NULL.
3175 @param vals A C array of uint16 numbers.
3176 @param count The number count. If this value is 0, an empty array is returned.
3177 @return The new array. NULL if arguments are invalid or allocation fails.
3178
3179 @b Example
3180 @code
3181 const uint16_t vals[3] = { 0, 1, 0 };
3182 yyjson_mut_val *arr = yyjson_mut_arr_with_uint16(doc, vals, 3);
3183 @endcode
3184 */
3186 yyjson_mut_doc *doc, const uint16_t *vals, size_t count);
3187
3188/**
3189 Creates and returns a new mutable array with the given uint32 numbers.
3190
3191 @param doc A mutable document, used for memory allocation only.
3192 If `doc` is NULL, returns NULL.
3193 @param vals A C array of uint32 numbers.
3194 @param count The number count. If this value is 0, an empty array is returned.
3195 @return The new array. NULL if arguments are invalid or allocation fails.
3196
3197 @b Example
3198 @code
3199 const uint32_t vals[3] = { 0, 1, 0 };
3200 yyjson_mut_val *arr = yyjson_mut_arr_with_uint32(doc, vals, 3);
3201 @endcode
3202 */
3204 yyjson_mut_doc *doc, const uint32_t *vals, size_t count);
3205
3206/**
3207 Creates and returns a new mutable array with the given uint64 numbers.
3208
3209 @param doc A mutable document, used for memory allocation only.
3210 If `doc` is NULL, returns NULL.
3211 @param vals A C array of uint64 numbers.
3212 @param count The number count. If this value is 0, an empty array is returned.
3213 @return The new array. NULL if arguments are invalid or allocation fails.
3214
3215 @b Example
3216 @code
3217 const uint64_t vals[3] = { 0, 1, 0 };
3218 yyjson_mut_val *arr = yyjson_mut_arr_with_uint64(doc, vals, 3);
3219 @endcode
3220 */
3222 yyjson_mut_doc *doc, const uint64_t *vals, size_t count);
3223
3224/**
3225 Creates and returns a new mutable array with the given float numbers.
3226
3227 @param doc A mutable document, used for memory allocation only.
3228 If `doc` is NULL, returns NULL.
3229 @param vals A C array of float numbers.
3230 @param count The number count. If this value is 0, an empty array is returned.
3231 @return The new array. NULL if arguments are invalid or allocation fails.
3232
3233 @b Example
3234 @code
3235 const float vals[3] = { -1.0f, 0.0f, 1.0f };
3236 yyjson_mut_val *arr = yyjson_mut_arr_with_float(doc, vals, 3);
3237 @endcode
3238 */
3240 yyjson_mut_doc *doc, const float *vals, size_t count);
3241
3242/**
3243 Creates and returns a new mutable array with the given double numbers.
3244
3245 @param doc A mutable document, used for memory allocation only.
3246 If `doc` is NULL, returns NULL.
3247 @param vals A C array of double numbers.
3248 @param count The number count. If this value is 0, an empty array is returned.
3249 @return The new array. NULL if arguments are invalid or allocation fails.
3250
3251 @b Example
3252 @code
3253 const double vals[3] = { -1.0, 0.0, 1.0 };
3254 yyjson_mut_val *arr = yyjson_mut_arr_with_double(doc, vals, 3);
3255 @endcode
3256 */
3258 yyjson_mut_doc *doc, const double *vals, size_t count);
3259
3260/**
3261 Creates and returns a new mutable array with the given strings, these strings
3262 will not be copied.
3263
3264 @param doc A mutable document, used for memory allocation only.
3265 If `doc` is NULL, returns NULL.
3266 @param vals A C array of UTF-8 null-terminator strings.
3267 If `vals` contains NULL, returns NULL.
3268 @param count The number of values in `vals`.
3269 If this value is 0, an empty array is returned.
3270 @return The new array. NULL if arguments are invalid or allocation fails.
3271
3272 @warning The input strings are not copied, you should keep these strings
3273 unmodified for the lifetime of this JSON document. If these strings will be
3274 modified, you should use `yyjson_mut_arr_with_strcpy()` instead.
3275
3276 @b Example
3277 @code
3278 const char *vals[3] = { "a", "b", "c" };
3279 yyjson_mut_val *arr = yyjson_mut_arr_with_str(doc, vals, 3);
3280 @endcode
3281 */
3283 yyjson_mut_doc *doc, const char **vals, size_t count);
3284
3285/**
3286 Creates and returns a new mutable array with the given strings and string
3287 lengths, these strings will not be copied.
3288
3289 @param doc A mutable document, used for memory allocation only.
3290 If `doc` is NULL, returns NULL.
3291 @param vals A C array of UTF-8 strings, null-terminator is not required.
3292 If `vals` contains NULL, returns NULL.
3293 @param lens A C array of string lengths, in bytes.
3294 @param count The number of strings in `vals`.
3295 If this value is 0, an empty array is returned.
3296 @return The new array. NULL if arguments are invalid or allocation fails.
3297
3298 @warning The input strings are not copied, you should keep these strings
3299 unmodified for the lifetime of this JSON document. If these strings will be
3300 modified, you should use `yyjson_mut_arr_with_strncpy()` instead.
3301
3302 @b Example
3303 @code
3304 const char *vals[3] = { "a", "bb", "c" };
3305 const size_t lens[3] = { 1, 2, 1 };
3306 yyjson_mut_val *arr = yyjson_mut_arr_with_strn(doc, vals, lens, 3);
3307 @endcode
3308 */
3310 yyjson_mut_doc *doc, const char **vals, const size_t *lens, size_t count);
3311
3312/**
3313 Creates and returns a new mutable array with the given strings, these strings
3314 will be copied.
3315
3316 @param doc A mutable document, used for memory allocation only.
3317 If `doc` is NULL, returns NULL.
3318 @param vals A C array of UTF-8 null-terminator strings.
3319 If `vals` contains NULL, returns NULL.
3320 @param count The number of values in `vals`.
3321 If this value is 0, an empty array is returned.
3322 @return The new array. NULL if arguments are invalid or allocation fails.
3323
3324 @b Example
3325 @code
3326 const char *vals[3] = { "a", "b", "c" };
3327 yyjson_mut_val *arr = yyjson_mut_arr_with_strcpy(doc, vals, 3);
3328 @endcode
3329 */
3331 yyjson_mut_doc *doc, const char **vals, size_t count);
3332
3333/**
3334 Creates and returns a new mutable array with the given strings and string
3335 lengths, these strings will be copied.
3336
3337 @param doc A mutable document, used for memory allocation only.
3338 If `doc` is NULL, returns NULL.
3339 @param vals A C array of UTF-8 strings, null-terminator is not required.
3340 If `vals` contains NULL, returns NULL.
3341 @param lens A C array of string lengths, in bytes.
3342 @param count The number of strings in `vals`.
3343 If this value is 0, an empty array is returned.
3344 @return The new array. NULL if arguments are invalid or allocation fails.
3345
3346 @b Example
3347 @code
3348 const char *vals[3] = { "a", "bb", "c" };
3349 const size_t lens[3] = { 1, 2, 1 };
3350 yyjson_mut_val *arr = yyjson_mut_arr_with_strn(doc, vals, lens, 3);
3351 @endcode
3352 */
3354 yyjson_mut_doc *doc, const char **vals, const size_t *lens, size_t count);
3355
3356
3357
3358/*==============================================================================
3359 * MARK: - Mutable JSON Array Modification API
3360 *============================================================================*/
3361
3362/**
3363 Inserts a value into an array at a given index.
3364 @param arr The array to which the value is to be inserted.
3365 Returns false if it is NULL or not an array.
3366 @param val The value to be inserted. Returns false if it is NULL.
3367 @param idx The index to which to insert the new value.
3368 Returns false if the index is out of range.
3369 @return Whether the operation was successful.
3370 @warning This function takes a linear search time.
3371 */
3373 yyjson_mut_val *val, size_t idx);
3374
3375/**
3376 Inserts a value at the end of the array.
3377 @param arr The array to which the value is to be inserted.
3378 Returns false if it is NULL or not an array.
3379 @param val The value to be inserted. Returns false if it is NULL.
3380 @return Whether the operation was successful.
3381 */
3383 yyjson_mut_val *val);
3384
3385/**
3386 Inserts a value at the head of the array.
3387 @param arr The array to which the value is to be inserted.
3388 Returns false if it is NULL or not an array.
3389 @param val The value to be inserted. Returns false if it is NULL.
3390 @return Whether successful.
3391 */
3393 yyjson_mut_val *val);
3394
3395/**
3396 Replaces a value at index and returns old value.
3397 @param arr The array to which the value is to be replaced.
3398 Returns false if it is NULL or not an array.
3399 @param idx The index to which to replace the value.
3400 Returns false if the index is out of range.
3401 @param val The new value to replace. Returns false if it is NULL.
3402 @return Old value, or NULL on error.
3403 @warning This function takes a linear search time.
3404 */
3406 size_t idx,
3407 yyjson_mut_val *val);
3408
3409/**
3410 Removes and returns a value at index.
3411 @param arr The array from which the value is to be removed.
3412 Returns false if it is NULL or not an array.
3413 @param idx The index from which to remove the value.
3414 Returns false if the index is out of range.
3415 @return Old value, or NULL on error.
3416 @warning This function takes a linear search time.
3417 */
3419 size_t idx);
3420
3421/**
3422 Removes and returns the first value in this array.
3423 @param arr The array from which the value is to be removed.
3424 Returns false if it is NULL or not an array.
3425 @return The first value, or NULL on error.
3426 */
3428 yyjson_mut_val *arr);
3429
3430/**
3431 Removes and returns the last value in this array.
3432 @param arr The array from which the value is to be removed.
3433 Returns false if it is NULL or not an array.
3434 @return The last value, or NULL on error.
3435 */
3437 yyjson_mut_val *arr);
3438
3439/**
3440 Removes all values within a specified range in the array.
3441 @param arr The array from which the value is to be removed.
3442 Returns false if it is NULL or not an array.
3443 @param idx The start index of the range (0 is the first).
3444 @param len The number of items in the range (can be 0).
3445 @return Whether the operation was successful.
3446 @warning This function takes a linear search time.
3447 */
3449 size_t idx, size_t len);
3450
3451/**
3452 Removes all values in this array.
3453 @param arr The array from which all of the values are to be removed.
3454 Returns false if it is NULL or not an array.
3455 @return Whether the operation was successful.
3456 */
3458
3459/**
3460 Rotates values in this array for the given number of times.
3461 For example: `[1,2,3,4,5]` rotate 2 is `[3,4,5,1,2]`.
3462 @param arr The array to be rotated.
3463 @param idx Index (or times) to rotate.
3464 @warning This function takes a linear search time.
3465 */
3467 size_t idx);
3468
3469
3470
3471/*==============================================================================
3472 * MARK: - Mutable JSON Array Modification Convenience API
3473 *============================================================================*/
3474
3475/**
3476 Adds a value at the end of the array.
3477 @param arr The array to which the value is to be inserted.
3478 Returns false if it is NULL or not an array.
3479 @param val The value to be inserted. Returns false if it is NULL.
3480 @return Whether the operation was successful.
3481 */
3483 yyjson_mut_val *val);
3484
3485/**
3486 Adds a `null` value at the end of the array.
3487 @param doc The `doc` is only used for memory allocation.
3488 @param arr The array to which the value is to be inserted.
3489 Returns false if it is NULL or not an array.
3490 @return Whether the operation was successful.
3491 */
3493 yyjson_mut_val *arr);
3494
3495/**
3496 Adds a `true` value at the end of the array.
3497 @param doc The `doc` is only used for memory allocation.
3498 @param arr The array to which the value is to be inserted.
3499 Returns false if it is NULL or not an array.
3500 @return Whether the operation was successful.
3501 */
3503 yyjson_mut_val *arr);
3504
3505/**
3506 Adds a `false` value at the end of the array.
3507 @param doc The `doc` is only used for memory allocation.
3508 @param arr The array to which the value is to be inserted.
3509 Returns false if it is NULL or not an array.
3510 @return Whether the operation was successful.
3511 */
3513 yyjson_mut_val *arr);
3514
3515/**
3516 Adds a bool value at the end of the array.
3517 @param doc The `doc` is only used for memory allocation.
3518 @param arr The array to which the value is to be inserted.
3519 Returns false if it is NULL or not an array.
3520 @param val The bool value to be added.
3521 @return Whether the operation was successful.
3522 */
3524 yyjson_mut_val *arr,
3525 bool val);
3526
3527/**
3528 Adds an unsigned integer value at the end of the array.
3529 @param doc The `doc` is only used for memory allocation.
3530 @param arr The array to which the value is to be inserted.
3531 Returns false if it is NULL or not an array.
3532 @param num The number to be added.
3533 @return Whether the operation was successful.
3534 */
3536 yyjson_mut_val *arr,
3537 uint64_t num);
3538
3539/**
3540 Adds a signed integer value at the end of the array.
3541 @param doc The `doc` is only used for memory allocation.
3542 @param arr The array to which the value is to be inserted.
3543 Returns false if it is NULL or not an array.
3544 @param num The number to be added.
3545 @return Whether the operation was successful.
3546 */
3548 yyjson_mut_val *arr,
3549 int64_t num);
3550
3551/**
3552 Adds an integer value at the end of the array.
3553 @param doc The `doc` is only used for memory allocation.
3554 @param arr The array to which the value is to be inserted.
3555 Returns false if it is NULL or not an array.
3556 @param num The number to be added.
3557 @return Whether the operation was successful.
3558 */
3560 yyjson_mut_val *arr,
3561 int64_t num);
3562
3563/**
3564 Adds a float value at the end of the array.
3565 @param doc The `doc` is only used for memory allocation.
3566 @param arr The array to which the value is to be inserted.
3567 Returns false if it is NULL or not an array.
3568 @param num The number to be added.
3569 @return Whether the operation was successful.
3570 */
3572 yyjson_mut_val *arr,
3573 float num);
3574
3575/**
3576 Adds a double value at the end of the array.
3577 @param doc The `doc` is only used for memory allocation.
3578 @param arr The array to which the value is to be inserted.
3579 Returns false if it is NULL or not an array.
3580 @param num The number to be added.
3581 @return Whether the operation was successful.
3582 */
3584 yyjson_mut_val *arr,
3585 double num);
3586
3587/**
3588 Adds a double value at the end of the array.
3589 @param doc The `doc` is only used for memory allocation.
3590 @param arr The array to which the value is to be inserted.
3591 Returns false if it is NULL or not an array.
3592 @param num The number to be added.
3593 @return Whether the operation was successful.
3594 */
3596 yyjson_mut_val *arr,
3597 double num);
3598
3599/**
3600 Adds a string value at the end of the array (no copy).
3601 @param doc The `doc` is only used for memory allocation.
3602 @param arr The array to which the value is to be inserted.
3603 Returns false if it is NULL or not an array.
3604 @param str A null-terminated UTF-8 string.
3605 @return Whether the operation was successful.
3606 @warning The input string is not copied, you should keep this string unmodified
3607 for the lifetime of this JSON document.
3608 */
3610 yyjson_mut_val *arr,
3611 const char *str);
3612
3613/**
3614 Adds a string value at the end of the array (no copy).
3615 @param doc The `doc` is only used for memory allocation.
3616 @param arr The array to which the value is to be inserted.
3617 Returns false if it is NULL or not an array.
3618 @param str A UTF-8 string, null-terminator is not required.
3619 @param len The length of the string, in bytes.
3620 @return Whether the operation was successful.
3621 @warning The input string is not copied, you should keep this string unmodified
3622 for the lifetime of this JSON document.
3623 */
3625 yyjson_mut_val *arr,
3626 const char *str,
3627 size_t len);
3628
3629/**
3630 Adds a string value at the end of the array (copied).
3631 @param doc The `doc` is only used for memory allocation.
3632 @param arr The array to which the value is to be inserted.
3633 Returns false if it is NULL or not an array.
3634 @param str A null-terminated UTF-8 string.
3635 @return Whether the operation was successful.
3636 */
3638 yyjson_mut_val *arr,
3639 const char *str);
3640
3641/**
3642 Adds a string value at the end of the array (copied).
3643 @param doc The `doc` is only used for memory allocation.
3644 @param arr The array to which the value is to be inserted.
3645 Returns false if it is NULL or not an array.
3646 @param str A UTF-8 string, null-terminator is not required.
3647 @param len The length of the string, in bytes.
3648 @return Whether the operation was successful.
3649 */
3651 yyjson_mut_val *arr,
3652 const char *str,
3653 size_t len);
3654
3655/**
3656 Creates and adds a new array at the end of the array.
3657 @param doc The `doc` is only used for memory allocation.
3658 @param arr The array to which the value is to be inserted.
3659 Returns false if it is NULL or not an array.
3660 @return The new array, or NULL on error.
3661 */
3663 yyjson_mut_val *arr);
3664
3665/**
3666 Creates and adds a new object at the end of the array.
3667 @param doc The `doc` is only used for memory allocation.
3668 @param arr The array to which the value is to be inserted.
3669 Returns false if it is NULL or not an array.
3670 @return The new object, or NULL on error.
3671 */
3673 yyjson_mut_val *arr);
3674
3675
3676
3677/*==============================================================================
3678 * MARK: - Mutable JSON Object API
3679 *============================================================================*/
3680
3681/** Returns the number of key-value pairs in this object.
3682 Returns 0 if `obj` is NULL or type is not object. */
3684
3685/** Returns the value to which the specified key is mapped.
3686 Returns NULL if this object contains no mapping for the key.
3687 Returns NULL if `obj/key` is NULL, or type is not object.
3688
3689 The `key` should be a null-terminated UTF-8 string.
3690
3691 @warning This function takes a linear search time. */
3693 const char *key);
3694
3695/** Returns the value to which the specified key is mapped.
3696 Returns NULL if this object contains no mapping for the key.
3697 Returns NULL if `obj/key` is NULL, or type is not object.
3698
3699 The `key` should be a UTF-8 string, null-terminator is not required.
3700 The `key_len` should be the length of the key, in bytes.
3701
3702 @warning This function takes a linear search time. */
3704 const char *key,
3705 size_t key_len);
3706
3707
3708
3709/*==============================================================================
3710 * MARK: - Mutable JSON Object Iterator API
3711 *============================================================================*/
3712
3713/**
3714 A mutable JSON object iterator.
3715
3716 @warning You should not modify the object while iterating over it, but you can
3717 use `yyjson_mut_obj_iter_remove()` to remove current value.
3718
3719 @b Example
3720 @code
3721 yyjson_mut_val *key, *val;
3722 yyjson_mut_obj_iter iter = yyjson_mut_obj_iter_with(obj);
3723 while ((key = yyjson_mut_obj_iter_next(&iter))) {
3724 val = yyjson_mut_obj_iter_get_val(key);
3725 your_func(key, val);
3726 if (your_val_is_unused(key, val)) {
3727 yyjson_mut_obj_iter_remove(&iter);
3728 }
3729 }
3730 @endcode
3731
3732 If the ordering of the keys is known at compile-time, you can use this method
3733 to speed up value lookups:
3734 @code
3735 // {"k1":1, "k2": 3, "k3": 3}
3736 yyjson_mut_val *key, *val;
3737 yyjson_mut_obj_iter iter = yyjson_mut_obj_iter_with(obj);
3738 yyjson_mut_val *v1 = yyjson_mut_obj_iter_get(&iter, "k1");
3739 yyjson_mut_val *v3 = yyjson_mut_obj_iter_get(&iter, "k3");
3740 @endcode
3741 @see `yyjson_mut_obj_iter_get()` and `yyjson_mut_obj_iter_getn()`
3742 */
3743typedef struct yyjson_mut_obj_iter {
3744 size_t idx; /**< next key's index */
3745 size_t max; /**< maximum key index (obj.size) */
3746 yyjson_mut_val *cur; /**< current key */
3747 yyjson_mut_val *pre; /**< previous key */
3748 yyjson_mut_val *obj; /**< the object being iterated */
3750
3751/**
3752 Initialize an iterator for this object.
3753
3754 @param obj The object to be iterated over.
3755 If `obj` is NULL or not an object, `iter` is cleared.
3756 @param iter The iterator to be initialized.
3757 If `iter` is NULL, returns false.
3758 @return true if the `iter` has been successfully initialized.
3759
3760 @note The iterator does not need to be destroyed.
3761 */
3763 yyjson_mut_obj_iter *iter);
3764
3765/**
3766 Create an iterator with an object, same as `yyjson_mut_obj_iter_init()`.
3767
3768 @param obj The object to be iterated over.
3769 If `obj` is NULL or not an object, returns an empty iterator.
3770 @return A new iterator for the object.
3771
3772 @note The iterator does not need to be destroyed.
3773 */
3775 yyjson_mut_val *obj);
3776
3777/**
3778 Returns whether the iteration has more elements.
3779 If `iter` is NULL, returns false.
3780 */
3782 yyjson_mut_obj_iter *iter);
3783
3784/**
3785 Returns the next key in the iteration, or NULL on end.
3786 If `iter` is NULL, returns NULL.
3787 */
3789 yyjson_mut_obj_iter *iter);
3790
3791/**
3792 Returns the value for key inside the iteration.
3793 If `iter` is NULL, returns NULL.
3794 */
3796 yyjson_mut_val *key);
3797
3798/**
3799 Removes current key-value pair in the iteration, returns the removed value.
3800 If `iter` is NULL, returns NULL.
3801 */
3803 yyjson_mut_obj_iter *iter);
3804
3805/**
3806 Iterates to a specified key and returns the value.
3807
3808 This function does the same thing as `yyjson_mut_obj_get()`, but is much faster
3809 if the ordering of the keys is known at compile-time and you are using the same
3810 order to look up the values. If the key exists in this object, then the
3811 iterator will stop at the next key, otherwise the iterator will not change and
3812 NULL is returned.
3813
3814 @param iter The object iterator, should not be NULL.
3815 @param key The key, should be a UTF-8 string with null-terminator.
3816 @return The value to which the specified key is mapped.
3817 NULL if the key is not found or arguments are invalid.
3818
3819 @warning This function takes a linear search time if the key is not nearby.
3820 */
3822 yyjson_mut_obj_iter *iter, const char *key);
3823
3824/**
3825 Iterates to a specified key and returns the value.
3826
3827 This function does the same thing as `yyjson_mut_obj_getn()` but is much faster
3828 if the ordering of the keys is known at compile-time and you are using the same
3829 order to look up the values. If the key exists in this object, then the
3830 iterator will stop at the next key, otherwise the iterator will not change and
3831 NULL is returned.
3832
3833 @param iter The object iterator, should not be NULL.
3834 @param key The key, should be a UTF-8 string, null-terminator is not required.
3835 @param key_len The length of `key`, in bytes.
3836 @return The value to which the specified key is mapped.
3837 NULL if the key is not found or arguments are invalid.
3838
3839 @warning This function takes a linear search time if the key is not nearby.
3840 */
3842 yyjson_mut_obj_iter *iter, const char *key, size_t key_len);
3843
3844/**
3845 Macro for iterating over an object.
3846 It works like iterator, but with a more intuitive API.
3847
3848 @warning You should not modify the object while iterating over it.
3849
3850 @b Example
3851 @code
3852 size_t idx, max;
3853 yyjson_mut_val *key, *val;
3854 yyjson_mut_obj_foreach(obj, idx, max, key, val) {
3855 your_func(key, val);
3856 }
3857 @endcode
3858 */
3859#define yyjson_mut_obj_foreach(obj, idx, max, key, val) \
3860 for ((idx) = 0, \
3861 (max) = yyjson_mut_obj_size(obj), \
3862 (key) = (max) ? ((yyjson_mut_val *)(obj)->uni.ptr)->next->next : NULL, \
3863 (val) = (key) ? (key)->next : NULL; \
3864 (idx) < (max); \
3865 (idx)++, \
3866 (key) = (val)->next, \
3867 (val) = (key)->next)
3868
3869
3870
3871/*==============================================================================
3872 * MARK: - Mutable JSON Object Creation API
3873 *============================================================================*/
3874
3875/** Creates and returns a mutable object, returns NULL on error. */
3877
3878/**
3879 Creates and returns a mutable object with keys and values, returns NULL on
3880 error. The keys and values are not copied. They should be null-terminated
3881 UTF-8 strings.
3882
3883 @warning The input strings are not copied; you should keep them
3884 unmodified for the lifetime of this JSON document.
3885
3886 @b Example
3887 @code
3888 const char *keys[2] = { "id", "name" };
3889 const char *vals[2] = { "01", "Harry" };
3890 yyjson_mut_val *obj = yyjson_mut_obj_with_str(doc, keys, vals, 2);
3891 @endcode
3892 */
3894 const char **keys,
3895 const char **vals,
3896 size_t count);
3897
3898/**
3899 Creates and returns a mutable object with key-value pairs and pair count,
3900 returns NULL on error. The keys and values are not copied. They should be
3901 null-terminated UTF-8 strings.
3902
3903 @warning The input strings are not copied; you should keep them
3904 unmodified for the lifetime of this JSON document.
3905
3906 @b Example
3907 @code
3908 const char *kv_pairs[4] = { "id", "01", "name", "Harry" };
3909 yyjson_mut_val *obj = yyjson_mut_obj_with_kv(doc, kv_pairs, 2);
3910 @endcode
3911 */
3913 const char **kv_pairs,
3914 size_t pair_count);
3915
3916
3917
3918/*==============================================================================
3919 * MARK: - Mutable JSON Object Modification API
3920 *============================================================================*/
3921
3922/**
3923 Adds a key-value pair at the end of the object.
3924 This function allows duplicate keys in one object.
3925 @param obj The object to which the new key-value pair is to be added.
3926 @param key The key, should be a string which is created by `yyjson_mut_str()`,
3927 `yyjson_mut_strn()`, `yyjson_mut_strcpy()` or `yyjson_mut_strncpy()`.
3928 @param val The value to add to the object.
3929 @return Whether the operation was successful.
3930 */
3932 yyjson_mut_val *key,
3933 yyjson_mut_val *val);
3934/**
3935 Sets a key-value pair at the end of the object.
3936 This function may remove all key-value pairs for the given key before adding.
3937 @param obj The object to which the new key-value pair is to be added.
3938 @param key The key, should be a string which is created by `yyjson_mut_str()`,
3939 `yyjson_mut_strn()`, `yyjson_mut_strcpy()` or `yyjson_mut_strncpy()`.
3940 @param val The value to add to the object. If this value is null, the behavior
3941 is the same as `yyjson_mut_obj_remove()`.
3942 @return Whether the operation was successful.
3943 */
3945 yyjson_mut_val *key,
3946 yyjson_mut_val *val);
3947
3948/**
3949 Inserts a key-value pair to the object at the given position.
3950 This function allows duplicate keys in one object.
3951 @param obj The object to which the new key-value pair is to be added.
3952 @param key The key, should be a string which is created by `yyjson_mut_str()`,
3953 `yyjson_mut_strn()`, `yyjson_mut_strcpy()` or `yyjson_mut_strncpy()`.
3954 @param val The value to add to the object.
3955 @param idx The index to which to insert the new pair.
3956 @return Whether the operation was successful.
3957 */
3959 yyjson_mut_val *key,
3960 yyjson_mut_val *val,
3961 size_t idx);
3962
3963/**
3964 Removes all key-value pairs from the object with the given key.
3965 @param obj The object from which the key-value pair is to be removed.
3966 @param key The key, should be a string value.
3967 @return The first matched value, or NULL if no matched value.
3968 @warning This function takes a linear search time.
3969 */
3971 yyjson_mut_val *key);
3972
3973/**
3974 Removes all key-value pairs from the object with the given key.
3975 @param obj The object from which the key-value pair is to be removed.
3976 @param key The key, should be a UTF-8 string with null-terminator.
3977 @return The first matched value, or NULL if no matched value.
3978 @warning This function takes a linear search time.
3979 */
3981 yyjson_mut_val *obj, const char *key);
3982
3983/**
3984 Removes all key-value pairs from the object with the given key.
3985 @param obj The object from which the key-value pair is to be removed.
3986 @param key The key, should be a UTF-8 string, null-terminator is not required.
3987 @param key_len The length of the key.
3988 @return The first matched value, or NULL if no matched value.
3989 @warning This function takes a linear search time.
3990 */
3992 yyjson_mut_val *obj, const char *key, size_t key_len);
3993
3994/**
3995 Removes all key-value pairs in this object.
3996 @param obj The object from which all of the values are to be removed.
3997 @return Whether the operation was successful.
3998 */
4000
4001/**
4002 Replaces value from the object with given key.
4003 If the key does not exist, or the value is NULL, it will fail.
4004 @param obj The object to which the value is to be replaced.
4005 @param key The key, should be a string value.
4006 @param val The value to replace into the object.
4007 @return Whether the operation was successful.
4008 @warning This function takes a linear search time.
4009 */
4011 yyjson_mut_val *key,
4012 yyjson_mut_val *val);
4013
4014/**
4015 Rotates key-value pairs in the object for the given number of times.
4016 For example: `{"a":1,"b":2,"c":3,"d":4}` rotate 1 is
4017 `{"b":2,"c":3,"d":4,"a":1}`.
4018 @param obj The object to be rotated.
4019 @param idx Index (or times) to rotate.
4020 @return Whether the operation was successful.
4021 @warning This function takes a linear search time.
4022 */
4024 size_t idx);
4025
4026
4027
4028/*==============================================================================
4029 * MARK: - Mutable JSON Object Modification Convenience API
4030 *============================================================================*/
4031
4032/** Adds a `null` value at the end of the object.
4033 The `key` should be a null-terminated UTF-8 string.
4034 This function allows duplicate keys in one object.
4035
4036 @warning The key string is not copied, you should keep the string
4037 unmodified for the lifetime of this JSON document. */
4039 yyjson_mut_val *obj,
4040 const char *key);
4041
4042/** Adds a `true` value at the end of the object.
4043 The `key` should be a null-terminated UTF-8 string.
4044 This function allows duplicate keys in one object.
4045
4046 @warning The key string is not copied, you should keep the string
4047 unmodified for the lifetime of this JSON document. */
4049 yyjson_mut_val *obj,
4050 const char *key);
4051
4052/** Adds a `false` value at the end of the object.
4053 The `key` should be a null-terminated UTF-8 string.
4054 This function allows duplicate keys in one object.
4055
4056 @warning The key string is not copied, you should keep the string
4057 unmodified for the lifetime of this JSON document. */
4059 yyjson_mut_val *obj,
4060 const char *key);
4061
4062/** Adds a bool value at the end of the object.
4063 The `key` should be a null-terminated UTF-8 string.
4064 This function allows duplicate keys in one object.
4065
4066 @warning The key string is not copied, you should keep the string
4067 unmodified for the lifetime of this JSON document. */
4069 yyjson_mut_val *obj,
4070 const char *key, bool val);
4071
4072/** Adds an unsigned integer value at the end of the object.
4073 The `key` should be a null-terminated UTF-8 string.
4074 This function allows duplicate keys in one object.
4075
4076 @warning The key string is not copied, you should keep the string
4077 unmodified for the lifetime of this JSON document. */
4079 yyjson_mut_val *obj,
4080 const char *key, uint64_t val);
4081
4082/** Adds a signed integer value at the end of the object.
4083 The `key` should be a null-terminated UTF-8 string.
4084 This function allows duplicate keys in one object.
4085
4086 @warning The key string is not copied, you should keep the string
4087 unmodified for the lifetime of this JSON document. */
4089 yyjson_mut_val *obj,
4090 const char *key, int64_t val);
4091
4092/** Adds an int value at the end of the object.
4093 The `key` should be a null-terminated UTF-8 string.
4094 This function allows duplicate keys in one object.
4095
4096 @warning The key string is not copied, you should keep the string
4097 unmodified for the lifetime of this JSON document. */
4099 yyjson_mut_val *obj,
4100 const char *key, int64_t val);
4101
4102/** Adds a float value at the end of the object.
4103 The `key` should be a null-terminated UTF-8 string.
4104 This function allows duplicate keys in one object.
4105
4106 @warning The key string is not copied, you should keep the string
4107 unmodified for the lifetime of this JSON document. */
4109 yyjson_mut_val *obj,
4110 const char *key, float val);
4111
4112/** Adds a double value at the end of the object.
4113 The `key` should be a null-terminated UTF-8 string.
4114 This function allows duplicate keys in one object.
4115
4116 @warning The key string is not copied, you should keep the string
4117 unmodified for the lifetime of this JSON document. */
4119 yyjson_mut_val *obj,
4120 const char *key, double val);
4121
4122/** Adds a real value at the end of the object.
4123 The `key` should be a null-terminated UTF-8 string.
4124 This function allows duplicate keys in one object.
4125
4126 @warning The key string is not copied, you should keep the string
4127 unmodified for the lifetime of this JSON document. */
4129 yyjson_mut_val *obj,
4130 const char *key, double val);
4131
4132/** Adds a string value at the end of the object.
4133 The `key` and `val` should be null-terminated UTF-8 strings.
4134 This function allows duplicate keys in one object.
4135
4136 @warning The key/value strings are not copied, you should keep these strings
4137 unmodified for the lifetime of this JSON document. */
4139 yyjson_mut_val *obj,
4140 const char *key, const char *val);
4141
4142/** Adds a string value at the end of the object.
4143 The `key` should be a null-terminated UTF-8 string.
4144 The `val` should be a UTF-8 string, null-terminator is not required.
4145 The `len` should be the length of the `val`, in bytes.
4146 This function allows duplicate keys in one object.
4147
4148 @warning The key/value strings are not copied, you should keep these strings
4149 unmodified for the lifetime of this JSON document. */
4151 yyjson_mut_val *obj,
4152 const char *key,
4153 const char *val, size_t len);
4154
4155/** Adds a string value at the end of the object.
4156 The `key` and `val` should be null-terminated UTF-8 strings.
4157 The value string is copied.
4158 This function allows duplicate keys in one object.
4159
4160 @warning The key string is not copied, you should keep the string
4161 unmodified for the lifetime of this JSON document. */
4163 yyjson_mut_val *obj,
4164 const char *key,
4165 const char *val);
4166
4167/** Adds a string value at the end of the object.
4168 The `key` should be a null-terminated UTF-8 string.
4169 The `val` should be a UTF-8 string, null-terminator is not required.
4170 The `len` should be the length of the `val`, in bytes.
4171 This function allows duplicate keys in one object.
4172
4173 @warning The key strings are not copied, you should keep these strings
4174 unmodified for the lifetime of this JSON document. */
4176 yyjson_mut_val *obj,
4177 const char *key,
4178 const char *val, size_t len);
4179
4180/**
4181 Creates and adds a new array to the target object.
4182 The `key` should be a null-terminated UTF-8 string.
4183 This function allows duplicate keys in one object.
4184
4185 @warning The key string is not copied, you should keep these strings
4186 unmodified for the lifetime of this JSON document.
4187 @return The new array, or NULL on error.
4188 */
4190 yyjson_mut_val *obj,
4191 const char *key);
4192
4193/**
4194 Creates and adds a new object to the target object.
4195 The `key` should be a null-terminated UTF-8 string.
4196 This function allows duplicate keys in one object.
4197
4198 @warning The key string is not copied, you should keep these strings
4199 unmodified for the lifetime of this JSON document.
4200 @return The new object, or NULL on error.
4201 */
4203 yyjson_mut_val *obj,
4204 const char *key);
4205
4206/** Adds a JSON value at the end of the object.
4207 The `key` should be a null-terminated UTF-8 string.
4208 This function allows duplicate keys in one object.
4209
4210 @warning The key string is not copied, you should keep the string
4211 unmodified for the lifetime of this JSON document. */
4213 yyjson_mut_val *obj,
4214 const char *key,
4215 yyjson_mut_val *val);
4216
4217/** Removes all key-value pairs for the given key.
4218 Returns the first value to which the specified key is mapped or NULL if this
4219 object contains no mapping for the key.
4220 The `key` should be a null-terminated UTF-8 string.
4221
4222 @warning This function takes a linear search time. */
4224 yyjson_mut_val *obj, const char *key);
4225
4226/** Removes all key-value pairs for the given key.
4227 Returns the first value to which the specified key is mapped or NULL if this
4228 object contains no mapping for the key.
4229 The `key` should be a UTF-8 string, null-terminator is not required.
4230 The `len` should be the length of the key, in bytes.
4231
4232 @warning This function takes a linear search time. */
4234 yyjson_mut_val *obj, const char *key, size_t len);
4235
4236/** Replaces all matching keys with the new key.
4237 Returns true if at least one key was renamed.
4238 The `key` and `new_key` should be a null-terminated UTF-8 string.
4239 The `new_key` is copied and held by doc.
4240
4241 @warning This function takes a linear search time.
4242 If `new_key` already exists, it will cause duplicate keys.
4243 */
4245 yyjson_mut_val *obj,
4246 const char *key,
4247 const char *new_key);
4248
4249/** Replaces all matching keys with the new key.
4250 Returns true if at least one key was renamed.
4251 The `key` and `new_key` should be a UTF-8 string,
4252 null-terminator is not required. The `new_key` is copied and held by doc.
4253
4254 @warning This function takes a linear search time.
4255 If `new_key` already exists, it will cause duplicate keys.
4256 */
4258 yyjson_mut_val *obj,
4259 const char *key,
4260 size_t len,
4261 const char *new_key,
4262 size_t new_len);
4263
4264
4265
4266#if !defined(YYJSON_DISABLE_UTILS) || !YYJSON_DISABLE_UTILS
4267
4268/*==============================================================================
4269 * MARK: - JSON Pointer API (RFC 6901)
4270 * https://tools.ietf.org/html/rfc6901
4271 *============================================================================*/
4272
4273/** JSON Pointer error code. */
4274typedef uint32_t yyjson_ptr_code;
4275
4276/** No JSON pointer error. */
4278
4279/** Invalid input parameter, such as NULL input. */
4281
4282/** JSON pointer syntax error, such as invalid escape or missing prefix. */
4284
4285/** JSON pointer resolve failed, such as index out of range, key not found. */
4287
4288/** Document's root is NULL, but it is required for the function call. */
4290
4291/** Cannot set root as the target is not a document. */
4293
4294/** The memory allocation failed and a new value could not be created. */
4296
4297/** Error information for JSON pointer. */
4298typedef struct yyjson_ptr_err {
4299 /** Error code, see `yyjson_ptr_code` for all possible values. */
4301 /** Error message, constant, no need to free (NULL if no error). */
4302 const char *msg;
4303 /** Error byte position for input JSON pointer (0 if no error). */
4304 size_t pos;
4306
4307/**
4308 A context for JSON pointer operation.
4309
4310 This struct stores the context of JSON Pointer operation result. The struct
4311 can be used with three helper functions: `ctx_append()`, `ctx_replace()`, and
4312 `ctx_remove()`, which perform the corresponding operations on the container
4313 without re-parsing the JSON Pointer.
4314
4315 For example:
4316 @code
4317 // doc before: {"a":[0,1,null]}
4318 // ptr: "/a/2"
4319 val = yyjson_mut_doc_ptr_getx(doc, ptr, strlen(ptr), &ctx, &err);
4320 if (yyjson_is_null(val)) {
4321 yyjson_ptr_ctx_remove(&ctx);
4322 }
4323 // doc after: {"a":[0,1]}
4324 @endcode
4325 */
4326typedef struct yyjson_ptr_ctx {
4327 /**
4328 The container (parent) of the target value. It can be either an array or
4329 an object. If the target location has no value, but all its parent
4330 containers exist, and the target location can be used to insert a new
4331 value, then `ctn` is the parent container of the target location.
4332 Otherwise, `ctn` is NULL.
4333 */
4335 /**
4336 The previous sibling of the target value. It can be either a value in an
4337 array or a key in an object. As the container is a `circular linked list`
4338 of elements, `pre` is the previous node of the target value. If the
4339 operation is `add` or `set`, then `pre` is the previous node of the new
4340 value, not the original target value. If the target value does not exist,
4341 `pre` is NULL.
4342 */
4344 /**
4345 The removed value if the operation is `set`, `replace` or `remove`. It can
4346 be used to restore the original state of the document if needed.
4347 */
4350
4351/**
4352 Get value by a JSON Pointer.
4353 @param doc The JSON document to be queried.
4354 @param ptr The JSON pointer string (UTF-8 with null-terminator).
4355 @return The value referenced by the JSON pointer.
4356 NULL if `doc` or `ptr` is NULL, or the JSON pointer cannot be resolved.
4357 */
4359 const char *ptr);
4360
4361/**
4362 Get value by a JSON Pointer.
4363 @param doc The JSON document to be queried.
4364 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4365 @param len The length of `ptr` in bytes.
4366 @return The value referenced by the JSON pointer.
4367 NULL if `doc` or `ptr` is NULL, or the JSON pointer cannot be resolved.
4368 */
4370 const char *ptr, size_t len);
4371
4372/**
4373 Get value by a JSON Pointer.
4374 @param doc The JSON document to be queried.
4375 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4376 @param len The length of `ptr` in bytes.
4377 @param err A pointer to store the error information, or NULL if not needed.
4378 @return The value referenced by the JSON pointer.
4379 NULL if `doc` or `ptr` is NULL, or the JSON pointer cannot be resolved.
4380 */
4382 const char *ptr, size_t len,
4383 yyjson_ptr_err *err);
4384
4385/**
4386 Get value by a JSON Pointer.
4387 @param val The JSON value to be queried.
4388 @param ptr The JSON pointer string (UTF-8 with null-terminator).
4389 @return The value referenced by the JSON pointer.
4390 NULL if `val` or `ptr` is NULL, or the JSON pointer cannot be resolved.
4391 */
4393 const char *ptr);
4394
4395/**
4396 Get value by a JSON Pointer.
4397 @param val The JSON value to be queried.
4398 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4399 @param len The length of `ptr` in bytes.
4400 @return The value referenced by the JSON pointer.
4401 NULL if `val` or `ptr` is NULL, or the JSON pointer cannot be resolved.
4402 */
4404 const char *ptr, size_t len);
4405
4406/**
4407 Get value by a JSON Pointer.
4408 @param val The JSON value to be queried.
4409 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4410 @param len The length of `ptr` in bytes.
4411 @param err A pointer to store the error information, or NULL if not needed.
4412 @return The value referenced by the JSON pointer.
4413 NULL if `val` or `ptr` is NULL, or the JSON pointer cannot be resolved.
4414 */
4416 const char *ptr, size_t len,
4417 yyjson_ptr_err *err);
4418
4419/**
4420 Get value by a JSON Pointer.
4421 @param doc The JSON document to be queried.
4422 @param ptr The JSON pointer string (UTF-8 with null-terminator).
4423 @return The value referenced by the JSON pointer.
4424 NULL if `doc` or `ptr` is NULL, or the JSON pointer cannot be resolved.
4425 */
4427 const yyjson_mut_doc *doc, const char *ptr);
4428
4429/**
4430 Get value by a JSON Pointer.
4431 @param doc The JSON document to be queried.
4432 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4433 @param len The length of `ptr` in bytes.
4434 @return The value referenced by the JSON pointer.
4435 NULL if `doc` or `ptr` is NULL, or the JSON pointer cannot be resolved.
4436 */
4438 const yyjson_mut_doc *doc, const char *ptr, size_t len);
4439
4440/**
4441 Get value by a JSON Pointer.
4442 @param doc The JSON document to be queried.
4443 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4444 @param len The length of `ptr` in bytes.
4445 @param ctx A pointer to store the result context, or NULL if not needed.
4446 @param err A pointer to store the error information, or NULL if not needed.
4447 @return The value referenced by the JSON pointer.
4448 NULL if `doc` or `ptr` is NULL, or the JSON pointer cannot be resolved.
4449 */
4451 const yyjson_mut_doc *doc, const char *ptr, size_t len,
4452 yyjson_ptr_ctx *ctx, yyjson_ptr_err *err);
4453
4454/**
4455 Get value by a JSON Pointer.
4456 @param val The JSON value to be queried.
4457 @param ptr The JSON pointer string (UTF-8 with null-terminator).
4458 @return The value referenced by the JSON pointer.
4459 NULL if `val` or `ptr` is NULL, or the JSON pointer cannot be resolved.
4460 */
4462 const char *ptr);
4463
4464/**
4465 Get value by a JSON Pointer.
4466 @param val The JSON value to be queried.
4467 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4468 @param len The length of `ptr` in bytes.
4469 @return The value referenced by the JSON pointer.
4470 NULL if `val` or `ptr` is NULL, or the JSON pointer cannot be resolved.
4471 */
4473 const char *ptr,
4474 size_t len);
4475
4476/**
4477 Get value by a JSON Pointer.
4478 @param val The JSON value to be queried.
4479 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4480 @param len The length of `ptr` in bytes.
4481 @param ctx A pointer to store the result context, or NULL if not needed.
4482 @param err A pointer to store the error information, or NULL if not needed.
4483 @return The value referenced by the JSON pointer.
4484 NULL if `val` or `ptr` is NULL, or the JSON pointer cannot be resolved.
4485 */
4487 const char *ptr,
4488 size_t len,
4489 yyjson_ptr_ctx *ctx,
4490 yyjson_ptr_err *err);
4491
4492/**
4493 Add (insert) value by a JSON pointer.
4494 @param doc The target JSON document.
4495 @param ptr The JSON pointer string (UTF-8 with null-terminator).
4496 @param new_val The value to be added.
4497 @return true if JSON pointer is valid and new value is added, false otherwise.
4498 @note The parent nodes will be created if they do not exist.
4499 */
4501 const char *ptr,
4502 yyjson_mut_val *new_val);
4503
4504/**
4505 Add (insert) value by a JSON pointer.
4506 @param doc The target JSON document.
4507 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4508 @param len The length of `ptr` in bytes.
4509 @param new_val The value to be added.
4510 @return true if JSON pointer is valid and new value is added, false otherwise.
4511 @note The parent nodes will be created if they do not exist.
4512 */
4514 const char *ptr, size_t len,
4515 yyjson_mut_val *new_val);
4516
4517/**
4518 Add (insert) value by a JSON pointer.
4519 @param doc The target JSON document.
4520 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4521 @param len The length of `ptr` in bytes.
4522 @param new_val The value to be added.
4523 @param create_parent Whether to create parent nodes if they do not exist.
4524 @param ctx A pointer to store the result context, or NULL if not needed.
4525 @param err A pointer to store the error information, or NULL if not needed.
4526 @return true if JSON pointer is valid and new value is added, false otherwise.
4527 */
4529 const char *ptr, size_t len,
4530 yyjson_mut_val *new_val,
4531 bool create_parent,
4532 yyjson_ptr_ctx *ctx,
4533 yyjson_ptr_err *err);
4534
4535/**
4536 Add (insert) value by a JSON pointer.
4537 @param val The target JSON value.
4538 @param ptr The JSON pointer string (UTF-8 with null-terminator).
4539 @param doc Only used to create new values when needed.
4540 @param new_val The value to be added.
4541 @return true if JSON pointer is valid and new value is added, false otherwise.
4542 @note The parent nodes will be created if they do not exist.
4543 */
4545 const char *ptr,
4546 yyjson_mut_val *new_val,
4547 yyjson_mut_doc *doc);
4548
4549/**
4550 Add (insert) value by a JSON pointer.
4551 @param val The target JSON value.
4552 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4553 @param len The length of `ptr` in bytes.
4554 @param doc Only used to create new values when needed.
4555 @param new_val The value to be added.
4556 @return true if JSON pointer is valid and new value is added, false otherwise.
4557 @note The parent nodes will be created if they do not exist.
4558 */
4560 const char *ptr, size_t len,
4561 yyjson_mut_val *new_val,
4562 yyjson_mut_doc *doc);
4563
4564/**
4565 Add (insert) value by a JSON pointer.
4566 @param val The target JSON value.
4567 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4568 @param len The length of `ptr` in bytes.
4569 @param doc Only used to create new values when needed.
4570 @param new_val The value to be added.
4571 @param create_parent Whether to create parent nodes if they do not exist.
4572 @param ctx A pointer to store the result context, or NULL if not needed.
4573 @param err A pointer to store the error information, or NULL if not needed.
4574 @return true if JSON pointer is valid and new value is added, false otherwise.
4575 */
4577 const char *ptr, size_t len,
4578 yyjson_mut_val *new_val,
4579 yyjson_mut_doc *doc,
4580 bool create_parent,
4581 yyjson_ptr_ctx *ctx,
4582 yyjson_ptr_err *err);
4583
4584/**
4585 Set value by a JSON pointer.
4586 @param doc The target JSON document.
4587 @param ptr The JSON pointer string (UTF-8 with null-terminator).
4588 @param new_val The value to be set, pass NULL to remove.
4589 @return true if JSON pointer is valid and new value is set, false otherwise.
4590 @note The parent nodes will be created if they do not exist.
4591 If the target value already exists, it will be replaced by the new value.
4592 */
4594 const char *ptr,
4595 yyjson_mut_val *new_val);
4596
4597/**
4598 Set value by a JSON pointer.
4599 @param doc The target JSON document.
4600 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4601 @param len The length of `ptr` in bytes.
4602 @param new_val The value to be set, pass NULL to remove.
4603 @return true if JSON pointer is valid and new value is set, false otherwise.
4604 @note The parent nodes will be created if they do not exist.
4605 If the target value already exists, it will be replaced by the new value.
4606 */
4608 const char *ptr, size_t len,
4609 yyjson_mut_val *new_val);
4610
4611/**
4612 Set value by a JSON pointer.
4613 @param doc The target JSON document.
4614 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4615 @param len The length of `ptr` in bytes.
4616 @param new_val The value to be set, pass NULL to remove.
4617 @param create_parent Whether to create parent nodes if they do not exist.
4618 @param ctx A pointer to store the result context, or NULL if not needed.
4619 @param err A pointer to store the error information, or NULL if not needed.
4620 @return true if JSON pointer is valid and new value is set, false otherwise.
4621 @note If the target value already exists, it will be replaced by the new value.
4622 */
4624 const char *ptr, size_t len,
4625 yyjson_mut_val *new_val,
4626 bool create_parent,
4627 yyjson_ptr_ctx *ctx,
4628 yyjson_ptr_err *err);
4629
4630/**
4631 Set value by a JSON pointer.
4632 @param val The target JSON value.
4633 @param ptr The JSON pointer string (UTF-8 with null-terminator).
4634 @param new_val The value to be set, pass NULL to remove.
4635 @param doc Only used to create new values when needed.
4636 @return true if JSON pointer is valid and new value is set, false otherwise.
4637 @note The parent nodes will be created if they do not exist.
4638 If the target value already exists, it will be replaced by the new value.
4639 */
4641 const char *ptr,
4642 yyjson_mut_val *new_val,
4643 yyjson_mut_doc *doc);
4644
4645/**
4646 Set value by a JSON pointer.
4647 @param val The target JSON value.
4648 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4649 @param len The length of `ptr` in bytes.
4650 @param new_val The value to be set, pass NULL to remove.
4651 @param doc Only used to create new values when needed.
4652 @return true if JSON pointer is valid and new value is set, false otherwise.
4653 @note The parent nodes will be created if they do not exist.
4654 If the target value already exists, it will be replaced by the new value.
4655 */
4657 const char *ptr, size_t len,
4658 yyjson_mut_val *new_val,
4659 yyjson_mut_doc *doc);
4660
4661/**
4662 Set value by a JSON pointer.
4663 @param val The target JSON value.
4664 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4665 @param len The length of `ptr` in bytes.
4666 @param new_val The value to be set, pass NULL to remove.
4667 @param doc Only used to create new values when needed.
4668 @param create_parent Whether to create parent nodes if they do not exist.
4669 @param ctx A pointer to store the result context, or NULL if not needed.
4670 @param err A pointer to store the error information, or NULL if not needed.
4671 @return true if JSON pointer is valid and new value is set, false otherwise.
4672 @note If the target value already exists, it will be replaced by the new value.
4673 */
4675 const char *ptr, size_t len,
4676 yyjson_mut_val *new_val,
4677 yyjson_mut_doc *doc,
4678 bool create_parent,
4679 yyjson_ptr_ctx *ctx,
4680 yyjson_ptr_err *err);
4681
4682/**
4683 Replace value by a JSON pointer.
4684 @param doc The target JSON document.
4685 @param ptr The JSON pointer string (UTF-8 with null-terminator).
4686 @param new_val The new value to replace the old one.
4687 @return The old value that was replaced, or NULL if not found.
4688 */
4690 yyjson_mut_doc *doc, const char *ptr, yyjson_mut_val *new_val);
4691
4692/**
4693 Replace value by a JSON pointer.
4694 @param doc The target JSON document.
4695 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4696 @param len The length of `ptr` in bytes.
4697 @param new_val The new value to replace the old one.
4698 @return The old value that was replaced, or NULL if not found.
4699 */
4701 yyjson_mut_doc *doc, const char *ptr, size_t len, yyjson_mut_val *new_val);
4702
4703/**
4704 Replace value by a JSON pointer.
4705 @param doc The target JSON document.
4706 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4707 @param len The length of `ptr` in bytes.
4708 @param new_val The new value to replace the old one.
4709 @param ctx A pointer to store the result context, or NULL if not needed.
4710 @param err A pointer to store the error information, or NULL if not needed.
4711 @return The old value that was replaced, or NULL if not found.
4712 */
4714 yyjson_mut_doc *doc, const char *ptr, size_t len, yyjson_mut_val *new_val,
4715 yyjson_ptr_ctx *ctx, yyjson_ptr_err *err);
4716
4717/**
4718 Replace value by a JSON pointer.
4719 @param val The target JSON value.
4720 @param ptr The JSON pointer string (UTF-8 with null-terminator).
4721 @param new_val The new value to replace the old one.
4722 @return The old value that was replaced, or NULL if not found.
4723 */
4725 yyjson_mut_val *val, const char *ptr, yyjson_mut_val *new_val);
4726
4727/**
4728 Replace value by a JSON pointer.
4729 @param val The target JSON value.
4730 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4731 @param len The length of `ptr` in bytes.
4732 @param new_val The new value to replace the old one.
4733 @return The old value that was replaced, or NULL if not found.
4734 */
4736 yyjson_mut_val *val, const char *ptr, size_t len, yyjson_mut_val *new_val);
4737
4738/**
4739 Replace value by a JSON pointer.
4740 @param val The target JSON value.
4741 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4742 @param len The length of `ptr` in bytes.
4743 @param new_val The new value to replace the old one.
4744 @param ctx A pointer to store the result context, or NULL if not needed.
4745 @param err A pointer to store the error information, or NULL if not needed.
4746 @return The old value that was replaced, or NULL if not found.
4747 */
4749 yyjson_mut_val *val, const char *ptr, size_t len, yyjson_mut_val *new_val,
4750 yyjson_ptr_ctx *ctx, yyjson_ptr_err *err);
4751
4752/**
4753 Remove value by a JSON pointer.
4754 @param doc The target JSON document.
4755 @param ptr The JSON pointer string (UTF-8 with null-terminator).
4756 @return The removed value, or NULL on error.
4757 */
4759 yyjson_mut_doc *doc, const char *ptr);
4760
4761/**
4762 Remove value by a JSON pointer.
4763 @param doc The target JSON document.
4764 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4765 @param len The length of `ptr` in bytes.
4766 @return The removed value, or NULL on error.
4767 */
4769 yyjson_mut_doc *doc, const char *ptr, size_t len);
4770
4771/**
4772 Remove value by a JSON pointer.
4773 @param doc The target JSON document.
4774 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4775 @param len The length of `ptr` in bytes.
4776 @param ctx A pointer to store the result context, or NULL if not needed.
4777 @param err A pointer to store the error information, or NULL if not needed.
4778 @return The removed value, or NULL on error.
4779 */
4781 yyjson_mut_doc *doc, const char *ptr, size_t len,
4782 yyjson_ptr_ctx *ctx, yyjson_ptr_err *err);
4783
4784/**
4785 Remove value by a JSON pointer.
4786 @param val The target JSON value.
4787 @param ptr The JSON pointer string (UTF-8 with null-terminator).
4788 @return The removed value, or NULL on error.
4789 */
4791 const char *ptr);
4792
4793/**
4794 Remove value by a JSON pointer.
4795 @param val The target JSON value.
4796 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4797 @param len The length of `ptr` in bytes.
4798 @return The removed value, or NULL on error.
4799 */
4801 const char *ptr,
4802 size_t len);
4803
4804/**
4805 Remove value by a JSON pointer.
4806 @param val The target JSON value.
4807 @param ptr The JSON pointer string (UTF-8, null-terminator is not required).
4808 @param len The length of `ptr` in bytes.
4809 @param ctx A pointer to store the result context, or NULL if not needed.
4810 @param err A pointer to store the error information, or NULL if not needed.
4811 @return The removed value, or NULL on error.
4812 */
4814 const char *ptr,
4815 size_t len,
4816 yyjson_ptr_ctx *ctx,
4817 yyjson_ptr_err *err);
4818
4819/**
4820 Append value by JSON pointer context.
4821 @param ctx The context from the `yyjson_mut_ptr_xxx()` calls.
4822 @param key New key if `ctx->ctn` is object, or NULL if `ctx->ctn` is array.
4823 @param val New value to be added.
4824 @return true on success or false on fail.
4825 */
4827 yyjson_mut_val *key,
4828 yyjson_mut_val *val);
4829
4830/**
4831 Replace value by JSON pointer context.
4832 @param ctx The context from the `yyjson_mut_ptr_xxx()` calls.
4833 @param val New value to be replaced.
4834 @return true on success or false on fail.
4835 @note On success, the old value will be returned via `ctx->old`.
4836 */
4838 yyjson_mut_val *val);
4839
4840/**
4841 Remove value by JSON pointer context.
4842 @param ctx The context from the `yyjson_mut_ptr_xxx()` calls.
4843 @return true on success or false on fail.
4844 @note On success, the old value will be returned via `ctx->old`.
4845 */
4847
4848
4849
4850/*==============================================================================
4851 * MARK: - JSON Patch API (RFC 6902)
4852 * https://tools.ietf.org/html/rfc6902
4853 *============================================================================*/
4854
4855/** Result code for JSON patch. */
4856typedef uint32_t yyjson_patch_code;
4857
4858/** Success, no error. */
4860
4861/** Invalid parameter, such as NULL input or non-array patch. */
4863
4864/** Memory allocation failed. */
4866
4867/** JSON patch operation is not object type. */
4869
4870/** JSON patch operation is missing a required key. */
4872
4873/** JSON patch operation member is invalid. */
4875
4876/** JSON patch `test` operation failed (values not equal). */
4878
4879/** JSON patch operation failed on JSON pointer. */
4881
4882/** Error information for JSON patch. */
4883typedef struct yyjson_patch_err {
4884 /** Error code, see `yyjson_patch_code` for all possible values. */
4886 /** Index of the error operation (0 if no error). */
4887 size_t idx;
4888 /** Error message, constant, no need to free (NULL if no error). */
4889 const char *msg;
4890 /** JSON pointer error if `code == YYJSON_PATCH_ERROR_POINTER`. */
4893
4894/**
4895 Creates and returns a patched JSON value (RFC 6902).
4896 The memory of the returned value is allocated by the `doc`.
4897 The `err` is used to receive error information, pass NULL if not needed.
4898 Returns NULL if the patch could not be applied.
4899 */
4901 const yyjson_val *orig,
4902 const yyjson_val *patch,
4903 yyjson_patch_err *err);
4904
4905/**
4906 Creates and returns a patched JSON value (RFC 6902).
4907 The memory of the returned value is allocated by the `doc`.
4908 The `err` is used to receive error information, pass NULL if not needed.
4909 Returns NULL if the patch could not be applied.
4910 */
4912 const yyjson_mut_val *orig,
4913 const yyjson_mut_val *patch,
4914 yyjson_patch_err *err);
4915
4916
4917
4918/*==============================================================================
4919 * MARK: - JSON Merge-Patch API (RFC 7386)
4920 * https://tools.ietf.org/html/rfc7386
4921 *============================================================================*/
4922
4923/**
4924 Creates and returns a merge-patched JSON value (RFC 7386).
4925 The memory of the returned value is allocated by the `doc`.
4926 Returns NULL if the patch could not be applied.
4927
4928 @warning This function is recursive and may cause a stack overflow if the
4929 object level is too deep.
4930 */
4932 const yyjson_val *orig,
4933 const yyjson_val *patch);
4934
4935/**
4936 Creates and returns a merge-patched JSON value (RFC 7386).
4937 The memory of the returned value is allocated by the `doc`.
4938 Returns NULL if the patch could not be applied.
4939
4940 @warning This function is recursive and may cause a stack overflow if the
4941 object level is too deep.
4942 */
4944 const yyjson_mut_val *orig,
4945 const yyjson_mut_val *patch);
4946
4947#endif /* YYJSON_DISABLE_UTILS */
4948
4949
4950
4951/*==============================================================================
4952 * MARK: - JSON Structure (Implementation)
4953 *============================================================================*/
4954
4955/** Payload of a JSON value (8 bytes). */
4956typedef union yyjson_val_uni {
4957 uint64_t u64;
4958 int64_t i64;
4959 double f64;
4960 const char *str;
4961 void *ptr;
4962 size_t ofs;
4964
4965/**
4966 Immutable JSON value, 16 bytes.
4967 */
4969 uint64_t tag; /**< type, subtype and length */
4970 yyjson_val_uni uni; /**< payload */
4971};
4972
4974 /** Root value of the document (nonnull). */
4976 /** Allocator used by document (nonnull). */
4978 /** The total number of bytes read when parsing JSON (nonzero). */
4979 size_t dat_read;
4980 /** The total number of values read when parsing JSON (nonzero). */
4981 size_t val_read;
4982 /** The string pool used by JSON values (nullable). */
4984};
4985
4986
4987
4988/*==============================================================================
4989 * MARK: - Unsafe JSON Value API (Implementation)
4990 *============================================================================*/
4991
4992/*
4993 Whether the string does not need to be escaped for serialization.
4994 This function is used to optimize the writing speed of small constant strings.
4995 This function works only if the compiler can evaluate it at compile time.
4996
4997 Clang supports it since v8.0,
4998 earlier versions do not support constant_p(strlen) and return false.
4999 GCC supports it since at least v4.4,
5000 earlier versions may compile it as run-time instructions.
5001 ICC supports it since at least v16,
5002 earlier versions are uncertain.
5003
5004 @param str The C string.
5005 @param len The returned value from strlen(str).
5006 */
5007yyjson_api_inline bool unsafe_yyjson_is_str_noesc(const char *str, size_t len) {
5008#if YYJSON_HAS_CONSTANT_P && \
5009 (!YYJSON_IS_REAL_GCC || yyjson_gcc_available(4, 4, 0))
5010 if (yyjson_constant_p(len) && len <= 32) {
5011 /*
5012 Same as the following loop:
5013
5014 for (size_t i = 0; i < len; i++) {
5015 char c = str[i];
5016 if (c < ' ' || c > '~' || c == '"' || c == '\\') return false;
5017 }
5018
5019 GCC evaluates it at compile time only if the string length is within 17
5020 and -O3 (which turns on the -fpeel-loops flag) is used.
5021 So the loop is unrolled for GCC.
5022 */
5023# define yyjson_repeat32_incr(x) \
5024 x(0) x(1) x(2) x(3) x(4) x(5) x(6) x(7) \
5025 x(8) x(9) x(10) x(11) x(12) x(13) x(14) x(15) \
5026 x(16) x(17) x(18) x(19) x(20) x(21) x(22) x(23) \
5027 x(24) x(25) x(26) x(27) x(28) x(29) x(30) x(31)
5028# define yyjson_check_char_noesc(i) \
5029 if (i < len) { \
5030 char c = str[i]; \
5031 if (c < ' ' || c > '~' || c == '"' || c == '\\') return false; }
5032 yyjson_repeat32_incr(yyjson_check_char_noesc)
5033# undef yyjson_repeat32_incr
5034# undef yyjson_check_char_noesc
5035 return true;
5036 }
5037#else
5038 (void)str;
5039 (void)len;
5040#endif
5041 return false;
5042}
5043
5044yyjson_api_inline double unsafe_yyjson_u64_to_f64(uint64_t num) {
5045#if YYJSON_U64_TO_F64_NO_IMPL
5046 uint64_t msb = ((uint64_t)1) << 63;
5047 if ((num & msb) == 0) {
5048 return (double)(int64_t)num;
5049 } else {
5050 return ((double)(int64_t)((num >> 1) | (num & 1))) * (double)2.0;
5051 }
5052#else
5053 return (double)num;
5054#endif
5055}
5056
5057yyjson_api_inline yyjson_type unsafe_yyjson_get_type(const void *val) {
5058 uint8_t tag = (uint8_t)((const yyjson_val *)val)->tag;
5059 return (yyjson_type)(tag & YYJSON_TYPE_MASK);
5060}
5061
5062yyjson_api_inline yyjson_subtype unsafe_yyjson_get_subtype(const void *val) {
5063 uint8_t tag = (uint8_t)((const yyjson_val *)val)->tag;
5064 return (yyjson_subtype)(tag & YYJSON_SUBTYPE_MASK);
5065}
5066
5067yyjson_api_inline uint8_t unsafe_yyjson_get_tag(const void *val) {
5068 uint8_t tag = (uint8_t)((const yyjson_val *)val)->tag;
5069 return (uint8_t)(tag & YYJSON_TAG_MASK);
5070}
5071
5072yyjson_api_inline bool unsafe_yyjson_is_raw(const void *val) {
5073 return unsafe_yyjson_get_type(val) == YYJSON_TYPE_RAW;
5074}
5075
5076yyjson_api_inline bool unsafe_yyjson_is_null(const void *val) {
5077 return unsafe_yyjson_get_type(val) == YYJSON_TYPE_NULL;
5078}
5079
5080yyjson_api_inline bool unsafe_yyjson_is_bool(const void *val) {
5081 return unsafe_yyjson_get_type(val) == YYJSON_TYPE_BOOL;
5082}
5083
5084yyjson_api_inline bool unsafe_yyjson_is_num(const void *val) {
5085 return unsafe_yyjson_get_type(val) == YYJSON_TYPE_NUM;
5086}
5087
5088yyjson_api_inline bool unsafe_yyjson_is_str(const void *val) {
5089 return unsafe_yyjson_get_type(val) == YYJSON_TYPE_STR;
5090}
5091
5092yyjson_api_inline bool unsafe_yyjson_is_arr(const void *val) {
5093 return unsafe_yyjson_get_type(val) == YYJSON_TYPE_ARR;
5094}
5095
5096yyjson_api_inline bool unsafe_yyjson_is_obj(const void *val) {
5097 return unsafe_yyjson_get_type(val) == YYJSON_TYPE_OBJ;
5098}
5099
5100yyjson_api_inline bool unsafe_yyjson_is_ctn(const void *val) {
5101 uint8_t mask = YYJSON_TYPE_ARR & YYJSON_TYPE_OBJ;
5102 return (unsafe_yyjson_get_tag(val) & mask) == mask;
5103}
5104
5105yyjson_api_inline bool unsafe_yyjson_is_uint(const void *val) {
5106 const uint8_t patt = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT;
5107 return unsafe_yyjson_get_tag(val) == patt;
5108}
5109
5110yyjson_api_inline bool unsafe_yyjson_is_sint(const void *val) {
5111 const uint8_t patt = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT;
5112 return unsafe_yyjson_get_tag(val) == patt;
5113}
5114
5115yyjson_api_inline bool unsafe_yyjson_is_int(const void *val) {
5116 const uint8_t mask = YYJSON_TAG_MASK & (~YYJSON_SUBTYPE_SINT);
5117 const uint8_t patt = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT;
5118 return (unsafe_yyjson_get_tag(val) & mask) == patt;
5119}
5120
5121yyjson_api_inline bool unsafe_yyjson_is_real(const void *val) {
5122 const uint8_t patt = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_REAL;
5123 return unsafe_yyjson_get_tag(val) == patt;
5124}
5125
5126yyjson_api_inline bool unsafe_yyjson_is_true(const void *val) {
5127 const uint8_t patt = YYJSON_TYPE_BOOL | YYJSON_SUBTYPE_TRUE;
5128 return unsafe_yyjson_get_tag(val) == patt;
5129}
5130
5131yyjson_api_inline bool unsafe_yyjson_is_false(const void *val) {
5132 const uint8_t patt = YYJSON_TYPE_BOOL | YYJSON_SUBTYPE_FALSE;
5133 return unsafe_yyjson_get_tag(val) == patt;
5134}
5135
5136yyjson_api_inline bool unsafe_yyjson_arr_is_flat(const yyjson_val *val) {
5137 size_t ofs = val->uni.ofs;
5138 size_t len = (size_t)(val->tag >> YYJSON_TAG_BIT);
5139 return len * sizeof(yyjson_val) + sizeof(yyjson_val) == ofs;
5140}
5141
5142yyjson_api_inline const char *unsafe_yyjson_get_raw(const void *val) {
5143 return ((const yyjson_val *)val)->uni.str;
5144}
5145
5146yyjson_api_inline bool unsafe_yyjson_get_bool(const void *val) {
5147 uint8_t tag = unsafe_yyjson_get_tag(val);
5148 return (bool)((tag & YYJSON_SUBTYPE_MASK) >> YYJSON_TYPE_BIT);
5149}
5150
5151yyjson_api_inline uint64_t unsafe_yyjson_get_uint(const void *val) {
5152 return ((const yyjson_val *)val)->uni.u64;
5153}
5154
5155yyjson_api_inline int64_t unsafe_yyjson_get_sint(const void *val) {
5156 return ((const yyjson_val *)val)->uni.i64;
5157}
5158
5159yyjson_api_inline int unsafe_yyjson_get_int(const void *val) {
5160 return (int)((const yyjson_val *)val)->uni.i64;
5161}
5162
5163yyjson_api_inline double unsafe_yyjson_get_real(const void *val) {
5164 return ((const yyjson_val *)val)->uni.f64;
5165}
5166
5167yyjson_api_inline double unsafe_yyjson_get_num(const void *val) {
5168 uint8_t tag = unsafe_yyjson_get_tag(val);
5169 if (tag == (YYJSON_TYPE_NUM | YYJSON_SUBTYPE_REAL)) {
5170 return ((const yyjson_val *)val)->uni.f64;
5171 } else if (tag == (YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT)) {
5172 return (double)((const yyjson_val *)val)->uni.i64;
5173 } else if (tag == (YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT)) {
5174 return unsafe_yyjson_u64_to_f64(((const yyjson_val *)val)->uni.u64);
5175 }
5176 return 0.0;
5177}
5178
5179yyjson_api_inline const char *unsafe_yyjson_get_str(const void *val) {
5180 return ((const yyjson_val *)val)->uni.str;
5181}
5182
5183yyjson_api_inline size_t unsafe_yyjson_get_len(const void *val) {
5184 return (size_t)(((const yyjson_val *)val)->tag >> YYJSON_TAG_BIT);
5185}
5186
5187yyjson_api_inline yyjson_val *unsafe_yyjson_get_first(const yyjson_val *ctn) {
5188 return yyjson_constcast(yyjson_val *)ctn + 1;
5189}
5190
5191yyjson_api_inline yyjson_val *unsafe_yyjson_get_next(const yyjson_val *val) {
5192 bool is_ctn = unsafe_yyjson_is_ctn(val);
5193 size_t ctn_ofs = val->uni.ofs;
5194 size_t ofs = (is_ctn ? ctn_ofs : sizeof(yyjson_val));
5195 uint8_t *ptr = yyjson_constcast(uint8_t *)val;
5196 return (yyjson_val *)(void *)(ptr + ofs);
5197}
5198
5199yyjson_api_inline bool unsafe_yyjson_equals_strn(const void *val,
5200 const char *str, size_t len) {
5201 return unsafe_yyjson_get_len(val) == len &&
5202 memcmp(((const yyjson_val *)val)->uni.str, str, len) == 0;
5203}
5204
5205yyjson_api_inline bool unsafe_yyjson_equals_str(const void *val,
5206 const char *str) {
5207 return unsafe_yyjson_equals_strn(val, str, strlen(str));
5208}
5209
5210yyjson_api_inline void unsafe_yyjson_set_type(void *val, yyjson_type type,
5211 yyjson_subtype subtype) {
5212 uint8_t tag = (type | subtype);
5213 uint64_t new_tag = ((yyjson_val *)val)->tag;
5214 new_tag = (new_tag & (~(uint64_t)YYJSON_TAG_MASK)) | (uint64_t)tag;
5215 ((yyjson_val *)val)->tag = new_tag;
5216}
5217
5218yyjson_api_inline void unsafe_yyjson_set_len(void *val, size_t len) {
5219 uint64_t tag = ((yyjson_val *)val)->tag & YYJSON_TAG_MASK;
5220 tag |= (uint64_t)len << YYJSON_TAG_BIT;
5221 ((yyjson_val *)val)->tag = tag;
5222}
5223
5224yyjson_api_inline void unsafe_yyjson_set_tag(void *val, yyjson_type type,
5225 yyjson_subtype subtype,
5226 size_t len) {
5227 uint64_t tag = (uint64_t)len << YYJSON_TAG_BIT;
5228 tag |= (type | subtype);
5229 ((yyjson_val *)val)->tag = tag;
5230}
5231
5232yyjson_api_inline void unsafe_yyjson_inc_len(void *val) {
5233 uint64_t tag = ((yyjson_val *)val)->tag;
5234 tag += (uint64_t)(1 << YYJSON_TAG_BIT);
5235 ((yyjson_val *)val)->tag = tag;
5236}
5237
5238yyjson_api_inline void unsafe_yyjson_set_raw(void *val, const char *raw,
5239 size_t len) {
5240 unsafe_yyjson_set_tag(val, YYJSON_TYPE_RAW, YYJSON_SUBTYPE_NONE, len);
5241 ((yyjson_val *)val)->uni.str = raw;
5242}
5243
5244yyjson_api_inline void unsafe_yyjson_set_null(void *val) {
5245 unsafe_yyjson_set_tag(val, YYJSON_TYPE_NULL, YYJSON_SUBTYPE_NONE, 0);
5246}
5247
5248yyjson_api_inline void unsafe_yyjson_set_bool(void *val, bool num) {
5249 yyjson_subtype subtype = num ? YYJSON_SUBTYPE_TRUE : YYJSON_SUBTYPE_FALSE;
5250 unsafe_yyjson_set_tag(val, YYJSON_TYPE_BOOL, subtype, 0);
5251}
5252
5253yyjson_api_inline void unsafe_yyjson_set_uint(void *val, uint64_t num) {
5254 unsafe_yyjson_set_tag(val, YYJSON_TYPE_NUM, YYJSON_SUBTYPE_UINT, 0);
5255 ((yyjson_val *)val)->uni.u64 = num;
5256}
5257
5258yyjson_api_inline void unsafe_yyjson_set_sint(void *val, int64_t num) {
5259 unsafe_yyjson_set_tag(val, YYJSON_TYPE_NUM, YYJSON_SUBTYPE_SINT, 0);
5260 ((yyjson_val *)val)->uni.i64 = num;
5261}
5262
5263yyjson_api_inline void unsafe_yyjson_set_fp_to_fixed(void *val, int prec) {
5264 ((yyjson_val *)val)->tag &= ~((uint64_t)YYJSON_WRITE_FP_TO_FIXED(15) << 32);
5265 ((yyjson_val *)val)->tag |= (uint64_t)YYJSON_WRITE_FP_TO_FIXED(prec) << 32;
5266}
5267
5268yyjson_api_inline void unsafe_yyjson_set_fp_to_float(void *val, bool flt) {
5269 uint64_t flag = (uint64_t)YYJSON_WRITE_FP_TO_FLOAT << 32;
5270 if (flt) ((yyjson_val *)val)->tag |= flag;
5271 else ((yyjson_val *)val)->tag &= ~flag;
5272}
5273
5274yyjson_api_inline void unsafe_yyjson_set_float(void *val, float num) {
5275 unsafe_yyjson_set_tag(val, YYJSON_TYPE_NUM, YYJSON_SUBTYPE_REAL, 0);
5276 ((yyjson_val *)val)->tag |= (uint64_t)YYJSON_WRITE_FP_TO_FLOAT << 32;
5277 ((yyjson_val *)val)->uni.f64 = (double)num;
5278}
5279
5280yyjson_api_inline void unsafe_yyjson_set_double(void *val, double num) {
5281 unsafe_yyjson_set_tag(val, YYJSON_TYPE_NUM, YYJSON_SUBTYPE_REAL, 0);
5282 ((yyjson_val *)val)->uni.f64 = num;
5283}
5284
5285yyjson_api_inline void unsafe_yyjson_set_real(void *val, double num) {
5286 unsafe_yyjson_set_tag(val, YYJSON_TYPE_NUM, YYJSON_SUBTYPE_REAL, 0);
5287 ((yyjson_val *)val)->uni.f64 = num;
5288}
5289
5290yyjson_api_inline void unsafe_yyjson_set_str_noesc(void *val, bool noesc) {
5291 ((yyjson_val *)val)->tag &= ~(uint64_t)YYJSON_SUBTYPE_MASK;
5292 if (noesc) ((yyjson_val *)val)->tag |= (uint64_t)YYJSON_SUBTYPE_NOESC;
5293}
5294
5295yyjson_api_inline void unsafe_yyjson_set_strn(void *val, const char *str,
5296 size_t len) {
5297 unsafe_yyjson_set_tag(val, YYJSON_TYPE_STR, YYJSON_SUBTYPE_NONE, len);
5298 ((yyjson_val *)val)->uni.str = str;
5299}
5300
5301yyjson_api_inline void unsafe_yyjson_set_str(void *val, const char *str) {
5302 size_t len = strlen(str);
5303 bool noesc = unsafe_yyjson_is_str_noesc(str, len);
5304 yyjson_subtype subtype = noesc ? YYJSON_SUBTYPE_NOESC : YYJSON_SUBTYPE_NONE;
5305 unsafe_yyjson_set_tag(val, YYJSON_TYPE_STR, subtype, len);
5306 ((yyjson_val *)val)->uni.str = str;
5307}
5308
5309yyjson_api_inline void unsafe_yyjson_set_arr(void *val, size_t size) {
5310 unsafe_yyjson_set_tag(val, YYJSON_TYPE_ARR, YYJSON_SUBTYPE_NONE, size);
5311}
5312
5313yyjson_api_inline void unsafe_yyjson_set_obj(void *val, size_t size) {
5314 unsafe_yyjson_set_tag(val, YYJSON_TYPE_OBJ, YYJSON_SUBTYPE_NONE, size);
5315}
5316
5317
5318
5319/*==============================================================================
5320 * MARK: - JSON Document API (Implementation)
5321 *============================================================================*/
5322
5323yyjson_api_inline yyjson_val *yyjson_doc_get_root(const yyjson_doc *doc) {
5324 return doc ? doc->root : NULL;
5325}
5326
5327yyjson_api_inline size_t yyjson_doc_get_read_size(const yyjson_doc *doc) {
5328 return doc ? doc->dat_read : 0;
5329}
5330
5331yyjson_api_inline size_t yyjson_doc_get_val_count(const yyjson_doc *doc) {
5332 return doc ? doc->val_read : 0;
5333}
5334
5335yyjson_api_inline void yyjson_doc_free(yyjson_doc *doc) {
5336 if (doc) {
5337 yyjson_alc alc = doc->alc;
5338 memset(&doc->alc, 0, sizeof(alc));
5339 if (doc->str_pool) alc.free(alc.ctx, doc->str_pool);
5340 alc.free(alc.ctx, doc);
5341 }
5342}
5343
5344
5345
5346/*==============================================================================
5347 * MARK: - JSON Value Type API (Implementation)
5348 *============================================================================*/
5349
5350yyjson_api_inline bool yyjson_is_raw(const yyjson_val *val) {
5351 return val ? unsafe_yyjson_is_raw(val) : false;
5352}
5353
5354yyjson_api_inline bool yyjson_is_null(const yyjson_val *val) {
5355 return val ? unsafe_yyjson_is_null(val) : false;
5356}
5357
5358yyjson_api_inline bool yyjson_is_true(const yyjson_val *val) {
5359 return val ? unsafe_yyjson_is_true(val) : false;
5360}
5361
5362yyjson_api_inline bool yyjson_is_false(const yyjson_val *val) {
5363 return val ? unsafe_yyjson_is_false(val) : false;
5364}
5365
5366yyjson_api_inline bool yyjson_is_bool(const yyjson_val *val) {
5367 return val ? unsafe_yyjson_is_bool(val) : false;
5368}
5369
5370yyjson_api_inline bool yyjson_is_uint(const yyjson_val *val) {
5371 return val ? unsafe_yyjson_is_uint(val) : false;
5372}
5373
5374yyjson_api_inline bool yyjson_is_sint(const yyjson_val *val) {
5375 return val ? unsafe_yyjson_is_sint(val) : false;
5376}
5377
5378yyjson_api_inline bool yyjson_is_int(const yyjson_val *val) {
5379 return val ? unsafe_yyjson_is_int(val) : false;
5380}
5381
5382yyjson_api_inline bool yyjson_is_real(const yyjson_val *val) {
5383 return val ? unsafe_yyjson_is_real(val) : false;
5384}
5385
5386yyjson_api_inline bool yyjson_is_num(const yyjson_val *val) {
5387 return val ? unsafe_yyjson_is_num(val) : false;
5388}
5389
5390yyjson_api_inline bool yyjson_is_str(const yyjson_val *val) {
5391 return val ? unsafe_yyjson_is_str(val) : false;
5392}
5393
5394yyjson_api_inline bool yyjson_is_arr(const yyjson_val *val) {
5395 return val ? unsafe_yyjson_is_arr(val) : false;
5396}
5397
5398yyjson_api_inline bool yyjson_is_obj(const yyjson_val *val) {
5399 return val ? unsafe_yyjson_is_obj(val) : false;
5400}
5401
5402yyjson_api_inline bool yyjson_is_ctn(const yyjson_val *val) {
5403 return val ? unsafe_yyjson_is_ctn(val) : false;
5404}
5405
5406
5407
5408/*==============================================================================
5409 * MARK: - JSON Value Content API (Implementation)
5410 *============================================================================*/
5411
5412yyjson_api_inline yyjson_type yyjson_get_type(const yyjson_val *val) {
5413 return val ? unsafe_yyjson_get_type(val) : YYJSON_TYPE_NONE;
5414}
5415
5416yyjson_api_inline yyjson_subtype yyjson_get_subtype(const yyjson_val *val) {
5417 return val ? unsafe_yyjson_get_subtype(val) : YYJSON_SUBTYPE_NONE;
5418}
5419
5420yyjson_api_inline uint8_t yyjson_get_tag(const yyjson_val *val) {
5421 return val ? unsafe_yyjson_get_tag(val) : 0;
5422}
5423
5424yyjson_api_inline const char *yyjson_get_type_desc(const yyjson_val *val) {
5425 switch (yyjson_get_tag(val)) {
5426 case YYJSON_TYPE_RAW | YYJSON_SUBTYPE_NONE: return "raw";
5427 case YYJSON_TYPE_NULL | YYJSON_SUBTYPE_NONE: return "null";
5428 case YYJSON_TYPE_STR | YYJSON_SUBTYPE_NONE: return "string";
5429 case YYJSON_TYPE_STR | YYJSON_SUBTYPE_NOESC: return "string";
5430 case YYJSON_TYPE_ARR | YYJSON_SUBTYPE_NONE: return "array";
5431 case YYJSON_TYPE_OBJ | YYJSON_SUBTYPE_NONE: return "object";
5432 case YYJSON_TYPE_BOOL | YYJSON_SUBTYPE_TRUE: return "true";
5433 case YYJSON_TYPE_BOOL | YYJSON_SUBTYPE_FALSE: return "false";
5434 case YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT: return "uint";
5435 case YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT: return "sint";
5436 case YYJSON_TYPE_NUM | YYJSON_SUBTYPE_REAL: return "real";
5437 default: return "unknown";
5438 }
5439}
5440
5441yyjson_api_inline const char *yyjson_get_raw(const yyjson_val *val) {
5442 return yyjson_is_raw(val) ? unsafe_yyjson_get_raw(val) : NULL;
5443}
5444
5445yyjson_api_inline bool yyjson_get_bool(const yyjson_val *val) {
5446 return yyjson_is_bool(val) ? unsafe_yyjson_get_bool(val) : false;
5447}
5448
5449yyjson_api_inline uint64_t yyjson_get_uint(const yyjson_val *val) {
5450 return yyjson_is_int(val) ? unsafe_yyjson_get_uint(val) : 0;
5451}
5452
5453yyjson_api_inline int64_t yyjson_get_sint(const yyjson_val *val) {
5454 return yyjson_is_int(val) ? unsafe_yyjson_get_sint(val) : 0;
5455}
5456
5457yyjson_api_inline int yyjson_get_int(const yyjson_val *val) {
5458 return yyjson_is_int(val) ? unsafe_yyjson_get_int(val) : 0;
5459}
5460
5461yyjson_api_inline double yyjson_get_real(const yyjson_val *val) {
5462 return yyjson_is_real(val) ? unsafe_yyjson_get_real(val) : 0.0;
5463}
5464
5465yyjson_api_inline double yyjson_get_num(const yyjson_val *val) {
5466 return val ? unsafe_yyjson_get_num(val) : 0.0;
5467}
5468
5469yyjson_api_inline const char *yyjson_get_str(const yyjson_val *val) {
5470 return yyjson_is_str(val) ? unsafe_yyjson_get_str(val) : NULL;
5471}
5472
5473yyjson_api_inline size_t yyjson_get_len(const yyjson_val *val) {
5474 return val ? unsafe_yyjson_get_len(val) : 0;
5475}
5476
5477yyjson_api_inline bool yyjson_equals_str(const yyjson_val *val,
5478 const char *str) {
5479 if (yyjson_likely(val && str)) {
5480 return unsafe_yyjson_is_str(val) &&
5481 unsafe_yyjson_equals_str(val, str);
5482 }
5483 return false;
5484}
5485
5486yyjson_api_inline bool yyjson_equals_strn(const yyjson_val *val,
5487 const char *str, size_t len) {
5488 if (yyjson_likely(val && str)) {
5489 return unsafe_yyjson_is_str(val) &&
5490 unsafe_yyjson_equals_strn(val, str, len);
5491 }
5492 return false;
5493}
5494
5495yyjson_api bool unsafe_yyjson_equals(const yyjson_val *lhs,
5496 const yyjson_val *rhs);
5497
5498yyjson_api_inline bool yyjson_equals(const yyjson_val *lhs,
5499 const yyjson_val *rhs) {
5500 if (yyjson_unlikely(!lhs || !rhs)) return false;
5501 return unsafe_yyjson_equals(lhs, rhs);
5502}
5503
5504yyjson_api_inline bool yyjson_set_raw(yyjson_val *val,
5505 const char *raw, size_t len) {
5506 if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
5507 if (yyjson_unlikely(!raw)) return false;
5508 unsafe_yyjson_set_raw(val, raw, len);
5509 return true;
5510}
5511
5512yyjson_api_inline bool yyjson_set_null(yyjson_val *val) {
5513 if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
5514 unsafe_yyjson_set_null(val);
5515 return true;
5516}
5517
5518yyjson_api_inline bool yyjson_set_bool(yyjson_val *val, bool num) {
5519 if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
5520 unsafe_yyjson_set_bool(val, num);
5521 return true;
5522}
5523
5524yyjson_api_inline bool yyjson_set_uint(yyjson_val *val, uint64_t num) {
5525 if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
5526 unsafe_yyjson_set_uint(val, num);
5527 return true;
5528}
5529
5530yyjson_api_inline bool yyjson_set_sint(yyjson_val *val, int64_t num) {
5531 if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
5532 unsafe_yyjson_set_sint(val, num);
5533 return true;
5534}
5535
5536yyjson_api_inline bool yyjson_set_int(yyjson_val *val, int64_t num) {
5537 if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
5538 unsafe_yyjson_set_sint(val, num);
5539 return true;
5540}
5541
5542yyjson_api_inline bool yyjson_set_float(yyjson_val *val, float num) {
5543 if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
5544 unsafe_yyjson_set_float(val, num);
5545 return true;
5546}
5547
5548yyjson_api_inline bool yyjson_set_double(yyjson_val *val, double num) {
5549 if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
5550 unsafe_yyjson_set_double(val, num);
5551 return true;
5552}
5553
5554yyjson_api_inline bool yyjson_set_real(yyjson_val *val, double num) {
5555 if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
5556 unsafe_yyjson_set_real(val, num);
5557 return true;
5558}
5559
5560yyjson_api_inline bool yyjson_set_fp_to_fixed(yyjson_val *val, int prec) {
5561 if (yyjson_unlikely(!yyjson_is_real(val))) return false;
5562 unsafe_yyjson_set_fp_to_fixed(val, prec);
5563 return true;
5564}
5565
5566yyjson_api_inline bool yyjson_set_fp_to_float(yyjson_val *val, bool flt) {
5567 if (yyjson_unlikely(!yyjson_is_real(val))) return false;
5568 unsafe_yyjson_set_fp_to_float(val, flt);
5569 return true;
5570}
5571
5572yyjson_api_inline bool yyjson_set_str(yyjson_val *val, const char *str) {
5573 if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
5574 if (yyjson_unlikely(!str)) return false;
5575 unsafe_yyjson_set_str(val, str);
5576 return true;
5577}
5578
5579yyjson_api_inline bool yyjson_set_strn(yyjson_val *val,
5580 const char *str, size_t len) {
5581 if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val))) return false;
5582 if (yyjson_unlikely(!str)) return false;
5583 unsafe_yyjson_set_strn(val, str, len);
5584 return true;
5585}
5586
5587yyjson_api_inline bool yyjson_set_str_noesc(yyjson_val *val, bool noesc) {
5588 if (yyjson_unlikely(!yyjson_is_str(val))) return false;
5589 unsafe_yyjson_set_str_noesc(val, noesc);
5590 return true;
5591}
5592
5593
5594
5595/*==============================================================================
5596 * MARK: - JSON Array API (Implementation)
5597 *============================================================================*/
5598
5599yyjson_api_inline size_t yyjson_arr_size(const yyjson_val *arr) {
5600 return yyjson_is_arr(arr) ? unsafe_yyjson_get_len(arr) : 0;
5601}
5602
5603yyjson_api_inline yyjson_val *yyjson_arr_get(const yyjson_val *arr,
5604 size_t idx) {
5605 if (yyjson_likely(yyjson_is_arr(arr))) {
5606 if (yyjson_likely(unsafe_yyjson_get_len(arr) > idx)) {
5607 yyjson_val *val = unsafe_yyjson_get_first(arr);
5608 if (unsafe_yyjson_arr_is_flat(arr)) {
5609 return val + idx;
5610 } else {
5611 while (idx-- > 0) val = unsafe_yyjson_get_next(val);
5612 return val;
5613 }
5614 }
5615 }
5616 return NULL;
5617}
5618
5619yyjson_api_inline yyjson_val *yyjson_arr_get_first(const yyjson_val *arr) {
5620 if (yyjson_likely(yyjson_is_arr(arr))) {
5621 if (yyjson_likely(unsafe_yyjson_get_len(arr) > 0)) {
5622 return unsafe_yyjson_get_first(arr);
5623 }
5624 }
5625 return NULL;
5626}
5627
5628yyjson_api_inline yyjson_val *yyjson_arr_get_last(const yyjson_val *arr) {
5629 if (yyjson_likely(yyjson_is_arr(arr))) {
5630 size_t len = unsafe_yyjson_get_len(arr);
5631 if (yyjson_likely(len > 0)) {
5632 yyjson_val *val = unsafe_yyjson_get_first(arr);
5633 if (unsafe_yyjson_arr_is_flat(arr)) {
5634 return val + (len - 1);
5635 } else {
5636 while (len-- > 1) val = unsafe_yyjson_get_next(val);
5637 return val;
5638 }
5639 }
5640 }
5641 return NULL;
5642}
5643
5644
5645
5646/*==============================================================================
5647 * MARK: - JSON Array Iterator API (Implementation)
5648 *============================================================================*/
5649
5650yyjson_api_inline bool yyjson_arr_iter_init(const yyjson_val *arr,
5651 yyjson_arr_iter *iter) {
5652 if (yyjson_likely(yyjson_is_arr(arr) && iter)) {
5653 iter->idx = 0;
5654 iter->max = unsafe_yyjson_get_len(arr);
5655 iter->cur = unsafe_yyjson_get_first(arr);
5656 return true;
5657 }
5658 if (iter) memset(iter, 0, sizeof(yyjson_arr_iter));
5659 return false;
5660}
5661
5662yyjson_api_inline yyjson_arr_iter yyjson_arr_iter_with(const yyjson_val *arr) {
5663 yyjson_arr_iter iter;
5664 yyjson_arr_iter_init(arr, &iter);
5665 return iter;
5666}
5667
5668yyjson_api_inline bool yyjson_arr_iter_has_next(yyjson_arr_iter *iter) {
5669 return iter ? iter->idx < iter->max : false;
5670}
5671
5672yyjson_api_inline yyjson_val *yyjson_arr_iter_next(yyjson_arr_iter *iter) {
5673 yyjson_val *val;
5674 if (iter && iter->idx < iter->max) {
5675 val = iter->cur;
5676 iter->cur = unsafe_yyjson_get_next(val);
5677 iter->idx++;
5678 return val;
5679 }
5680 return NULL;
5681}
5682
5683
5684
5685/*==============================================================================
5686 * MARK: - JSON Object API (Implementation)
5687 *============================================================================*/
5688
5689yyjson_api_inline size_t yyjson_obj_size(const yyjson_val *obj) {
5690 return yyjson_is_obj(obj) ? unsafe_yyjson_get_len(obj) : 0;
5691}
5692
5693yyjson_api_inline yyjson_val *yyjson_obj_get(const yyjson_val *obj,
5694 const char *key) {
5695 return yyjson_obj_getn(obj, key, key ? strlen(key) : 0);
5696}
5697
5698yyjson_api_inline yyjson_val *yyjson_obj_getn(const yyjson_val *obj,
5699 const char *_key,
5700 size_t key_len) {
5701 if (yyjson_likely(yyjson_is_obj(obj) && _key)) {
5702 size_t len = unsafe_yyjson_get_len(obj);
5703 yyjson_val *key = unsafe_yyjson_get_first(obj);
5704 while (len-- > 0) {
5705 if (unsafe_yyjson_equals_strn(key, _key, key_len)) return key + 1;
5706 key = unsafe_yyjson_get_next(key + 1);
5707 }
5708 }
5709 return NULL;
5710}
5711
5712
5713
5714/*==============================================================================
5715 * MARK: - JSON Object Iterator API (Implementation)
5716 *============================================================================*/
5717
5718yyjson_api_inline bool yyjson_obj_iter_init(const yyjson_val *obj,
5719 yyjson_obj_iter *iter) {
5720 if (yyjson_likely(yyjson_is_obj(obj) && iter)) {
5721 iter->idx = 0;
5722 iter->max = unsafe_yyjson_get_len(obj);
5723 iter->cur = unsafe_yyjson_get_first(obj);
5724 iter->obj = yyjson_constcast(yyjson_val *)obj;
5725 return true;
5726 }
5727 if (iter) memset(iter, 0, sizeof(yyjson_obj_iter));
5728 return false;
5729}
5730
5731yyjson_api_inline yyjson_obj_iter yyjson_obj_iter_with(const yyjson_val *obj) {
5732 yyjson_obj_iter iter;
5733 yyjson_obj_iter_init(obj, &iter);
5734 return iter;
5735}
5736
5737yyjson_api_inline bool yyjson_obj_iter_has_next(yyjson_obj_iter *iter) {
5738 return iter ? iter->idx < iter->max : false;
5739}
5740
5741yyjson_api_inline yyjson_val *yyjson_obj_iter_next(yyjson_obj_iter *iter) {
5742 if (iter && iter->idx < iter->max) {
5743 yyjson_val *key = iter->cur;
5744 iter->idx++;
5745 iter->cur = unsafe_yyjson_get_next(key + 1);
5746 return key;
5747 }
5748 return NULL;
5749}
5750
5751yyjson_api_inline yyjson_val *yyjson_obj_iter_get_val(yyjson_val *key) {
5752 return key ? key + 1 : NULL;
5753}
5754
5755yyjson_api_inline yyjson_val *yyjson_obj_iter_get(yyjson_obj_iter *iter,
5756 const char *key) {
5757 return yyjson_obj_iter_getn(iter, key, key ? strlen(key) : 0);
5758}
5759
5760yyjson_api_inline yyjson_val *yyjson_obj_iter_getn(yyjson_obj_iter *iter,
5761 const char *key,
5762 size_t key_len) {
5763 if (iter && key) {
5764 size_t idx = iter->idx;
5765 size_t max = iter->max;
5766 yyjson_val *cur = iter->cur;
5767 if (yyjson_unlikely(idx == max)) {
5768 idx = 0;
5769 cur = unsafe_yyjson_get_first(iter->obj);
5770 }
5771 while (idx++ < max) {
5772 yyjson_val *next = unsafe_yyjson_get_next(cur + 1);
5773 if (unsafe_yyjson_equals_strn(cur, key, key_len)) {
5774 iter->idx = idx;
5775 iter->cur = next;
5776 return cur + 1;
5777 }
5778 cur = next;
5779 if (idx == iter->max && iter->idx < iter->max) {
5780 idx = 0;
5781 max = iter->idx;
5782 cur = unsafe_yyjson_get_first(iter->obj);
5783 }
5784 }
5785 }
5786 return NULL;
5787}
5788
5789
5790
5791/*==============================================================================
5792 * MARK: - Mutable JSON Structure (Implementation)
5793 *============================================================================*/
5794
5795/**
5796 Mutable JSON value, 24 bytes.
5797 The 'tag' and 'uni' fields are the same as immutable value.
5798 The 'next' field links all elements inside the container to be a cycle.
5799 */
5800struct yyjson_mut_val {
5801 uint64_t tag; /**< type, subtype and length */
5802 yyjson_val_uni uni; /**< payload */
5803 yyjson_mut_val *next; /**< the next value in circular linked list */
5804};
5805
5806/**
5807 A memory chunk in string memory pool.
5808 */
5809typedef struct yyjson_str_chunk {
5810 struct yyjson_str_chunk *next; /* next chunk linked list */
5811 size_t chunk_size; /* chunk size in bytes */
5812 /* char str[]; flexible array member */
5813} yyjson_str_chunk;
5814
5815/**
5816 A memory pool to hold all strings in a mutable document.
5817 */
5818typedef struct yyjson_str_pool {
5819 char *cur; /* cursor inside current chunk */
5820 char *end; /* the end of current chunk */
5821 size_t chunk_size; /* chunk size in bytes while creating new chunk */
5822 size_t chunk_size_max; /* maximum chunk size in bytes */
5823 yyjson_str_chunk *chunks; /* a linked list of chunks, nullable */
5824} yyjson_str_pool;
5825
5826/**
5827 A memory chunk in value memory pool.
5828 `sizeof(yyjson_val_chunk)` should not be larger than `sizeof(yyjson_mut_val)`.
5829 */
5830typedef struct yyjson_val_chunk {
5831 struct yyjson_val_chunk *next; /* next chunk linked list */
5832 size_t chunk_size; /* chunk size in bytes */
5833 /* char pad[sizeof(yyjson_mut_val) - sizeof(yyjson_val_chunk)]; padding */
5834 /* yyjson_mut_val vals[]; flexible array member */
5835} yyjson_val_chunk;
5836
5837/**
5838 A memory pool to hold all values in a mutable document.
5839 */
5840typedef struct yyjson_val_pool {
5841 yyjson_mut_val *cur; /* cursor inside current chunk */
5842 yyjson_mut_val *end; /* the end of current chunk */
5843 size_t chunk_size; /* chunk size in bytes while creating new chunk */
5844 size_t chunk_size_max; /* maximum chunk size in bytes */
5845 yyjson_val_chunk *chunks; /* a linked list of chunks, nullable */
5846} yyjson_val_pool;
5847
5848struct yyjson_mut_doc {
5849 yyjson_mut_val *root; /**< root value of the JSON document, nullable */
5850 yyjson_alc alc; /**< a valid allocator, nonnull */
5851 yyjson_str_pool str_pool; /**< string memory pool */
5852 yyjson_val_pool val_pool; /**< value memory pool */
5853};
5854
5855/* Ensures the capacity to at least equal to the specified byte length. */
5856yyjson_api bool unsafe_yyjson_str_pool_grow(yyjson_str_pool *pool,
5857 const yyjson_alc *alc,
5858 size_t len);
5859
5860/* Ensures the capacity to at least equal to the specified value count. */
5861yyjson_api bool unsafe_yyjson_val_pool_grow(yyjson_val_pool *pool,
5862 const yyjson_alc *alc,
5863 size_t count);
5864
5865/* Allocate memory for string. */
5866yyjson_api_inline char *unsafe_yyjson_mut_str_alc(yyjson_mut_doc *doc,
5867 size_t len) {
5868 char *mem;
5869 const yyjson_alc *alc = &doc->alc;
5870 yyjson_str_pool *pool = &doc->str_pool;
5871 /* `len + 1` is used below to reserve space for a null terminator;
5872 reject the value that would wrap it to 0 and produce an under-sized
5873 allocation with an out-of-bounds memcpy at the call sites. */
5874 if (yyjson_unlikely(len == (size_t)-1)) return NULL;
5875 if (yyjson_unlikely((size_t)(pool->end - pool->cur) <= len)) {
5876 if (yyjson_unlikely(!unsafe_yyjson_str_pool_grow(pool, alc, len + 1))) {
5877 return NULL;
5878 }
5879 }
5880 mem = pool->cur;
5881 pool->cur = mem + len + 1;
5882 return mem;
5883}
5884
5885yyjson_api_inline char *unsafe_yyjson_mut_strncpy(yyjson_mut_doc *doc,
5886 const char *str, size_t len) {
5887 char *mem = unsafe_yyjson_mut_str_alc(doc, len);
5888 if (yyjson_unlikely(!mem)) return NULL;
5889 memcpy((void *)mem, (const void *)str, len);
5890 mem[len] = '\0';
5891 return mem;
5892}
5893
5894yyjson_api_inline yyjson_mut_val *unsafe_yyjson_mut_val(yyjson_mut_doc *doc,
5895 size_t count) {
5896 yyjson_mut_val *val;
5897 yyjson_alc *alc = &doc->alc;
5898 yyjson_val_pool *pool = &doc->val_pool;
5899 if (yyjson_unlikely((size_t)(pool->end - pool->cur) < count)) {
5900 if (yyjson_unlikely(!unsafe_yyjson_val_pool_grow(pool, alc, count))) {
5901 return NULL;
5902 }
5903 }
5904 val = pool->cur;
5905 pool->cur += count;
5906 return val;
5907}
5908
5909
5910
5911/*==============================================================================
5912 * MARK: - Mutable JSON Document API (Implementation)
5913 *============================================================================*/
5914
5915yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_get_root(yyjson_mut_doc *doc) {
5916 return doc ? doc->root : NULL;
5917}
5918
5919yyjson_api_inline void yyjson_mut_doc_set_root(yyjson_mut_doc *doc,
5920 yyjson_mut_val *root) {
5921 if (doc) doc->root = root;
5922}
5923
5924
5925
5926/*==============================================================================
5927 * MARK: - Mutable JSON Value Type API (Implementation)
5928 *============================================================================*/
5929
5930yyjson_api_inline bool yyjson_mut_is_raw(const yyjson_mut_val *val) {
5931 return val ? unsafe_yyjson_is_raw(val) : false;
5932}
5933
5934yyjson_api_inline bool yyjson_mut_is_null(const yyjson_mut_val *val) {
5935 return val ? unsafe_yyjson_is_null(val) : false;
5936}
5937
5938yyjson_api_inline bool yyjson_mut_is_true(const yyjson_mut_val *val) {
5939 return val ? unsafe_yyjson_is_true(val) : false;
5940}
5941
5942yyjson_api_inline bool yyjson_mut_is_false(const yyjson_mut_val *val) {
5943 return val ? unsafe_yyjson_is_false(val) : false;
5944}
5945
5946yyjson_api_inline bool yyjson_mut_is_bool(const yyjson_mut_val *val) {
5947 return val ? unsafe_yyjson_is_bool(val) : false;
5948}
5949
5950yyjson_api_inline bool yyjson_mut_is_uint(const yyjson_mut_val *val) {
5951 return val ? unsafe_yyjson_is_uint(val) : false;
5952}
5953
5954yyjson_api_inline bool yyjson_mut_is_sint(const yyjson_mut_val *val) {
5955 return val ? unsafe_yyjson_is_sint(val) : false;
5956}
5957
5958yyjson_api_inline bool yyjson_mut_is_int(const yyjson_mut_val *val) {
5959 return val ? unsafe_yyjson_is_int(val) : false;
5960}
5961
5962yyjson_api_inline bool yyjson_mut_is_real(const yyjson_mut_val *val) {
5963 return val ? unsafe_yyjson_is_real(val) : false;
5964}
5965
5966yyjson_api_inline bool yyjson_mut_is_num(const yyjson_mut_val *val) {
5967 return val ? unsafe_yyjson_is_num(val) : false;
5968}
5969
5970yyjson_api_inline bool yyjson_mut_is_str(const yyjson_mut_val *val) {
5971 return val ? unsafe_yyjson_is_str(val) : false;
5972}
5973
5974yyjson_api_inline bool yyjson_mut_is_arr(const yyjson_mut_val *val) {
5975 return val ? unsafe_yyjson_is_arr(val) : false;
5976}
5977
5978yyjson_api_inline bool yyjson_mut_is_obj(const yyjson_mut_val *val) {
5979 return val ? unsafe_yyjson_is_obj(val) : false;
5980}
5981
5982yyjson_api_inline bool yyjson_mut_is_ctn(const yyjson_mut_val *val) {
5983 return val ? unsafe_yyjson_is_ctn(val) : false;
5984}
5985
5986
5987
5988/*==============================================================================
5989 * MARK: - Mutable JSON Value Content API (Implementation)
5990 *============================================================================*/
5991
5992yyjson_api_inline yyjson_type yyjson_mut_get_type(const yyjson_mut_val *val) {
5993 return yyjson_get_type((const yyjson_val *)val);
5994}
5995
5996yyjson_api_inline yyjson_subtype yyjson_mut_get_subtype(
5997 const yyjson_mut_val *val) {
5998 return yyjson_get_subtype((const yyjson_val *)val);
5999}
6000
6001yyjson_api_inline uint8_t yyjson_mut_get_tag(const yyjson_mut_val *val) {
6002 return yyjson_get_tag((const yyjson_val *)val);
6003}
6004
6005yyjson_api_inline const char *yyjson_mut_get_type_desc(
6006 const yyjson_mut_val *val) {
6007 return yyjson_get_type_desc((const yyjson_val *)val);
6008}
6009
6010yyjson_api_inline const char *yyjson_mut_get_raw(const yyjson_mut_val *val) {
6011 return yyjson_get_raw((const yyjson_val *)val);
6012}
6013
6014yyjson_api_inline bool yyjson_mut_get_bool(const yyjson_mut_val *val) {
6015 return yyjson_get_bool((const yyjson_val *)val);
6016}
6017
6018yyjson_api_inline uint64_t yyjson_mut_get_uint(const yyjson_mut_val *val) {
6019 return yyjson_get_uint((const yyjson_val *)val);
6020}
6021
6022yyjson_api_inline int64_t yyjson_mut_get_sint(const yyjson_mut_val *val) {
6023 return yyjson_get_sint((const yyjson_val *)val);
6024}
6025
6026yyjson_api_inline int yyjson_mut_get_int(const yyjson_mut_val *val) {
6027 return yyjson_get_int((const yyjson_val *)val);
6028}
6029
6030yyjson_api_inline double yyjson_mut_get_real(const yyjson_mut_val *val) {
6031 return yyjson_get_real((const yyjson_val *)val);
6032}
6033
6034yyjson_api_inline double yyjson_mut_get_num(const yyjson_mut_val *val) {
6035 return yyjson_get_num((const yyjson_val *)val);
6036}
6037
6038yyjson_api_inline const char *yyjson_mut_get_str(const yyjson_mut_val *val) {
6039 return yyjson_get_str((const yyjson_val *)val);
6040}
6041
6042yyjson_api_inline size_t yyjson_mut_get_len(const yyjson_mut_val *val) {
6043 return yyjson_get_len((const yyjson_val *)val);
6044}
6045
6046yyjson_api_inline bool yyjson_mut_equals_str(const yyjson_mut_val *val,
6047 const char *str) {
6048 return yyjson_equals_str((const yyjson_val *)val, str);
6049}
6050
6051yyjson_api_inline bool yyjson_mut_equals_strn(const yyjson_mut_val *val,
6052 const char *str, size_t len) {
6053 return yyjson_equals_strn((const yyjson_val *)val, str, len);
6054}
6055
6056yyjson_api bool unsafe_yyjson_mut_equals(const yyjson_mut_val *lhs,
6057 const yyjson_mut_val *rhs);
6058
6059yyjson_api_inline bool yyjson_mut_equals(const yyjson_mut_val *lhs,
6060 const yyjson_mut_val *rhs) {
6061 if (yyjson_unlikely(!lhs || !rhs)) return false;
6062 return unsafe_yyjson_mut_equals(lhs, rhs);
6063}
6064
6065yyjson_api_inline bool yyjson_mut_set_raw(yyjson_mut_val *val,
6066 const char *raw, size_t len) {
6067 if (yyjson_unlikely(!val || !raw)) return false;
6068 unsafe_yyjson_set_raw(val, raw, len);
6069 return true;
6070}
6071
6072yyjson_api_inline bool yyjson_mut_set_null(yyjson_mut_val *val) {
6073 if (yyjson_unlikely(!val)) return false;
6074 unsafe_yyjson_set_null(val);
6075 return true;
6076}
6077
6078yyjson_api_inline bool yyjson_mut_set_bool(yyjson_mut_val *val, bool num) {
6079 if (yyjson_unlikely(!val)) return false;
6080 unsafe_yyjson_set_bool(val, num);
6081 return true;
6082}
6083
6084yyjson_api_inline bool yyjson_mut_set_uint(yyjson_mut_val *val, uint64_t num) {
6085 if (yyjson_unlikely(!val)) return false;
6086 unsafe_yyjson_set_uint(val, num);
6087 return true;
6088}
6089
6090yyjson_api_inline bool yyjson_mut_set_sint(yyjson_mut_val *val, int64_t num) {
6091 if (yyjson_unlikely(!val)) return false;
6092 unsafe_yyjson_set_sint(val, num);
6093 return true;
6094}
6095
6096yyjson_api_inline bool yyjson_mut_set_int(yyjson_mut_val *val, int64_t num) {
6097 if (yyjson_unlikely(!val)) return false;
6098 unsafe_yyjson_set_sint(val, num);
6099 return true;
6100}
6101
6102yyjson_api_inline bool yyjson_mut_set_float(yyjson_mut_val *val, float num) {
6103 if (yyjson_unlikely(!val)) return false;
6104 unsafe_yyjson_set_float(val, num);
6105 return true;
6106}
6107
6108yyjson_api_inline bool yyjson_mut_set_double(yyjson_mut_val *val, double num) {
6109 if (yyjson_unlikely(!val)) return false;
6110 unsafe_yyjson_set_double(val, num);
6111 return true;
6112}
6113
6114yyjson_api_inline bool yyjson_mut_set_real(yyjson_mut_val *val, double num) {
6115 if (yyjson_unlikely(!val)) return false;
6116 unsafe_yyjson_set_real(val, num);
6117 return true;
6118}
6119
6120yyjson_api_inline bool yyjson_mut_set_fp_to_fixed(yyjson_mut_val *val,
6121 int prec) {
6122 if (yyjson_unlikely(!yyjson_mut_is_real(val))) return false;
6123 unsafe_yyjson_set_fp_to_fixed(val, prec);
6124 return true;
6125}
6126
6127yyjson_api_inline bool yyjson_mut_set_fp_to_float(yyjson_mut_val *val,
6128 bool flt) {
6129 if (yyjson_unlikely(!yyjson_mut_is_real(val))) return false;
6130 unsafe_yyjson_set_fp_to_float(val, flt);
6131 return true;
6132}
6133
6134yyjson_api_inline bool yyjson_mut_set_str(yyjson_mut_val *val,
6135 const char *str) {
6136 if (yyjson_unlikely(!val || !str)) return false;
6137 unsafe_yyjson_set_str(val, str);
6138 return true;
6139}
6140
6141yyjson_api_inline bool yyjson_mut_set_strn(yyjson_mut_val *val,
6142 const char *str, size_t len) {
6143 if (yyjson_unlikely(!val || !str)) return false;
6144 unsafe_yyjson_set_strn(val, str, len);
6145 return true;
6146}
6147
6148yyjson_api_inline bool yyjson_mut_set_str_noesc(yyjson_mut_val *val,
6149 bool noesc) {
6150 if (yyjson_unlikely(!yyjson_mut_is_str(val))) return false;
6151 unsafe_yyjson_set_str_noesc(val, noesc);
6152 return true;
6153}
6154
6155yyjson_api_inline bool yyjson_mut_set_arr(yyjson_mut_val *val) {
6156 if (yyjson_unlikely(!val)) return false;
6157 unsafe_yyjson_set_arr(val, 0);
6158 return true;
6159}
6160
6161yyjson_api_inline bool yyjson_mut_set_obj(yyjson_mut_val *val) {
6162 if (yyjson_unlikely(!val)) return false;
6163 unsafe_yyjson_set_obj(val, 0);
6164 return true;
6165}
6166
6167
6168
6169/*==============================================================================
6170 * MARK: - Mutable JSON Value Creation API (Implementation)
6171 *============================================================================*/
6172
6173#define yyjson_mut_val_one(func) \
6174 if (yyjson_likely(doc)) { \
6175 yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1); \
6176 if (yyjson_likely(val)) { \
6177 func \
6178 return val; \
6179 } \
6180 } \
6181 return NULL
6182
6183#define yyjson_mut_val_one_str(func) \
6184 if (yyjson_likely(doc && str)) { \
6185 yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1); \
6186 if (yyjson_likely(val)) { \
6187 func \
6188 return val; \
6189 } \
6190 } \
6191 return NULL
6192
6193yyjson_api_inline yyjson_mut_val *yyjson_mut_raw(yyjson_mut_doc *doc,
6194 const char *str) {
6195 yyjson_mut_val_one_str({ unsafe_yyjson_set_raw(val, str, strlen(str)); });
6196}
6197
6198yyjson_api_inline yyjson_mut_val *yyjson_mut_rawn(yyjson_mut_doc *doc,
6199 const char *str,
6200 size_t len) {
6201 yyjson_mut_val_one_str({ unsafe_yyjson_set_raw(val, str, len); });
6202}
6203
6204yyjson_api_inline yyjson_mut_val *yyjson_mut_rawcpy(yyjson_mut_doc *doc,
6205 const char *str) {
6206 yyjson_mut_val_one_str({
6207 size_t len = strlen(str);
6208 char *new_str = unsafe_yyjson_mut_strncpy(doc, str, len);
6209 if (yyjson_unlikely(!new_str)) return NULL;
6210 unsafe_yyjson_set_raw(val, new_str, len);
6211 });
6212}
6213
6214yyjson_api_inline yyjson_mut_val *yyjson_mut_rawncpy(yyjson_mut_doc *doc,
6215 const char *str,
6216 size_t len) {
6217 yyjson_mut_val_one_str({
6218 char *new_str = unsafe_yyjson_mut_strncpy(doc, str, len);
6219 if (yyjson_unlikely(!new_str)) return NULL;
6220 unsafe_yyjson_set_raw(val, new_str, len);
6221 });
6222}
6223
6224yyjson_api_inline yyjson_mut_val *yyjson_mut_null(yyjson_mut_doc *doc) {
6225 yyjson_mut_val_one({ unsafe_yyjson_set_null(val); });
6226}
6227
6228yyjson_api_inline yyjson_mut_val *yyjson_mut_true(yyjson_mut_doc *doc) {
6229 yyjson_mut_val_one({ unsafe_yyjson_set_bool(val, true); });
6230}
6231
6232yyjson_api_inline yyjson_mut_val *yyjson_mut_false(yyjson_mut_doc *doc) {
6233 yyjson_mut_val_one({ unsafe_yyjson_set_bool(val, false); });
6234}
6235
6236yyjson_api_inline yyjson_mut_val *yyjson_mut_bool(yyjson_mut_doc *doc,
6237 bool _val) {
6238 yyjson_mut_val_one({ unsafe_yyjson_set_bool(val, _val); });
6239}
6240
6241yyjson_api_inline yyjson_mut_val *yyjson_mut_uint(yyjson_mut_doc *doc,
6242 uint64_t num) {
6243 yyjson_mut_val_one({ unsafe_yyjson_set_uint(val, num); });
6244}
6245
6246yyjson_api_inline yyjson_mut_val *yyjson_mut_sint(yyjson_mut_doc *doc,
6247 int64_t num) {
6248 yyjson_mut_val_one({ unsafe_yyjson_set_sint(val, num); });
6249}
6250
6251yyjson_api_inline yyjson_mut_val *yyjson_mut_int(yyjson_mut_doc *doc,
6252 int64_t num) {
6253 yyjson_mut_val_one({ unsafe_yyjson_set_sint(val, num); });
6254}
6255
6256yyjson_api_inline yyjson_mut_val *yyjson_mut_float(yyjson_mut_doc *doc,
6257 float num) {
6258 yyjson_mut_val_one({ unsafe_yyjson_set_float(val, num); });
6259}
6260
6261yyjson_api_inline yyjson_mut_val *yyjson_mut_double(yyjson_mut_doc *doc,
6262 double num) {
6263 yyjson_mut_val_one({ unsafe_yyjson_set_double(val, num); });
6264}
6265
6266yyjson_api_inline yyjson_mut_val *yyjson_mut_real(yyjson_mut_doc *doc,
6267 double num) {
6268 yyjson_mut_val_one({ unsafe_yyjson_set_real(val, num); });
6269}
6270
6271yyjson_api_inline yyjson_mut_val *yyjson_mut_str(yyjson_mut_doc *doc,
6272 const char *str) {
6273 yyjson_mut_val_one_str({ unsafe_yyjson_set_str(val, str); });
6274}
6275
6276yyjson_api_inline yyjson_mut_val *yyjson_mut_strn(yyjson_mut_doc *doc,
6277 const char *str,
6278 size_t len) {
6279 yyjson_mut_val_one_str({ unsafe_yyjson_set_strn(val, str, len); });
6280}
6281
6282yyjson_api_inline yyjson_mut_val *yyjson_mut_strcpy(yyjson_mut_doc *doc,
6283 const char *str) {
6284 yyjson_mut_val_one_str({
6285 size_t len = strlen(str);
6286 bool noesc = unsafe_yyjson_is_str_noesc(str, len);
6287 yyjson_subtype sub = noesc ? YYJSON_SUBTYPE_NOESC : YYJSON_SUBTYPE_NONE;
6288 char *new_str = unsafe_yyjson_mut_strncpy(doc, str, len);
6289 if (yyjson_unlikely(!new_str)) return NULL;
6290 unsafe_yyjson_set_tag(val, YYJSON_TYPE_STR, sub, len);
6291 val->uni.str = new_str;
6292 });
6293}
6294
6295yyjson_api_inline yyjson_mut_val *yyjson_mut_strncpy(yyjson_mut_doc *doc,
6296 const char *str,
6297 size_t len) {
6298 yyjson_mut_val_one_str({
6299 char *new_str = unsafe_yyjson_mut_strncpy(doc, str, len);
6300 if (yyjson_unlikely(!new_str)) return NULL;
6301 unsafe_yyjson_set_strn(val, new_str, len);
6302 });
6303}
6304
6305#undef yyjson_mut_val_one
6306#undef yyjson_mut_val_one_str
6307
6308
6309
6310/*==============================================================================
6311 * MARK: - Mutable JSON Array API (Implementation)
6312 *============================================================================*/
6313
6314yyjson_api_inline size_t yyjson_mut_arr_size(const yyjson_mut_val *arr) {
6315 return yyjson_mut_is_arr(arr) ? unsafe_yyjson_get_len(arr) : 0;
6316}
6317
6318yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_get(const yyjson_mut_val *arr,
6319 size_t idx) {
6320 if (yyjson_likely(idx < yyjson_mut_arr_size(arr))) {
6321 yyjson_mut_val *val = (yyjson_mut_val *)arr->uni.ptr;
6322 while (idx-- > 0) val = val->next;
6323 return val->next;
6324 }
6325 return NULL;
6326}
6327
6328yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_get_first(
6329 const yyjson_mut_val *arr) {
6330 if (yyjson_likely(yyjson_mut_arr_size(arr) > 0)) {
6331 return ((yyjson_mut_val *)arr->uni.ptr)->next;
6332 }
6333 return NULL;
6334}
6335
6336yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_get_last(
6337 const yyjson_mut_val *arr) {
6338 if (yyjson_likely(yyjson_mut_arr_size(arr) > 0)) {
6339 return ((yyjson_mut_val *)arr->uni.ptr);
6340 }
6341 return NULL;
6342}
6343
6344
6345
6346/*==============================================================================
6347 * MARK: - Mutable JSON Array Iterator API (Implementation)
6348 *============================================================================*/
6349
6350yyjson_api_inline bool yyjson_mut_arr_iter_init(yyjson_mut_val *arr,
6351 yyjson_mut_arr_iter *iter) {
6352 if (yyjson_likely(yyjson_mut_is_arr(arr) && iter)) {
6353 iter->idx = 0;
6354 iter->max = unsafe_yyjson_get_len(arr);
6355 iter->cur = iter->max ? (yyjson_mut_val *)arr->uni.ptr : NULL;
6356 iter->pre = NULL;
6357 iter->arr = arr;
6358 return true;
6359 }
6360 if (iter) memset(iter, 0, sizeof(yyjson_mut_arr_iter));
6361 return false;
6362}
6363
6364yyjson_api_inline yyjson_mut_arr_iter yyjson_mut_arr_iter_with(
6365 yyjson_mut_val *arr) {
6366 yyjson_mut_arr_iter iter;
6367 yyjson_mut_arr_iter_init(arr, &iter);
6368 return iter;
6369}
6370
6371yyjson_api_inline bool yyjson_mut_arr_iter_has_next(yyjson_mut_arr_iter *iter) {
6372 return iter ? iter->idx < iter->max : false;
6373}
6374
6375yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_iter_next(
6376 yyjson_mut_arr_iter *iter) {
6377 if (iter && iter->idx < iter->max) {
6378 yyjson_mut_val *val = iter->cur;
6379 iter->pre = val;
6380 iter->cur = val->next;
6381 iter->idx++;
6382 return iter->cur;
6383 }
6384 return NULL;
6385}
6386
6387yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_iter_remove(
6388 yyjson_mut_arr_iter *iter) {
6389 if (yyjson_likely(iter && 0 < iter->idx && iter->idx <= iter->max)) {
6390 yyjson_mut_val *prev = iter->pre;
6391 yyjson_mut_val *cur = iter->cur;
6392 yyjson_mut_val *next = cur->next;
6393 if (yyjson_unlikely(iter->idx == iter->max)) iter->arr->uni.ptr = prev;
6394 iter->idx--;
6395 iter->max--;
6396 unsafe_yyjson_set_len(iter->arr, iter->max);
6397 prev->next = next;
6398 iter->cur = prev;
6399 return cur;
6400 }
6401 return NULL;
6402}
6403
6404
6405
6406/*==============================================================================
6407 * MARK: - Mutable JSON Array Creation API (Implementation)
6408 *============================================================================*/
6409
6410yyjson_api_inline yyjson_mut_val *yyjson_mut_arr(yyjson_mut_doc *doc) {
6411 if (yyjson_likely(doc)) {
6412 yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1);
6413 if (yyjson_likely(val)) {
6414 val->tag = YYJSON_TYPE_ARR | YYJSON_SUBTYPE_NONE;
6415 return val;
6416 }
6417 }
6418 return NULL;
6419}
6420
6421#define yyjson_mut_arr_with_func(func) \
6422 if (yyjson_likely(doc && ((0 < count && count < \
6423 (~(size_t)0) / sizeof(yyjson_mut_val) && vals) || count == 0))) { \
6424 yyjson_mut_val *arr = unsafe_yyjson_mut_val(doc, 1 + count); \
6425 if (yyjson_likely(arr)) { \
6426 arr->tag = ((uint64_t)count << YYJSON_TAG_BIT) | YYJSON_TYPE_ARR; \
6427 if (count > 0) { \
6428 size_t i; \
6429 for (i = 0; i < count; i++) { \
6430 yyjson_mut_val *val = arr + i + 1; \
6431 func \
6432 val->next = val + 1; \
6433 } \
6434 arr[count].next = arr + 1; \
6435 arr->uni.ptr = arr + count; \
6436 } \
6437 return arr; \
6438 } \
6439 } \
6440 return NULL
6441
6442yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_bool(
6443 yyjson_mut_doc *doc, const bool *vals, size_t count) {
6444 yyjson_mut_arr_with_func({
6445 unsafe_yyjson_set_bool(val, vals[i]);
6446 });
6447}
6448
6449yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_sint(
6450 yyjson_mut_doc *doc, const int64_t *vals, size_t count) {
6451 return yyjson_mut_arr_with_sint64(doc, vals, count);
6452}
6453
6454yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_uint(
6455 yyjson_mut_doc *doc, const uint64_t *vals, size_t count) {
6456 return yyjson_mut_arr_with_uint64(doc, vals, count);
6457}
6458
6459yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_real(
6460 yyjson_mut_doc *doc, const double *vals, size_t count) {
6461 yyjson_mut_arr_with_func({
6462 unsafe_yyjson_set_real(val, vals[i]);
6463 });
6464}
6465
6466yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_sint8(
6467 yyjson_mut_doc *doc, const int8_t *vals, size_t count) {
6468 yyjson_mut_arr_with_func({
6469 unsafe_yyjson_set_sint(val, vals[i]);
6470 });
6471}
6472
6473yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_sint16(
6474 yyjson_mut_doc *doc, const int16_t *vals, size_t count) {
6475 yyjson_mut_arr_with_func({
6476 unsafe_yyjson_set_sint(val, vals[i]);
6477 });
6478}
6479
6480yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_sint32(
6481 yyjson_mut_doc *doc, const int32_t *vals, size_t count) {
6482 yyjson_mut_arr_with_func({
6483 unsafe_yyjson_set_sint(val, vals[i]);
6484 });
6485}
6486
6487yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_sint64(
6488 yyjson_mut_doc *doc, const int64_t *vals, size_t count) {
6489 yyjson_mut_arr_with_func({
6490 unsafe_yyjson_set_sint(val, vals[i]);
6491 });
6492}
6493
6494yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_uint8(
6495 yyjson_mut_doc *doc, const uint8_t *vals, size_t count) {
6496 yyjson_mut_arr_with_func({
6497 unsafe_yyjson_set_uint(val, vals[i]);
6498 });
6499}
6500
6501yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_uint16(
6502 yyjson_mut_doc *doc, const uint16_t *vals, size_t count) {
6503 yyjson_mut_arr_with_func({
6504 unsafe_yyjson_set_uint(val, vals[i]);
6505 });
6506}
6507
6508yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_uint32(
6509 yyjson_mut_doc *doc, const uint32_t *vals, size_t count) {
6510 yyjson_mut_arr_with_func({
6511 unsafe_yyjson_set_uint(val, vals[i]);
6512 });
6513}
6514
6515yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_uint64(
6516 yyjson_mut_doc *doc, const uint64_t *vals, size_t count) {
6517 yyjson_mut_arr_with_func({
6518 unsafe_yyjson_set_uint(val, vals[i]);
6519 });
6520}
6521
6522yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_float(
6523 yyjson_mut_doc *doc, const float *vals, size_t count) {
6524 yyjson_mut_arr_with_func({
6525 unsafe_yyjson_set_float(val, vals[i]);
6526 });
6527}
6528
6529yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_double(
6530 yyjson_mut_doc *doc, const double *vals, size_t count) {
6531 yyjson_mut_arr_with_func({
6532 unsafe_yyjson_set_double(val, vals[i]);
6533 });
6534}
6535
6536yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_str(
6537 yyjson_mut_doc *doc, const char **vals, size_t count) {
6538 yyjson_mut_arr_with_func({
6539 if (yyjson_unlikely(!vals[i])) return NULL;
6540 unsafe_yyjson_set_str(val, vals[i]);
6541 });
6542}
6543
6544yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_strn(
6545 yyjson_mut_doc *doc, const char **vals, const size_t *lens, size_t count) {
6546 if (yyjson_unlikely(count > 0 && !lens)) return NULL;
6547 yyjson_mut_arr_with_func({
6548 if (yyjson_unlikely(!vals[i])) return NULL;
6549 unsafe_yyjson_set_strn(val, vals[i], lens[i]);
6550 });
6551}
6552
6553yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_strcpy(
6554 yyjson_mut_doc *doc, const char **vals, size_t count) {
6555 size_t len;
6556 const char *str, *new_str;
6557 yyjson_mut_arr_with_func({
6558 str = vals[i];
6559 if (yyjson_unlikely(!str)) return NULL;
6560 len = strlen(str);
6561 new_str = unsafe_yyjson_mut_strncpy(doc, str, len);
6562 if (yyjson_unlikely(!new_str)) return NULL;
6563 unsafe_yyjson_set_strn(val, new_str, len);
6564 });
6565}
6566
6567yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_with_strncpy(
6568 yyjson_mut_doc *doc, const char **vals, const size_t *lens, size_t count) {
6569 size_t len;
6570 const char *str, *new_str;
6571 if (yyjson_unlikely(count > 0 && !lens)) return NULL;
6572 yyjson_mut_arr_with_func({
6573 str = vals[i];
6574 if (yyjson_unlikely(!str)) return NULL;
6575 len = lens[i];
6576 new_str = unsafe_yyjson_mut_strncpy(doc, str, len);
6577 if (yyjson_unlikely(!new_str)) return NULL;
6578 unsafe_yyjson_set_strn(val, new_str, len);
6579 });
6580}
6581
6582#undef yyjson_mut_arr_with_func
6583
6584
6585
6586/*==============================================================================
6587 * MARK: - Mutable JSON Array Modification API (Implementation)
6588 *============================================================================*/
6589
6590yyjson_api_inline bool yyjson_mut_arr_insert(yyjson_mut_val *arr,
6591 yyjson_mut_val *val, size_t idx) {
6592 if (yyjson_likely(yyjson_mut_is_arr(arr) && val)) {
6593 size_t len = unsafe_yyjson_get_len(arr);
6594 if (yyjson_likely(idx <= len)) {
6595 unsafe_yyjson_set_len(arr, len + 1);
6596 if (len == 0) {
6597 val->next = val;
6598 arr->uni.ptr = val;
6599 } else {
6600 yyjson_mut_val *prev = ((yyjson_mut_val *)arr->uni.ptr);
6601 yyjson_mut_val *next = prev->next;
6602 if (idx == len) {
6603 prev->next = val;
6604 val->next = next;
6605 arr->uni.ptr = val;
6606 } else {
6607 while (idx-- > 0) {
6608 prev = next;
6609 next = next->next;
6610 }
6611 prev->next = val;
6612 val->next = next;
6613 }
6614 }
6615 return true;
6616 }
6617 }
6618 return false;
6619}
6620
6621yyjson_api_inline bool yyjson_mut_arr_append(yyjson_mut_val *arr,
6622 yyjson_mut_val *val) {
6623 if (yyjson_likely(yyjson_mut_is_arr(arr) && val)) {
6624 size_t len = unsafe_yyjson_get_len(arr);
6625 unsafe_yyjson_set_len(arr, len + 1);
6626 if (len == 0) {
6627 val->next = val;
6628 } else {
6629 yyjson_mut_val *prev = ((yyjson_mut_val *)arr->uni.ptr);
6630 yyjson_mut_val *next = prev->next;
6631 prev->next = val;
6632 val->next = next;
6633 }
6634 arr->uni.ptr = val;
6635 return true;
6636 }
6637 return false;
6638}
6639
6640yyjson_api_inline bool yyjson_mut_arr_prepend(yyjson_mut_val *arr,
6641 yyjson_mut_val *val) {
6642 if (yyjson_likely(yyjson_mut_is_arr(arr) && val)) {
6643 size_t len = unsafe_yyjson_get_len(arr);
6644 unsafe_yyjson_set_len(arr, len + 1);
6645 if (len == 0) {
6646 val->next = val;
6647 arr->uni.ptr = val;
6648 } else {
6649 yyjson_mut_val *prev = ((yyjson_mut_val *)arr->uni.ptr);
6650 yyjson_mut_val *next = prev->next;
6651 prev->next = val;
6652 val->next = next;
6653 }
6654 return true;
6655 }
6656 return false;
6657}
6658
6659yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_replace(yyjson_mut_val *arr,
6660 size_t idx,
6661 yyjson_mut_val *val) {
6662 if (yyjson_likely(yyjson_mut_is_arr(arr) && val)) {
6663 size_t len = unsafe_yyjson_get_len(arr);
6664 if (yyjson_likely(idx < len)) {
6665 if (yyjson_likely(len > 1)) {
6666 yyjson_mut_val *prev = ((yyjson_mut_val *)arr->uni.ptr);
6667 yyjson_mut_val *next = prev->next;
6668 while (idx-- > 0) {
6669 prev = next;
6670 next = next->next;
6671 }
6672 prev->next = val;
6673 val->next = next->next;
6674 if ((void *)next == arr->uni.ptr) arr->uni.ptr = val;
6675 return next;
6676 } else {
6677 yyjson_mut_val *prev = ((yyjson_mut_val *)arr->uni.ptr);
6678 val->next = val;
6679 arr->uni.ptr = val;
6680 return prev;
6681 }
6682 }
6683 }
6684 return NULL;
6685}
6686
6687yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_remove(yyjson_mut_val *arr,
6688 size_t idx) {
6689 if (yyjson_likely(yyjson_mut_is_arr(arr))) {
6690 size_t len = unsafe_yyjson_get_len(arr);
6691 if (yyjson_likely(idx < len)) {
6692 unsafe_yyjson_set_len(arr, len - 1);
6693 if (yyjson_likely(len > 1)) {
6694 yyjson_mut_val *prev = ((yyjson_mut_val *)arr->uni.ptr);
6695 yyjson_mut_val *next = prev->next;
6696 while (idx-- > 0) {
6697 prev = next;
6698 next = next->next;
6699 }
6700 prev->next = next->next;
6701 if ((void *)next == arr->uni.ptr) arr->uni.ptr = prev;
6702 return next;
6703 } else {
6704 return ((yyjson_mut_val *)arr->uni.ptr);
6705 }
6706 }
6707 }
6708 return NULL;
6709}
6710
6711yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_remove_first(
6712 yyjson_mut_val *arr) {
6713 if (yyjson_likely(yyjson_mut_is_arr(arr))) {
6714 size_t len = unsafe_yyjson_get_len(arr);
6715 if (len > 1) {
6716 yyjson_mut_val *prev = ((yyjson_mut_val *)arr->uni.ptr);
6717 yyjson_mut_val *next = prev->next;
6718 prev->next = next->next;
6719 unsafe_yyjson_set_len(arr, len - 1);
6720 return next;
6721 } else if (len == 1) {
6722 yyjson_mut_val *prev = ((yyjson_mut_val *)arr->uni.ptr);
6723 unsafe_yyjson_set_len(arr, 0);
6724 return prev;
6725 }
6726 }
6727 return NULL;
6728}
6729
6730yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_remove_last(
6731 yyjson_mut_val *arr) {
6732 if (yyjson_likely(yyjson_mut_is_arr(arr))) {
6733 size_t len = unsafe_yyjson_get_len(arr);
6734 if (yyjson_likely(len > 1)) {
6735 yyjson_mut_val *prev = ((yyjson_mut_val *)arr->uni.ptr);
6736 yyjson_mut_val *next = prev->next;
6737 unsafe_yyjson_set_len(arr, len - 1);
6738 while (--len > 0) prev = prev->next;
6739 prev->next = next;
6740 next = (yyjson_mut_val *)arr->uni.ptr;
6741 arr->uni.ptr = prev;
6742 return next;
6743 } else if (len == 1) {
6744 yyjson_mut_val *prev = ((yyjson_mut_val *)arr->uni.ptr);
6745 unsafe_yyjson_set_len(arr, 0);
6746 return prev;
6747 }
6748 }
6749 return NULL;
6750}
6751
6752yyjson_api_inline bool yyjson_mut_arr_remove_range(yyjson_mut_val *arr,
6753 size_t _idx, size_t _len) {
6754 if (yyjson_likely(yyjson_mut_is_arr(arr))) {
6755 yyjson_mut_val *prev, *next;
6756 bool tail_removed;
6757 size_t len = unsafe_yyjson_get_len(arr);
6758 if (yyjson_unlikely(_len > len || _idx > len - _len)) return false;
6759 if (yyjson_unlikely(_len == 0)) return true;
6760 unsafe_yyjson_set_len(arr, len - _len);
6761 if (yyjson_unlikely(len == _len)) return true;
6762 tail_removed = (_idx + _len == len);
6763 prev = ((yyjson_mut_val *)arr->uni.ptr);
6764 while (_idx-- > 0) prev = prev->next;
6765 next = prev->next;
6766 while (_len-- > 0) next = next->next;
6767 prev->next = next;
6768 if (yyjson_unlikely(tail_removed)) arr->uni.ptr = prev;
6769 return true;
6770 }
6771 return false;
6772}
6773
6774yyjson_api_inline bool yyjson_mut_arr_clear(yyjson_mut_val *arr) {
6775 if (yyjson_likely(yyjson_mut_is_arr(arr))) {
6776 unsafe_yyjson_set_len(arr, 0);
6777 return true;
6778 }
6779 return false;
6780}
6781
6782yyjson_api_inline bool yyjson_mut_arr_rotate(yyjson_mut_val *arr,
6783 size_t idx) {
6784 if (yyjson_likely(yyjson_mut_is_arr(arr) &&
6785 unsafe_yyjson_get_len(arr) > idx)) {
6786 yyjson_mut_val *val = (yyjson_mut_val *)arr->uni.ptr;
6787 while (idx-- > 0) val = val->next;
6788 arr->uni.ptr = (void *)val;
6789 return true;
6790 }
6791 return false;
6792}
6793
6794
6795
6796/*==============================================================================
6797 * MARK: - Mutable JSON Array Modification Convenience API (Implementation)
6798 *============================================================================*/
6799
6800yyjson_api_inline bool yyjson_mut_arr_add_val(yyjson_mut_val *arr,
6801 yyjson_mut_val *val) {
6802 return yyjson_mut_arr_append(arr, val);
6803}
6804
6805yyjson_api_inline bool yyjson_mut_arr_add_null(yyjson_mut_doc *doc,
6806 yyjson_mut_val *arr) {
6807 if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
6808 yyjson_mut_val *val = yyjson_mut_null(doc);
6809 return yyjson_mut_arr_append(arr, val);
6810 }
6811 return false;
6812}
6813
6814yyjson_api_inline bool yyjson_mut_arr_add_true(yyjson_mut_doc *doc,
6815 yyjson_mut_val *arr) {
6816 if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
6817 yyjson_mut_val *val = yyjson_mut_true(doc);
6818 return yyjson_mut_arr_append(arr, val);
6819 }
6820 return false;
6821}
6822
6823yyjson_api_inline bool yyjson_mut_arr_add_false(yyjson_mut_doc *doc,
6824 yyjson_mut_val *arr) {
6825 if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
6826 yyjson_mut_val *val = yyjson_mut_false(doc);
6827 return yyjson_mut_arr_append(arr, val);
6828 }
6829 return false;
6830}
6831
6832yyjson_api_inline bool yyjson_mut_arr_add_bool(yyjson_mut_doc *doc,
6833 yyjson_mut_val *arr,
6834 bool _val) {
6835 if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
6836 yyjson_mut_val *val = yyjson_mut_bool(doc, _val);
6837 return yyjson_mut_arr_append(arr, val);
6838 }
6839 return false;
6840}
6841
6842yyjson_api_inline bool yyjson_mut_arr_add_uint(yyjson_mut_doc *doc,
6843 yyjson_mut_val *arr,
6844 uint64_t num) {
6845 if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
6846 yyjson_mut_val *val = yyjson_mut_uint(doc, num);
6847 return yyjson_mut_arr_append(arr, val);
6848 }
6849 return false;
6850}
6851
6852yyjson_api_inline bool yyjson_mut_arr_add_sint(yyjson_mut_doc *doc,
6853 yyjson_mut_val *arr,
6854 int64_t num) {
6855 if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
6856 yyjson_mut_val *val = yyjson_mut_sint(doc, num);
6857 return yyjson_mut_arr_append(arr, val);
6858 }
6859 return false;
6860}
6861
6862yyjson_api_inline bool yyjson_mut_arr_add_int(yyjson_mut_doc *doc,
6863 yyjson_mut_val *arr,
6864 int64_t num) {
6865 if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
6866 yyjson_mut_val *val = yyjson_mut_sint(doc, num);
6867 return yyjson_mut_arr_append(arr, val);
6868 }
6869 return false;
6870}
6871
6872yyjson_api_inline bool yyjson_mut_arr_add_float(yyjson_mut_doc *doc,
6873 yyjson_mut_val *arr,
6874 float num) {
6875 if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
6876 yyjson_mut_val *val = yyjson_mut_float(doc, num);
6877 return yyjson_mut_arr_append(arr, val);
6878 }
6879 return false;
6880}
6881
6882yyjson_api_inline bool yyjson_mut_arr_add_double(yyjson_mut_doc *doc,
6883 yyjson_mut_val *arr,
6884 double num) {
6885 if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
6886 yyjson_mut_val *val = yyjson_mut_double(doc, num);
6887 return yyjson_mut_arr_append(arr, val);
6888 }
6889 return false;
6890}
6891
6892yyjson_api_inline bool yyjson_mut_arr_add_real(yyjson_mut_doc *doc,
6893 yyjson_mut_val *arr,
6894 double num) {
6895 if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
6896 yyjson_mut_val *val = yyjson_mut_real(doc, num);
6897 return yyjson_mut_arr_append(arr, val);
6898 }
6899 return false;
6900}
6901
6902yyjson_api_inline bool yyjson_mut_arr_add_str(yyjson_mut_doc *doc,
6903 yyjson_mut_val *arr,
6904 const char *str) {
6905 if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
6906 yyjson_mut_val *val = yyjson_mut_str(doc, str);
6907 return yyjson_mut_arr_append(arr, val);
6908 }
6909 return false;
6910}
6911
6912yyjson_api_inline bool yyjson_mut_arr_add_strn(yyjson_mut_doc *doc,
6913 yyjson_mut_val *arr,
6914 const char *str, size_t len) {
6915 if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
6916 yyjson_mut_val *val = yyjson_mut_strn(doc, str, len);
6917 return yyjson_mut_arr_append(arr, val);
6918 }
6919 return false;
6920}
6921
6922yyjson_api_inline bool yyjson_mut_arr_add_strcpy(yyjson_mut_doc *doc,
6923 yyjson_mut_val *arr,
6924 const char *str) {
6925 if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
6926 yyjson_mut_val *val = yyjson_mut_strcpy(doc, str);
6927 return yyjson_mut_arr_append(arr, val);
6928 }
6929 return false;
6930}
6931
6932yyjson_api_inline bool yyjson_mut_arr_add_strncpy(yyjson_mut_doc *doc,
6933 yyjson_mut_val *arr,
6934 const char *str, size_t len) {
6935 if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
6936 yyjson_mut_val *val = yyjson_mut_strncpy(doc, str, len);
6937 return yyjson_mut_arr_append(arr, val);
6938 }
6939 return false;
6940}
6941
6942yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_add_arr(yyjson_mut_doc *doc,
6943 yyjson_mut_val *arr) {
6944 if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
6945 yyjson_mut_val *val = yyjson_mut_arr(doc);
6946 return yyjson_mut_arr_append(arr, val) ? val : NULL;
6947 }
6948 return NULL;
6949}
6950
6951yyjson_api_inline yyjson_mut_val *yyjson_mut_arr_add_obj(yyjson_mut_doc *doc,
6952 yyjson_mut_val *arr) {
6953 if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
6954 yyjson_mut_val *val = yyjson_mut_obj(doc);
6955 return yyjson_mut_arr_append(arr, val) ? val : NULL;
6956 }
6957 return NULL;
6958}
6959
6960
6961
6962/*==============================================================================
6963 * MARK: - Mutable JSON Object API (Implementation)
6964 *============================================================================*/
6965
6966yyjson_api_inline size_t yyjson_mut_obj_size(const yyjson_mut_val *obj) {
6967 return yyjson_mut_is_obj(obj) ? unsafe_yyjson_get_len(obj) : 0;
6968}
6969
6970yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_get(const yyjson_mut_val *obj,
6971 const char *key) {
6972 return yyjson_mut_obj_getn(obj, key, key ? strlen(key) : 0);
6973}
6974
6975yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_getn(const yyjson_mut_val *obj,
6976 const char *_key,
6977 size_t key_len) {
6978 size_t len = yyjson_mut_obj_size(obj);
6979 if (yyjson_likely(len && _key)) {
6980 yyjson_mut_val *key = ((yyjson_mut_val *)obj->uni.ptr)->next->next;
6981 while (len-- > 0) {
6982 if (unsafe_yyjson_equals_strn(key, _key, key_len)) return key->next;
6983 key = key->next->next;
6984 }
6985 }
6986 return NULL;
6987}
6988
6989
6990
6991/*==============================================================================
6992 * MARK: - Mutable JSON Object Iterator API (Implementation)
6993 *============================================================================*/
6994
6995yyjson_api_inline bool yyjson_mut_obj_iter_init(yyjson_mut_val *obj,
6996 yyjson_mut_obj_iter *iter) {
6997 if (yyjson_likely(yyjson_mut_is_obj(obj) && iter)) {
6998 iter->idx = 0;
6999 iter->max = unsafe_yyjson_get_len(obj);
7000 iter->cur = iter->max ? (yyjson_mut_val *)obj->uni.ptr : NULL;
7001 iter->pre = NULL;
7002 iter->obj = obj;
7003 return true;
7004 }
7005 if (iter) memset(iter, 0, sizeof(yyjson_mut_obj_iter));
7006 return false;
7007}
7008
7009yyjson_api_inline yyjson_mut_obj_iter yyjson_mut_obj_iter_with(
7010 yyjson_mut_val *obj) {
7011 yyjson_mut_obj_iter iter;
7012 yyjson_mut_obj_iter_init(obj, &iter);
7013 return iter;
7014}
7015
7016yyjson_api_inline bool yyjson_mut_obj_iter_has_next(yyjson_mut_obj_iter *iter) {
7017 return iter ? iter->idx < iter->max : false;
7018}
7019
7020yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_iter_next(
7021 yyjson_mut_obj_iter *iter) {
7022 if (iter && iter->idx < iter->max) {
7023 yyjson_mut_val *key = iter->cur;
7024 iter->pre = key;
7025 iter->cur = key->next->next;
7026 iter->idx++;
7027 return iter->cur;
7028 }
7029 return NULL;
7030}
7031
7032yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_iter_get_val(
7033 yyjson_mut_val *key) {
7034 return key ? key->next : NULL;
7035}
7036
7037yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_iter_remove(
7038 yyjson_mut_obj_iter *iter) {
7039 if (yyjson_likely(iter && 0 < iter->idx && iter->idx <= iter->max)) {
7040 yyjson_mut_val *prev = iter->pre;
7041 yyjson_mut_val *cur = iter->cur;
7042 yyjson_mut_val *next = cur->next->next;
7043 if (yyjson_unlikely(iter->idx == iter->max)) iter->obj->uni.ptr = prev;
7044 iter->idx--;
7045 iter->max--;
7046 unsafe_yyjson_set_len(iter->obj, iter->max);
7047 prev->next->next = next;
7048 iter->cur = prev;
7049 return cur->next;
7050 }
7051 return NULL;
7052}
7053
7054yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_iter_get(
7055 yyjson_mut_obj_iter *iter, const char *key) {
7056 return yyjson_mut_obj_iter_getn(iter, key, key ? strlen(key) : 0);
7057}
7058
7059yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_iter_getn(
7060 yyjson_mut_obj_iter *iter, const char *key, size_t key_len) {
7061 if (iter && key) {
7062 size_t idx = 0;
7063 size_t max = iter->max;
7064 yyjson_mut_val *pre, *cur = iter->cur;
7065 while (idx++ < max) {
7066 pre = cur;
7067 cur = cur->next->next;
7068 if (unsafe_yyjson_equals_strn(cur, key, key_len)) {
7069 iter->idx += idx;
7070 if (iter->idx > max) iter->idx -= max;
7071 iter->pre = pre;
7072 iter->cur = cur;
7073 return cur->next;
7074 }
7075 }
7076 }
7077 return NULL;
7078}
7079
7080
7081
7082/*==============================================================================
7083 * MARK: - Mutable JSON Object Creation API (Implementation)
7084 *============================================================================*/
7085
7086yyjson_api_inline yyjson_mut_val *yyjson_mut_obj(yyjson_mut_doc *doc) {
7087 if (yyjson_likely(doc)) {
7088 yyjson_mut_val *val = unsafe_yyjson_mut_val(doc, 1);
7089 if (yyjson_likely(val)) {
7090 val->tag = YYJSON_TYPE_OBJ | YYJSON_SUBTYPE_NONE;
7091 return val;
7092 }
7093 }
7094 return NULL;
7095}
7096
7097yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_with_str(yyjson_mut_doc *doc,
7098 const char **keys,
7099 const char **vals,
7100 size_t count) {
7101 if (yyjson_likely(doc && ((count > 0 && count <
7102 (~(size_t)0) / sizeof(yyjson_mut_val) / 2 &&
7103 keys && vals) || (count == 0)))) {
7104 yyjson_mut_val *obj = unsafe_yyjson_mut_val(doc, 1 + count * 2);
7105 if (yyjson_likely(obj)) {
7106 obj->tag = ((uint64_t)count << YYJSON_TAG_BIT) | YYJSON_TYPE_OBJ;
7107 if (count > 0) {
7108 size_t i;
7109 for (i = 0; i < count; i++) {
7110 yyjson_mut_val *key = obj + (i * 2 + 1);
7111 yyjson_mut_val *val = obj + (i * 2 + 2);
7112 uint64_t key_len, val_len;
7113 if (yyjson_unlikely(!keys[i] || !vals[i])) return NULL;
7114 key_len = (uint64_t)strlen(keys[i]);
7115 val_len = (uint64_t)strlen(vals[i]);
7116 key->tag = (key_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
7117 val->tag = (val_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
7118 key->uni.str = keys[i];
7119 val->uni.str = vals[i];
7120 key->next = val;
7121 val->next = val + 1;
7122 }
7123 obj[count * 2].next = obj + 1;
7124 obj->uni.ptr = obj + (count * 2 - 1);
7125 }
7126 return obj;
7127 }
7128 }
7129 return NULL;
7130}
7131
7132yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_with_kv(yyjson_mut_doc *doc,
7133 const char **pairs,
7134 size_t count) {
7135 if (yyjson_likely(doc && ((count > 0 && count <
7136 (~(size_t)0) / sizeof(yyjson_mut_val) / 2 &&
7137 pairs) || (count == 0)))) {
7138 yyjson_mut_val *obj = unsafe_yyjson_mut_val(doc, 1 + count * 2);
7139 if (yyjson_likely(obj)) {
7140 obj->tag = ((uint64_t)count << YYJSON_TAG_BIT) | YYJSON_TYPE_OBJ;
7141 if (count > 0) {
7142 size_t i;
7143 for (i = 0; i < count; i++) {
7144 yyjson_mut_val *key = obj + (i * 2 + 1);
7145 yyjson_mut_val *val = obj + (i * 2 + 2);
7146 const char *key_str = pairs[i * 2 + 0];
7147 const char *val_str = pairs[i * 2 + 1];
7148 uint64_t key_len, val_len;
7149 if (yyjson_unlikely(!key_str || !val_str)) return NULL;
7150 key_len = (uint64_t)strlen(key_str);
7151 val_len = (uint64_t)strlen(val_str);
7152 key->tag = (key_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
7153 val->tag = (val_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
7154 key->uni.str = key_str;
7155 val->uni.str = val_str;
7156 key->next = val;
7157 val->next = val + 1;
7158 }
7159 obj[count * 2].next = obj + 1;
7160 obj->uni.ptr = obj + (count * 2 - 1);
7161 }
7162 return obj;
7163 }
7164 }
7165 return NULL;
7166}
7167
7168
7169
7170/*==============================================================================
7171 * MARK: - Mutable JSON Object Modification API (Implementation)
7172 *============================================================================*/
7173
7174yyjson_api_inline void unsafe_yyjson_mut_obj_add(yyjson_mut_val *obj,
7175 yyjson_mut_val *key,
7176 yyjson_mut_val *val,
7177 size_t len) {
7178 if (yyjson_likely(len)) {
7179 yyjson_mut_val *prev_val = ((yyjson_mut_val *)obj->uni.ptr)->next;
7180 yyjson_mut_val *next_key = prev_val->next;
7181 prev_val->next = key;
7182 val->next = next_key;
7183 } else {
7184 val->next = key;
7185 }
7186 key->next = val;
7187 obj->uni.ptr = (void *)key;
7188 unsafe_yyjson_set_len(obj, len + 1);
7189}
7190
7191yyjson_api_inline yyjson_mut_val *unsafe_yyjson_mut_obj_remove(
7192 yyjson_mut_val *obj, const char *key, size_t key_len) {
7193 size_t obj_len = unsafe_yyjson_get_len(obj);
7194 if (obj_len) {
7195 yyjson_mut_val *pre_key = (yyjson_mut_val *)obj->uni.ptr;
7196 yyjson_mut_val *cur_key = pre_key->next->next;
7197 yyjson_mut_val *removed_item = NULL;
7198 size_t i;
7199 for (i = 0; i < obj_len; i++) {
7200 if (unsafe_yyjson_equals_strn(cur_key, key, key_len)) {
7201 if (!removed_item) removed_item = cur_key->next;
7202 cur_key = cur_key->next->next;
7203 pre_key->next->next = cur_key;
7204 if (i + 1 == obj_len) obj->uni.ptr = pre_key;
7205 i--;
7206 obj_len--;
7207 } else {
7208 pre_key = cur_key;
7209 cur_key = cur_key->next->next;
7210 }
7211 }
7212 unsafe_yyjson_set_len(obj, obj_len);
7213 return removed_item;
7214 } else {
7215 return NULL;
7216 }
7217}
7218
7219yyjson_api_inline bool unsafe_yyjson_mut_obj_replace(yyjson_mut_val *obj,
7220 yyjson_mut_val *key,
7221 yyjson_mut_val *val) {
7222 size_t key_len = unsafe_yyjson_get_len(key);
7223 size_t obj_len = unsafe_yyjson_get_len(obj);
7224 if (obj_len) {
7225 yyjson_mut_val *pre_key = (yyjson_mut_val *)obj->uni.ptr;
7226 yyjson_mut_val *cur_key = pre_key->next->next;
7227 size_t i;
7228 for (i = 0; i < obj_len; i++) {
7229 if (unsafe_yyjson_equals_strn(cur_key, key->uni.str, key_len)) {
7230 cur_key->next->tag = val->tag;
7231 cur_key->next->uni.u64 = val->uni.u64;
7232 return true;
7233 } else {
7234 cur_key = cur_key->next->next;
7235 }
7236 }
7237 }
7238 return false;
7239}
7240
7241yyjson_api_inline void unsafe_yyjson_mut_obj_rotate(yyjson_mut_val *obj,
7242 size_t idx) {
7243 yyjson_mut_val *key = (yyjson_mut_val *)obj->uni.ptr;
7244 while (idx-- > 0) key = key->next->next;
7245 obj->uni.ptr = (void *)key;
7246}
7247
7248yyjson_api_inline bool yyjson_mut_obj_add(yyjson_mut_val *obj,
7249 yyjson_mut_val *key,
7250 yyjson_mut_val *val) {
7251 if (yyjson_likely(yyjson_mut_is_obj(obj) &&
7252 yyjson_mut_is_str(key) && val)) {
7253 unsafe_yyjson_mut_obj_add(obj, key, val, unsafe_yyjson_get_len(obj));
7254 return true;
7255 }
7256 return false;
7257}
7258
7259yyjson_api_inline bool yyjson_mut_obj_put(yyjson_mut_val *obj,
7260 yyjson_mut_val *key,
7261 yyjson_mut_val *val) {
7262 bool replaced = false;
7263 size_t key_len;
7264 yyjson_mut_obj_iter iter;
7265 yyjson_mut_val *cur_key;
7266 if (yyjson_unlikely(!yyjson_mut_is_obj(obj) ||
7267 !yyjson_mut_is_str(key))) return false;
7268 key_len = unsafe_yyjson_get_len(key);
7269 yyjson_mut_obj_iter_init(obj, &iter);
7270 while ((cur_key = yyjson_mut_obj_iter_next(&iter)) != 0) {
7271 if (unsafe_yyjson_equals_strn(cur_key, key->uni.str, key_len)) {
7272 if (!replaced && val) {
7273 replaced = true;
7274 val->next = cur_key->next->next;
7275 cur_key->next = val;
7276 } else {
7277 yyjson_mut_obj_iter_remove(&iter);
7278 }
7279 }
7280 }
7281 if (!replaced && val) unsafe_yyjson_mut_obj_add(obj, key, val, iter.max);
7282 return true;
7283}
7284
7285yyjson_api_inline bool yyjson_mut_obj_insert(yyjson_mut_val *obj,
7286 yyjson_mut_val *key,
7287 yyjson_mut_val *val,
7288 size_t idx) {
7289 if (yyjson_likely(yyjson_mut_is_obj(obj) &&
7290 yyjson_mut_is_str(key) && val)) {
7291 size_t len = unsafe_yyjson_get_len(obj);
7292 if (yyjson_likely(len >= idx)) {
7293 if (len > idx) {
7294 void *ptr = obj->uni.ptr;
7295 unsafe_yyjson_mut_obj_rotate(obj, idx);
7296 unsafe_yyjson_mut_obj_add(obj, key, val, len);
7297 obj->uni.ptr = ptr;
7298 } else {
7299 unsafe_yyjson_mut_obj_add(obj, key, val, len);
7300 }
7301 return true;
7302 }
7303 }
7304 return false;
7305}
7306
7307yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_remove(yyjson_mut_val *obj,
7308 yyjson_mut_val *key) {
7309 if (yyjson_likely(yyjson_mut_is_obj(obj) && yyjson_mut_is_str(key))) {
7310 return unsafe_yyjson_mut_obj_remove(obj, key->uni.str,
7311 unsafe_yyjson_get_len(key));
7312 }
7313 return NULL;
7314}
7315
7316yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_remove_key(
7317 yyjson_mut_val *obj, const char *key) {
7318 if (yyjson_likely(yyjson_mut_is_obj(obj) && key)) {
7319 size_t key_len = strlen(key);
7320 return unsafe_yyjson_mut_obj_remove(obj, key, key_len);
7321 }
7322 return NULL;
7323}
7324
7325yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_remove_keyn(
7326 yyjson_mut_val *obj, const char *key, size_t key_len) {
7327 if (yyjson_likely(yyjson_mut_is_obj(obj) && key)) {
7328 return unsafe_yyjson_mut_obj_remove(obj, key, key_len);
7329 }
7330 return NULL;
7331}
7332
7333yyjson_api_inline bool yyjson_mut_obj_clear(yyjson_mut_val *obj) {
7334 if (yyjson_likely(yyjson_mut_is_obj(obj))) {
7335 unsafe_yyjson_set_len(obj, 0);
7336 return true;
7337 }
7338 return false;
7339}
7340
7341yyjson_api_inline bool yyjson_mut_obj_replace(yyjson_mut_val *obj,
7342 yyjson_mut_val *key,
7343 yyjson_mut_val *val) {
7344 if (yyjson_likely(yyjson_mut_is_obj(obj) &&
7345 yyjson_mut_is_str(key) && val)) {
7346 return unsafe_yyjson_mut_obj_replace(obj, key, val);
7347 }
7348 return false;
7349}
7350
7351yyjson_api_inline bool yyjson_mut_obj_rotate(yyjson_mut_val *obj,
7352 size_t idx) {
7353 if (yyjson_likely(yyjson_mut_is_obj(obj) &&
7354 unsafe_yyjson_get_len(obj) > idx)) {
7355 unsafe_yyjson_mut_obj_rotate(obj, idx);
7356 return true;
7357 }
7358 return false;
7359}
7360
7361
7362
7363/*==============================================================================
7364 * MARK: - Mutable JSON Object Modification Convenience API (Implementation)
7365 *============================================================================*/
7366
7367#define yyjson_mut_obj_add_func(func) \
7368 if (yyjson_likely(doc && yyjson_mut_is_obj(obj) && _key)) { \
7369 yyjson_mut_val *key = unsafe_yyjson_mut_val(doc, 2); \
7370 if (yyjson_likely(key)) { \
7371 size_t len = unsafe_yyjson_get_len(obj); \
7372 yyjson_mut_val *val = key + 1; \
7373 size_t key_len = strlen(_key); \
7374 bool noesc = unsafe_yyjson_is_str_noesc(_key, key_len); \
7375 key->tag = YYJSON_TYPE_STR; \
7376 key->tag |= noesc ? YYJSON_SUBTYPE_NOESC : YYJSON_SUBTYPE_NONE; \
7377 key->tag |= (uint64_t)strlen(_key) << YYJSON_TAG_BIT; \
7378 key->uni.str = _key; \
7379 func \
7380 unsafe_yyjson_mut_obj_add(obj, key, val, len); \
7381 return true; \
7382 } \
7383 } \
7384 return false
7385
7386yyjson_api_inline bool yyjson_mut_obj_add_null(yyjson_mut_doc *doc,
7387 yyjson_mut_val *obj,
7388 const char *_key) {
7389 yyjson_mut_obj_add_func({ unsafe_yyjson_set_null(val); });
7390}
7391
7392yyjson_api_inline bool yyjson_mut_obj_add_true(yyjson_mut_doc *doc,
7393 yyjson_mut_val *obj,
7394 const char *_key) {
7395 yyjson_mut_obj_add_func({ unsafe_yyjson_set_bool(val, true); });
7396}
7397
7398yyjson_api_inline bool yyjson_mut_obj_add_false(yyjson_mut_doc *doc,
7399 yyjson_mut_val *obj,
7400 const char *_key) {
7401 yyjson_mut_obj_add_func({ unsafe_yyjson_set_bool(val, false); });
7402}
7403
7404yyjson_api_inline bool yyjson_mut_obj_add_bool(yyjson_mut_doc *doc,
7405 yyjson_mut_val *obj,
7406 const char *_key,
7407 bool _val) {
7408 yyjson_mut_obj_add_func({ unsafe_yyjson_set_bool(val, _val); });
7409}
7410
7411yyjson_api_inline bool yyjson_mut_obj_add_uint(yyjson_mut_doc *doc,
7412 yyjson_mut_val *obj,
7413 const char *_key,
7414 uint64_t _val) {
7415 yyjson_mut_obj_add_func({ unsafe_yyjson_set_uint(val, _val); });
7416}
7417
7418yyjson_api_inline bool yyjson_mut_obj_add_sint(yyjson_mut_doc *doc,
7419 yyjson_mut_val *obj,
7420 const char *_key,
7421 int64_t _val) {
7422 yyjson_mut_obj_add_func({ unsafe_yyjson_set_sint(val, _val); });
7423}
7424
7425yyjson_api_inline bool yyjson_mut_obj_add_int(yyjson_mut_doc *doc,
7426 yyjson_mut_val *obj,
7427 const char *_key,
7428 int64_t _val) {
7429 yyjson_mut_obj_add_func({ unsafe_yyjson_set_sint(val, _val); });
7430}
7431
7432yyjson_api_inline bool yyjson_mut_obj_add_float(yyjson_mut_doc *doc,
7433 yyjson_mut_val *obj,
7434 const char *_key,
7435 float _val) {
7436 yyjson_mut_obj_add_func({ unsafe_yyjson_set_float(val, _val); });
7437}
7438
7439yyjson_api_inline bool yyjson_mut_obj_add_double(yyjson_mut_doc *doc,
7440 yyjson_mut_val *obj,
7441 const char *_key,
7442 double _val) {
7443 yyjson_mut_obj_add_func({ unsafe_yyjson_set_double(val, _val); });
7444}
7445
7446yyjson_api_inline bool yyjson_mut_obj_add_real(yyjson_mut_doc *doc,
7447 yyjson_mut_val *obj,
7448 const char *_key,
7449 double _val) {
7450 yyjson_mut_obj_add_func({ unsafe_yyjson_set_real(val, _val); });
7451}
7452
7453yyjson_api_inline bool yyjson_mut_obj_add_str(yyjson_mut_doc *doc,
7454 yyjson_mut_val *obj,
7455 const char *_key,
7456 const char *_val) {
7457 if (yyjson_unlikely(!_val)) return false;
7458 yyjson_mut_obj_add_func({
7459 size_t val_len = strlen(_val);
7460 bool val_noesc = unsafe_yyjson_is_str_noesc(_val, val_len);
7461 val->tag = ((uint64_t)strlen(_val) << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
7462 val->tag |= val_noesc ? YYJSON_SUBTYPE_NOESC : YYJSON_SUBTYPE_NONE;
7463 val->uni.str = _val;
7464 });
7465}
7466
7467yyjson_api_inline bool yyjson_mut_obj_add_strn(yyjson_mut_doc *doc,
7468 yyjson_mut_val *obj,
7469 const char *_key,
7470 const char *_val,
7471 size_t _len) {
7472 if (yyjson_unlikely(!_val)) return false;
7473 yyjson_mut_obj_add_func({
7474 val->tag = ((uint64_t)_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
7475 val->uni.str = _val;
7476 });
7477}
7478
7479yyjson_api_inline bool yyjson_mut_obj_add_strcpy(yyjson_mut_doc *doc,
7480 yyjson_mut_val *obj,
7481 const char *_key,
7482 const char *_val) {
7483 if (yyjson_unlikely(!_val)) return false;
7484 yyjson_mut_obj_add_func({
7485 size_t _len = strlen(_val);
7486 val->uni.str = unsafe_yyjson_mut_strncpy(doc, _val, _len);
7487 if (yyjson_unlikely(!val->uni.str)) return false;
7488 val->tag = ((uint64_t)_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
7489 });
7490}
7491
7492yyjson_api_inline bool yyjson_mut_obj_add_strncpy(yyjson_mut_doc *doc,
7493 yyjson_mut_val *obj,
7494 const char *_key,
7495 const char *_val,
7496 size_t _len) {
7497 if (yyjson_unlikely(!_val)) return false;
7498 yyjson_mut_obj_add_func({
7499 val->uni.str = unsafe_yyjson_mut_strncpy(doc, _val, _len);
7500 if (yyjson_unlikely(!val->uni.str)) return false;
7501 val->tag = ((uint64_t)_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
7502 });
7503}
7504
7505yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_add_arr(yyjson_mut_doc *doc,
7506 yyjson_mut_val *obj,
7507 const char *_key) {
7508 yyjson_mut_val *key = yyjson_mut_str(doc, _key);
7509 yyjson_mut_val *val = yyjson_mut_arr(doc);
7510 return yyjson_mut_obj_add(obj, key, val) ? val : NULL;
7511}
7512
7513yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_add_obj(yyjson_mut_doc *doc,
7514 yyjson_mut_val *obj,
7515 const char *_key) {
7516 yyjson_mut_val *key = yyjson_mut_str(doc, _key);
7517 yyjson_mut_val *val = yyjson_mut_obj(doc);
7518 return yyjson_mut_obj_add(obj, key, val) ? val : NULL;
7519}
7520
7521yyjson_api_inline bool yyjson_mut_obj_add_val(yyjson_mut_doc *doc,
7522 yyjson_mut_val *obj,
7523 const char *_key,
7524 yyjson_mut_val *_val) {
7525 if (yyjson_unlikely(!_val)) return false;
7526 yyjson_mut_obj_add_func({
7527 val = _val;
7528 });
7529}
7530
7531yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_remove_str(yyjson_mut_val *obj,
7532 const char *key) {
7533 return yyjson_mut_obj_remove_strn(obj, key, key ? strlen(key) : 0);
7534}
7535
7536yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_remove_strn(
7537 yyjson_mut_val *obj, const char *_key, size_t _len) {
7538 if (yyjson_likely(yyjson_mut_is_obj(obj) && _key)) {
7539 yyjson_mut_val *key;
7540 yyjson_mut_obj_iter iter;
7541 yyjson_mut_val *val_removed = NULL;
7542 yyjson_mut_obj_iter_init(obj, &iter);
7543 while ((key = yyjson_mut_obj_iter_next(&iter)) != NULL) {
7544 if (unsafe_yyjson_equals_strn(key, _key, _len)) {
7545 if (!val_removed) val_removed = key->next;
7546 yyjson_mut_obj_iter_remove(&iter);
7547 }
7548 }
7549 return val_removed;
7550 }
7551 return NULL;
7552}
7553
7554yyjson_api_inline bool yyjson_mut_obj_rename_key(yyjson_mut_doc *doc,
7555 yyjson_mut_val *obj,
7556 const char *key,
7557 const char *new_key) {
7558 if (!key || !new_key) return false;
7559 return yyjson_mut_obj_rename_keyn(doc, obj, key, strlen(key),
7560 new_key, strlen(new_key));
7561}
7562
7563yyjson_api_inline bool yyjson_mut_obj_rename_keyn(yyjson_mut_doc *doc,
7564 yyjson_mut_val *obj,
7565 const char *key,
7566 size_t len,
7567 const char *new_key,
7568 size_t new_len) {
7569 char *cpy_key = NULL;
7570 yyjson_mut_val *old_key;
7571 yyjson_mut_obj_iter iter;
7572 if (!doc || !obj || !key || !new_key) return false;
7573 yyjson_mut_obj_iter_init(obj, &iter);
7574 while ((old_key = yyjson_mut_obj_iter_next(&iter))) {
7575 if (unsafe_yyjson_equals_strn((void *)old_key, key, len)) {
7576 if (!cpy_key) {
7577 cpy_key = unsafe_yyjson_mut_strncpy(doc, new_key, new_len);
7578 if (!cpy_key) return false;
7579 }
7580 yyjson_mut_set_strn(old_key, cpy_key, new_len);
7581 }
7582 }
7583 return cpy_key != NULL;
7584}
7585
7586
7587
7588#if !defined(YYJSON_DISABLE_UTILS) || !YYJSON_DISABLE_UTILS
7589
7590/*==============================================================================
7591 * MARK: - JSON Pointer API (Implementation)
7592 *============================================================================*/
7593
7594#define yyjson_ptr_set_err(_code, _msg) do { \
7595 if (err) { \
7596 err->code = YYJSON_PTR_ERR_##_code; \
7597 err->msg = _msg; \
7598 err->pos = 0; \
7599 } \
7600} while(false)
7601
7602/* require: val != NULL, *ptr == '/', len > 0 */
7603yyjson_api yyjson_val *unsafe_yyjson_ptr_getx(const yyjson_val *val,
7604 const char *ptr, size_t len,
7605 yyjson_ptr_err *err);
7606
7607/* require: val != NULL, *ptr == '/', len > 0 */
7608yyjson_api yyjson_mut_val *unsafe_yyjson_mut_ptr_getx(const yyjson_mut_val *val,
7609 const char *ptr,
7610 size_t len,
7611 yyjson_ptr_ctx *ctx,
7612 yyjson_ptr_err *err);
7613
7614/* require: val/new_val/doc != NULL, *ptr == '/', len > 0 */
7615yyjson_api bool unsafe_yyjson_mut_ptr_putx(yyjson_mut_val *val,
7616 const char *ptr, size_t len,
7617 yyjson_mut_val *new_val,
7618 yyjson_mut_doc *doc,
7619 bool create_parent, bool insert_new,
7620 yyjson_ptr_ctx *ctx,
7621 yyjson_ptr_err *err);
7622
7623/* require: val/err != NULL, *ptr == '/', len > 0 */
7624yyjson_api yyjson_mut_val *unsafe_yyjson_mut_ptr_replacex(
7625 yyjson_mut_val *val, const char *ptr, size_t len, yyjson_mut_val *new_val,
7626 yyjson_ptr_ctx *ctx, yyjson_ptr_err *err);
7627
7628/* require: val/err != NULL, *ptr == '/', len > 0 */
7629yyjson_api yyjson_mut_val *unsafe_yyjson_mut_ptr_removex(yyjson_mut_val *val,
7630 const char *ptr,
7631 size_t len,
7632 yyjson_ptr_ctx *ctx,
7633 yyjson_ptr_err *err);
7634
7635yyjson_api_inline yyjson_val *yyjson_doc_ptr_get(const yyjson_doc *doc,
7636 const char *ptr) {
7637 if (yyjson_unlikely(!ptr)) return NULL;
7638 return yyjson_doc_ptr_getn(doc, ptr, strlen(ptr));
7639}
7640
7641yyjson_api_inline yyjson_val *yyjson_doc_ptr_getn(const yyjson_doc *doc,
7642 const char *ptr, size_t len) {
7643 return yyjson_doc_ptr_getx(doc, ptr, len, NULL);
7644}
7645
7646yyjson_api_inline yyjson_val *yyjson_doc_ptr_getx(const yyjson_doc *doc,
7647 const char *ptr, size_t len,
7648 yyjson_ptr_err *err) {
7649 yyjson_ptr_set_err(NONE, NULL);
7650 if (yyjson_unlikely(!doc || !ptr)) {
7651 yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
7652 return NULL;
7653 }
7654 if (yyjson_unlikely(!doc->root)) {
7655 yyjson_ptr_set_err(NULL_ROOT, "document's root is NULL");
7656 return NULL;
7657 }
7658 if (yyjson_unlikely(len == 0)) {
7659 return doc->root;
7660 }
7661 if (yyjson_unlikely(*ptr != '/')) {
7662 yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
7663 return NULL;
7664 }
7665 return unsafe_yyjson_ptr_getx(doc->root, ptr, len, err);
7666}
7667
7668yyjson_api_inline yyjson_val *yyjson_ptr_get(const yyjson_val *val,
7669 const char *ptr) {
7670 if (yyjson_unlikely(!ptr)) return NULL;
7671 return yyjson_ptr_getn(val, ptr, strlen(ptr));
7672}
7673
7674yyjson_api_inline yyjson_val *yyjson_ptr_getn(const yyjson_val *val,
7675 const char *ptr, size_t len) {
7676 return yyjson_ptr_getx(val, ptr, len, NULL);
7677}
7678
7679yyjson_api_inline yyjson_val *yyjson_ptr_getx(const yyjson_val *val,
7680 const char *ptr, size_t len,
7681 yyjson_ptr_err *err) {
7682 yyjson_ptr_set_err(NONE, NULL);
7683 if (yyjson_unlikely(!val || !ptr)) {
7684 yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
7685 return NULL;
7686 }
7687 if (yyjson_unlikely(len == 0)) {
7688 return yyjson_constcast(yyjson_val *)val;
7689 }
7690 if (yyjson_unlikely(*ptr != '/')) {
7691 yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
7692 return NULL;
7693 }
7694 return unsafe_yyjson_ptr_getx(val, ptr, len, err);
7695}
7696
7697yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_get(
7698 const yyjson_mut_doc *doc, const char *ptr) {
7699 if (!ptr) return NULL;
7700 return yyjson_mut_doc_ptr_getn(doc, ptr, strlen(ptr));
7701}
7702
7703yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_getn(
7704 const yyjson_mut_doc *doc, const char *ptr, size_t len) {
7705 return yyjson_mut_doc_ptr_getx(doc, ptr, len, NULL, NULL);
7706}
7707
7708yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_getx(
7709 const yyjson_mut_doc *doc, const char *ptr, size_t len,
7710 yyjson_ptr_ctx *ctx, yyjson_ptr_err *err) {
7711 yyjson_ptr_set_err(NONE, NULL);
7712 if (ctx) memset(ctx, 0, sizeof(*ctx));
7713
7714 if (yyjson_unlikely(!doc || !ptr)) {
7715 yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
7716 return NULL;
7717 }
7718 if (yyjson_unlikely(!doc->root)) {
7719 yyjson_ptr_set_err(NULL_ROOT, "document's root is NULL");
7720 return NULL;
7721 }
7722 if (yyjson_unlikely(len == 0)) {
7723 return doc->root;
7724 }
7725 if (yyjson_unlikely(*ptr != '/')) {
7726 yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
7727 return NULL;
7728 }
7729 return unsafe_yyjson_mut_ptr_getx(doc->root, ptr, len, ctx, err);
7730}
7731
7732yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_get(const yyjson_mut_val *val,
7733 const char *ptr) {
7734 if (!ptr) return NULL;
7735 return yyjson_mut_ptr_getn(val, ptr, strlen(ptr));
7736}
7737
7738yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_getn(const yyjson_mut_val *val,
7739 const char *ptr,
7740 size_t len) {
7741 return yyjson_mut_ptr_getx(val, ptr, len, NULL, NULL);
7742}
7743
7744yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_getx(const yyjson_mut_val *val,
7745 const char *ptr,
7746 size_t len,
7747 yyjson_ptr_ctx *ctx,
7748 yyjson_ptr_err *err) {
7749 yyjson_ptr_set_err(NONE, NULL);
7750 if (ctx) memset(ctx, 0, sizeof(*ctx));
7751
7752 if (yyjson_unlikely(!val || !ptr)) {
7753 yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
7754 return NULL;
7755 }
7756 if (yyjson_unlikely(len == 0)) {
7757 return yyjson_constcast(yyjson_mut_val *)val;
7758 }
7759 if (yyjson_unlikely(*ptr != '/')) {
7760 yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
7761 return NULL;
7762 }
7763 return unsafe_yyjson_mut_ptr_getx(val, ptr, len, ctx, err);
7764}
7765
7766yyjson_api_inline bool yyjson_mut_doc_ptr_add(yyjson_mut_doc *doc,
7767 const char *ptr,
7768 yyjson_mut_val *new_val) {
7769 if (yyjson_unlikely(!ptr)) return false;
7770 return yyjson_mut_doc_ptr_addn(doc, ptr, strlen(ptr), new_val);
7771}
7772
7773yyjson_api_inline bool yyjson_mut_doc_ptr_addn(yyjson_mut_doc *doc,
7774 const char *ptr,
7775 size_t len,
7776 yyjson_mut_val *new_val) {
7777 return yyjson_mut_doc_ptr_addx(doc, ptr, len, new_val, true, NULL, NULL);
7778}
7779
7780yyjson_api_inline bool yyjson_mut_doc_ptr_addx(yyjson_mut_doc *doc,
7781 const char *ptr, size_t len,
7782 yyjson_mut_val *new_val,
7783 bool create_parent,
7784 yyjson_ptr_ctx *ctx,
7785 yyjson_ptr_err *err) {
7786 yyjson_ptr_set_err(NONE, NULL);
7787 if (ctx) memset(ctx, 0, sizeof(*ctx));
7788
7789 if (yyjson_unlikely(!doc || !ptr || !new_val)) {
7790 yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
7791 return false;
7792 }
7793 if (yyjson_unlikely(len == 0)) {
7794 if (doc->root) {
7795 yyjson_ptr_set_err(SET_ROOT, "cannot set document's root");
7796 return false;
7797 } else {
7798 doc->root = new_val;
7799 return true;
7800 }
7801 }
7802 if (yyjson_unlikely(*ptr != '/')) {
7803 yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
7804 return false;
7805 }
7806 if (yyjson_unlikely(!doc->root && !create_parent)) {
7807 yyjson_ptr_set_err(NULL_ROOT, "document's root is NULL");
7808 return false;
7809 }
7810 if (yyjson_unlikely(!doc->root)) {
7811 yyjson_mut_val *root = yyjson_mut_obj(doc);
7812 if (yyjson_unlikely(!root)) {
7813 yyjson_ptr_set_err(MEMORY_ALLOCATION, "failed to create value");
7814 return false;
7815 }
7816 if (unsafe_yyjson_mut_ptr_putx(root, ptr, len, new_val, doc,
7817 create_parent, true, ctx, err)) {
7818 doc->root = root;
7819 return true;
7820 }
7821 return false;
7822 }
7823 return unsafe_yyjson_mut_ptr_putx(doc->root, ptr, len, new_val, doc,
7824 create_parent, true, ctx, err);
7825}
7826
7827yyjson_api_inline bool yyjson_mut_ptr_add(yyjson_mut_val *val,
7828 const char *ptr,
7829 yyjson_mut_val *new_val,
7830 yyjson_mut_doc *doc) {
7831 if (yyjson_unlikely(!ptr)) return false;
7832 return yyjson_mut_ptr_addn(val, ptr, strlen(ptr), new_val, doc);
7833}
7834
7835yyjson_api_inline bool yyjson_mut_ptr_addn(yyjson_mut_val *val,
7836 const char *ptr, size_t len,
7837 yyjson_mut_val *new_val,
7838 yyjson_mut_doc *doc) {
7839 return yyjson_mut_ptr_addx(val, ptr, len, new_val, doc, true, NULL, NULL);
7840}
7841
7842yyjson_api_inline bool yyjson_mut_ptr_addx(yyjson_mut_val *val,
7843 const char *ptr, size_t len,
7844 yyjson_mut_val *new_val,
7845 yyjson_mut_doc *doc,
7846 bool create_parent,
7847 yyjson_ptr_ctx *ctx,
7848 yyjson_ptr_err *err) {
7849 yyjson_ptr_set_err(NONE, NULL);
7850 if (ctx) memset(ctx, 0, sizeof(*ctx));
7851
7852 if (yyjson_unlikely(!val || !ptr || !new_val || !doc)) {
7853 yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
7854 return false;
7855 }
7856 if (yyjson_unlikely(len == 0)) {
7857 yyjson_ptr_set_err(SET_ROOT, "cannot set root");
7858 return false;
7859 }
7860 if (yyjson_unlikely(*ptr != '/')) {
7861 yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
7862 return false;
7863 }
7864 return unsafe_yyjson_mut_ptr_putx(val, ptr, len, new_val,
7865 doc, create_parent, true, ctx, err);
7866}
7867
7868yyjson_api_inline bool yyjson_mut_doc_ptr_set(yyjson_mut_doc *doc,
7869 const char *ptr,
7870 yyjson_mut_val *new_val) {
7871 if (yyjson_unlikely(!ptr)) return false;
7872 return yyjson_mut_doc_ptr_setn(doc, ptr, strlen(ptr), new_val);
7873}
7874
7875yyjson_api_inline bool yyjson_mut_doc_ptr_setn(yyjson_mut_doc *doc,
7876 const char *ptr, size_t len,
7877 yyjson_mut_val *new_val) {
7878 return yyjson_mut_doc_ptr_setx(doc, ptr, len, new_val, true, NULL, NULL);
7879}
7880
7881yyjson_api_inline bool yyjson_mut_doc_ptr_setx(yyjson_mut_doc *doc,
7882 const char *ptr, size_t len,
7883 yyjson_mut_val *new_val,
7884 bool create_parent,
7885 yyjson_ptr_ctx *ctx,
7886 yyjson_ptr_err *err) {
7887 yyjson_ptr_set_err(NONE, NULL);
7888 if (ctx) memset(ctx, 0, sizeof(*ctx));
7889
7890 if (yyjson_unlikely(!doc || !ptr)) {
7891 yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
7892 return false;
7893 }
7894 if (yyjson_unlikely(len == 0)) {
7895 if (ctx) ctx->old = doc->root;
7896 doc->root = new_val;
7897 return true;
7898 }
7899 if (yyjson_unlikely(*ptr != '/')) {
7900 yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
7901 return false;
7902 }
7903 if (!new_val) {
7904 if (!doc->root) {
7905 yyjson_ptr_set_err(RESOLVE, "JSON pointer cannot be resolved");
7906 return false;
7907 }
7908 return !!unsafe_yyjson_mut_ptr_removex(doc->root, ptr, len, ctx, err);
7909 }
7910 if (yyjson_unlikely(!doc->root && !create_parent)) {
7911 yyjson_ptr_set_err(NULL_ROOT, "document's root is NULL");
7912 return false;
7913 }
7914 if (yyjson_unlikely(!doc->root)) {
7915 yyjson_mut_val *root = yyjson_mut_obj(doc);
7916 if (yyjson_unlikely(!root)) {
7917 yyjson_ptr_set_err(MEMORY_ALLOCATION, "failed to create value");
7918 return false;
7919 }
7920 if (unsafe_yyjson_mut_ptr_putx(root, ptr, len, new_val, doc,
7921 create_parent, false, ctx, err)) {
7922 doc->root = root;
7923 return true;
7924 }
7925 return false;
7926 }
7927 return unsafe_yyjson_mut_ptr_putx(doc->root, ptr, len, new_val, doc,
7928 create_parent, false, ctx, err);
7929}
7930
7931yyjson_api_inline bool yyjson_mut_ptr_set(yyjson_mut_val *val,
7932 const char *ptr,
7933 yyjson_mut_val *new_val,
7934 yyjson_mut_doc *doc) {
7935 if (yyjson_unlikely(!ptr)) return false;
7936 return yyjson_mut_ptr_setn(val, ptr, strlen(ptr), new_val, doc);
7937}
7938
7939yyjson_api_inline bool yyjson_mut_ptr_setn(yyjson_mut_val *val,
7940 const char *ptr, size_t len,
7941 yyjson_mut_val *new_val,
7942 yyjson_mut_doc *doc) {
7943 return yyjson_mut_ptr_setx(val, ptr, len, new_val, doc, true, NULL, NULL);
7944}
7945
7946yyjson_api_inline bool yyjson_mut_ptr_setx(yyjson_mut_val *val,
7947 const char *ptr, size_t len,
7948 yyjson_mut_val *new_val,
7949 yyjson_mut_doc *doc,
7950 bool create_parent,
7951 yyjson_ptr_ctx *ctx,
7952 yyjson_ptr_err *err) {
7953 yyjson_ptr_set_err(NONE, NULL);
7954 if (ctx) memset(ctx, 0, sizeof(*ctx));
7955
7956 if (yyjson_unlikely(!val || !ptr || !doc)) {
7957 yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
7958 return false;
7959 }
7960 if (yyjson_unlikely(len == 0)) {
7961 yyjson_ptr_set_err(SET_ROOT, "cannot set root");
7962 return false;
7963 }
7964 if (yyjson_unlikely(*ptr != '/')) {
7965 yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
7966 return false;
7967 }
7968 if (!new_val) {
7969 return !!unsafe_yyjson_mut_ptr_removex(val, ptr, len, ctx, err);
7970 }
7971 return unsafe_yyjson_mut_ptr_putx(val, ptr, len, new_val, doc,
7972 create_parent, false, ctx, err);
7973}
7974
7975yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_replace(
7976 yyjson_mut_doc *doc, const char *ptr, yyjson_mut_val *new_val) {
7977 if (!ptr) return NULL;
7978 return yyjson_mut_doc_ptr_replacen(doc, ptr, strlen(ptr), new_val);
7979}
7980
7981yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_replacen(
7982 yyjson_mut_doc *doc, const char *ptr, size_t len, yyjson_mut_val *new_val) {
7983 return yyjson_mut_doc_ptr_replacex(doc, ptr, len, new_val, NULL, NULL);
7984}
7985
7986yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_replacex(
7987 yyjson_mut_doc *doc, const char *ptr, size_t len, yyjson_mut_val *new_val,
7988 yyjson_ptr_ctx *ctx, yyjson_ptr_err *err) {
7989
7990 yyjson_ptr_set_err(NONE, NULL);
7991 if (ctx) memset(ctx, 0, sizeof(*ctx));
7992
7993 if (yyjson_unlikely(!doc || !ptr || !new_val)) {
7994 yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
7995 return NULL;
7996 }
7997 if (yyjson_unlikely(len == 0)) {
7998 yyjson_mut_val *root = doc->root;
7999 if (yyjson_unlikely(!root)) {
8000 yyjson_ptr_set_err(RESOLVE, "JSON pointer cannot be resolved");
8001 return NULL;
8002 }
8003 if (ctx) ctx->old = root;
8004 doc->root = new_val;
8005 return root;
8006 }
8007 if (yyjson_unlikely(!doc->root)) {
8008 yyjson_ptr_set_err(NULL_ROOT, "document's root is NULL");
8009 return NULL;
8010 }
8011 if (yyjson_unlikely(*ptr != '/')) {
8012 yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
8013 return NULL;
8014 }
8015 return unsafe_yyjson_mut_ptr_replacex(doc->root, ptr, len, new_val,
8016 ctx, err);
8017}
8018
8019yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_replace(
8020 yyjson_mut_val *val, const char *ptr, yyjson_mut_val *new_val) {
8021 if (!ptr) return NULL;
8022 return yyjson_mut_ptr_replacen(val, ptr, strlen(ptr), new_val);
8023}
8024
8025yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_replacen(
8026 yyjson_mut_val *val, const char *ptr, size_t len, yyjson_mut_val *new_val) {
8027 return yyjson_mut_ptr_replacex(val, ptr, len, new_val, NULL, NULL);
8028}
8029
8030yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_replacex(
8031 yyjson_mut_val *val, const char *ptr, size_t len, yyjson_mut_val *new_val,
8032 yyjson_ptr_ctx *ctx, yyjson_ptr_err *err) {
8033
8034 yyjson_ptr_set_err(NONE, NULL);
8035 if (ctx) memset(ctx, 0, sizeof(*ctx));
8036
8037 if (yyjson_unlikely(!val || !ptr || !new_val)) {
8038 yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
8039 return NULL;
8040 }
8041 if (yyjson_unlikely(len == 0)) {
8042 yyjson_ptr_set_err(SET_ROOT, "cannot set root");
8043 return NULL;
8044 }
8045 if (yyjson_unlikely(*ptr != '/')) {
8046 yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
8047 return NULL;
8048 }
8049 return unsafe_yyjson_mut_ptr_replacex(val, ptr, len, new_val, ctx, err);
8050}
8051
8052yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_remove(
8053 yyjson_mut_doc *doc, const char *ptr) {
8054 if (!ptr) return NULL;
8055 return yyjson_mut_doc_ptr_removen(doc, ptr, strlen(ptr));
8056}
8057
8058yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_removen(
8059 yyjson_mut_doc *doc, const char *ptr, size_t len) {
8060 return yyjson_mut_doc_ptr_removex(doc, ptr, len, NULL, NULL);
8061}
8062
8063yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_ptr_removex(
8064 yyjson_mut_doc *doc, const char *ptr, size_t len,
8065 yyjson_ptr_ctx *ctx, yyjson_ptr_err *err) {
8066
8067 yyjson_ptr_set_err(NONE, NULL);
8068 if (ctx) memset(ctx, 0, sizeof(*ctx));
8069
8070 if (yyjson_unlikely(!doc || !ptr)) {
8071 yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
8072 return NULL;
8073 }
8074 if (yyjson_unlikely(!doc->root)) {
8075 yyjson_ptr_set_err(NULL_ROOT, "document's root is NULL");
8076 return NULL;
8077 }
8078 if (yyjson_unlikely(len == 0)) {
8079 yyjson_mut_val *root = doc->root;
8080 if (ctx) ctx->old = root;
8081 doc->root = NULL;
8082 return root;
8083 }
8084 if (yyjson_unlikely(*ptr != '/')) {
8085 yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
8086 return NULL;
8087 }
8088 return unsafe_yyjson_mut_ptr_removex(doc->root, ptr, len, ctx, err);
8089}
8090
8091yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_remove(yyjson_mut_val *val,
8092 const char *ptr) {
8093 if (!ptr) return NULL;
8094 return yyjson_mut_ptr_removen(val, ptr, strlen(ptr));
8095}
8096
8097yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_removen(yyjson_mut_val *val,
8098 const char *ptr,
8099 size_t len) {
8100 return yyjson_mut_ptr_removex(val, ptr, len, NULL, NULL);
8101}
8102
8103yyjson_api_inline yyjson_mut_val *yyjson_mut_ptr_removex(yyjson_mut_val *val,
8104 const char *ptr,
8105 size_t len,
8106 yyjson_ptr_ctx *ctx,
8107 yyjson_ptr_err *err) {
8108 yyjson_ptr_set_err(NONE, NULL);
8109 if (ctx) memset(ctx, 0, sizeof(*ctx));
8110
8111 if (yyjson_unlikely(!val || !ptr)) {
8112 yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
8113 return NULL;
8114 }
8115 if (yyjson_unlikely(len == 0)) {
8116 yyjson_ptr_set_err(SET_ROOT, "cannot set root");
8117 return NULL;
8118 }
8119 if (yyjson_unlikely(*ptr != '/')) {
8120 yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
8121 return NULL;
8122 }
8123 return unsafe_yyjson_mut_ptr_removex(val, ptr, len, ctx, err);
8124}
8125
8126yyjson_api_inline bool yyjson_ptr_ctx_append(yyjson_ptr_ctx *ctx,
8127 yyjson_mut_val *key,
8128 yyjson_mut_val *val) {
8129 yyjson_mut_val *ctn, *pre_key, *pre_val, *cur_key, *cur_val;
8130 if (!ctx || !ctx->ctn || !val) return false;
8131 ctn = ctx->ctn;
8132
8133 if (yyjson_mut_is_obj(ctn)) {
8134 if (!key) return false;
8135 key->next = val;
8136 pre_key = ctx->pre;
8137 if (unsafe_yyjson_get_len(ctn) == 0) {
8138 val->next = key;
8139 ctn->uni.ptr = key;
8140 ctx->pre = key;
8141 } else if (!pre_key) {
8142 pre_key = (yyjson_mut_val *)ctn->uni.ptr;
8143 pre_val = pre_key->next;
8144 val->next = pre_val->next;
8145 pre_val->next = key;
8146 ctn->uni.ptr = key;
8147 ctx->pre = pre_key;
8148 } else {
8149 cur_key = pre_key->next->next;
8150 cur_val = cur_key->next;
8151 val->next = cur_val->next;
8152 cur_val->next = key;
8153 if (ctn->uni.ptr == cur_key) ctn->uni.ptr = key;
8154 ctx->pre = cur_key;
8155 }
8156 } else {
8157 pre_val = ctx->pre;
8158 if (unsafe_yyjson_get_len(ctn) == 0) {
8159 val->next = val;
8160 ctn->uni.ptr = val;
8161 ctx->pre = val;
8162 } else if (!pre_val) {
8163 pre_val = (yyjson_mut_val *)ctn->uni.ptr;
8164 val->next = pre_val->next;
8165 pre_val->next = val;
8166 ctn->uni.ptr = val;
8167 ctx->pre = pre_val;
8168 } else {
8169 cur_val = pre_val->next;
8170 val->next = cur_val->next;
8171 cur_val->next = val;
8172 if (ctn->uni.ptr == cur_val) ctn->uni.ptr = val;
8173 ctx->pre = cur_val;
8174 }
8175 }
8176 unsafe_yyjson_inc_len(ctn);
8177 return true;
8178}
8179
8180yyjson_api_inline bool yyjson_ptr_ctx_replace(yyjson_ptr_ctx *ctx,
8181 yyjson_mut_val *val) {
8182 yyjson_mut_val *ctn, *pre_key, *cur_key, *pre_val, *cur_val;
8183 if (!ctx || !ctx->ctn || !ctx->pre || !val) return false;
8184 ctn = ctx->ctn;
8185 if (yyjson_mut_is_obj(ctn)) {
8186 pre_key = ctx->pre;
8187 pre_val = pre_key->next;
8188 cur_key = pre_val->next;
8189 cur_val = cur_key->next;
8190 /* replace current value */
8191 cur_key->next = val;
8192 val->next = cur_val->next;
8193 ctx->old = cur_val;
8194 } else {
8195 pre_val = ctx->pre;
8196 cur_val = pre_val->next;
8197 /* replace current value */
8198 if (pre_val != cur_val) {
8199 val->next = cur_val->next;
8200 pre_val->next = val;
8201 if (ctn->uni.ptr == cur_val) ctn->uni.ptr = val;
8202 } else {
8203 val->next = val;
8204 ctn->uni.ptr = val;
8205 ctx->pre = val;
8206 }
8207 ctx->old = cur_val;
8208 }
8209 return true;
8210}
8211
8212yyjson_api_inline bool yyjson_ptr_ctx_remove(yyjson_ptr_ctx *ctx) {
8213 yyjson_mut_val *ctn, *pre_key, *pre_val, *cur_key, *cur_val;
8214 size_t len;
8215 if (!ctx || !ctx->ctn || !ctx->pre) return false;
8216 ctn = ctx->ctn;
8217 if (yyjson_mut_is_obj(ctn)) {
8218 pre_key = ctx->pre;
8219 pre_val = pre_key->next;
8220 cur_key = pre_val->next;
8221 cur_val = cur_key->next;
8222 /* remove current key-value */
8223 pre_val->next = cur_val->next;
8224 if (ctn->uni.ptr == cur_key) ctn->uni.ptr = pre_key;
8225 ctx->pre = NULL;
8226 ctx->old = cur_val;
8227 } else {
8228 pre_val = ctx->pre;
8229 cur_val = pre_val->next;
8230 /* remove current key-value */
8231 pre_val->next = cur_val->next;
8232 if (ctn->uni.ptr == cur_val) ctn->uni.ptr = pre_val;
8233 ctx->pre = NULL;
8234 ctx->old = cur_val;
8235 }
8236 len = unsafe_yyjson_get_len(ctn) - 1;
8237 if (len == 0) ctn->uni.ptr = NULL;
8238 unsafe_yyjson_set_len(ctn, len);
8239 return true;
8240}
8241
8242#undef yyjson_ptr_set_err
8243
8244
8245
8246/*==============================================================================
8247 * MARK: - JSON Value at Pointer API (Implementation)
8248 *============================================================================*/
8249
8250/**
8251 Set provided `value` if the JSON Pointer (RFC 6901) exists and is type bool.
8252 Returns true if value at `ptr` exists and is the correct type, otherwise false.
8253 */
8254yyjson_api_inline bool yyjson_ptr_get_bool(
8255 const yyjson_val *root, const char *ptr, bool *value) {
8256 yyjson_val *val = yyjson_ptr_get(root, ptr);
8257 if (value && yyjson_is_bool(val)) {
8258 *value = unsafe_yyjson_get_bool(val);
8259 return true;
8260 } else {
8261 return false;
8262 }
8263}
8264
8265/**
8266 Set provided `value` if the JSON Pointer (RFC 6901) exists and is an integer
8267 that fits in `uint64_t`. Returns true if successful, otherwise false.
8268 */
8269yyjson_api_inline bool yyjson_ptr_get_uint(
8270 const yyjson_val *root, const char *ptr, uint64_t *value) {
8271 yyjson_val *val = yyjson_ptr_get(root, ptr);
8272 if (value && val) {
8273 uint64_t ret = val->uni.u64;
8274 if (unsafe_yyjson_is_uint(val) ||
8275 (unsafe_yyjson_is_sint(val) && !(ret >> 63))) {
8276 *value = ret;
8277 return true;
8278 }
8279 }
8280 return false;
8281}
8282
8283/**
8284 Set provided `value` if the JSON Pointer (RFC 6901) exists and is an integer
8285 that fits in `int64_t`. Returns true if successful, otherwise false.
8286 */
8287yyjson_api_inline bool yyjson_ptr_get_sint(
8288 const yyjson_val *root, const char *ptr, int64_t *value) {
8289 yyjson_val *val = yyjson_ptr_get(root, ptr);
8290 if (value && val) {
8291 int64_t ret = val->uni.i64;
8292 if (unsafe_yyjson_is_sint(val) ||
8293 (unsafe_yyjson_is_uint(val) && ret >= 0)) {
8294 *value = ret;
8295 return true;
8296 }
8297 }
8298 return false;
8299}
8300
8301/**
8302 Set provided `value` if the JSON Pointer (RFC 6901) exists and is type real.
8303 Returns true if value at `ptr` exists and is the correct type, otherwise false.
8304 */
8305yyjson_api_inline bool yyjson_ptr_get_real(
8306 const yyjson_val *root, const char *ptr, double *value) {
8307 yyjson_val *val = yyjson_ptr_get(root, ptr);
8308 if (value && yyjson_is_real(val)) {
8309 *value = unsafe_yyjson_get_real(val);
8310 return true;
8311 } else {
8312 return false;
8313 }
8314}
8315
8316/**
8317 Set provided `value` if the JSON Pointer (RFC 6901) exists and is type sint,
8318 uint or real.
8319 Returns true if value at `ptr` exists and is the correct type, otherwise false.
8320 */
8321yyjson_api_inline bool yyjson_ptr_get_num(
8322 const yyjson_val *root, const char *ptr, double *value) {
8323 yyjson_val *val = yyjson_ptr_get(root, ptr);
8324 if (value && yyjson_is_num(val)) {
8325 *value = unsafe_yyjson_get_num(val);
8326 return true;
8327 } else {
8328 return false;
8329 }
8330}
8331
8332/**
8333 Set provided `value` if the JSON Pointer (RFC 6901) exists and is type string.
8334 Returns true if value at `ptr` exists and is the correct type, otherwise false.
8335 */
8336yyjson_api_inline bool yyjson_ptr_get_str(
8337 const yyjson_val *root, const char *ptr, const char **value) {
8338 yyjson_val *val = yyjson_ptr_get(root, ptr);
8339 if (value && yyjson_is_str(val)) {
8340 *value = unsafe_yyjson_get_str(val);
8341 return true;
8342 } else {
8343 return false;
8344 }
8345}
8346
8347
8348
8349/*==============================================================================
8350 * MARK: - Deprecated
8351 *============================================================================*/
8352
8353/** Compatibility alias for `yyjson_doc_ptr_get`. */
8354yyjson_deprecated("renamed to yyjson_doc_ptr_get")
8355yyjson_api_inline yyjson_val *yyjson_doc_get_pointer(yyjson_doc *doc,
8356 const char *ptr) {
8357 return yyjson_doc_ptr_get(doc, ptr);
8358}
8359
8360/** Compatibility alias for `yyjson_doc_ptr_getn`. */
8361yyjson_deprecated("renamed to yyjson_doc_ptr_getn")
8362yyjson_api_inline yyjson_val *yyjson_doc_get_pointern(yyjson_doc *doc,
8363 const char *ptr,
8364 size_t len) {
8365 return yyjson_doc_ptr_getn(doc, ptr, len);
8366}
8367
8368/** Compatibility alias for `yyjson_mut_doc_ptr_get`. */
8369yyjson_deprecated("renamed to yyjson_mut_doc_ptr_get")
8370yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_get_pointer(
8371 yyjson_mut_doc *doc, const char *ptr) {
8372 return yyjson_mut_doc_ptr_get(doc, ptr);
8373}
8374
8375/** Compatibility alias for `yyjson_mut_doc_ptr_getn`. */
8376yyjson_deprecated("renamed to yyjson_mut_doc_ptr_getn")
8377yyjson_api_inline yyjson_mut_val *yyjson_mut_doc_get_pointern(
8378 yyjson_mut_doc *doc, const char *ptr, size_t len) {
8379 return yyjson_mut_doc_ptr_getn(doc, ptr, len);
8380}
8381
8382/** Compatibility alias for `yyjson_ptr_get`. */
8383yyjson_deprecated("renamed to yyjson_ptr_get")
8384yyjson_api_inline yyjson_val *yyjson_get_pointer(yyjson_val *val,
8385 const char *ptr) {
8386 return yyjson_ptr_get(val, ptr);
8387}
8388
8389/** Compatibility alias for `yyjson_ptr_getn`. */
8390yyjson_deprecated("renamed to yyjson_ptr_getn")
8391yyjson_api_inline yyjson_val *yyjson_get_pointern(yyjson_val *val,
8392 const char *ptr,
8393 size_t len) {
8394 return yyjson_ptr_getn(val, ptr, len);
8395}
8396
8397/** Compatibility alias for `yyjson_mut_ptr_get`. */
8398yyjson_deprecated("renamed to yyjson_mut_ptr_get")
8399yyjson_api_inline yyjson_mut_val *yyjson_mut_get_pointer(yyjson_mut_val *val,
8400 const char *ptr) {
8401 return yyjson_mut_ptr_get(val, ptr);
8402}
8403
8404/** Compatibility alias for `yyjson_mut_ptr_getn`. */
8405yyjson_deprecated("renamed to yyjson_mut_ptr_getn")
8406yyjson_api_inline yyjson_mut_val *yyjson_mut_get_pointern(yyjson_mut_val *val,
8407 const char *ptr,
8408 size_t len) {
8409 return yyjson_mut_ptr_getn(val, ptr, len);
8410}
8411
8412/** Compatibility alias for `unsafe_yyjson_ptr_getx`. */
8413yyjson_deprecated("renamed to unsafe_yyjson_ptr_getn")
8414yyjson_api_inline yyjson_val *unsafe_yyjson_get_pointer(yyjson_val *val,
8415 const char *ptr,
8416 size_t len) {
8417 yyjson_ptr_err err;
8418 return unsafe_yyjson_ptr_getx(val, ptr, len, &err);
8419}
8420
8421/** Compatibility alias for `unsafe_yyjson_mut_ptr_getx`. */
8422yyjson_deprecated("renamed to unsafe_yyjson_mut_ptr_getx")
8423yyjson_api_inline yyjson_mut_val *unsafe_yyjson_mut_get_pointer(
8424 yyjson_mut_val *val, const char *ptr, size_t len) {
8425 yyjson_ptr_err err;
8426 return unsafe_yyjson_mut_ptr_getx(val, ptr, len, NULL, &err);
8427}
8428
8429#endif /* YYJSON_DISABLE_UTILS */
8430
8431
8432
8433/*==============================================================================
8434 * MARK: - Compiler Hint End
8435 *============================================================================*/
8436
8437#if defined(__clang__)
8438# pragma clang diagnostic pop
8439#elif YYJSON_IS_REAL_GCC
8440# if yyjson_gcc_available(4, 6, 0)
8441# pragma GCC diagnostic pop
8442# endif
8443#elif defined(_MSC_VER)
8444# pragma warning(pop)
8445#endif /* warning suppress end */
8446
8447#ifdef __cplusplus
8448}
8449#endif /* extern "C" end */
8450
8451#endif /* YYJSON_H */
void(* free)(void *ctx, void *ptr)
Definition yyjson.h:668
void * ctx
Definition yyjson.h:670
yyjson_val * cur
Definition yyjson.h:2194
size_t dat_read
Definition yyjson.h:4979
char * str_pool
Definition yyjson.h:4983
yyjson_alc alc
Definition yyjson.h:4977
size_t val_read
Definition yyjson.h:4981
yyjson_val * root
Definition yyjson.h:4975
yyjson_val * val
Definition yyjson.c:6568
yyjson_alc alc
Definition yyjson.c:6558
yyjson_read_flag flg
Definition yyjson.c:6559
yyjson_mut_val * cur
Definition yyjson.h:2920
yyjson_mut_val * pre
Definition yyjson.h:2921
yyjson_mut_val * arr
Definition yyjson.h:2922
yyjson_mut_val * cur
Definition yyjson.h:3746
yyjson_mut_val * pre
Definition yyjson.h:3747
yyjson_mut_val * obj
Definition yyjson.h:3748
yyjson_val * obj
Definition yyjson.h:2320
yyjson_val * cur
Definition yyjson.h:2319
yyjson_ptr_err ptr
Definition yyjson.h:4891
yyjson_patch_code code
Definition yyjson.h:4885
const char * msg
Definition yyjson.h:4889
yyjson_mut_val * old
Definition yyjson.h:4348
yyjson_mut_val * ctn
Definition yyjson.h:4334
yyjson_mut_val * pre
Definition yyjson.h:4343
const char * msg
Definition yyjson.h:4302
yyjson_ptr_code code
Definition yyjson.h:4300
yyjson_read_code code
Definition yyjson.h:960
const char * msg
Definition yyjson.h:962
yyjson_val_uni uni
Definition yyjson.h:4970
uint64_t tag
Definition yyjson.h:4969
const char * msg
Definition yyjson.h:1338
yyjson_write_code code
Definition yyjson.h:1336
uint64_t u64
Definition yyjson.h:4957
const char * str
Definition yyjson.h:4960
int64_t i64
Definition yyjson.h:4958
yyjson_api_inline size_t yyjson_mut_get_len(const yyjson_mut_val *val)
Definition yyjson.h:6042
yyjson_api_inline bool yyjson_is_ctn(const yyjson_val *val)
Definition yyjson.h:5402
yyjson_api_inline char * yyjson_val_write(const yyjson_val *val, yyjson_write_flag flg, size_t *len)
Definition yyjson.h:1738
yyjson_api_inline yyjson_mut_val * yyjson_mut_ptr_get(const yyjson_mut_val *val, const char *ptr)
Definition yyjson.h:7732
uint8_t yyjson_subtype
Definition yyjson.h:614
yyjson_api_inline size_t yyjson_mut_arr_size(const yyjson_mut_val *arr)
Definition yyjson.h:6314
yyjson_api_inline yyjson_mut_val * yyjson_mut_true(yyjson_mut_doc *doc)
Definition yyjson.h:6228
yyjson_api_inline yyjson_mut_val * yyjson_mut_doc_ptr_remove(yyjson_mut_doc *doc, const char *ptr)
Definition yyjson.h:8052
yyjson_api_inline bool yyjson_mut_is_int(const yyjson_mut_val *val)
Definition yyjson.h:5958
static const yyjson_read_flag YYJSON_READ_ALLOW_TRAILING_COMMAS
Definition yyjson.h:826
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_with_sint(yyjson_mut_doc *doc, const int64_t *vals, size_t count)
Definition yyjson.h:6449
uint32_t yyjson_read_code
Definition yyjson.h:907
yyjson_api_inline bool yyjson_set_fp_to_float(yyjson_val *val, bool flt)
Definition yyjson.h:5566
yyjson_api_inline bool yyjson_set_null(yyjson_val *val)
Definition yyjson.h:5512
yyjson_api_inline int yyjson_get_int(const yyjson_val *val)
Definition yyjson.h:5457
yyjson_api_inline bool yyjson_mut_arr_add_str(yyjson_mut_doc *doc, yyjson_mut_val *arr, const char *str)
Definition yyjson.h:6902
static const yyjson_read_code YYJSON_READ_ERROR_MEMORY_ALLOCATION
Definition yyjson.h:916
yyjson_api yyjson_mut_val * yyjson_mut_val_mut_copy(yyjson_mut_doc *doc, const yyjson_mut_val *val)
Definition yyjson.c:2826
yyjson_api_inline bool yyjson_mut_set_fp_to_fixed(yyjson_mut_val *val, int prec)
Definition yyjson.h:6120
yyjson_api_inline bool yyjson_mut_set_real(yyjson_mut_val *val, double num)
Definition yyjson.h:6114
static const yyjson_read_code YYJSON_READ_ERROR_UNEXPECTED_CONTENT
Definition yyjson.h:922
yyjson_api yyjson_mut_val * yyjson_mut_merge_patch(yyjson_mut_doc *doc, const yyjson_mut_val *orig, const yyjson_mut_val *patch)
Definition yyjson.c:11336
static const yyjson_write_flag YYJSON_WRITE_ESCAPE_SLASHES
Definition yyjson.h:1254
yyjson_api_inline bool yyjson_mut_obj_rotate(yyjson_mut_val *obj, size_t idx)
Definition yyjson.h:7351
static const yyjson_patch_code YYJSON_PATCH_ERROR_INVALID_PARAMETER
Definition yyjson.h:4862
yyjson_api_inline bool yyjson_mut_set_bool(yyjson_mut_val *val, bool num)
Definition yyjson.h:6078
yyjson_api_inline bool yyjson_mut_arr_add_true(yyjson_mut_doc *doc, yyjson_mut_val *arr)
Definition yyjson.h:6814
yyjson_api_inline yyjson_mut_val * yyjson_mut_strn(yyjson_mut_doc *doc, const char *str, size_t len)
Definition yyjson.h:6276
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj_remove_key(yyjson_mut_val *obj, const char *key)
Definition yyjson.h:7316
yyjson_api_inline bool yyjson_mut_equals_str(const yyjson_mut_val *val, const char *str)
Definition yyjson.h:6046
static const yyjson_patch_code YYJSON_PATCH_ERROR_INVALID_MEMBER
Definition yyjson.h:4874
yyjson_api_inline bool yyjson_is_str(const yyjson_val *val)
Definition yyjson.h:5390
yyjson_api_inline bool yyjson_mut_arr_prepend(yyjson_mut_val *arr, yyjson_mut_val *val)
Definition yyjson.h:6640
yyjson_api_inline bool yyjson_mut_set_fp_to_float(yyjson_mut_val *val, bool flt)
Definition yyjson.h:6127
yyjson_api_inline yyjson_mut_val * yyjson_mut_strncpy(yyjson_mut_doc *doc, const char *str, size_t len)
Definition yyjson.h:6295
yyjson_api_inline bool yyjson_mut_arr_add_strncpy(yyjson_mut_doc *doc, yyjson_mut_val *arr, const char *str, size_t len)
Definition yyjson.h:6932
yyjson_api_inline bool yyjson_is_obj(const yyjson_val *val)
Definition yyjson.h:5398
static const yyjson_read_flag YYJSON_READ_ALLOW_EXT_NUMBER
Definition yyjson.h:862
yyjson_api_inline yyjson_mut_val * yyjson_mut_real(yyjson_mut_doc *doc, double num)
Definition yyjson.h:6266
static const yyjson_write_code YYJSON_WRITE_ERROR_NAN_OR_INF
Definition yyjson.h:1322
yyjson_api_inline bool yyjson_mut_ptr_setx(yyjson_mut_val *val, const char *ptr, size_t len, yyjson_mut_val *new_val, yyjson_mut_doc *doc, bool create_parent, yyjson_ptr_ctx *ctx, yyjson_ptr_err *err)
Definition yyjson.h:7946
yyjson_api_inline yyjson_mut_val * yyjson_mut_false(yyjson_mut_doc *doc)
Definition yyjson.h:6232
yyjson_api_inline bool yyjson_mut_set_double(yyjson_mut_val *val, double num)
Definition yyjson.h:6108
static const yyjson_read_code YYJSON_READ_ERROR_LITERAL
Definition yyjson.h:943
yyjson_api_inline yyjson_mut_val * yyjson_mut_doc_ptr_replace(yyjson_mut_doc *doc, const char *ptr, yyjson_mut_val *new_val)
Definition yyjson.h:7975
yyjson_api_inline const char * yyjson_get_type_desc(const yyjson_val *val)
Definition yyjson.h:5424
static const yyjson_read_flag YYJSON_READ_NUMBER_AS_RAW
Definition yyjson.h:837
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj_add_arr(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key)
Definition yyjson.h:7505
yyjson_api_inline bool yyjson_mut_obj_add_strncpy(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key, const char *val, size_t len)
Definition yyjson.h:7492
yyjson_api_inline yyjson_val * yyjson_obj_iter_get(yyjson_obj_iter *iter, const char *key)
Definition yyjson.h:5755
yyjson_api_inline bool yyjson_set_fp_to_fixed(yyjson_val *val, int prec)
Definition yyjson.h:5560
static const yyjson_write_code YYJSON_WRITE_SUCCESS
Definition yyjson.h:1310
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_iter_remove(yyjson_mut_arr_iter *iter)
Definition yyjson.h:6387
yyjson_api_inline bool yyjson_mut_obj_add_val(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key, yyjson_mut_val *val)
Definition yyjson.h:7521
yyjson_api_inline bool yyjson_mut_arr_iter_has_next(yyjson_mut_arr_iter *iter)
Definition yyjson.h:6371
yyjson_api_inline bool yyjson_arr_iter_has_next(yyjson_arr_iter *iter)
Definition yyjson.h:5668
yyjson_api_inline bool yyjson_mut_doc_ptr_setn(yyjson_mut_doc *doc, const char *ptr, size_t len, yyjson_mut_val *new_val)
Definition yyjson.h:7875
yyjson_api_inline bool yyjson_mut_set_float(yyjson_mut_val *val, float num)
Definition yyjson.h:6102
yyjson_api_inline size_t yyjson_mut_obj_size(const yyjson_mut_val *obj)
Definition yyjson.h:6966
yyjson_api_inline bool yyjson_mut_ptr_addx(yyjson_mut_val *val, const char *ptr, size_t len, yyjson_mut_val *new_val, yyjson_mut_doc *doc, bool create_parent, yyjson_ptr_ctx *ctx, yyjson_ptr_err *err)
Definition yyjson.h:7842
yyjson_api char * yyjson_write_number(const yyjson_val *val, char *buf)
Definition yyjson.c:8427
const char * ptr
Definition yyjson.h:8356
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_remove(yyjson_mut_val *arr, size_t idx)
Definition yyjson.h:6687
yyjson_api_inline yyjson_mut_val * yyjson_mut_doc_ptr_getx(const yyjson_mut_doc *doc, const char *ptr, size_t len, yyjson_ptr_ctx *ctx, yyjson_ptr_err *err)
Definition yyjson.h:7708
yyjson_api_inline bool yyjson_mut_arr_clear(yyjson_mut_val *arr)
Definition yyjson.h:6774
yyjson_api_inline bool yyjson_mut_is_bool(const yyjson_mut_val *val)
Definition yyjson.h:5946
yyjson_api_inline yyjson_mut_val * yyjson_mut_doc_ptr_removex(yyjson_mut_doc *doc, const char *ptr, size_t len, yyjson_ptr_ctx *ctx, yyjson_ptr_err *err)
Definition yyjson.h:8063
yyjson_api_inline bool yyjson_mut_arr_add_strcpy(yyjson_mut_doc *doc, yyjson_mut_val *arr, const char *str)
Definition yyjson.h:6922
yyjson_api_inline bool yyjson_mut_set_strn(yyjson_mut_val *val, const char *str, size_t len)
Definition yyjson.h:6141
yyjson_api_inline bool yyjson_mut_obj_add_double(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key, double val)
Definition yyjson.h:7439
yyjson_api bool yyjson_write_fp(FILE *fp, const yyjson_doc *doc, yyjson_write_flag flg, const yyjson_alc *alc, yyjson_write_err *err)
Definition yyjson.c:9796
yyjson_api yyjson_mut_val * yyjson_mut_patch(yyjson_mut_doc *doc, const yyjson_mut_val *orig, const yyjson_mut_val *patch, yyjson_patch_err *err)
Definition yyjson.c:11147
static const yyjson_ptr_code YYJSON_PTR_ERR_PARAMETER
Definition yyjson.h:4280
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_with_uint8(yyjson_mut_doc *doc, const uint8_t *vals, size_t count)
Definition yyjson.h:6494
yyjson_api const char * yyjson_read_number(const char *dat, yyjson_val *val, yyjson_read_flag flg, const yyjson_alc *alc, yyjson_read_err *err)
Definition yyjson.c:6469
static const yyjson_read_code YYJSON_READ_ERROR_FILE_READ
Definition yyjson.h:949
yyjson_api bool yyjson_write_file(const char *path, const yyjson_doc *doc, yyjson_write_flag flg, const yyjson_alc *alc, yyjson_write_err *err)
Definition yyjson.c:9787
yyjson_api size_t yyjson_write_buf(char *buf, size_t buf_len, const yyjson_doc *doc, yyjson_write_flag flg, yyjson_write_err *err)
Definition yyjson.c:9821
static const yyjson_patch_code YYJSON_PATCH_SUCCESS
Definition yyjson.h:4859
yyjson_api_inline const char * yyjson_mut_get_str(const yyjson_mut_val *val)
Definition yyjson.h:6038
yyjson_api yyjson_mut_doc * yyjson_mut_doc_mut_copy(const yyjson_mut_doc *doc, const yyjson_alc *alc)
Definition yyjson.c:2695
yyjson_api_inline bool yyjson_is_sint(const yyjson_val *val)
Definition yyjson.h:5374
static const yyjson_read_flag YYJSON_READ_BIGNUM_AS_RAW
Definition yyjson.h:853
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj_get(const yyjson_mut_val *obj, const char *key)
Definition yyjson.h:6970
yyjson_api_inline uint64_t yyjson_get_uint(const yyjson_val *val)
Definition yyjson.h:5449
yyjson_api void yyjson_incr_free(yyjson_incr_state *state)
Definition yyjson.c:6613
yyjson_api_inline bool yyjson_mut_obj_rename_keyn(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key, size_t len, const char *new_key, size_t new_len)
Definition yyjson.h:7563
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_replace(yyjson_mut_val *arr, size_t idx, yyjson_mut_val *val)
Definition yyjson.h:6659
yyjson_api_inline yyjson_val * yyjson_obj_iter_get_val(yyjson_val *key)
Definition yyjson.h:5751
yyjson_api_inline yyjson_mut_val * yyjson_mut_ptr_removen(yyjson_mut_val *val, const char *ptr, size_t len)
Definition yyjson.h:8097
yyjson_api_inline yyjson_mut_val * yyjson_mut_float(yyjson_mut_doc *doc, float num)
Definition yyjson.h:6256
yyjson_api_inline yyjson_mut_val * yyjson_mut_rawcpy(yyjson_mut_doc *doc, const char *str)
Definition yyjson.h:6204
uint32_t yyjson_read_flag
Definition yyjson.h:799
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj_remove_keyn(yyjson_mut_val *obj, const char *key, size_t key_len)
Definition yyjson.h:7325
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_with_sint64(yyjson_mut_doc *doc, const int64_t *vals, size_t count)
Definition yyjson.h:6487
yyjson_api_inline int64_t yyjson_get_sint(const yyjson_val *val)
Definition yyjson.h:5453
static const yyjson_read_flag YYJSON_READ_ALLOW_UNQUOTED_KEY
Definition yyjson.h:887
static const yyjson_write_flag YYJSON_WRITE_ALLOW_INF_AND_NAN
Definition yyjson.h:1257
yyjson_api_inline bool yyjson_mut_arr_add_double(yyjson_mut_doc *doc, yyjson_mut_val *arr, double num)
Definition yyjson.h:6882
static const yyjson_patch_code YYJSON_PATCH_ERROR_INVALID_OPERATION
Definition yyjson.h:4868
yyjson_api_inline yyjson_val * yyjson_arr_get_first(const yyjson_val *arr)
Definition yyjson.h:5619
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj_iter_getn(yyjson_mut_obj_iter *iter, const char *key, size_t key_len)
Definition yyjson.h:7059
yyjson_api bool yyjson_val_write_fp(FILE *fp, const yyjson_val *val, yyjson_write_flag flg, const yyjson_alc *alc, yyjson_write_err *err)
Definition yyjson.c:9761
yyjson_api_inline yyjson_mut_val * yyjson_mut_rawn(yyjson_mut_doc *doc, const char *str, size_t len)
Definition yyjson.h:6198
yyjson_api yyjson_mut_doc * yyjson_doc_mut_copy(const yyjson_doc *doc, const yyjson_alc *alc)
Definition yyjson.c:2678
yyjson_api_inline bool yyjson_mut_obj_add_sint(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key, int64_t val)
Definition yyjson.h:7418
static const yyjson_write_code YYJSON_WRITE_ERROR_INVALID_VALUE_TYPE
Definition yyjson.h:1319
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_with_strn(yyjson_mut_doc *doc, const char **vals, const size_t *lens, size_t count)
Definition yyjson.h:6544
static const yyjson_ptr_code YYJSON_PTR_ERR_NONE
Definition yyjson.h:4277
static const yyjson_write_code YYJSON_WRITE_ERROR_FILE_OPEN
Definition yyjson.h:1325
yyjson_api_inline yyjson_mut_val * yyjson_mut_ptr_replacex(yyjson_mut_val *val, const char *ptr, size_t len, yyjson_mut_val *new_val, yyjson_ptr_ctx *ctx, yyjson_ptr_err *err)
Definition yyjson.h:8030
yyjson_api_inline yyjson_val * yyjson_doc_ptr_getn(const yyjson_doc *doc, const char *ptr, size_t len)
Definition yyjson.h:7641
yyjson_api char * yyjson_write_opts(const yyjson_doc *doc, yyjson_write_flag flg, const yyjson_alc *alc, size_t *len, yyjson_write_err *err)
Definition yyjson.c:9724
static const yyjson_write_flag YYJSON_WRITE_INF_AND_NAN_AS_NULL
Definition yyjson.h:1261
yyjson_api_inline int64_t yyjson_mut_get_sint(const yyjson_mut_val *val)
Definition yyjson.h:6022
yyjson_api_inline bool yyjson_set_str_noesc(yyjson_val *val, bool noesc)
Definition yyjson.h:5587
yyjson_api_inline bool yyjson_mut_obj_add_strn(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key, const char *val, size_t len)
Definition yyjson.h:7467
yyjson_api size_t yyjson_mut_val_write_buf(char *buf, size_t buf_len, const yyjson_mut_val *val, yyjson_write_flag flg, yyjson_write_err *err)
Definition yyjson.c:10365
yyjson_api_inline bool yyjson_mut_is_ctn(const yyjson_mut_val *val)
Definition yyjson.h:5982
yyjson_api_inline bool yyjson_mut_doc_ptr_setx(yyjson_mut_doc *doc, const char *ptr, size_t len, yyjson_mut_val *new_val, bool create_parent, yyjson_ptr_ctx *ctx, yyjson_ptr_err *err)
Definition yyjson.h:7881
static const yyjson_read_code YYJSON_READ_ERROR_MORE
Definition yyjson.h:952
yyjson_api_inline yyjson_val * yyjson_arr_get(const yyjson_val *arr, size_t idx)
Definition yyjson.h:5603
yyjson_api yyjson_incr_state * yyjson_incr_new(char *buf, size_t buf_len, yyjson_read_flag flg, const yyjson_alc *alc)
Definition yyjson.c:6575
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj_with_str(yyjson_mut_doc *doc, const char **keys, const char **vals, size_t count)
Definition yyjson.h:7097
static const yyjson_read_flag YYJSON_READ_ALLOW_INF_AND_NAN
Definition yyjson.h:833
yyjson_api size_t yyjson_val_write_buf(char *buf, size_t buf_len, const yyjson_val *val, yyjson_write_flag flg, yyjson_write_err *err)
Definition yyjson.c:9807
uint8_t yyjson_type
Definition yyjson.h:595
static const yyjson_write_code YYJSON_WRITE_ERROR_MEMORY_ALLOCATION
Definition yyjson.h:1316
yyjson_api_inline bool yyjson_mut_ptr_set(yyjson_mut_val *val, const char *ptr, yyjson_mut_val *new_val, yyjson_mut_doc *doc)
Definition yyjson.h:7931
static const yyjson_ptr_code YYJSON_PTR_ERR_SYNTAX
Definition yyjson.h:4283
yyjson_api_inline yyjson_mut_val * yyjson_mut_doc_ptr_removen(yyjson_mut_doc *doc, const char *ptr, size_t len)
Definition yyjson.h:8058
yyjson_api_inline yyjson_val * yyjson_doc_ptr_get(const yyjson_doc *doc, const char *ptr)
Definition yyjson.h:7635
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_with_float(yyjson_mut_doc *doc, const float *vals, size_t count)
Definition yyjson.h:6522
yyjson_api_inline bool yyjson_mut_set_raw(yyjson_mut_val *val, const char *raw, size_t len)
Definition yyjson.h:6065
yyjson_api_inline bool yyjson_mut_obj_add_false(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key)
Definition yyjson.h:7398
yyjson_api_inline bool yyjson_mut_set_obj(yyjson_mut_val *val)
Definition yyjson.h:6161
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_with_sint32(yyjson_mut_doc *doc, const int32_t *vals, size_t count)
Definition yyjson.h:6480
yyjson_api_inline double yyjson_mut_get_num(const yyjson_mut_val *val)
Definition yyjson.h:6034
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj_iter_next(yyjson_mut_obj_iter *iter)
Definition yyjson.h:7020
yyjson_api_inline bool yyjson_mut_obj_add_int(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key, int64_t val)
Definition yyjson.h:7425
yyjson_api_inline yyjson_mut_val * yyjson_mut_bool(yyjson_mut_doc *doc, bool val)
Definition yyjson.h:6236
yyjson_api_inline bool yyjson_mut_is_real(const yyjson_mut_val *val)
Definition yyjson.h:5962
static const yyjson_read_code YYJSON_READ_SUCCESS
Definition yyjson.h:910
yyjson_api_inline bool yyjson_mut_arr_add_bool(yyjson_mut_doc *doc, yyjson_mut_val *arr, bool val)
Definition yyjson.h:6832
static const yyjson_ptr_code YYJSON_PTR_ERR_NULL_ROOT
Definition yyjson.h:4289
yyjson_api_inline bool yyjson_equals_strn(const yyjson_val *val, const char *str, size_t len)
Definition yyjson.h:5486
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_get_first(const yyjson_mut_val *arr)
Definition yyjson.h:6328
yyjson_api yyjson_doc * yyjson_mut_doc_imut_copy(const yyjson_mut_doc *doc, const yyjson_alc *alc)
Definition yyjson.c:2898
static const yyjson_patch_code YYJSON_PATCH_ERROR_MISSING_KEY
Definition yyjson.h:4871
yyjson_api_inline bool yyjson_mut_doc_ptr_addn(yyjson_mut_doc *doc, const char *ptr, size_t len, yyjson_mut_val *new_val)
Definition yyjson.h:7773
yyjson_api_inline bool yyjson_mut_obj_add_uint(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key, uint64_t val)
Definition yyjson.h:7411
yyjson_api_inline bool yyjson_is_true(const yyjson_val *val)
Definition yyjson.h:5358
yyjson_api_inline yyjson_val * yyjson_obj_iter_next(yyjson_obj_iter *iter)
Definition yyjson.h:5741
yyjson_api yyjson_doc * yyjson_read_file(const char *path, yyjson_read_flag flg, const yyjson_alc *alc, yyjson_read_err *err)
Definition yyjson.c:6341
yyjson_api bool yyjson_alc_pool_init(yyjson_alc *alc, void *buf, size_t size)
Definition yyjson.c:2376
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj_remove_str(yyjson_mut_val *obj, const char *key)
Definition yyjson.h:7531
static const yyjson_read_flag YYJSON_READ_ALLOW_EXT_WHITESPACE
Definition yyjson.h:879
static const yyjson_read_code YYJSON_READ_ERROR_DEPTH
Definition yyjson.h:955
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj_remove(yyjson_mut_val *obj, yyjson_mut_val *key)
Definition yyjson.h:7307
yyjson_api_inline size_t yyjson_obj_size(const yyjson_val *obj)
Definition yyjson.h:5689
#define yyjson_api_inline
Definition yyjson.h:350
yyjson_api_inline yyjson_mut_val * yyjson_mut_ptr_removex(yyjson_mut_val *val, const char *ptr, size_t len, yyjson_ptr_ctx *ctx, yyjson_ptr_err *err)
Definition yyjson.h:8103
yyjson_api_inline yyjson_val * yyjson_doc_get_root(const yyjson_doc *doc)
Definition yyjson.h:5323
#define yyjson_api
Definition yyjson.h:344
yyjson_api_inline bool yyjson_mut_is_uint(const yyjson_mut_val *val)
Definition yyjson.h:5950
yyjson_api yyjson_alc * yyjson_alc_dyn_new(void)
Definition yyjson.c:2524
yyjson_api_inline bool yyjson_mut_equals_strn(const yyjson_mut_val *val, const char *str, size_t len)
Definition yyjson.h:6051
yyjson_api_inline bool yyjson_mut_doc_ptr_set(yyjson_mut_doc *doc, const char *ptr, yyjson_mut_val *new_val)
Definition yyjson.h:7868
yyjson_api_inline bool yyjson_mut_arr_rotate(yyjson_mut_val *arr, size_t idx)
Definition yyjson.h:6782
yyjson_api_inline bool yyjson_mut_set_null(yyjson_mut_val *val)
Definition yyjson.h:6072
static const yyjson_patch_code YYJSON_PATCH_ERROR_POINTER
Definition yyjson.h:4880
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj_iter_remove(yyjson_mut_obj_iter *iter)
Definition yyjson.h:7037
yyjson_api_inline yyjson_val * yyjson_ptr_getx(const yyjson_val *val, const char *ptr, size_t len, yyjson_ptr_err *err)
Definition yyjson.h:7679
yyjson_api_inline bool yyjson_mut_arr_add_uint(yyjson_mut_doc *doc, yyjson_mut_val *arr, uint64_t num)
Definition yyjson.h:6842
yyjson_api_inline bool yyjson_mut_obj_add_null(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key)
Definition yyjson.h:7386
yyjson_api_inline bool yyjson_is_arr(const yyjson_val *val)
Definition yyjson.h:5394
yyjson_api_inline char * yyjson_mut_val_write(const yyjson_mut_val *val, yyjson_write_flag flg, size_t *len)
Definition yyjson.h:1869
static const yyjson_read_code YYJSON_READ_ERROR_INVALID_COMMENT
Definition yyjson.h:934
yyjson_api_inline int yyjson_mut_get_int(const yyjson_mut_val *val)
Definition yyjson.h:6026
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_with_real(yyjson_mut_doc *doc, const double *vals, size_t count)
Definition yyjson.h:6459
yyjson_api_inline yyjson_mut_val * yyjson_mut_doc_ptr_replacen(yyjson_mut_doc *doc, const char *ptr, size_t len, yyjson_mut_val *new_val)
Definition yyjson.h:7981
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj(yyjson_mut_doc *doc)
Definition yyjson.h:7086
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj_add_obj(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key)
Definition yyjson.h:7513
yyjson_api bool yyjson_val_write_file(const char *path, const yyjson_val *val, yyjson_write_flag flg, const yyjson_alc *alc, yyjson_write_err *err)
Definition yyjson.c:9735
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_with_sint16(yyjson_mut_doc *doc, const int16_t *vals, size_t count)
Definition yyjson.h:6473
yyjson_api_inline bool yyjson_is_false(const yyjson_val *val)
Definition yyjson.h:5362
yyjson_api_inline yyjson_val * yyjson_obj_get(const yyjson_val *obj, const char *key)
Definition yyjson.h:5693
yyjson_api_inline yyjson_mut_val * yyjson_mut_null(yyjson_mut_doc *doc)
Definition yyjson.h:6224
yyjson_api_inline bool yyjson_mut_set_int(yyjson_mut_val *val, int64_t num)
Definition yyjson.h:6096
yyjson_api_inline yyjson_mut_val * yyjson_mut_raw(yyjson_mut_doc *doc, const char *str)
Definition yyjson.h:6193
yyjson_api_inline yyjson_type yyjson_get_type(const yyjson_val *val)
Definition yyjson.h:5412
yyjson_api_inline bool yyjson_set_raw(yyjson_val *val, const char *raw, size_t len)
Definition yyjson.h:5504
static const yyjson_read_code YYJSON_READ_ERROR_FILE_OPEN
Definition yyjson.h:946
static const yyjson_write_code YYJSON_WRITE_ERROR_FILE_WRITE
Definition yyjson.h:1328
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_iter_next(yyjson_mut_arr_iter *iter)
Definition yyjson.h:6375
yyjson_api char * yyjson_val_write_opts(const yyjson_val *val, yyjson_write_flag flg, const yyjson_alc *alc, size_t *len, yyjson_write_err *err)
Definition yyjson.c:9716
yyjson_api_inline yyjson_val * yyjson_obj_iter_getn(yyjson_obj_iter *iter, const char *key, size_t key_len)
Definition yyjson.h:5760
yyjson_api void yyjson_mut_doc_free(yyjson_mut_doc *doc)
Definition yyjson.c:2653
yyjson_api char * yyjson_mut_write_opts(const yyjson_mut_doc *doc, yyjson_write_flag flg, const yyjson_alc *alc, size_t *len, yyjson_write_err *err)
Definition yyjson.c:10347
static const yyjson_write_flag YYJSON_WRITE_PRETTY_TWO_SPACES
Definition yyjson.h:1272
yyjson_api_inline bool yyjson_is_int(const yyjson_val *val)
Definition yyjson.h:5378
yyjson_api_inline bool yyjson_is_real(const yyjson_val *val)
Definition yyjson.h:5382
yyjson_api_inline bool yyjson_obj_iter_init(const yyjson_val *obj, yyjson_obj_iter *iter)
Definition yyjson.h:5718
static const yyjson_write_code YYJSON_WRITE_ERROR_INVALID_PARAMETER
Definition yyjson.h:1313
yyjson_api yyjson_doc * yyjson_read_fp(FILE *fp, yyjson_read_flag flg, const yyjson_alc *alc, yyjson_read_err *err)
Definition yyjson.c:6369
yyjson_api_inline bool yyjson_mut_obj_add_true(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key)
Definition yyjson.h:7392
yyjson_api_inline yyjson_mut_val * yyjson_mut_ptr_getn(const yyjson_mut_val *val, const char *ptr, size_t len)
Definition yyjson.h:7738
static const yyjson_read_code YYJSON_READ_ERROR_INVALID_PARAMETER
Definition yyjson.h:913
yyjson_api_inline bool yyjson_mut_set_uint(yyjson_mut_val *val, uint64_t num)
Definition yyjson.h:6084
yyjson_api_inline bool yyjson_mut_set_str(yyjson_mut_val *val, const char *str)
Definition yyjson.h:6134
yyjson_api_inline yyjson_mut_val * yyjson_mut_ptr_remove(yyjson_mut_val *val, const char *ptr)
Definition yyjson.h:8091
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_with_uint16(yyjson_mut_doc *doc, const uint16_t *vals, size_t count)
Definition yyjson.h:6501
static const yyjson_read_flag YYJSON_READ_JSON5
Definition yyjson.h:894
yyjson_api uint32_t yyjson_version(void)
Definition yyjson.c:58
yyjson_api_inline char * yyjson_mut_write(const yyjson_mut_doc *doc, yyjson_write_flag flg, size_t *len)
Definition yyjson.h:1604
yyjson_api_inline yyjson_mut_val * yyjson_mut_uint(yyjson_mut_doc *doc, uint64_t num)
Definition yyjson.h:6241
static const yyjson_read_flag YYJSON_READ_NOFLAG
Definition yyjson.h:809
yyjson_api_inline yyjson_mut_val * yyjson_mut_rawncpy(yyjson_mut_doc *doc, const char *str, size_t len)
Definition yyjson.h:6214
yyjson_api_inline void yyjson_mut_doc_set_root(yyjson_mut_doc *doc, yyjson_mut_val *root)
Definition yyjson.h:5919
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_add_arr(yyjson_mut_doc *doc, yyjson_mut_val *arr)
Definition yyjson.h:6942
static const yyjson_read_code YYJSON_READ_ERROR_INVALID_NUMBER
Definition yyjson.h:937
yyjson_api_inline bool yyjson_set_uint(yyjson_val *val, uint64_t num)
Definition yyjson.h:5524
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_with_strcpy(yyjson_mut_doc *doc, const char **vals, size_t count)
Definition yyjson.h:6553
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_remove_last(yyjson_mut_val *arr)
Definition yyjson.h:6730
yyjson_api_inline bool yyjson_ptr_ctx_remove(yyjson_ptr_ctx *ctx)
Definition yyjson.h:8212
yyjson_api_inline yyjson_mut_val * yyjson_mut_int(yyjson_mut_doc *doc, int64_t num)
Definition yyjson.h:6251
yyjson_api_inline bool yyjson_mut_arr_add_false(yyjson_mut_doc *doc, yyjson_mut_val *arr)
Definition yyjson.h:6823
yyjson_api_inline yyjson_mut_val * yyjson_mut_strcpy(yyjson_mut_doc *doc, const char *str)
Definition yyjson.h:6282
yyjson_api_inline bool yyjson_equals_str(const yyjson_val *val, const char *str)
Definition yyjson.h:5477
yyjson_api_inline bool yyjson_mut_obj_replace(yyjson_mut_val *obj, yyjson_mut_val *key, yyjson_mut_val *val)
Definition yyjson.h:7341
yyjson_api_inline bool yyjson_mut_arr_add_strn(yyjson_mut_doc *doc, yyjson_mut_val *arr, const char *str, size_t len)
Definition yyjson.h:6912
yyjson_api_inline yyjson_mut_val * yyjson_mut_double(yyjson_mut_doc *doc, double num)
Definition yyjson.h:6261
yyjson_api_inline bool yyjson_mut_obj_insert(yyjson_mut_val *obj, yyjson_mut_val *key, yyjson_mut_val *val, size_t idx)
Definition yyjson.h:7285
yyjson_api_inline bool yyjson_mut_is_obj(const yyjson_mut_val *val)
Definition yyjson.h:5978
yyjson_api_inline bool yyjson_mut_obj_add_str(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key, const char *val)
Definition yyjson.h:7453
yyjson_api_inline size_t yyjson_doc_get_read_size(const yyjson_doc *doc)
Definition yyjson.h:5327
yyjson_api_inline bool yyjson_set_str(yyjson_val *val, const char *str)
Definition yyjson.h:5572
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_get_last(const yyjson_mut_val *arr)
Definition yyjson.h:6336
yyjson_api_inline bool yyjson_equals(const yyjson_val *lhs, const yyjson_val *rhs)
Definition yyjson.h:5498
yyjson_api_inline yyjson_mut_arr_iter yyjson_mut_arr_iter_with(yyjson_mut_val *arr)
Definition yyjson.h:6364
yyjson_api bool yyjson_mut_doc_set_val_pool_size(yyjson_mut_doc *doc, size_t count)
Definition yyjson.c:2646
yyjson_api_inline char * yyjson_mut_write_number(const yyjson_mut_val *val, char *buf)
Definition yyjson.h:1898
yyjson_api_inline bool yyjson_set_strn(yyjson_val *val, const char *str, size_t len)
Definition yyjson.h:5579
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj_iter_get(yyjson_mut_obj_iter *iter, const char *key)
Definition yyjson.h:7054
yyjson_api_inline bool yyjson_ptr_ctx_append(yyjson_ptr_ctx *ctx, yyjson_mut_val *key, yyjson_mut_val *val)
Definition yyjson.h:8126
static const yyjson_read_flag YYJSON_READ_ALLOW_EXT_ESCAPE
Definition yyjson.h:871
yyjson_api_inline const char * yyjson_mut_get_type_desc(const yyjson_mut_val *val)
Definition yyjson.h:6005
yyjson_api_inline yyjson_mut_val * yyjson_mut_doc_get_root(yyjson_mut_doc *doc)
Definition yyjson.h:5915
static const yyjson_read_flag YYJSON_READ_INSITU
Definition yyjson.h:817
yyjson_api_inline bool yyjson_mut_arr_add_real(yyjson_mut_doc *doc, yyjson_mut_val *arr, double num)
Definition yyjson.h:6892
yyjson_api_inline bool yyjson_mut_obj_add_real(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key, double val)
Definition yyjson.h:7446
yyjson_api_inline bool yyjson_mut_ptr_addn(yyjson_mut_val *val, const char *ptr, size_t len, yyjson_mut_val *new_val, yyjson_mut_doc *doc)
Definition yyjson.h:7835
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj_iter_get_val(yyjson_mut_val *key)
Definition yyjson.h:7032
yyjson_api void yyjson_alc_dyn_free(yyjson_alc *alc)
Definition yyjson.c:2540
yyjson_api yyjson_doc * yyjson_mut_val_imut_copy(const yyjson_mut_val *val, const yyjson_alc *alc)
Definition yyjson.c:2904
yyjson_api_inline yyjson_val * yyjson_ptr_get(const yyjson_val *val, const char *ptr)
Definition yyjson.h:7668
yyjson_api_inline bool yyjson_is_uint(const yyjson_val *val)
Definition yyjson.h:5370
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_with_uint64(yyjson_mut_doc *doc, const uint64_t *vals, size_t count)
Definition yyjson.h:6515
yyjson_api_inline bool yyjson_set_float(yyjson_val *val, float num)
Definition yyjson.h:5542
yyjson_api_inline bool yyjson_mut_arr_add_float(yyjson_mut_doc *doc, yyjson_mut_val *arr, float num)
Definition yyjson.h:6872
yyjson_api_inline yyjson_subtype yyjson_mut_get_subtype(const yyjson_mut_val *val)
Definition yyjson.h:5996
yyjson_api_inline yyjson_mut_val * yyjson_mut_doc_ptr_getn(const yyjson_mut_doc *doc, const char *ptr, size_t len)
Definition yyjson.h:7703
static const yyjson_write_flag YYJSON_WRITE_NEWLINE_AT_END
Definition yyjson.h:1276
yyjson_api_inline uint64_t yyjson_mut_get_uint(const yyjson_mut_val *val)
Definition yyjson.h:6018
yyjson_api_inline bool yyjson_mut_equals(const yyjson_mut_val *lhs, const yyjson_mut_val *rhs)
Definition yyjson.h:6059
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_with_uint(yyjson_mut_doc *doc, const uint64_t *vals, size_t count)
Definition yyjson.h:6454
yyjson_api_inline bool yyjson_mut_arr_add_val(yyjson_mut_val *arr, yyjson_mut_val *val)
Definition yyjson.h:6800
yyjson_api yyjson_mut_val * yyjson_val_mut_copy(yyjson_mut_doc *doc, const yyjson_val *val)
Definition yyjson.c:2714
yyjson_api_inline bool yyjson_mut_arr_add_sint(yyjson_mut_doc *doc, yyjson_mut_val *arr, int64_t num)
Definition yyjson.h:6852
yyjson_api_inline bool yyjson_mut_ptr_add(yyjson_mut_val *val, const char *ptr, yyjson_mut_val *new_val, yyjson_mut_doc *doc)
Definition yyjson.h:7827
static const yyjson_read_code YYJSON_READ_ERROR_INVALID_STRING
Definition yyjson.h:940
yyjson_api_inline yyjson_mut_val * yyjson_mut_doc_ptr_get(const yyjson_mut_doc *doc, const char *ptr)
Definition yyjson.h:7697
yyjson_api_inline yyjson_val * yyjson_arr_iter_next(yyjson_arr_iter *iter)
Definition yyjson.h:5672
yyjson_api_inline bool yyjson_is_num(const yyjson_val *val)
Definition yyjson.h:5386
yyjson_api_inline bool yyjson_obj_iter_has_next(yyjson_obj_iter *iter)
Definition yyjson.h:5737
yyjson_api_inline yyjson_mut_val * yyjson_mut_ptr_getx(const yyjson_mut_val *val, const char *ptr, size_t len, yyjson_ptr_ctx *ctx, yyjson_ptr_err *err)
Definition yyjson.h:7744
static const yyjson_write_code YYJSON_WRITE_ERROR_INVALID_STRING
Definition yyjson.h:1331
yyjson_api_inline bool yyjson_mut_arr_remove_range(yyjson_mut_val *arr, size_t idx, size_t len)
Definition yyjson.h:6752
yyjson_api_inline bool yyjson_is_null(const yyjson_val *val)
Definition yyjson.h:5354
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_with_sint8(yyjson_mut_doc *doc, const int8_t *vals, size_t count)
Definition yyjson.h:6466
yyjson_api_inline uint8_t yyjson_get_tag(const yyjson_val *val)
Definition yyjson.h:5420
yyjson_api_inline bool yyjson_mut_is_num(const yyjson_mut_val *val)
Definition yyjson.h:5966
yyjson_api_inline bool yyjson_set_int(yyjson_val *val, int64_t num)
Definition yyjson.h:5536
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_get(const yyjson_mut_val *arr, size_t idx)
Definition yyjson.h:6318
yyjson_api_inline size_t yyjson_get_len(const yyjson_val *val)
Definition yyjson.h:5473
yyjson_api char * yyjson_mut_val_write_opts(const yyjson_mut_val *val, yyjson_write_flag flg, const yyjson_alc *alc, size_t *len, yyjson_write_err *err)
Definition yyjson.c:10339
static const yyjson_read_flag YYJSON_READ_ALLOW_INVALID_UNICODE
Definition yyjson.h:847
yyjson_api_inline bool yyjson_mut_obj_add_bool(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key, bool val)
Definition yyjson.h:7404
yyjson_api_inline bool yyjson_mut_obj_add_strcpy(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key, const char *val)
Definition yyjson.h:7479
yyjson_api_inline bool yyjson_mut_obj_add(yyjson_mut_val *obj, yyjson_mut_val *key, yyjson_mut_val *val)
Definition yyjson.h:7248
const char size_t len
Definition yyjson.h:8364
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj_getn(const yyjson_mut_val *obj, const char *key, size_t key_len)
Definition yyjson.h:6975
static const yyjson_write_flag YYJSON_WRITE_ESCAPE_UNICODE
Definition yyjson.h:1251
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_with_uint32(yyjson_mut_doc *doc, const uint32_t *vals, size_t count)
Definition yyjson.h:6508
yyjson_api_inline yyjson_arr_iter yyjson_arr_iter_with(const yyjson_val *arr)
Definition yyjson.h:5662
uint32_t yyjson_ptr_code
Definition yyjson.h:4274
static const yyjson_ptr_code YYJSON_PTR_ERR_MEMORY_ALLOCATION
Definition yyjson.h:4295
yyjson_api_inline bool yyjson_ptr_ctx_replace(yyjson_ptr_ctx *ctx, yyjson_mut_val *val)
Definition yyjson.h:8180
yyjson_api_inline size_t yyjson_arr_size(const yyjson_val *arr)
Definition yyjson.h:5599
yyjson_api bool yyjson_locate_pos(const char *str, size_t len, size_t pos, size_t *line, size_t *col, size_t *chr)
Definition yyjson.c:3078
yyjson_api_inline bool yyjson_set_real(yyjson_val *val, double num)
Definition yyjson.h:5554
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_with_double(yyjson_mut_doc *doc, const double *vals, size_t count)
Definition yyjson.h:6529
yyjson_api_inline bool yyjson_mut_ptr_setn(yyjson_mut_val *val, const char *ptr, size_t len, yyjson_mut_val *new_val, yyjson_mut_doc *doc)
Definition yyjson.h:7939
yyjson_api bool yyjson_mut_write_fp(FILE *fp, const yyjson_mut_doc *doc, yyjson_write_flag flg, const yyjson_alc *alc, yyjson_write_err *err)
Definition yyjson.c:10450
yyjson_api size_t yyjson_mut_write_buf(char *buf, size_t buf_len, const yyjson_mut_doc *doc, yyjson_write_flag flg, yyjson_write_err *err)
Definition yyjson.c:10379
yyjson_api_inline bool yyjson_mut_obj_iter_has_next(yyjson_mut_obj_iter *iter)
Definition yyjson.h:7016
yyjson_api_inline const char * yyjson_get_raw(const yyjson_val *val)
Definition yyjson.h:5441
yyjson_api_inline bool yyjson_mut_set_str_noesc(yyjson_mut_val *val, bool noesc)
Definition yyjson.h:6148
yyjson_api bool yyjson_mut_val_write_fp(FILE *fp, const yyjson_mut_val *val, yyjson_write_flag flg, const yyjson_alc *alc, yyjson_write_err *err)
Definition yyjson.c:10415
yyjson_api yyjson_mut_val * yyjson_patch(yyjson_mut_doc *doc, const yyjson_val *orig, const yyjson_val *patch, yyjson_patch_err *err)
Definition yyjson.c:11026
yyjson_api_inline bool yyjson_mut_obj_put(yyjson_mut_val *obj, yyjson_mut_val *key, yyjson_mut_val *val)
Definition yyjson.h:7259
yyjson_api_inline bool yyjson_mut_is_str(const yyjson_mut_val *val)
Definition yyjson.h:5970
yyjson_api_inline bool yyjson_mut_is_false(const yyjson_mut_val *val)
Definition yyjson.h:5942
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_add_obj(yyjson_mut_doc *doc, yyjson_mut_val *arr)
Definition yyjson.h:6951
yyjson_api_inline yyjson_mut_val * yyjson_mut_sint(yyjson_mut_doc *doc, int64_t num)
Definition yyjson.h:6246
yyjson_api yyjson_doc * yyjson_read_opts(char *dat, size_t len, yyjson_read_flag flg, const yyjson_alc *alc, yyjson_read_err *err)
Definition yyjson.c:6251
yyjson_api_inline yyjson_obj_iter yyjson_obj_iter_with(const yyjson_val *obj)
Definition yyjson.h:5731
yyjson_api_inline bool yyjson_set_double(yyjson_val *val, double num)
Definition yyjson.h:5548
#define yyjson_constant_p(value)
Definition yyjson.h:313
yyjson_api_inline size_t yyjson_doc_get_val_count(const yyjson_doc *doc)
Definition yyjson.h:5331
yyjson_api_inline bool yyjson_set_sint(yyjson_val *val, int64_t num)
Definition yyjson.h:5530
yyjson_api_inline bool yyjson_mut_arr_add_int(yyjson_mut_doc *doc, yyjson_mut_val *arr, int64_t num)
Definition yyjson.h:6862
yyjson_api_inline char * yyjson_write(const yyjson_doc *doc, yyjson_write_flag flg, size_t *len)
Definition yyjson.h:1471
yyjson_api_inline bool yyjson_mut_doc_ptr_addx(yyjson_mut_doc *doc, const char *ptr, size_t len, yyjson_mut_val *new_val, bool create_parent, yyjson_ptr_ctx *ctx, yyjson_ptr_err *err)
Definition yyjson.h:7780
yyjson_api bool yyjson_mut_write_file(const char *path, const yyjson_mut_doc *doc, yyjson_write_flag flg, const yyjson_alc *alc, yyjson_write_err *err)
Definition yyjson.c:10441
static const yyjson_read_flag YYJSON_READ_STOP_WHEN_DONE
Definition yyjson.h:822
yyjson_api_inline bool yyjson_mut_obj_iter_init(yyjson_mut_val *obj, yyjson_mut_obj_iter *iter)
Definition yyjson.h:6995
yyjson_api_inline bool yyjson_mut_set_sint(yyjson_mut_val *val, int64_t num)
Definition yyjson.h:6090
yyjson_api yyjson_mut_val * yyjson_merge_patch(yyjson_mut_doc *doc, const yyjson_val *orig, const yyjson_val *patch)
Definition yyjson.c:11284
yyjson_api_inline yyjson_val * yyjson_obj_getn(const yyjson_val *obj, const char *key, size_t key_len)
Definition yyjson.h:5698
yyjson_api_inline double yyjson_mut_get_real(const yyjson_mut_val *val)
Definition yyjson.h:6030
uint32_t yyjson_patch_code
Definition yyjson.h:4856
static const yyjson_read_code YYJSON_READ_ERROR_JSON_STRUCTURE
Definition yyjson.h:931
yyjson_api_inline yyjson_mut_val * yyjson_mut_ptr_replace(yyjson_mut_val *val, const char *ptr, yyjson_mut_val *new_val)
Definition yyjson.h:8019
static const yyjson_patch_code YYJSON_PATCH_ERROR_MEMORY_ALLOCATION
Definition yyjson.h:4865
yyjson_api_inline bool yyjson_mut_arr_iter_init(yyjson_mut_val *arr, yyjson_mut_arr_iter *iter)
Definition yyjson.h:6350
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_with_strncpy(yyjson_mut_doc *doc, const char **vals, const size_t *lens, size_t count)
Definition yyjson.h:6567
static const yyjson_read_code YYJSON_READ_ERROR_EMPTY_CONTENT
Definition yyjson.h:919
yyjson_api_inline bool yyjson_set_bool(yyjson_val *val, bool num)
Definition yyjson.h:5518
yyjson_api_inline yyjson_type yyjson_mut_get_type(const yyjson_mut_val *val)
Definition yyjson.h:5992
yyjson_api_inline void yyjson_doc_free(yyjson_doc *doc)
Definition yyjson.h:5335
static const yyjson_patch_code YYJSON_PATCH_ERROR_EQUAL
Definition yyjson.h:4877
static const yyjson_read_flag YYJSON_READ_ALLOW_SINGLE_QUOTED_STR
Definition yyjson.h:882
yyjson_api_inline bool yyjson_is_raw(const yyjson_val *val)
Definition yyjson.h:5350
yyjson_api yyjson_doc * yyjson_incr_read(yyjson_incr_state *state, size_t len, yyjson_read_err *err)
Definition yyjson.c:6627
yyjson_api_inline yyjson_val * yyjson_doc_ptr_getx(const yyjson_doc *doc, const char *ptr, size_t len, yyjson_ptr_err *err)
Definition yyjson.h:7646
yyjson_api bool yyjson_mut_val_write_file(const char *path, const yyjson_mut_val *val, yyjson_write_flag flg, const yyjson_alc *alc, yyjson_write_err *err)
Definition yyjson.c:10389
yyjson_api_inline bool yyjson_mut_arr_insert(yyjson_mut_val *arr, yyjson_mut_val *val, size_t idx)
Definition yyjson.h:6590
static const yyjson_write_flag YYJSON_WRITE_NOFLAG
Definition yyjson.h:1245
uint32_t yyjson_write_code
Definition yyjson.h:1307
yyjson_api_inline bool yyjson_mut_doc_ptr_add(yyjson_mut_doc *doc, const char *ptr, yyjson_mut_val *new_val)
Definition yyjson.h:7766
static const yyjson_write_flag YYJSON_WRITE_ALLOW_INVALID_UNICODE
Definition yyjson.h:1268
yyjson_api yyjson_mut_doc * yyjson_mut_doc_new(const yyjson_alc *alc)
Definition yyjson.c:2663
yyjson_api_inline const char * yyjson_get_str(const yyjson_val *val)
Definition yyjson.h:5469
yyjson_api_inline bool yyjson_mut_is_raw(const yyjson_mut_val *val)
Definition yyjson.h:5930
yyjson_api_inline const char * yyjson_mut_get_raw(const yyjson_mut_val *val)
Definition yyjson.h:6010
yyjson_api_inline uint8_t yyjson_mut_get_tag(const yyjson_mut_val *val)
Definition yyjson.h:6001
yyjson_api_inline size_t yyjson_read_max_memory_usage(size_t len, yyjson_read_flag flg)
Definition yyjson.h:1173
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj_remove_strn(yyjson_mut_val *obj, const char *key, size_t len)
Definition yyjson.h:7536
yyjson_api_inline bool yyjson_mut_is_sint(const yyjson_mut_val *val)
Definition yyjson.h:5954
static const yyjson_read_code YYJSON_READ_ERROR_UNEXPECTED_END
Definition yyjson.h:925
yyjson_api_inline double yyjson_get_real(const yyjson_val *val)
Definition yyjson.h:5461
yyjson_api_inline yyjson_mut_val * yyjson_mut_str(yyjson_mut_doc *doc, const char *str)
Definition yyjson.h:6271
yyjson_api_inline bool yyjson_mut_is_arr(const yyjson_mut_val *val)
Definition yyjson.h:5974
yyjson_api_inline bool yyjson_mut_obj_rename_key(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key, const char *new_key)
Definition yyjson.h:7554
yyjson_api_inline yyjson_doc * yyjson_read(const char *dat, size_t len, yyjson_read_flag flg)
Definition yyjson.h:1066
yyjson_api_inline bool yyjson_mut_obj_add_float(yyjson_mut_doc *doc, yyjson_mut_val *obj, const char *key, float val)
Definition yyjson.h:7432
static const yyjson_write_flag YYJSON_WRITE_PRETTY
Definition yyjson.h:1248
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr(yyjson_mut_doc *doc)
Definition yyjson.h:6410
static const yyjson_read_code YYJSON_READ_ERROR_UNEXPECTED_CHARACTER
Definition yyjson.h:928
yyjson_api bool yyjson_mut_doc_set_str_pool_size(yyjson_mut_doc *doc, size_t len)
Definition yyjson.c:2639
yyjson_api_inline bool yyjson_mut_get_bool(const yyjson_mut_val *val)
Definition yyjson.h:6014
yyjson_api_inline const char * yyjson_mut_read_number(const char *dat, yyjson_mut_val *val, yyjson_read_flag flg, const yyjson_alc *alc, yyjson_read_err *err)
Definition yyjson.h:1221
yyjson_api_inline yyjson_mut_val * yyjson_mut_doc_ptr_replacex(yyjson_mut_doc *doc, const char *ptr, size_t len, yyjson_mut_val *new_val, yyjson_ptr_ctx *ctx, yyjson_ptr_err *err)
Definition yyjson.h:7986
yyjson_api_inline yyjson_mut_obj_iter yyjson_mut_obj_iter_with(yyjson_mut_val *obj)
Definition yyjson.h:7009
yyjson_api_inline bool yyjson_mut_obj_clear(yyjson_mut_val *obj)
Definition yyjson.h:7333
yyjson_api_inline yyjson_val * yyjson_arr_get_last(const yyjson_val *arr)
Definition yyjson.h:5628
yyjson_api_inline yyjson_subtype yyjson_get_subtype(const yyjson_val *val)
Definition yyjson.h:5416
yyjson_api_inline bool yyjson_mut_arr_append(yyjson_mut_val *arr, yyjson_mut_val *val)
Definition yyjson.h:6621
yyjson_api_inline bool yyjson_arr_iter_init(const yyjson_val *arr, yyjson_arr_iter *iter)
Definition yyjson.h:5650
yyjson_api_inline yyjson_val * yyjson_ptr_getn(const yyjson_val *val, const char *ptr, size_t len)
Definition yyjson.h:7674
static const yyjson_read_flag YYJSON_READ_ALLOW_BOM
Definition yyjson.h:856
yyjson_api_inline bool yyjson_mut_is_null(const yyjson_mut_val *val)
Definition yyjson.h:5934
yyjson_api_inline yyjson_mut_val * yyjson_mut_ptr_replacen(yyjson_mut_val *val, const char *ptr, size_t len, yyjson_mut_val *new_val)
Definition yyjson.h:8025
yyjson_api_inline double yyjson_get_num(const yyjson_val *val)
Definition yyjson.h:5465
yyjson_api_inline bool yyjson_mut_is_true(const yyjson_mut_val *val)
Definition yyjson.h:5938
yyjson_api_inline bool unsafe_yyjson_is_str_noesc(const char *str, size_t len)
Definition yyjson.h:5007
static const yyjson_write_flag YYJSON_WRITE_LOWERCASE_HEX
Definition yyjson.h:1280
yyjson_api_inline bool yyjson_mut_set_arr(yyjson_mut_val *val)
Definition yyjson.h:6155
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_remove_first(yyjson_mut_val *arr)
Definition yyjson.h:6711
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_with_str(yyjson_mut_doc *doc, const char **vals, size_t count)
Definition yyjson.h:6536
static const yyjson_ptr_code YYJSON_PTR_ERR_SET_ROOT
Definition yyjson.h:4292
yyjson_api_inline bool yyjson_mut_arr_add_null(yyjson_mut_doc *doc, yyjson_mut_val *arr)
Definition yyjson.h:6805
uint32_t yyjson_write_flag
Definition yyjson.h:1238
yyjson_api_inline yyjson_mut_val * yyjson_mut_obj_with_kv(yyjson_mut_doc *doc, const char **kv_pairs, size_t pair_count)
Definition yyjson.h:7132
yyjson_api_inline bool yyjson_get_bool(const yyjson_val *val)
Definition yyjson.h:5445
yyjson_api_inline yyjson_mut_val * yyjson_mut_arr_with_bool(yyjson_mut_doc *doc, const bool *vals, size_t count)
Definition yyjson.h:6442
yyjson_api_inline bool yyjson_is_bool(const yyjson_val *val)
Definition yyjson.h:5366
static const yyjson_read_flag YYJSON_READ_ALLOW_COMMENTS
Definition yyjson.h:829
static const yyjson_ptr_code YYJSON_PTR_ERR_RESOLVE
Definition yyjson.h:4286