#ifndef YYJSON_H
#define YYJSON_H
#include <float.h>
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef YYJSON_DISABLE_READER
#endif
#ifndef YYJSON_DISABLE_WRITER
#endif
#ifndef YYJSON_DISABLE_UTILS
#endif
#ifndef YYJSON_DISABLE_FAST_FP_CONV
#endif
#ifndef YYJSON_DISABLE_NON_STANDARD
#endif
#ifndef YYJSON_DISABLE_UTF8_VALIDATION
#endif
#ifndef YYJSON_DISABLE_UNALIGNED_MEMORY_ACCESS
#endif
#ifndef YYJSON_EXPORTS
#endif
#ifndef YYJSON_IMPORTS
#endif
#ifndef YYJSON_HAS_STDINT_H
#endif
#ifndef YYJSON_HAS_STDBOOL_H
#endif
#ifdef _MSC_VER
#define YYJSON_MSC_VER _MSC_VER
#else
#define YYJSON_MSC_VER 0
#endif
#ifdef __GNUC__
#define YYJSON_GCC_VER __GNUC__
#if defined(__GNUC_PATCHLEVEL__)
#define yyjson_gcc_available(major, minor, patch) \
((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= \
(major * 10000 + minor * 100 + patch))
#else
#define yyjson_gcc_available(major, minor, patch) \
((__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= (major * 10000 + minor * 100 + patch))
#endif
#else
#define YYJSON_GCC_VER 0
#define yyjson_gcc_available(major, minor, patch) 0
#endif
#if !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__ICC) && defined(__GNUC__)
#define YYJSON_IS_REAL_GCC 1
#else
#define YYJSON_IS_REAL_GCC 0
#endif
#if defined(__STDC__) && (__STDC__ >= 1) && defined(__STDC_VERSION__)
#define YYJSON_STDC_VER __STDC_VERSION__
#else
#define YYJSON_STDC_VER 0
#endif
#if defined(__cplusplus)
#define YYJSON_CPP_VER __cplusplus
#else
#define YYJSON_CPP_VER 0
#endif
#ifndef yyjson_has_builtin
#ifdef __has_builtin
#define yyjson_has_builtin(x) __has_builtin(x)
#else
#define yyjson_has_builtin(x) 0
#endif
#endif
#ifndef yyjson_has_attribute
#ifdef __has_attribute
#define yyjson_has_attribute(x) __has_attribute(x)
#else
#define yyjson_has_attribute(x) 0
#endif
#endif
#ifndef yyjson_has_feature
#ifdef __has_feature
#define yyjson_has_feature(x) __has_feature(x)
#else
#define yyjson_has_feature(x) 0
#endif
#endif
#ifndef yyjson_has_include
#ifdef __has_include
#define yyjson_has_include(x) __has_include(x)
#else
#define yyjson_has_include(x) 0
#endif
#endif
#ifndef yyjson_inline
#if YYJSON_MSC_VER >= 1200
#define yyjson_inline __forceinline
#elif defined(_MSC_VER)
#define yyjson_inline __inline
#elif yyjson_has_attribute(always_inline) || YYJSON_GCC_VER >= 4
#define yyjson_inline __inline__ __attribute__((always_inline))
#elif defined(__clang__) || defined(__GNUC__)
#define yyjson_inline __inline__
#elif defined(__cplusplus) || YYJSON_STDC_VER >= 199901L
#define yyjson_inline inline
#else
#define yyjson_inline
#endif
#endif
#ifndef yyjson_noinline
#if YYJSON_MSC_VER >= 1400
#define yyjson_noinline __declspec(noinline)
#elif yyjson_has_attribute(noinline) || YYJSON_GCC_VER >= 4
#define yyjson_noinline __attribute__((noinline))
#else
#define yyjson_noinline
#endif
#endif
#ifndef yyjson_align
#if YYJSON_MSC_VER >= 1300
#define yyjson_align(x) __declspec(align(x))
#elif yyjson_has_attribute(aligned) || defined(__GNUC__)
#define yyjson_align(x) __attribute__((aligned(x)))
#elif YYJSON_CPP_VER >= 201103L
#define yyjson_align(x) alignas(x)
#else
#define yyjson_align(x)
#endif
#endif
#ifndef yyjson_likely
#if yyjson_has_builtin(__builtin_expect) || (YYJSON_GCC_VER >= 4 && YYJSON_GCC_VER != 5)
#define yyjson_likely(expr) __builtin_expect(!!(expr), 1)
#else
#define yyjson_likely(expr) (expr)
#endif
#endif
#ifndef yyjson_unlikely
#if yyjson_has_builtin(__builtin_expect) || (YYJSON_GCC_VER >= 4 && YYJSON_GCC_VER != 5)
#define yyjson_unlikely(expr) __builtin_expect(!!(expr), 0)
#else
#define yyjson_unlikely(expr) (expr)
#endif
#endif
#ifndef yyjson_constant_p
#if yyjson_has_builtin(__builtin_constant_p) || (YYJSON_GCC_VER >= 3)
#define YYJSON_HAS_CONSTANT_P 1
#define yyjson_constant_p(value) __builtin_constant_p(value)
#else
#define YYJSON_HAS_CONSTANT_P 0
#define yyjson_constant_p(value) 0
#endif
#endif
#ifndef yyjson_deprecated
#if YYJSON_MSC_VER >= 1400
#define yyjson_deprecated(msg) __declspec(deprecated(msg))
#elif yyjson_has_feature(attribute_deprecated_with_message) || \
(YYJSON_GCC_VER > 4 || (YYJSON_GCC_VER == 4 && __GNUC_MINOR__ >= 5))
#define yyjson_deprecated(msg) __attribute__((deprecated(msg)))
#elif YYJSON_GCC_VER >= 3
#define yyjson_deprecated(msg) __attribute__((deprecated))
#else
#define yyjson_deprecated(msg)
#endif
#endif
#ifndef yyjson_api
#if defined(_WIN32)
#if defined(YYJSON_EXPORTS) && YYJSON_EXPORTS
#define yyjson_api __declspec(dllexport)
#elif defined(YYJSON_IMPORTS) && YYJSON_IMPORTS
#define yyjson_api __declspec(dllimport)
#else
#define yyjson_api
#endif
#elif yyjson_has_attribute(visibility) || YYJSON_GCC_VER >= 4
#define yyjson_api __attribute__((visibility("default")))
#else
#define yyjson_api
#endif
#endif
#ifndef yyjson_api_inline
#define yyjson_api_inline static yyjson_inline
#endif
#if (defined(YYJSON_HAS_STDINT_H) && YYJSON_HAS_STDINT_H) || YYJSON_MSC_VER >= 1600 || \
YYJSON_STDC_VER >= 199901L || defined(_STDINT_H) || defined(_STDINT_H_) || \
defined(__CLANG_STDINT_H) || defined(_STDINT_H_INCLUDED) || yyjson_has_include(<stdint.h>)
#include <stdint.h>
#elif defined(_MSC_VER)
#if _MSC_VER < 1300
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#endif
#else
#if UCHAR_MAX == 0xFFU
typedef signed char int8_t;
typedef unsigned char uint8_t;
#else
#error cannot find 8-bit integer type
#endif
#if USHRT_MAX == 0xFFFFU
typedef unsigned short uint16_t;
typedef signed short int16_t;
#elif UINT_MAX == 0xFFFFU
typedef unsigned int uint16_t;
typedef signed int int16_t;
#else
#error cannot find 16-bit integer type
#endif
#if UINT_MAX == 0xFFFFFFFFUL
typedef unsigned int uint32_t;
typedef signed int int32_t;
#elif ULONG_MAX == 0xFFFFFFFFUL
typedef unsigned long uint32_t;
typedef signed long int32_t;
#elif USHRT_MAX == 0xFFFFFFFFUL
typedef unsigned short uint32_t;
typedef signed short int32_t;
#else
#error cannot find 32-bit integer type
#endif
#if defined(__INT64_TYPE__) && defined(__UINT64_TYPE__)
typedef __INT64_TYPE__ int64_t;
typedef __UINT64_TYPE__ uint64_t;
#elif defined(__GNUC__) || defined(__clang__)
#if !defined(_SYS_TYPES_H) && !defined(__int8_t_defined)
__extension__ typedef long long int64_t;
#endif
__extension__ typedef unsigned long long uint64_t;
#elif defined(_LONG_LONG) || defined(__MWERKS__) || defined(_CRAYC) || defined(__SUNPRO_C) || \
defined(__SUNPRO_CC)
typedef long long int64_t;
typedef unsigned long long uint64_t;
#elif (defined(__BORLANDC__) && __BORLANDC__ > 0x460) || defined(__WATCOM_INT64__) || \
defined(__alpha) || defined(__DECC)
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#error cannot find 64-bit integer type
#endif
#endif
#if (defined(YYJSON_HAS_STDBOOL_H) && YYJSON_HAS_STDBOOL_H) || \
(yyjson_has_include(<stdbool.h>) && !defined(__STRICT_ANSI__)) || YYJSON_MSC_VER >= 1800 || \
YYJSON_STDC_VER >= 199901L
#include <stdbool.h>
#elif !defined(__bool_true_false_are_defined)
#define __bool_true_false_are_defined 1
#if defined(__cplusplus)
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
#define _Bool bool
#if __cplusplus < 201103L
#define bool bool
#define false false
#define true true
#endif
#endif
#else
#define bool unsigned char
#define true 1
#define false 0
#endif
#endif
#if defined(CHAR_BIT)
#if CHAR_BIT != 8
#error non 8-bit char is not supported
#endif
#endif
#ifndef YYJSON_U64_TO_F64_NO_IMPL
#if (0 < YYJSON_MSC_VER) && (YYJSON_MSC_VER <= 1200)
#define YYJSON_U64_TO_F64_NO_IMPL 1
#else
#define YYJSON_U64_TO_F64_NO_IMPL 0
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function"
#pragma clang diagnostic ignored "-Wunused-parameter"
#elif defined(__GNUC__)
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#endif
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#elif defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4800)
#endif
#define YYJSON_VERSION_MAJOR 0
#define YYJSON_VERSION_MINOR 10
#define YYJSON_VERSION_PATCH 0
#define YYJSON_VERSION_HEX 0x000A00
#define YYJSON_VERSION_STRING "0.10.0"
yyjson_api uint32_t yyjson_version(void);
typedef uint8_t yyjson_type;
#define YYJSON_TYPE_NONE ((uint8_t)0)
#define YYJSON_TYPE_RAW ((uint8_t)1)
#define YYJSON_TYPE_NULL ((uint8_t)2)
#define YYJSON_TYPE_BOOL ((uint8_t)3)
#define YYJSON_TYPE_NUM ((uint8_t)4)
#define YYJSON_TYPE_STR ((uint8_t)5)
#define YYJSON_TYPE_ARR ((uint8_t)6)
#define YYJSON_TYPE_OBJ ((uint8_t)7)
typedef uint8_t yyjson_subtype;
#define YYJSON_SUBTYPE_NONE ((uint8_t)(0 << 3))
#define YYJSON_SUBTYPE_FALSE ((uint8_t)(0 << 3))
#define YYJSON_SUBTYPE_TRUE ((uint8_t)(1 << 3))
#define YYJSON_SUBTYPE_UINT ((uint8_t)(0 << 3))
#define YYJSON_SUBTYPE_SINT ((uint8_t)(1 << 3))
#define YYJSON_SUBTYPE_REAL ((uint8_t)(2 << 3))
#define YYJSON_SUBTYPE_NOESC ((uint8_t)(1 << 3))
#define YYJSON_TYPE_MASK ((uint8_t)0x07)
#define YYJSON_TYPE_BIT ((uint8_t)3)
#define YYJSON_SUBTYPE_MASK ((uint8_t)0x18)
#define YYJSON_SUBTYPE_BIT ((uint8_t)2)
#define YYJSON_RESERVED_MASK ((uint8_t)0xE0)
#define YYJSON_RESERVED_BIT ((uint8_t)3)
#define YYJSON_TAG_MASK ((uint8_t)0xFF)
#define YYJSON_TAG_BIT ((uint8_t)8)
#define YYJSON_PADDING_SIZE 4
typedef struct yyjson_alc {
void* (*malloc)(void* ctx, size_t size);
void* (*realloc)(void* ctx, void* ptr, size_t old_size, size_t size);
void (*free)(void* ctx, void* ptr);
void* ctx;
} yyjson_alc;
yyjson_api bool yyjson_alc_pool_init(yyjson_alc* alc, void* buf, size_t size);
yyjson_api yyjson_alc* yyjson_alc_dyn_new(void);
yyjson_api void yyjson_alc_dyn_free(yyjson_alc* alc);
typedef struct yyjson_doc yyjson_doc;
typedef struct yyjson_val yyjson_val;
typedef struct yyjson_mut_doc yyjson_mut_doc;
typedef struct yyjson_mut_val yyjson_mut_val;
typedef uint32_t yyjson_read_flag;
static const yyjson_read_flag YYJSON_READ_NOFLAG = 0;
static const yyjson_read_flag YYJSON_READ_INSITU = 1 << 0;
static const yyjson_read_flag YYJSON_READ_STOP_WHEN_DONE = 1 << 1;
static const yyjson_read_flag YYJSON_READ_ALLOW_TRAILING_COMMAS = 1 << 2;
static const yyjson_read_flag YYJSON_READ_ALLOW_COMMENTS = 1 << 3;
static const yyjson_read_flag YYJSON_READ_ALLOW_INF_AND_NAN = 1 << 4;
static const yyjson_read_flag YYJSON_READ_NUMBER_AS_RAW = 1 << 5;
static const yyjson_read_flag YYJSON_READ_ALLOW_INVALID_UNICODE = 1 << 6;
static const yyjson_read_flag YYJSON_READ_BIGNUM_AS_RAW = 1 << 7;
typedef uint32_t yyjson_read_code;
static const yyjson_read_code YYJSON_READ_SUCCESS = 0;
static const yyjson_read_code YYJSON_READ_ERROR_INVALID_PARAMETER = 1;
static const yyjson_read_code YYJSON_READ_ERROR_MEMORY_ALLOCATION = 2;
static const yyjson_read_code YYJSON_READ_ERROR_EMPTY_CONTENT = 3;
static const yyjson_read_code YYJSON_READ_ERROR_UNEXPECTED_CONTENT = 4;
static const yyjson_read_code YYJSON_READ_ERROR_UNEXPECTED_END = 5;
static const yyjson_read_code YYJSON_READ_ERROR_UNEXPECTED_CHARACTER = 6;
static const yyjson_read_code YYJSON_READ_ERROR_JSON_STRUCTURE = 7;
static const yyjson_read_code YYJSON_READ_ERROR_INVALID_COMMENT = 8;
static const yyjson_read_code YYJSON_READ_ERROR_INVALID_NUMBER = 9;
static const yyjson_read_code YYJSON_READ_ERROR_INVALID_STRING = 10;
static const yyjson_read_code YYJSON_READ_ERROR_LITERAL = 11;
static const yyjson_read_code YYJSON_READ_ERROR_FILE_OPEN = 12;
static const yyjson_read_code YYJSON_READ_ERROR_FILE_READ = 13;
typedef struct yyjson_read_err {
yyjson_read_code code;
const char* msg;
size_t pos;
} yyjson_read_err;
yyjson_api bool yyjson_locate_pos(const char* str, size_t len, size_t pos, size_t* line,
size_t* col, size_t* chr);
yyjson_api yyjson_doc* yyjson_read_opts(char* dat, size_t len, yyjson_read_flag flg,
const yyjson_alc* alc, yyjson_read_err* err);
yyjson_api yyjson_doc* yyjson_read_file(const char* path, yyjson_read_flag flg,
const yyjson_alc* alc, yyjson_read_err* err);
yyjson_api yyjson_doc* yyjson_read_fp(FILE* fp, yyjson_read_flag flg, const yyjson_alc* alc,
yyjson_read_err* err);
yyjson_api_inline yyjson_doc* yyjson_read(const char* dat, size_t len, yyjson_read_flag flg) {
flg &= ~YYJSON_READ_INSITU;
return yyjson_read_opts((char*)(void*)(size_t)(const void*)dat, len, flg, NULL, NULL);
}
yyjson_api_inline size_t yyjson_read_max_memory_usage(size_t len, yyjson_read_flag flg) {
size_t mul = (size_t)12 + !(flg & YYJSON_READ_INSITU);
size_t pad = 256;
size_t max = (size_t)(~(size_t)0);
if (flg & YYJSON_READ_STOP_WHEN_DONE)
len = len < 256 ? 256 : len;
if (len >= (max - pad - mul) / mul)
return 0;
return len * mul + pad;
}
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);
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) {
return yyjson_read_number(dat, (yyjson_val*)val, flg, alc, err);
}
typedef uint32_t yyjson_write_flag;
static const yyjson_write_flag YYJSON_WRITE_NOFLAG = 0;
static const yyjson_write_flag YYJSON_WRITE_PRETTY = 1 << 0;
static const yyjson_write_flag YYJSON_WRITE_ESCAPE_UNICODE = 1 << 1;
static const yyjson_write_flag YYJSON_WRITE_ESCAPE_SLASHES = 1 << 2;
static const yyjson_write_flag YYJSON_WRITE_ALLOW_INF_AND_NAN = 1 << 3;
static const yyjson_write_flag YYJSON_WRITE_INF_AND_NAN_AS_NULL = 1 << 4;
static const yyjson_write_flag YYJSON_WRITE_ALLOW_INVALID_UNICODE = 1 << 5;
static const yyjson_write_flag YYJSON_WRITE_PRETTY_TWO_SPACES = 1 << 6;
static const yyjson_write_flag YYJSON_WRITE_NEWLINE_AT_END = 1 << 7;
typedef uint32_t yyjson_write_code;
static const yyjson_write_code YYJSON_WRITE_SUCCESS = 0;
static const yyjson_write_code YYJSON_WRITE_ERROR_INVALID_PARAMETER = 1;
static const yyjson_write_code YYJSON_WRITE_ERROR_MEMORY_ALLOCATION = 2;
static const yyjson_write_code YYJSON_WRITE_ERROR_INVALID_VALUE_TYPE = 3;
static const yyjson_write_code YYJSON_WRITE_ERROR_NAN_OR_INF = 4;
static const yyjson_write_code YYJSON_WRITE_ERROR_FILE_OPEN = 5;
static const yyjson_write_code YYJSON_WRITE_ERROR_FILE_WRITE = 6;
static const yyjson_write_code YYJSON_WRITE_ERROR_INVALID_STRING = 7;
typedef struct yyjson_write_err {
yyjson_write_code code;
const char* msg;
} yyjson_write_err;
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);
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);
yyjson_api bool yyjson_write_fp(FILE* fp, const yyjson_doc* doc, yyjson_write_flag flg,
const yyjson_alc* alc, yyjson_write_err* err);
yyjson_api_inline char* yyjson_write(const yyjson_doc* doc, yyjson_write_flag flg, size_t* len) {
return yyjson_write_opts(doc, flg, NULL, len, NULL);
}
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);
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);
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);
yyjson_api_inline char* yyjson_mut_write(const yyjson_mut_doc* doc, yyjson_write_flag flg,
size_t* len) {
return yyjson_mut_write_opts(doc, flg, NULL, len, NULL);
}
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);
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);
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);
yyjson_api_inline char* yyjson_val_write(const yyjson_val* val, yyjson_write_flag flg,
size_t* len) {
return yyjson_val_write_opts(val, flg, NULL, len, NULL);
}
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);
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);
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);
yyjson_api_inline char* yyjson_mut_val_write(const yyjson_mut_val* val, yyjson_write_flag flg,
size_t* len) {
return yyjson_mut_val_write_opts(val, flg, NULL, len, NULL);
}
yyjson_api_inline yyjson_val* yyjson_doc_get_root(yyjson_doc* doc);
yyjson_api_inline size_t yyjson_doc_get_read_size(yyjson_doc* doc);
yyjson_api_inline size_t yyjson_doc_get_val_count(yyjson_doc* doc);
yyjson_api_inline void yyjson_doc_free(yyjson_doc* doc);
yyjson_api_inline bool yyjson_is_raw(yyjson_val* val);
yyjson_api_inline bool yyjson_is_null(yyjson_val* val);
yyjson_api_inline bool yyjson_is_true(yyjson_val* val);
yyjson_api_inline bool yyjson_is_false(yyjson_val* val);
yyjson_api_inline bool yyjson_is_bool(yyjson_val* val);
yyjson_api_inline bool yyjson_is_uint(yyjson_val* val);
yyjson_api_inline bool yyjson_is_sint(yyjson_val* val);
yyjson_api_inline bool yyjson_is_int(yyjson_val* val);
yyjson_api_inline bool yyjson_is_real(yyjson_val* val);
yyjson_api_inline bool yyjson_is_num(yyjson_val* val);
yyjson_api_inline bool yyjson_is_str(yyjson_val* val);
yyjson_api_inline bool yyjson_is_arr(yyjson_val* val);
yyjson_api_inline bool yyjson_is_obj(yyjson_val* val);
yyjson_api_inline bool yyjson_is_ctn(yyjson_val* val);
yyjson_api_inline yyjson_type yyjson_get_type(yyjson_val* val);
yyjson_api_inline yyjson_subtype yyjson_get_subtype(yyjson_val* val);
yyjson_api_inline uint8_t yyjson_get_tag(yyjson_val* val);
yyjson_api_inline const char* yyjson_get_type_desc(yyjson_val* val);
yyjson_api_inline const char* yyjson_get_raw(yyjson_val* val);
yyjson_api_inline bool yyjson_get_bool(yyjson_val* val);
yyjson_api_inline uint64_t yyjson_get_uint(yyjson_val* val);
yyjson_api_inline int64_t yyjson_get_sint(yyjson_val* val);
yyjson_api_inline int yyjson_get_int(yyjson_val* val);
yyjson_api_inline double yyjson_get_real(yyjson_val* val);
yyjson_api_inline double yyjson_get_num(yyjson_val* val);
yyjson_api_inline const char* yyjson_get_str(yyjson_val* val);
yyjson_api_inline size_t yyjson_get_len(yyjson_val* val);
yyjson_api_inline bool yyjson_equals_str(yyjson_val* val, const char* str);
yyjson_api_inline bool yyjson_equals_strn(yyjson_val* val, const char* str, size_t len);
yyjson_api_inline bool yyjson_equals(yyjson_val* lhs, yyjson_val* rhs);
yyjson_api_inline bool yyjson_set_raw(yyjson_val* val, const char* raw, size_t len);
yyjson_api_inline bool yyjson_set_null(yyjson_val* val);
yyjson_api_inline bool yyjson_set_bool(yyjson_val* val, bool num);
yyjson_api_inline bool yyjson_set_uint(yyjson_val* val, uint64_t num);
yyjson_api_inline bool yyjson_set_sint(yyjson_val* val, int64_t num);
yyjson_api_inline bool yyjson_set_int(yyjson_val* val, int num);
yyjson_api_inline bool yyjson_set_real(yyjson_val* val, double num);
yyjson_api_inline bool yyjson_set_str(yyjson_val* val, const char* str);
yyjson_api_inline bool yyjson_set_strn(yyjson_val* val, const char* str, size_t len);
yyjson_api_inline size_t yyjson_arr_size(yyjson_val* arr);
yyjson_api_inline yyjson_val* yyjson_arr_get(yyjson_val* arr, size_t idx);
yyjson_api_inline yyjson_val* yyjson_arr_get_first(yyjson_val* arr);
yyjson_api_inline yyjson_val* yyjson_arr_get_last(yyjson_val* arr);
typedef struct yyjson_arr_iter {
size_t idx;
size_t max;
yyjson_val* cur;
} yyjson_arr_iter;
yyjson_api_inline bool yyjson_arr_iter_init(yyjson_val* arr, yyjson_arr_iter* iter);
yyjson_api_inline yyjson_arr_iter yyjson_arr_iter_with(yyjson_val* arr);
yyjson_api_inline bool yyjson_arr_iter_has_next(yyjson_arr_iter* iter);
yyjson_api_inline yyjson_val* yyjson_arr_iter_next(yyjson_arr_iter* iter);
#define yyjson_arr_foreach(arr, idx, max, val) \
for ((idx) = 0, (max) = yyjson_arr_size(arr), (val) = yyjson_arr_get_first(arr); \
(idx) < (max); (idx)++, (val) = unsafe_yyjson_get_next(val))
yyjson_api_inline size_t yyjson_obj_size(yyjson_val* obj);
yyjson_api_inline yyjson_val* yyjson_obj_get(yyjson_val* obj, const char* key);
yyjson_api_inline yyjson_val* yyjson_obj_getn(yyjson_val* obj, const char* key, size_t key_len);
typedef struct yyjson_obj_iter {
size_t idx;
size_t max;
yyjson_val* cur;
yyjson_val* obj;
} yyjson_obj_iter;
yyjson_api_inline bool yyjson_obj_iter_init(yyjson_val* obj, yyjson_obj_iter* iter);
yyjson_api_inline yyjson_obj_iter yyjson_obj_iter_with(yyjson_val* obj);
yyjson_api_inline bool yyjson_obj_iter_has_next(yyjson_obj_iter* iter);
yyjson_api_inline yyjson_val* yyjson_obj_iter_next(yyjson_obj_iter* iter);
yyjson_api_inline yyjson_val* yyjson_obj_iter_get_val(yyjson_val* key);
yyjson_api_inline yyjson_val* yyjson_obj_iter_get(yyjson_obj_iter* iter, const char* key);
yyjson_api_inline yyjson_val* yyjson_obj_iter_getn(yyjson_obj_iter* iter, const char* key,
size_t key_len);
#define yyjson_obj_foreach(obj, idx, max, key, val) \
for ((idx) = 0, (max) = yyjson_obj_size(obj), \
(key) = (obj) ? unsafe_yyjson_get_first(obj) : NULL, (val) = (key) + 1; \
(idx) < (max); (idx)++, (key) = unsafe_yyjson_get_next(val), (val) = (key) + 1)
yyjson_api_inline yyjson_mut_val* yyjson_mut_doc_get_root(yyjson_mut_doc* doc);
yyjson_api_inline void yyjson_mut_doc_set_root(yyjson_mut_doc* doc, yyjson_mut_val* root);
yyjson_api bool yyjson_mut_doc_set_str_pool_size(yyjson_mut_doc* doc, size_t len);
yyjson_api bool yyjson_mut_doc_set_val_pool_size(yyjson_mut_doc* doc, size_t count);
yyjson_api void yyjson_mut_doc_free(yyjson_mut_doc* doc);
yyjson_api yyjson_mut_doc* yyjson_mut_doc_new(const yyjson_alc* alc);
yyjson_api yyjson_mut_doc* yyjson_doc_mut_copy(yyjson_doc* doc, const yyjson_alc* alc);
yyjson_api yyjson_mut_doc* yyjson_mut_doc_mut_copy(yyjson_mut_doc* doc, const yyjson_alc* alc);
yyjson_api yyjson_mut_val* yyjson_val_mut_copy(yyjson_mut_doc* doc, yyjson_val* val);
yyjson_api yyjson_mut_val* yyjson_mut_val_mut_copy(yyjson_mut_doc* doc, yyjson_mut_val* val);
yyjson_api yyjson_doc* yyjson_mut_doc_imut_copy(yyjson_mut_doc* doc, const yyjson_alc* alc);
yyjson_api yyjson_doc* yyjson_mut_val_imut_copy(yyjson_mut_val* val, const yyjson_alc* alc);
yyjson_api_inline bool yyjson_mut_is_raw(yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_is_null(yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_is_true(yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_is_false(yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_is_bool(yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_is_uint(yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_is_sint(yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_is_int(yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_is_real(yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_is_num(yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_is_str(yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_is_arr(yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_is_obj(yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_is_ctn(yyjson_mut_val* val);
yyjson_api_inline yyjson_type yyjson_mut_get_type(yyjson_mut_val* val);
yyjson_api_inline yyjson_subtype yyjson_mut_get_subtype(yyjson_mut_val* val);
yyjson_api_inline uint8_t yyjson_mut_get_tag(yyjson_mut_val* val);
yyjson_api_inline const char* yyjson_mut_get_type_desc(yyjson_mut_val* val);
yyjson_api_inline const char* yyjson_mut_get_raw(yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_get_bool(yyjson_mut_val* val);
yyjson_api_inline uint64_t yyjson_mut_get_uint(yyjson_mut_val* val);
yyjson_api_inline int64_t yyjson_mut_get_sint(yyjson_mut_val* val);
yyjson_api_inline int yyjson_mut_get_int(yyjson_mut_val* val);
yyjson_api_inline double yyjson_mut_get_real(yyjson_mut_val* val);
yyjson_api_inline double yyjson_mut_get_num(yyjson_mut_val* val);
yyjson_api_inline const char* yyjson_mut_get_str(yyjson_mut_val* val);
yyjson_api_inline size_t yyjson_mut_get_len(yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_equals_str(yyjson_mut_val* val, const char* str);
yyjson_api_inline bool yyjson_mut_equals_strn(yyjson_mut_val* val, const char* str, size_t len);
yyjson_api_inline bool yyjson_mut_equals(yyjson_mut_val* lhs, yyjson_mut_val* rhs);
yyjson_api_inline bool yyjson_mut_set_raw(yyjson_mut_val* val, const char* raw, size_t len);
yyjson_api_inline bool yyjson_mut_set_null(yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_set_bool(yyjson_mut_val* val, bool num);
yyjson_api_inline bool yyjson_mut_set_uint(yyjson_mut_val* val, uint64_t num);
yyjson_api_inline bool yyjson_mut_set_sint(yyjson_mut_val* val, int64_t num);
yyjson_api_inline bool yyjson_mut_set_int(yyjson_mut_val* val, int num);
yyjson_api_inline bool yyjson_mut_set_real(yyjson_mut_val* val, double num);
yyjson_api_inline bool yyjson_mut_set_str(yyjson_mut_val* val, const char* str);
yyjson_api_inline bool yyjson_mut_set_strn(yyjson_mut_val* val, const char* str, size_t len);
yyjson_api_inline bool yyjson_mut_set_arr(yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_set_obj(yyjson_mut_val* val);
yyjson_api_inline yyjson_mut_val* yyjson_mut_raw(yyjson_mut_doc* doc, const char* str);
yyjson_api_inline yyjson_mut_val* yyjson_mut_rawn(yyjson_mut_doc* doc, const char* str, size_t len);
yyjson_api_inline yyjson_mut_val* yyjson_mut_rawcpy(yyjson_mut_doc* doc, const char* str);
yyjson_api_inline yyjson_mut_val* yyjson_mut_rawncpy(yyjson_mut_doc* doc, const char* str,
size_t len);
yyjson_api_inline yyjson_mut_val* yyjson_mut_null(yyjson_mut_doc* doc);
yyjson_api_inline yyjson_mut_val* yyjson_mut_true(yyjson_mut_doc* doc);
yyjson_api_inline yyjson_mut_val* yyjson_mut_false(yyjson_mut_doc* doc);
yyjson_api_inline yyjson_mut_val* yyjson_mut_bool(yyjson_mut_doc* doc, bool val);
yyjson_api_inline yyjson_mut_val* yyjson_mut_uint(yyjson_mut_doc* doc, uint64_t num);
yyjson_api_inline yyjson_mut_val* yyjson_mut_sint(yyjson_mut_doc* doc, int64_t num);
yyjson_api_inline yyjson_mut_val* yyjson_mut_int(yyjson_mut_doc* doc, int64_t num);
yyjson_api_inline yyjson_mut_val* yyjson_mut_real(yyjson_mut_doc* doc, double num);
yyjson_api_inline yyjson_mut_val* yyjson_mut_str(yyjson_mut_doc* doc, const char* str);
yyjson_api_inline yyjson_mut_val* yyjson_mut_strn(yyjson_mut_doc* doc, const char* str, size_t len);
yyjson_api_inline yyjson_mut_val* yyjson_mut_strcpy(yyjson_mut_doc* doc, const char* str);
yyjson_api_inline yyjson_mut_val* yyjson_mut_strncpy(yyjson_mut_doc* doc, const char* str,
size_t len);
yyjson_api_inline size_t yyjson_mut_arr_size(yyjson_mut_val* arr);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_get(yyjson_mut_val* arr, size_t idx);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_get_first(yyjson_mut_val* arr);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_get_last(yyjson_mut_val* arr);
typedef struct yyjson_mut_arr_iter {
size_t idx;
size_t max;
yyjson_mut_val* cur;
yyjson_mut_val* pre;
yyjson_mut_val* arr;
} yyjson_mut_arr_iter;
yyjson_api_inline bool yyjson_mut_arr_iter_init(yyjson_mut_val* arr, yyjson_mut_arr_iter* iter);
yyjson_api_inline yyjson_mut_arr_iter yyjson_mut_arr_iter_with(yyjson_mut_val* arr);
yyjson_api_inline bool yyjson_mut_arr_iter_has_next(yyjson_mut_arr_iter* iter);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_iter_next(yyjson_mut_arr_iter* iter);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_iter_remove(yyjson_mut_arr_iter* iter);
#define yyjson_mut_arr_foreach(arr, idx, max, val) \
for ((idx) = 0, (max) = yyjson_mut_arr_size(arr), (val) = yyjson_mut_arr_get_first(arr); \
(idx) < (max); (idx)++, (val) = (val)->next)
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr(yyjson_mut_doc* doc);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_bool(yyjson_mut_doc* doc, const bool* vals,
size_t count);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_sint(yyjson_mut_doc* doc, const int64_t* vals,
size_t count);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_uint(yyjson_mut_doc* doc,
const uint64_t* vals, size_t count);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_real(yyjson_mut_doc* doc, const double* vals,
size_t count);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_sint8(yyjson_mut_doc* doc, const int8_t* vals,
size_t count);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_sint16(yyjson_mut_doc* doc,
const int16_t* vals, size_t count);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_sint32(yyjson_mut_doc* doc,
const int32_t* vals, size_t count);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_sint64(yyjson_mut_doc* doc,
const int64_t* vals, size_t count);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_uint8(yyjson_mut_doc* doc,
const uint8_t* vals, size_t count);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_uint16(yyjson_mut_doc* doc,
const uint16_t* vals, size_t count);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_uint32(yyjson_mut_doc* doc,
const uint32_t* vals, size_t count);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_uint64(yyjson_mut_doc* doc,
const uint64_t* vals, size_t count);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_float(yyjson_mut_doc* doc, const float* vals,
size_t count);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_double(yyjson_mut_doc* doc,
const double* vals, size_t count);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_str(yyjson_mut_doc* doc, const char** vals,
size_t count);
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);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_strcpy(yyjson_mut_doc* doc, const char** vals,
size_t count);
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);
yyjson_api_inline bool yyjson_mut_arr_insert(yyjson_mut_val* arr, yyjson_mut_val* val, size_t idx);
yyjson_api_inline bool yyjson_mut_arr_append(yyjson_mut_val* arr, yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_arr_prepend(yyjson_mut_val* arr, yyjson_mut_val* val);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_replace(yyjson_mut_val* arr, size_t idx,
yyjson_mut_val* val);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_remove(yyjson_mut_val* arr, size_t idx);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_remove_first(yyjson_mut_val* arr);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_remove_last(yyjson_mut_val* arr);
yyjson_api_inline bool yyjson_mut_arr_remove_range(yyjson_mut_val* arr, size_t idx, size_t len);
yyjson_api_inline bool yyjson_mut_arr_clear(yyjson_mut_val* arr);
yyjson_api_inline bool yyjson_mut_arr_rotate(yyjson_mut_val* arr, size_t idx);
yyjson_api_inline bool yyjson_mut_arr_add_val(yyjson_mut_val* arr, yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_arr_add_null(yyjson_mut_doc* doc, yyjson_mut_val* arr);
yyjson_api_inline bool yyjson_mut_arr_add_true(yyjson_mut_doc* doc, yyjson_mut_val* arr);
yyjson_api_inline bool yyjson_mut_arr_add_false(yyjson_mut_doc* doc, yyjson_mut_val* arr);
yyjson_api_inline bool yyjson_mut_arr_add_bool(yyjson_mut_doc* doc, yyjson_mut_val* arr, bool val);
yyjson_api_inline bool yyjson_mut_arr_add_uint(yyjson_mut_doc* doc, yyjson_mut_val* arr,
uint64_t num);
yyjson_api_inline bool yyjson_mut_arr_add_sint(yyjson_mut_doc* doc, yyjson_mut_val* arr,
int64_t num);
yyjson_api_inline bool yyjson_mut_arr_add_int(yyjson_mut_doc* doc, yyjson_mut_val* arr,
int64_t num);
yyjson_api_inline bool yyjson_mut_arr_add_real(yyjson_mut_doc* doc, yyjson_mut_val* arr,
double num);
yyjson_api_inline bool yyjson_mut_arr_add_str(yyjson_mut_doc* doc, yyjson_mut_val* arr,
const char* str);
yyjson_api_inline bool yyjson_mut_arr_add_strn(yyjson_mut_doc* doc, yyjson_mut_val* arr,
const char* str, size_t len);
yyjson_api_inline bool yyjson_mut_arr_add_strcpy(yyjson_mut_doc* doc, yyjson_mut_val* arr,
const char* str);
yyjson_api_inline bool yyjson_mut_arr_add_strncpy(yyjson_mut_doc* doc, yyjson_mut_val* arr,
const char* str, size_t len);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_add_arr(yyjson_mut_doc* doc, yyjson_mut_val* arr);
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_add_obj(yyjson_mut_doc* doc, yyjson_mut_val* arr);
yyjson_api_inline size_t yyjson_mut_obj_size(yyjson_mut_val* obj);
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_get(yyjson_mut_val* obj, const char* key);
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_getn(yyjson_mut_val* obj, const char* key,
size_t key_len);
typedef struct yyjson_mut_obj_iter {
size_t idx;
size_t max;
yyjson_mut_val* cur;
yyjson_mut_val* pre;
yyjson_mut_val* obj;
} yyjson_mut_obj_iter;
yyjson_api_inline bool yyjson_mut_obj_iter_init(yyjson_mut_val* obj, yyjson_mut_obj_iter* iter);
yyjson_api_inline yyjson_mut_obj_iter yyjson_mut_obj_iter_with(yyjson_mut_val* obj);
yyjson_api_inline bool yyjson_mut_obj_iter_has_next(yyjson_mut_obj_iter* iter);
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_iter_next(yyjson_mut_obj_iter* iter);
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_iter_get_val(yyjson_mut_val* key);
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_iter_remove(yyjson_mut_obj_iter* iter);
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_iter_get(yyjson_mut_obj_iter* iter,
const char* key);
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_iter_getn(yyjson_mut_obj_iter* iter,
const char* key, size_t key_len);
#define yyjson_mut_obj_foreach(obj, idx, max, key, val) \
for ((idx) = 0, (max) = yyjson_mut_obj_size(obj), \
(key) = (max) ? ((yyjson_mut_val*)(obj)->uni.ptr)->next->next : NULL, \
(val) = (key) ? (key)->next : NULL; \
(idx) < (max); (idx)++, (key) = (val)->next, (val) = (key)->next)
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj(yyjson_mut_doc* doc);
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_with_str(yyjson_mut_doc* doc, const char** keys,
const char** vals, size_t count);
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_with_kv(yyjson_mut_doc* doc, const char** kv_pairs,
size_t pair_count);
yyjson_api_inline bool yyjson_mut_obj_add(yyjson_mut_val* obj, yyjson_mut_val* key,
yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_obj_put(yyjson_mut_val* obj, yyjson_mut_val* key,
yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_obj_insert(yyjson_mut_val* obj, yyjson_mut_val* key,
yyjson_mut_val* val, size_t idx);
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_remove(yyjson_mut_val* obj, yyjson_mut_val* key);
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_remove_key(yyjson_mut_val* obj, const char* key);
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_remove_keyn(yyjson_mut_val* obj, const char* key,
size_t key_len);
yyjson_api_inline bool yyjson_mut_obj_clear(yyjson_mut_val* obj);
yyjson_api_inline bool yyjson_mut_obj_replace(yyjson_mut_val* obj, yyjson_mut_val* key,
yyjson_mut_val* val);
yyjson_api_inline bool yyjson_mut_obj_rotate(yyjson_mut_val* obj, size_t idx);
yyjson_api_inline bool yyjson_mut_obj_add_null(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* key);
yyjson_api_inline bool yyjson_mut_obj_add_true(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* key);
yyjson_api_inline bool yyjson_mut_obj_add_false(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* key);
yyjson_api_inline bool yyjson_mut_obj_add_bool(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* key, bool val);
yyjson_api_inline bool yyjson_mut_obj_add_uint(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* key, uint64_t val);
yyjson_api_inline bool yyjson_mut_obj_add_sint(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* key, int64_t val);
yyjson_api_inline bool yyjson_mut_obj_add_int(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* key, int64_t val);
yyjson_api_inline bool yyjson_mut_obj_add_real(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* key, double val);
yyjson_api_inline bool yyjson_mut_obj_add_str(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* key, const char* val);
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);
yyjson_api_inline bool yyjson_mut_obj_add_strcpy(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* key, const char* val);
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);
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_add_arr(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* key);
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_add_obj(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* key);
yyjson_api_inline bool yyjson_mut_obj_add_val(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* key, yyjson_mut_val* val);
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_remove_str(yyjson_mut_val* obj, const char* key);
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_remove_strn(yyjson_mut_val* obj, const char* key,
size_t len);
yyjson_api_inline bool yyjson_mut_obj_rename_key(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* key, const char* new_key);
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);
typedef uint32_t yyjson_ptr_code;
static const yyjson_ptr_code YYJSON_PTR_ERR_NONE = 0;
static const yyjson_ptr_code YYJSON_PTR_ERR_PARAMETER = 1;
static const yyjson_ptr_code YYJSON_PTR_ERR_SYNTAX = 2;
static const yyjson_ptr_code YYJSON_PTR_ERR_RESOLVE = 3;
static const yyjson_ptr_code YYJSON_PTR_ERR_NULL_ROOT = 4;
static const yyjson_ptr_code YYJSON_PTR_ERR_SET_ROOT = 5;
static const yyjson_ptr_code YYJSON_PTR_ERR_MEMORY_ALLOCATION = 6;
typedef struct yyjson_ptr_err {
yyjson_ptr_code code;
const char* msg;
size_t pos;
} yyjson_ptr_err;
typedef struct yyjson_ptr_ctx {
yyjson_mut_val* ctn;
yyjson_mut_val* pre;
yyjson_mut_val* old;
} yyjson_ptr_ctx;
yyjson_api_inline yyjson_val* yyjson_doc_ptr_get(yyjson_doc* doc, const char* ptr);
yyjson_api_inline yyjson_val* yyjson_doc_ptr_getn(yyjson_doc* doc, const char* ptr, size_t len);
yyjson_api_inline yyjson_val* yyjson_doc_ptr_getx(yyjson_doc* doc, const char* ptr, size_t len,
yyjson_ptr_err* err);
yyjson_api_inline yyjson_val* yyjson_ptr_get(yyjson_val* val, const char* ptr);
yyjson_api_inline yyjson_val* yyjson_ptr_getn(yyjson_val* val, const char* ptr, size_t len);
yyjson_api_inline yyjson_val* yyjson_ptr_getx(yyjson_val* val, const char* ptr, size_t len,
yyjson_ptr_err* err);
yyjson_api_inline yyjson_mut_val* yyjson_mut_doc_ptr_get(yyjson_mut_doc* doc, const char* ptr);
yyjson_api_inline yyjson_mut_val* yyjson_mut_doc_ptr_getn(yyjson_mut_doc* doc, const char* ptr,
size_t len);
yyjson_api_inline yyjson_mut_val* yyjson_mut_doc_ptr_getx(yyjson_mut_doc* doc, const char* ptr,
size_t len, yyjson_ptr_ctx* ctx, yyjson_ptr_err* err);
yyjson_api_inline yyjson_mut_val* yyjson_mut_ptr_get(yyjson_mut_val* val, const char* ptr);
yyjson_api_inline yyjson_mut_val* yyjson_mut_ptr_getn(yyjson_mut_val* val, const char* ptr,
size_t len);
yyjson_api_inline yyjson_mut_val* yyjson_mut_ptr_getx(yyjson_mut_val* val, const char* ptr,
size_t len, yyjson_ptr_ctx* ctx, yyjson_ptr_err* err);
yyjson_api_inline bool yyjson_mut_doc_ptr_add(yyjson_mut_doc* doc, const char* ptr,
yyjson_mut_val* new_val);
yyjson_api_inline bool yyjson_mut_doc_ptr_addn(yyjson_mut_doc* doc, const char* ptr, size_t len,
yyjson_mut_val* new_val);
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);
yyjson_api_inline bool yyjson_mut_ptr_add(yyjson_mut_val* val, const char* ptr,
yyjson_mut_val* new_val, yyjson_mut_doc* doc);
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);
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);
yyjson_api_inline bool yyjson_mut_doc_ptr_set(yyjson_mut_doc* doc, const char* ptr,
yyjson_mut_val* new_val);
yyjson_api_inline bool yyjson_mut_doc_ptr_setn(yyjson_mut_doc* doc, const char* ptr, size_t len,
yyjson_mut_val* new_val);
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);
yyjson_api_inline bool yyjson_mut_ptr_set(yyjson_mut_val* val, const char* ptr,
yyjson_mut_val* new_val, yyjson_mut_doc* doc);
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);
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);
yyjson_api_inline yyjson_mut_val* yyjson_mut_doc_ptr_replace(yyjson_mut_doc* doc, const char* ptr,
yyjson_mut_val* new_val);
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);
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);
yyjson_api_inline yyjson_mut_val* yyjson_mut_ptr_replace(yyjson_mut_val* val, const char* ptr,
yyjson_mut_val* new_val);
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);
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);
yyjson_api_inline yyjson_mut_val* yyjson_mut_doc_ptr_remove(yyjson_mut_doc* doc, const char* ptr);
yyjson_api_inline yyjson_mut_val* yyjson_mut_doc_ptr_removen(yyjson_mut_doc* doc, const char* ptr,
size_t len);
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);
yyjson_api_inline yyjson_mut_val* yyjson_mut_ptr_remove(yyjson_mut_val* val, const char* ptr);
yyjson_api_inline yyjson_mut_val* yyjson_mut_ptr_removen(yyjson_mut_val* val, const char* ptr,
size_t len);
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);
yyjson_api_inline bool yyjson_ptr_ctx_append(yyjson_ptr_ctx* ctx, yyjson_mut_val* key,
yyjson_mut_val* val);
yyjson_api_inline bool yyjson_ptr_ctx_replace(yyjson_ptr_ctx* ctx, yyjson_mut_val* val);
yyjson_api_inline bool yyjson_ptr_ctx_remove(yyjson_ptr_ctx* ctx);
typedef uint32_t yyjson_patch_code;
static const yyjson_patch_code YYJSON_PATCH_SUCCESS = 0;
static const yyjson_patch_code YYJSON_PATCH_ERROR_INVALID_PARAMETER = 1;
static const yyjson_patch_code YYJSON_PATCH_ERROR_MEMORY_ALLOCATION = 2;
static const yyjson_patch_code YYJSON_PATCH_ERROR_INVALID_OPERATION = 3;
static const yyjson_patch_code YYJSON_PATCH_ERROR_MISSING_KEY = 4;
static const yyjson_patch_code YYJSON_PATCH_ERROR_INVALID_MEMBER = 5;
static const yyjson_patch_code YYJSON_PATCH_ERROR_EQUAL = 6;
static const yyjson_patch_code YYJSON_PATCH_ERROR_POINTER = 7;
typedef struct yyjson_patch_err {
yyjson_patch_code code;
size_t idx;
const char* msg;
yyjson_ptr_err ptr;
} yyjson_patch_err;
yyjson_api yyjson_mut_val* yyjson_patch(yyjson_mut_doc* doc, yyjson_val* orig, yyjson_val* patch,
yyjson_patch_err* err);
yyjson_api yyjson_mut_val* yyjson_mut_patch(yyjson_mut_doc* doc, yyjson_mut_val* orig,
yyjson_mut_val* patch, yyjson_patch_err* err);
yyjson_api yyjson_mut_val* yyjson_merge_patch(yyjson_mut_doc* doc, yyjson_val* orig,
yyjson_val* patch);
yyjson_api yyjson_mut_val* yyjson_mut_merge_patch(yyjson_mut_doc* doc, yyjson_mut_val* orig,
yyjson_mut_val* patch);
typedef union yyjson_val_uni {
uint64_t u64;
int64_t i64;
double f64;
const char* str;
void* ptr;
size_t ofs;
} yyjson_val_uni;
struct yyjson_val {
uint64_t tag;
yyjson_val_uni uni;
};
struct yyjson_doc {
yyjson_val* root;
yyjson_alc alc;
size_t dat_read;
size_t val_read;
char* str_pool;
};
yyjson_api_inline bool unsafe_yyjson_is_str_noesc(const char* str, size_t len) {
#if YYJSON_HAS_CONSTANT_P && (!YYJSON_IS_REAL_GCC || yyjson_gcc_available(4, 4, 0))
if (yyjson_constant_p(len) && len <= 32) {
#define yyjson_repeat32_incr(x) \
x(0) x(1) x(2) x(3) x(4) x(5) x(6) x(7) x(8) x(9) x(10) x(11) x(12) x(13) x(14) x(15) x(16) \
x(17) x(18) x(19) x(20) x(21) x(22) x(23) x(24) x(25) x(26) x(27) x(28) x(29) x(30) x(31)
#define yyjson_check_char_noesc(i) \
if (i < len) { \
char c = str[i]; \
if (c < ' ' || c > '~' || c == '"' || c == '\\') \
return false; \
}
yyjson_repeat32_incr(yyjson_check_char_noesc)
#undef yyjson_repeat32_incr
#undef yyjson_check_char_noesc
return true;
}
#else
(void)str;
(void)len;
#endif
return false;
}
yyjson_api_inline yyjson_type unsafe_yyjson_get_type(void* val) {
uint8_t tag = (uint8_t)((yyjson_val*)val)->tag;
return (yyjson_type)(tag & YYJSON_TYPE_MASK);
}
yyjson_api_inline yyjson_subtype unsafe_yyjson_get_subtype(void* val) {
uint8_t tag = (uint8_t)((yyjson_val*)val)->tag;
return (yyjson_subtype)(tag & YYJSON_SUBTYPE_MASK);
}
yyjson_api_inline uint8_t unsafe_yyjson_get_tag(void* val) {
uint8_t tag = (uint8_t)((yyjson_val*)val)->tag;
return (uint8_t)(tag & YYJSON_TAG_MASK);
}
yyjson_api_inline bool unsafe_yyjson_is_raw(void* val) {
return unsafe_yyjson_get_type(val) == YYJSON_TYPE_RAW;
}
yyjson_api_inline bool unsafe_yyjson_is_null(void* val) {
return unsafe_yyjson_get_type(val) == YYJSON_TYPE_NULL;
}
yyjson_api_inline bool unsafe_yyjson_is_bool(void* val) {
return unsafe_yyjson_get_type(val) == YYJSON_TYPE_BOOL;
}
yyjson_api_inline bool unsafe_yyjson_is_num(void* val) {
return unsafe_yyjson_get_type(val) == YYJSON_TYPE_NUM;
}
yyjson_api_inline bool unsafe_yyjson_is_str(void* val) {
return unsafe_yyjson_get_type(val) == YYJSON_TYPE_STR;
}
yyjson_api_inline bool unsafe_yyjson_is_arr(void* val) {
return unsafe_yyjson_get_type(val) == YYJSON_TYPE_ARR;
}
yyjson_api_inline bool unsafe_yyjson_is_obj(void* val) {
return unsafe_yyjson_get_type(val) == YYJSON_TYPE_OBJ;
}
yyjson_api_inline bool unsafe_yyjson_is_ctn(void* val) {
uint8_t mask = YYJSON_TYPE_ARR & YYJSON_TYPE_OBJ;
return (unsafe_yyjson_get_tag(val) & mask) == mask;
}
yyjson_api_inline bool unsafe_yyjson_is_uint(void* val) {
const uint8_t patt = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT;
return unsafe_yyjson_get_tag(val) == patt;
}
yyjson_api_inline bool unsafe_yyjson_is_sint(void* val) {
const uint8_t patt = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT;
return unsafe_yyjson_get_tag(val) == patt;
}
yyjson_api_inline bool unsafe_yyjson_is_int(void* val) {
const uint8_t mask = YYJSON_TAG_MASK & (~YYJSON_SUBTYPE_SINT);
const uint8_t patt = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT;
return (unsafe_yyjson_get_tag(val) & mask) == patt;
}
yyjson_api_inline bool unsafe_yyjson_is_real(void* val) {
const uint8_t patt = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_REAL;
return unsafe_yyjson_get_tag(val) == patt;
}
yyjson_api_inline bool unsafe_yyjson_is_true(void* val) {
const uint8_t patt = YYJSON_TYPE_BOOL | YYJSON_SUBTYPE_TRUE;
return unsafe_yyjson_get_tag(val) == patt;
}
yyjson_api_inline bool unsafe_yyjson_is_false(void* val) {
const uint8_t patt = YYJSON_TYPE_BOOL | YYJSON_SUBTYPE_FALSE;
return unsafe_yyjson_get_tag(val) == patt;
}
yyjson_api_inline bool unsafe_yyjson_arr_is_flat(yyjson_val* val) {
size_t ofs = val->uni.ofs;
size_t len = (size_t)(val->tag >> YYJSON_TAG_BIT);
return len * sizeof(yyjson_val) + sizeof(yyjson_val) == ofs;
}
yyjson_api_inline const char* unsafe_yyjson_get_raw(void* val) {
return ((yyjson_val*)val)->uni.str;
}
yyjson_api_inline bool unsafe_yyjson_get_bool(void* val) {
uint8_t tag = unsafe_yyjson_get_tag(val);
return (bool)((tag & YYJSON_SUBTYPE_MASK) >> YYJSON_TYPE_BIT);
}
yyjson_api_inline uint64_t unsafe_yyjson_get_uint(void* val) {
return ((yyjson_val*)val)->uni.u64;
}
yyjson_api_inline int64_t unsafe_yyjson_get_sint(void* val) {
return ((yyjson_val*)val)->uni.i64;
}
yyjson_api_inline int unsafe_yyjson_get_int(void* val) {
return (int)((yyjson_val*)val)->uni.i64;
}
yyjson_api_inline double unsafe_yyjson_get_real(void* val) {
return ((yyjson_val*)val)->uni.f64;
}
yyjson_api_inline double unsafe_yyjson_get_num(void* val) {
uint8_t tag = unsafe_yyjson_get_tag(val);
if (tag == (YYJSON_TYPE_NUM | YYJSON_SUBTYPE_REAL)) {
return ((yyjson_val*)val)->uni.f64;
} else if (tag == (YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT)) {
return (double)((yyjson_val*)val)->uni.i64;
} else if (tag == (YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT)) {
#if YYJSON_U64_TO_F64_NO_IMPL
uint64_t msb = ((uint64_t)1) << 63;
uint64_t num = ((yyjson_val*)val)->uni.u64;
if ((num & msb) == 0) {
return (double)(int64_t)num;
} else {
return ((double)(int64_t)((num >> 1) | (num & 1))) * (double)2.0;
}
#else
return (double)((yyjson_val*)val)->uni.u64;
#endif
}
return 0.0;
}
yyjson_api_inline const char* unsafe_yyjson_get_str(void* val) {
return ((yyjson_val*)val)->uni.str;
}
yyjson_api_inline size_t unsafe_yyjson_get_len(void* val) {
return (size_t)(((yyjson_val*)val)->tag >> YYJSON_TAG_BIT);
}
yyjson_api_inline yyjson_val* unsafe_yyjson_get_first(yyjson_val* ctn) {
return ctn + 1;
}
yyjson_api_inline yyjson_val* unsafe_yyjson_get_next(yyjson_val* val) {
bool is_ctn = unsafe_yyjson_is_ctn(val);
size_t ctn_ofs = val->uni.ofs;
size_t ofs = (is_ctn ? ctn_ofs : sizeof(yyjson_val));
return (yyjson_val*)(void*)((uint8_t*)val + ofs);
}
yyjson_api_inline bool unsafe_yyjson_equals_strn(void* val, const char* str, size_t len) {
return unsafe_yyjson_get_len(val) == len && memcmp(((yyjson_val*)val)->uni.str, str, len) == 0;
}
yyjson_api_inline bool unsafe_yyjson_equals_str(void* val, const char* str) {
return unsafe_yyjson_equals_strn(val, str, strlen(str));
}
yyjson_api_inline void unsafe_yyjson_set_type(void* val, yyjson_type type, yyjson_subtype subtype) {
uint8_t tag = (type | subtype);
uint64_t new_tag = ((yyjson_val*)val)->tag;
new_tag = (new_tag & (~(uint64_t)YYJSON_TAG_MASK)) | (uint64_t)tag;
((yyjson_val*)val)->tag = new_tag;
}
yyjson_api_inline void unsafe_yyjson_set_len(void* val, size_t len) {
uint64_t tag = ((yyjson_val*)val)->tag & YYJSON_TAG_MASK;
tag |= (uint64_t)len << YYJSON_TAG_BIT;
((yyjson_val*)val)->tag = tag;
}
yyjson_api_inline void unsafe_yyjson_inc_len(void* val) {
uint64_t tag = ((yyjson_val*)val)->tag;
tag += (uint64_t)(1 << YYJSON_TAG_BIT);
((yyjson_val*)val)->tag = tag;
}
yyjson_api_inline void unsafe_yyjson_set_raw(void* val, const char* raw, size_t len) {
unsafe_yyjson_set_type(val, YYJSON_TYPE_RAW, YYJSON_SUBTYPE_NONE);
unsafe_yyjson_set_len(val, len);
((yyjson_val*)val)->uni.str = raw;
}
yyjson_api_inline void unsafe_yyjson_set_null(void* val) {
unsafe_yyjson_set_type(val, YYJSON_TYPE_NULL, YYJSON_SUBTYPE_NONE);
unsafe_yyjson_set_len(val, 0);
}
yyjson_api_inline void unsafe_yyjson_set_bool(void* val, bool num) {
yyjson_subtype subtype = num ? YYJSON_SUBTYPE_TRUE : YYJSON_SUBTYPE_FALSE;
unsafe_yyjson_set_type(val, YYJSON_TYPE_BOOL, subtype);
unsafe_yyjson_set_len(val, 0);
}
yyjson_api_inline void unsafe_yyjson_set_uint(void* val, uint64_t num) {
unsafe_yyjson_set_type(val, YYJSON_TYPE_NUM, YYJSON_SUBTYPE_UINT);
unsafe_yyjson_set_len(val, 0);
((yyjson_val*)val)->uni.u64 = num;
}
yyjson_api_inline void unsafe_yyjson_set_sint(void* val, int64_t num) {
unsafe_yyjson_set_type(val, YYJSON_TYPE_NUM, YYJSON_SUBTYPE_SINT);
unsafe_yyjson_set_len(val, 0);
((yyjson_val*)val)->uni.i64 = num;
}
yyjson_api_inline void unsafe_yyjson_set_real(void* val, double num) {
unsafe_yyjson_set_type(val, YYJSON_TYPE_NUM, YYJSON_SUBTYPE_REAL);
unsafe_yyjson_set_len(val, 0);
((yyjson_val*)val)->uni.f64 = num;
}
yyjson_api_inline void unsafe_yyjson_set_str(void* val, const char* str) {
size_t len = strlen(str);
bool noesc = unsafe_yyjson_is_str_noesc(str, len);
yyjson_subtype sub = noesc ? YYJSON_SUBTYPE_NOESC : YYJSON_SUBTYPE_NONE;
unsafe_yyjson_set_type(val, YYJSON_TYPE_STR, sub);
unsafe_yyjson_set_len(val, len);
((yyjson_val*)val)->uni.str = str;
}
yyjson_api_inline void unsafe_yyjson_set_strn(void* val, const char* str, size_t len) {
unsafe_yyjson_set_type(val, YYJSON_TYPE_STR, YYJSON_SUBTYPE_NONE);
unsafe_yyjson_set_len(val, len);
((yyjson_val*)val)->uni.str = str;
}
yyjson_api_inline void unsafe_yyjson_set_arr(void* val, size_t size) {
unsafe_yyjson_set_type(val, YYJSON_TYPE_ARR, YYJSON_SUBTYPE_NONE);
unsafe_yyjson_set_len(val, size);
}
yyjson_api_inline void unsafe_yyjson_set_obj(void* val, size_t size) {
unsafe_yyjson_set_type(val, YYJSON_TYPE_OBJ, YYJSON_SUBTYPE_NONE);
unsafe_yyjson_set_len(val, size);
}
yyjson_api_inline yyjson_val* yyjson_doc_get_root(yyjson_doc* doc) {
return doc ? doc->root : NULL;
}
yyjson_api_inline size_t yyjson_doc_get_read_size(yyjson_doc* doc) {
return doc ? doc->dat_read : 0;
}
yyjson_api_inline size_t yyjson_doc_get_val_count(yyjson_doc* doc) {
return doc ? doc->val_read : 0;
}
yyjson_api_inline void yyjson_doc_free(yyjson_doc* doc) {
if (doc) {
yyjson_alc alc = doc->alc;
memset(&doc->alc, 0, sizeof(alc));
if (doc->str_pool)
alc.free(alc.ctx, doc->str_pool);
alc.free(alc.ctx, doc);
}
}
yyjson_api_inline bool yyjson_is_raw(yyjson_val* val) {
return val ? unsafe_yyjson_is_raw(val) : false;
}
yyjson_api_inline bool yyjson_is_null(yyjson_val* val) {
return val ? unsafe_yyjson_is_null(val) : false;
}
yyjson_api_inline bool yyjson_is_true(yyjson_val* val) {
return val ? unsafe_yyjson_is_true(val) : false;
}
yyjson_api_inline bool yyjson_is_false(yyjson_val* val) {
return val ? unsafe_yyjson_is_false(val) : false;
}
yyjson_api_inline bool yyjson_is_bool(yyjson_val* val) {
return val ? unsafe_yyjson_is_bool(val) : false;
}
yyjson_api_inline bool yyjson_is_uint(yyjson_val* val) {
return val ? unsafe_yyjson_is_uint(val) : false;
}
yyjson_api_inline bool yyjson_is_sint(yyjson_val* val) {
return val ? unsafe_yyjson_is_sint(val) : false;
}
yyjson_api_inline bool yyjson_is_int(yyjson_val* val) {
return val ? unsafe_yyjson_is_int(val) : false;
}
yyjson_api_inline bool yyjson_is_real(yyjson_val* val) {
return val ? unsafe_yyjson_is_real(val) : false;
}
yyjson_api_inline bool yyjson_is_num(yyjson_val* val) {
return val ? unsafe_yyjson_is_num(val) : false;
}
yyjson_api_inline bool yyjson_is_str(yyjson_val* val) {
return val ? unsafe_yyjson_is_str(val) : false;
}
yyjson_api_inline bool yyjson_is_arr(yyjson_val* val) {
return val ? unsafe_yyjson_is_arr(val) : false;
}
yyjson_api_inline bool yyjson_is_obj(yyjson_val* val) {
return val ? unsafe_yyjson_is_obj(val) : false;
}
yyjson_api_inline bool yyjson_is_ctn(yyjson_val* val) {
return val ? unsafe_yyjson_is_ctn(val) : false;
}
yyjson_api_inline yyjson_type yyjson_get_type(yyjson_val* val) {
return val ? unsafe_yyjson_get_type(val) : YYJSON_TYPE_NONE;
}
yyjson_api_inline yyjson_subtype yyjson_get_subtype(yyjson_val* val) {
return val ? unsafe_yyjson_get_subtype(val) : YYJSON_SUBTYPE_NONE;
}
yyjson_api_inline uint8_t yyjson_get_tag(yyjson_val* val) {
return val ? unsafe_yyjson_get_tag(val) : 0;
}
yyjson_api_inline const char* yyjson_get_type_desc(yyjson_val* val) {
switch (yyjson_get_tag(val)) {
case YYJSON_TYPE_RAW | YYJSON_SUBTYPE_NONE:
return "raw";
case YYJSON_TYPE_NULL | YYJSON_SUBTYPE_NONE:
return "null";
case YYJSON_TYPE_STR | YYJSON_SUBTYPE_NONE:
return "string";
case YYJSON_TYPE_STR | YYJSON_SUBTYPE_NOESC:
return "string";
case YYJSON_TYPE_ARR | YYJSON_SUBTYPE_NONE:
return "array";
case YYJSON_TYPE_OBJ | YYJSON_SUBTYPE_NONE:
return "object";
case YYJSON_TYPE_BOOL | YYJSON_SUBTYPE_TRUE:
return "true";
case YYJSON_TYPE_BOOL | YYJSON_SUBTYPE_FALSE:
return "false";
case YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT:
return "uint";
case YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT:
return "sint";
case YYJSON_TYPE_NUM | YYJSON_SUBTYPE_REAL:
return "real";
default:
return "unknown";
}
}
yyjson_api_inline const char* yyjson_get_raw(yyjson_val* val) {
return yyjson_is_raw(val) ? unsafe_yyjson_get_raw(val) : NULL;
}
yyjson_api_inline bool yyjson_get_bool(yyjson_val* val) {
return yyjson_is_bool(val) ? unsafe_yyjson_get_bool(val) : false;
}
yyjson_api_inline uint64_t yyjson_get_uint(yyjson_val* val) {
return yyjson_is_int(val) ? unsafe_yyjson_get_uint(val) : 0;
}
yyjson_api_inline int64_t yyjson_get_sint(yyjson_val* val) {
return yyjson_is_int(val) ? unsafe_yyjson_get_sint(val) : 0;
}
yyjson_api_inline int yyjson_get_int(yyjson_val* val) {
return yyjson_is_int(val) ? unsafe_yyjson_get_int(val) : 0;
}
yyjson_api_inline double yyjson_get_real(yyjson_val* val) {
return yyjson_is_real(val) ? unsafe_yyjson_get_real(val) : 0.0;
}
yyjson_api_inline double yyjson_get_num(yyjson_val* val) {
return val ? unsafe_yyjson_get_num(val) : 0.0;
}
yyjson_api_inline const char* yyjson_get_str(yyjson_val* val) {
return yyjson_is_str(val) ? unsafe_yyjson_get_str(val) : NULL;
}
yyjson_api_inline size_t yyjson_get_len(yyjson_val* val) {
return val ? unsafe_yyjson_get_len(val) : 0;
}
yyjson_api_inline bool yyjson_equals_str(yyjson_val* val, const char* str) {
if (yyjson_likely(val && str)) {
return unsafe_yyjson_is_str(val) && unsafe_yyjson_equals_str(val, str);
}
return false;
}
yyjson_api_inline bool yyjson_equals_strn(yyjson_val* val, const char* str, size_t len) {
if (yyjson_likely(val && str)) {
return unsafe_yyjson_is_str(val) && unsafe_yyjson_equals_strn(val, str, len);
}
return false;
}
yyjson_api bool unsafe_yyjson_equals(yyjson_val* lhs, yyjson_val* rhs);
yyjson_api_inline bool yyjson_equals(yyjson_val* lhs, yyjson_val* rhs) {
if (yyjson_unlikely(!lhs || !rhs))
return false;
return unsafe_yyjson_equals(lhs, rhs);
}
yyjson_api_inline bool yyjson_set_raw(yyjson_val* val, const char* raw, size_t len) {
if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val)))
return false;
unsafe_yyjson_set_raw(val, raw, len);
return true;
}
yyjson_api_inline bool yyjson_set_null(yyjson_val* val) {
if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val)))
return false;
unsafe_yyjson_set_null(val);
return true;
}
yyjson_api_inline bool yyjson_set_bool(yyjson_val* val, bool num) {
if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val)))
return false;
unsafe_yyjson_set_bool(val, num);
return true;
}
yyjson_api_inline bool yyjson_set_uint(yyjson_val* val, uint64_t num) {
if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val)))
return false;
unsafe_yyjson_set_uint(val, num);
return true;
}
yyjson_api_inline bool yyjson_set_sint(yyjson_val* val, int64_t num) {
if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val)))
return false;
unsafe_yyjson_set_sint(val, num);
return true;
}
yyjson_api_inline bool yyjson_set_int(yyjson_val* val, int num) {
if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val)))
return false;
unsafe_yyjson_set_sint(val, (int64_t)num);
return true;
}
yyjson_api_inline bool yyjson_set_real(yyjson_val* val, double num) {
if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val)))
return false;
unsafe_yyjson_set_real(val, num);
return true;
}
yyjson_api_inline bool yyjson_set_str(yyjson_val* val, const char* str) {
if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val)))
return false;
if (yyjson_unlikely(!str))
return false;
unsafe_yyjson_set_str(val, str);
return true;
}
yyjson_api_inline bool yyjson_set_strn(yyjson_val* val, const char* str, size_t len) {
if (yyjson_unlikely(!val || unsafe_yyjson_is_ctn(val)))
return false;
if (yyjson_unlikely(!str))
return false;
unsafe_yyjson_set_strn(val, str, len);
return true;
}
yyjson_api_inline size_t yyjson_arr_size(yyjson_val* arr) {
return yyjson_is_arr(arr) ? unsafe_yyjson_get_len(arr) : 0;
}
yyjson_api_inline yyjson_val* yyjson_arr_get(yyjson_val* arr, size_t idx) {
if (yyjson_likely(yyjson_is_arr(arr))) {
if (yyjson_likely(unsafe_yyjson_get_len(arr) > idx)) {
yyjson_val* val = unsafe_yyjson_get_first(arr);
if (unsafe_yyjson_arr_is_flat(arr)) {
return val + idx;
} else {
while (idx-- > 0)
val = unsafe_yyjson_get_next(val);
return val;
}
}
}
return NULL;
}
yyjson_api_inline yyjson_val* yyjson_arr_get_first(yyjson_val* arr) {
if (yyjson_likely(yyjson_is_arr(arr))) {
if (yyjson_likely(unsafe_yyjson_get_len(arr) > 0)) {
return unsafe_yyjson_get_first(arr);
}
}
return NULL;
}
yyjson_api_inline yyjson_val* yyjson_arr_get_last(yyjson_val* arr) {
if (yyjson_likely(yyjson_is_arr(arr))) {
size_t len = unsafe_yyjson_get_len(arr);
if (yyjson_likely(len > 0)) {
yyjson_val* val = unsafe_yyjson_get_first(arr);
if (unsafe_yyjson_arr_is_flat(arr)) {
return val + (len - 1);
} else {
while (len-- > 1)
val = unsafe_yyjson_get_next(val);
return val;
}
}
}
return NULL;
}
yyjson_api_inline bool yyjson_arr_iter_init(yyjson_val* arr, yyjson_arr_iter* iter) {
if (yyjson_likely(yyjson_is_arr(arr) && iter)) {
iter->idx = 0;
iter->max = unsafe_yyjson_get_len(arr);
iter->cur = unsafe_yyjson_get_first(arr);
return true;
}
if (iter)
memset(iter, 0, sizeof(yyjson_arr_iter));
return false;
}
yyjson_api_inline yyjson_arr_iter yyjson_arr_iter_with(yyjson_val* arr) {
yyjson_arr_iter iter;
yyjson_arr_iter_init(arr, &iter);
return iter;
}
yyjson_api_inline bool yyjson_arr_iter_has_next(yyjson_arr_iter* iter) {
return iter ? iter->idx < iter->max : false;
}
yyjson_api_inline yyjson_val* yyjson_arr_iter_next(yyjson_arr_iter* iter) {
yyjson_val* val;
if (iter && iter->idx < iter->max) {
val = iter->cur;
iter->cur = unsafe_yyjson_get_next(val);
iter->idx++;
return val;
}
return NULL;
}
yyjson_api_inline size_t yyjson_obj_size(yyjson_val* obj) {
return yyjson_is_obj(obj) ? unsafe_yyjson_get_len(obj) : 0;
}
yyjson_api_inline yyjson_val* yyjson_obj_get(yyjson_val* obj, const char* key) {
return yyjson_obj_getn(obj, key, key ? strlen(key) : 0);
}
yyjson_api_inline yyjson_val* yyjson_obj_getn(yyjson_val* obj, const char* _key, size_t key_len) {
if (yyjson_likely(yyjson_is_obj(obj) && _key)) {
size_t len = unsafe_yyjson_get_len(obj);
yyjson_val* key = unsafe_yyjson_get_first(obj);
while (len-- > 0) {
if (unsafe_yyjson_equals_strn(key, _key, key_len))
return key + 1;
key = unsafe_yyjson_get_next(key + 1);
}
}
return NULL;
}
yyjson_api_inline bool yyjson_obj_iter_init(yyjson_val* obj, yyjson_obj_iter* iter) {
if (yyjson_likely(yyjson_is_obj(obj) && iter)) {
iter->idx = 0;
iter->max = unsafe_yyjson_get_len(obj);
iter->cur = unsafe_yyjson_get_first(obj);
iter->obj = obj;
return true;
}
if (iter)
memset(iter, 0, sizeof(yyjson_obj_iter));
return false;
}
yyjson_api_inline yyjson_obj_iter yyjson_obj_iter_with(yyjson_val* obj) {
yyjson_obj_iter iter;
yyjson_obj_iter_init(obj, &iter);
return iter;
}
yyjson_api_inline bool yyjson_obj_iter_has_next(yyjson_obj_iter* iter) {
return iter ? iter->idx < iter->max : false;
}
yyjson_api_inline yyjson_val* yyjson_obj_iter_next(yyjson_obj_iter* iter) {
if (iter && iter->idx < iter->max) {
yyjson_val* key = iter->cur;
iter->idx++;
iter->cur = unsafe_yyjson_get_next(key + 1);
return key;
}
return NULL;
}
yyjson_api_inline yyjson_val* yyjson_obj_iter_get_val(yyjson_val* key) {
return key ? key + 1 : NULL;
}
yyjson_api_inline yyjson_val* yyjson_obj_iter_get(yyjson_obj_iter* iter, const char* key) {
return yyjson_obj_iter_getn(iter, key, key ? strlen(key) : 0);
}
yyjson_api_inline yyjson_val* yyjson_obj_iter_getn(yyjson_obj_iter* iter, const char* key,
size_t key_len) {
if (iter && key) {
size_t idx = iter->idx;
size_t max = iter->max;
yyjson_val* cur = iter->cur;
if (yyjson_unlikely(idx == max)) {
idx = 0;
cur = unsafe_yyjson_get_first(iter->obj);
}
while (idx++ < max) {
yyjson_val* next = unsafe_yyjson_get_next(cur + 1);
if (unsafe_yyjson_equals_strn(cur, key, key_len)) {
iter->idx = idx;
iter->cur = next;
return cur + 1;
}
cur = next;
if (idx == iter->max && iter->idx < iter->max) {
idx = 0;
max = iter->idx;
cur = unsafe_yyjson_get_first(iter->obj);
}
}
}
return NULL;
}
struct yyjson_mut_val {
uint64_t tag;
yyjson_val_uni uni;
yyjson_mut_val* next;
};
typedef struct yyjson_str_chunk {
struct yyjson_str_chunk* next;
size_t chunk_size;
} yyjson_str_chunk;
typedef struct yyjson_str_pool {
char* cur;
char* end;
size_t chunk_size;
size_t chunk_size_max;
yyjson_str_chunk* chunks;
} yyjson_str_pool;
typedef struct yyjson_val_chunk {
struct yyjson_val_chunk* next;
size_t chunk_size;
} yyjson_val_chunk;
typedef struct yyjson_val_pool {
yyjson_mut_val* cur;
yyjson_mut_val* end;
size_t chunk_size;
size_t chunk_size_max;
yyjson_val_chunk* chunks;
} yyjson_val_pool;
struct yyjson_mut_doc {
yyjson_mut_val* root;
yyjson_alc alc;
yyjson_str_pool str_pool;
yyjson_val_pool val_pool;
};
yyjson_api bool unsafe_yyjson_str_pool_grow(yyjson_str_pool* pool, const yyjson_alc* alc,
size_t len);
yyjson_api bool unsafe_yyjson_val_pool_grow(yyjson_val_pool* pool, const yyjson_alc* alc,
size_t count);
yyjson_api_inline char* unsafe_yyjson_mut_str_alc(yyjson_mut_doc* doc, size_t len) {
char* mem;
const yyjson_alc* alc = &doc->alc;
yyjson_str_pool* pool = &doc->str_pool;
if (yyjson_unlikely((size_t)(pool->end - pool->cur) <= len)) {
if (yyjson_unlikely(!unsafe_yyjson_str_pool_grow(pool, alc, len + 1))) {
return NULL;
}
}
mem = pool->cur;
pool->cur = mem + len + 1;
return mem;
}
yyjson_api_inline char* unsafe_yyjson_mut_strncpy(yyjson_mut_doc* doc, const char* str,
size_t len) {
char* mem = unsafe_yyjson_mut_str_alc(doc, len);
if (yyjson_unlikely(!mem))
return NULL;
memcpy((void*)mem, (const void*)str, len);
mem[len] = '\0';
return mem;
}
yyjson_api_inline yyjson_mut_val* unsafe_yyjson_mut_val(yyjson_mut_doc* doc, size_t count) {
yyjson_mut_val* val;
yyjson_alc* alc = &doc->alc;
yyjson_val_pool* pool = &doc->val_pool;
if (yyjson_unlikely((size_t)(pool->end - pool->cur) < count)) {
if (yyjson_unlikely(!unsafe_yyjson_val_pool_grow(pool, alc, count))) {
return NULL;
}
}
val = pool->cur;
pool->cur += count;
return val;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_doc_get_root(yyjson_mut_doc* doc) {
return doc ? doc->root : NULL;
}
yyjson_api_inline void yyjson_mut_doc_set_root(yyjson_mut_doc* doc, yyjson_mut_val* root) {
if (doc)
doc->root = root;
}
yyjson_api_inline bool yyjson_mut_is_raw(yyjson_mut_val* val) {
return val ? unsafe_yyjson_is_raw(val) : false;
}
yyjson_api_inline bool yyjson_mut_is_null(yyjson_mut_val* val) {
return val ? unsafe_yyjson_is_null(val) : false;
}
yyjson_api_inline bool yyjson_mut_is_true(yyjson_mut_val* val) {
return val ? unsafe_yyjson_is_true(val) : false;
}
yyjson_api_inline bool yyjson_mut_is_false(yyjson_mut_val* val) {
return val ? unsafe_yyjson_is_false(val) : false;
}
yyjson_api_inline bool yyjson_mut_is_bool(yyjson_mut_val* val) {
return val ? unsafe_yyjson_is_bool(val) : false;
}
yyjson_api_inline bool yyjson_mut_is_uint(yyjson_mut_val* val) {
return val ? unsafe_yyjson_is_uint(val) : false;
}
yyjson_api_inline bool yyjson_mut_is_sint(yyjson_mut_val* val) {
return val ? unsafe_yyjson_is_sint(val) : false;
}
yyjson_api_inline bool yyjson_mut_is_int(yyjson_mut_val* val) {
return val ? unsafe_yyjson_is_int(val) : false;
}
yyjson_api_inline bool yyjson_mut_is_real(yyjson_mut_val* val) {
return val ? unsafe_yyjson_is_real(val) : false;
}
yyjson_api_inline bool yyjson_mut_is_num(yyjson_mut_val* val) {
return val ? unsafe_yyjson_is_num(val) : false;
}
yyjson_api_inline bool yyjson_mut_is_str(yyjson_mut_val* val) {
return val ? unsafe_yyjson_is_str(val) : false;
}
yyjson_api_inline bool yyjson_mut_is_arr(yyjson_mut_val* val) {
return val ? unsafe_yyjson_is_arr(val) : false;
}
yyjson_api_inline bool yyjson_mut_is_obj(yyjson_mut_val* val) {
return val ? unsafe_yyjson_is_obj(val) : false;
}
yyjson_api_inline bool yyjson_mut_is_ctn(yyjson_mut_val* val) {
return val ? unsafe_yyjson_is_ctn(val) : false;
}
yyjson_api_inline yyjson_type yyjson_mut_get_type(yyjson_mut_val* val) {
return yyjson_get_type((yyjson_val*)val);
}
yyjson_api_inline yyjson_subtype yyjson_mut_get_subtype(yyjson_mut_val* val) {
return yyjson_get_subtype((yyjson_val*)val);
}
yyjson_api_inline uint8_t yyjson_mut_get_tag(yyjson_mut_val* val) {
return yyjson_get_tag((yyjson_val*)val);
}
yyjson_api_inline const char* yyjson_mut_get_type_desc(yyjson_mut_val* val) {
return yyjson_get_type_desc((yyjson_val*)val);
}
yyjson_api_inline const char* yyjson_mut_get_raw(yyjson_mut_val* val) {
return yyjson_get_raw((yyjson_val*)val);
}
yyjson_api_inline bool yyjson_mut_get_bool(yyjson_mut_val* val) {
return yyjson_get_bool((yyjson_val*)val);
}
yyjson_api_inline uint64_t yyjson_mut_get_uint(yyjson_mut_val* val) {
return yyjson_get_uint((yyjson_val*)val);
}
yyjson_api_inline int64_t yyjson_mut_get_sint(yyjson_mut_val* val) {
return yyjson_get_sint((yyjson_val*)val);
}
yyjson_api_inline int yyjson_mut_get_int(yyjson_mut_val* val) {
return yyjson_get_int((yyjson_val*)val);
}
yyjson_api_inline double yyjson_mut_get_real(yyjson_mut_val* val) {
return yyjson_get_real((yyjson_val*)val);
}
yyjson_api_inline double yyjson_mut_get_num(yyjson_mut_val* val) {
return yyjson_get_num((yyjson_val*)val);
}
yyjson_api_inline const char* yyjson_mut_get_str(yyjson_mut_val* val) {
return yyjson_get_str((yyjson_val*)val);
}
yyjson_api_inline size_t yyjson_mut_get_len(yyjson_mut_val* val) {
return yyjson_get_len((yyjson_val*)val);
}
yyjson_api_inline bool yyjson_mut_equals_str(yyjson_mut_val* val, const char* str) {
return yyjson_equals_str((yyjson_val*)val, str);
}
yyjson_api_inline bool yyjson_mut_equals_strn(yyjson_mut_val* val, const char* str, size_t len) {
return yyjson_equals_strn((yyjson_val*)val, str, len);
}
yyjson_api bool unsafe_yyjson_mut_equals(yyjson_mut_val* lhs, yyjson_mut_val* rhs);
yyjson_api_inline bool yyjson_mut_equals(yyjson_mut_val* lhs, yyjson_mut_val* rhs) {
if (yyjson_unlikely(!lhs || !rhs))
return false;
return unsafe_yyjson_mut_equals(lhs, rhs);
}
yyjson_api_inline bool yyjson_mut_set_raw(yyjson_mut_val* val, const char* raw, size_t len) {
if (yyjson_unlikely(!val || !raw))
return false;
unsafe_yyjson_set_raw(val, raw, len);
return true;
}
yyjson_api_inline bool yyjson_mut_set_null(yyjson_mut_val* val) {
if (yyjson_unlikely(!val))
return false;
unsafe_yyjson_set_null(val);
return true;
}
yyjson_api_inline bool yyjson_mut_set_bool(yyjson_mut_val* val, bool num) {
if (yyjson_unlikely(!val))
return false;
unsafe_yyjson_set_bool(val, num);
return true;
}
yyjson_api_inline bool yyjson_mut_set_uint(yyjson_mut_val* val, uint64_t num) {
if (yyjson_unlikely(!val))
return false;
unsafe_yyjson_set_uint(val, num);
return true;
}
yyjson_api_inline bool yyjson_mut_set_sint(yyjson_mut_val* val, int64_t num) {
if (yyjson_unlikely(!val))
return false;
unsafe_yyjson_set_sint(val, num);
return true;
}
yyjson_api_inline bool yyjson_mut_set_int(yyjson_mut_val* val, int num) {
if (yyjson_unlikely(!val))
return false;
unsafe_yyjson_set_sint(val, (int64_t)num);
return true;
}
yyjson_api_inline bool yyjson_mut_set_real(yyjson_mut_val* val, double num) {
if (yyjson_unlikely(!val))
return false;
unsafe_yyjson_set_real(val, num);
return true;
}
yyjson_api_inline bool yyjson_mut_set_str(yyjson_mut_val* val, const char* str) {
if (yyjson_unlikely(!val || !str))
return false;
unsafe_yyjson_set_str(val, str);
return true;
}
yyjson_api_inline bool yyjson_mut_set_strn(yyjson_mut_val* val, const char* str, size_t len) {
if (yyjson_unlikely(!val || !str))
return false;
unsafe_yyjson_set_strn(val, str, len);
return true;
}
yyjson_api_inline bool yyjson_mut_set_arr(yyjson_mut_val* val) {
if (yyjson_unlikely(!val))
return false;
unsafe_yyjson_set_arr(val, 0);
return true;
}
yyjson_api_inline bool yyjson_mut_set_obj(yyjson_mut_val* val) {
if (yyjson_unlikely(!val))
return false;
unsafe_yyjson_set_obj(val, 0);
return true;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_raw(yyjson_mut_doc* doc, const char* str) {
if (yyjson_likely(str))
return yyjson_mut_rawn(doc, str, strlen(str));
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_rawn(yyjson_mut_doc* doc, const char* str,
size_t len) {
if (yyjson_likely(doc && str)) {
yyjson_mut_val* val = unsafe_yyjson_mut_val(doc, 1);
if (yyjson_likely(val)) {
val->tag = ((uint64_t)len << YYJSON_TAG_BIT) | YYJSON_TYPE_RAW;
val->uni.str = str;
return val;
}
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_rawcpy(yyjson_mut_doc* doc, const char* str) {
if (yyjson_likely(str))
return yyjson_mut_rawncpy(doc, str, strlen(str));
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_rawncpy(yyjson_mut_doc* doc, const char* str,
size_t len) {
if (yyjson_likely(doc && str)) {
yyjson_mut_val* val = unsafe_yyjson_mut_val(doc, 1);
char* new_str = unsafe_yyjson_mut_strncpy(doc, str, len);
if (yyjson_likely(val && new_str)) {
val->tag = ((uint64_t)len << YYJSON_TAG_BIT) | YYJSON_TYPE_RAW;
val->uni.str = new_str;
return val;
}
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_null(yyjson_mut_doc* doc) {
if (yyjson_likely(doc)) {
yyjson_mut_val* val = unsafe_yyjson_mut_val(doc, 1);
if (yyjson_likely(val)) {
val->tag = YYJSON_TYPE_NULL | YYJSON_SUBTYPE_NONE;
return val;
}
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_true(yyjson_mut_doc* doc) {
if (yyjson_likely(doc)) {
yyjson_mut_val* val = unsafe_yyjson_mut_val(doc, 1);
if (yyjson_likely(val)) {
val->tag = YYJSON_TYPE_BOOL | YYJSON_SUBTYPE_TRUE;
return val;
}
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_false(yyjson_mut_doc* doc) {
if (yyjson_likely(doc)) {
yyjson_mut_val* val = unsafe_yyjson_mut_val(doc, 1);
if (yyjson_likely(val)) {
val->tag = YYJSON_TYPE_BOOL | YYJSON_SUBTYPE_FALSE;
return val;
}
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_bool(yyjson_mut_doc* doc, bool _val) {
if (yyjson_likely(doc)) {
yyjson_mut_val* val = unsafe_yyjson_mut_val(doc, 1);
if (yyjson_likely(val)) {
_val = !!_val;
val->tag = YYJSON_TYPE_BOOL | (uint8_t)((uint8_t)_val << 3);
return val;
}
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_uint(yyjson_mut_doc* doc, uint64_t num) {
if (yyjson_likely(doc)) {
yyjson_mut_val* val = unsafe_yyjson_mut_val(doc, 1);
if (yyjson_likely(val)) {
val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT;
val->uni.u64 = num;
return val;
}
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_sint(yyjson_mut_doc* doc, int64_t num) {
if (yyjson_likely(doc)) {
yyjson_mut_val* val = unsafe_yyjson_mut_val(doc, 1);
if (yyjson_likely(val)) {
val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT;
val->uni.i64 = num;
return val;
}
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_int(yyjson_mut_doc* doc, int64_t num) {
return yyjson_mut_sint(doc, num);
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_real(yyjson_mut_doc* doc, double num) {
if (yyjson_likely(doc)) {
yyjson_mut_val* val = unsafe_yyjson_mut_val(doc, 1);
if (yyjson_likely(val)) {
val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_REAL;
val->uni.f64 = num;
return val;
}
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_str(yyjson_mut_doc* doc, const char* str) {
if (yyjson_likely(doc && str)) {
size_t len = strlen(str);
bool noesc = unsafe_yyjson_is_str_noesc(str, len);
yyjson_subtype sub = noesc ? YYJSON_SUBTYPE_NOESC : YYJSON_SUBTYPE_NONE;
yyjson_mut_val* val = unsafe_yyjson_mut_val(doc, 1);
if (yyjson_likely(val)) {
val->tag = ((uint64_t)len << YYJSON_TAG_BIT) | (uint64_t)(YYJSON_TYPE_STR | sub);
val->uni.str = str;
return val;
}
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_strn(yyjson_mut_doc* doc, const char* str,
size_t len) {
if (yyjson_likely(doc && str)) {
yyjson_mut_val* val = unsafe_yyjson_mut_val(doc, 1);
if (yyjson_likely(val)) {
val->tag = ((uint64_t)len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
val->uni.str = str;
return val;
}
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_strcpy(yyjson_mut_doc* doc, const char* str) {
if (yyjson_likely(doc && str)) {
size_t len = strlen(str);
bool noesc = unsafe_yyjson_is_str_noesc(str, len);
yyjson_subtype sub = noesc ? YYJSON_SUBTYPE_NOESC : YYJSON_SUBTYPE_NONE;
yyjson_mut_val* val = unsafe_yyjson_mut_val(doc, 1);
char* new_str = unsafe_yyjson_mut_strncpy(doc, str, len);
if (yyjson_likely(val && new_str)) {
val->tag = ((uint64_t)len << YYJSON_TAG_BIT) | (uint64_t)(YYJSON_TYPE_STR | sub);
val->uni.str = new_str;
return val;
}
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_strncpy(yyjson_mut_doc* doc, const char* str,
size_t len) {
if (yyjson_likely(doc && str)) {
yyjson_mut_val* val = unsafe_yyjson_mut_val(doc, 1);
char* new_str = unsafe_yyjson_mut_strncpy(doc, str, len);
if (yyjson_likely(val && new_str)) {
val->tag = ((uint64_t)len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
val->uni.str = new_str;
return val;
}
}
return NULL;
}
yyjson_api_inline size_t yyjson_mut_arr_size(yyjson_mut_val* arr) {
return yyjson_mut_is_arr(arr) ? unsafe_yyjson_get_len(arr) : 0;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_get(yyjson_mut_val* arr, size_t idx) {
if (yyjson_likely(idx < yyjson_mut_arr_size(arr))) {
yyjson_mut_val* val = (yyjson_mut_val*)arr->uni.ptr;
while (idx-- > 0)
val = val->next;
return val->next;
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_get_first(yyjson_mut_val* arr) {
if (yyjson_likely(yyjson_mut_arr_size(arr) > 0)) {
return ((yyjson_mut_val*)arr->uni.ptr)->next;
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_get_last(yyjson_mut_val* arr) {
if (yyjson_likely(yyjson_mut_arr_size(arr) > 0)) {
return ((yyjson_mut_val*)arr->uni.ptr);
}
return NULL;
}
yyjson_api_inline bool yyjson_mut_arr_iter_init(yyjson_mut_val* arr, yyjson_mut_arr_iter* iter) {
if (yyjson_likely(yyjson_mut_is_arr(arr) && iter)) {
iter->idx = 0;
iter->max = unsafe_yyjson_get_len(arr);
iter->cur = iter->max ? (yyjson_mut_val*)arr->uni.ptr : NULL;
iter->pre = NULL;
iter->arr = arr;
return true;
}
if (iter)
memset(iter, 0, sizeof(yyjson_mut_arr_iter));
return false;
}
yyjson_api_inline yyjson_mut_arr_iter yyjson_mut_arr_iter_with(yyjson_mut_val* arr) {
yyjson_mut_arr_iter iter;
yyjson_mut_arr_iter_init(arr, &iter);
return iter;
}
yyjson_api_inline bool yyjson_mut_arr_iter_has_next(yyjson_mut_arr_iter* iter) {
return iter ? iter->idx < iter->max : false;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_iter_next(yyjson_mut_arr_iter* iter) {
if (iter && iter->idx < iter->max) {
yyjson_mut_val* val = iter->cur;
iter->pre = val;
iter->cur = val->next;
iter->idx++;
return iter->cur;
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_iter_remove(yyjson_mut_arr_iter* iter) {
if (yyjson_likely(iter && 0 < iter->idx && iter->idx <= iter->max)) {
yyjson_mut_val* prev = iter->pre;
yyjson_mut_val* cur = iter->cur;
yyjson_mut_val* next = cur->next;
if (yyjson_unlikely(iter->idx == iter->max))
iter->arr->uni.ptr = prev;
iter->idx--;
iter->max--;
unsafe_yyjson_set_len(iter->arr, iter->max);
prev->next = next;
iter->cur = next;
return cur;
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr(yyjson_mut_doc* doc) {
if (yyjson_likely(doc)) {
yyjson_mut_val* val = unsafe_yyjson_mut_val(doc, 1);
if (yyjson_likely(val)) {
val->tag = YYJSON_TYPE_ARR | YYJSON_SUBTYPE_NONE;
return val;
}
}
return NULL;
}
#define yyjson_mut_arr_with_func(func) \
if (yyjson_likely( \
doc && ((0 < count && count < (~(size_t)0) / sizeof(yyjson_mut_val) && vals) || \
count == 0))) { \
yyjson_mut_val* arr = unsafe_yyjson_mut_val(doc, 1 + count); \
if (yyjson_likely(arr)) { \
arr->tag = ((uint64_t)count << YYJSON_TAG_BIT) | YYJSON_TYPE_ARR; \
if (count > 0) { \
size_t i; \
for (i = 0; i < count; i++) { \
yyjson_mut_val* val = arr + i + 1; \
func val->next = val + 1; \
} \
arr[count].next = arr + 1; \
arr->uni.ptr = arr + count; \
} \
return arr; \
} \
} \
return NULL
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_bool(yyjson_mut_doc* doc, const bool* vals,
size_t count) {
yyjson_mut_arr_with_func({
bool _val = !!vals[i];
val->tag = YYJSON_TYPE_BOOL | (uint8_t)((uint8_t)_val << 3);
});
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_sint(yyjson_mut_doc* doc, const int64_t* vals,
size_t count) {
return yyjson_mut_arr_with_sint64(doc, vals, count);
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_uint(yyjson_mut_doc* doc,
const uint64_t* vals, size_t count) {
return yyjson_mut_arr_with_uint64(doc, vals, count);
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_real(yyjson_mut_doc* doc, const double* vals,
size_t count) {
return yyjson_mut_arr_with_double(doc, vals, count);
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_sint8(yyjson_mut_doc* doc, const int8_t* vals,
size_t count) {
yyjson_mut_arr_with_func({
val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT;
val->uni.i64 = (int64_t)vals[i];
});
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_sint16(yyjson_mut_doc* doc,
const int16_t* vals, size_t count) {
yyjson_mut_arr_with_func({
val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT;
val->uni.i64 = vals[i];
});
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_sint32(yyjson_mut_doc* doc,
const int32_t* vals, size_t count) {
yyjson_mut_arr_with_func({
val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT;
val->uni.i64 = vals[i];
});
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_sint64(yyjson_mut_doc* doc,
const int64_t* vals, size_t count) {
yyjson_mut_arr_with_func({
val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT;
val->uni.i64 = vals[i];
});
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_uint8(yyjson_mut_doc* doc,
const uint8_t* vals, size_t count) {
yyjson_mut_arr_with_func({
val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT;
val->uni.u64 = vals[i];
});
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_uint16(yyjson_mut_doc* doc,
const uint16_t* vals, size_t count) {
yyjson_mut_arr_with_func({
val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT;
val->uni.u64 = vals[i];
});
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_uint32(yyjson_mut_doc* doc,
const uint32_t* vals, size_t count) {
yyjson_mut_arr_with_func({
val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT;
val->uni.u64 = vals[i];
});
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_uint64(yyjson_mut_doc* doc,
const uint64_t* vals, size_t count) {
yyjson_mut_arr_with_func({
val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT;
val->uni.u64 = vals[i];
});
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_float(yyjson_mut_doc* doc, const float* vals,
size_t count) {
yyjson_mut_arr_with_func({
val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_REAL;
val->uni.f64 = (double)vals[i];
});
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_double(yyjson_mut_doc* doc,
const double* vals, size_t count) {
yyjson_mut_arr_with_func({
val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_REAL;
val->uni.f64 = vals[i];
});
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_str(yyjson_mut_doc* doc, const char** vals,
size_t count) {
yyjson_mut_arr_with_func({
uint64_t len = (uint64_t)strlen(vals[i]);
val->tag = (len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
val->uni.str = vals[i];
if (yyjson_unlikely(!val->uni.str))
return NULL;
});
}
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) {
if (yyjson_unlikely(count > 0 && !lens))
return NULL;
yyjson_mut_arr_with_func({
val->tag = ((uint64_t)lens[i] << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
val->uni.str = vals[i];
if (yyjson_unlikely(!val->uni.str))
return NULL;
});
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_with_strcpy(yyjson_mut_doc* doc, const char** vals,
size_t count) {
size_t len;
const char* str;
yyjson_mut_arr_with_func({
str = vals[i];
if (!str)
return NULL;
len = strlen(str);
val->tag = ((uint64_t)len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
val->uni.str = unsafe_yyjson_mut_strncpy(doc, str, len);
if (yyjson_unlikely(!val->uni.str))
return NULL;
});
}
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) {
size_t len;
const char* str;
if (yyjson_unlikely(count > 0 && !lens))
return NULL;
yyjson_mut_arr_with_func({
str = vals[i];
len = lens[i];
val->tag = ((uint64_t)len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
val->uni.str = unsafe_yyjson_mut_strncpy(doc, str, len);
if (yyjson_unlikely(!val->uni.str))
return NULL;
});
}
#undef yyjson_mut_arr_with_func
yyjson_api_inline bool yyjson_mut_arr_insert(yyjson_mut_val* arr, yyjson_mut_val* val, size_t idx) {
if (yyjson_likely(yyjson_mut_is_arr(arr) && val)) {
size_t len = unsafe_yyjson_get_len(arr);
if (yyjson_likely(idx <= len)) {
unsafe_yyjson_set_len(arr, len + 1);
if (len == 0) {
val->next = val;
arr->uni.ptr = val;
} else {
yyjson_mut_val* prev = ((yyjson_mut_val*)arr->uni.ptr);
yyjson_mut_val* next = prev->next;
if (idx == len) {
prev->next = val;
val->next = next;
arr->uni.ptr = val;
} else {
while (idx-- > 0) {
prev = next;
next = next->next;
}
prev->next = val;
val->next = next;
}
}
return true;
}
}
return false;
}
yyjson_api_inline bool yyjson_mut_arr_append(yyjson_mut_val* arr, yyjson_mut_val* val) {
if (yyjson_likely(yyjson_mut_is_arr(arr) && val)) {
size_t len = unsafe_yyjson_get_len(arr);
unsafe_yyjson_set_len(arr, len + 1);
if (len == 0) {
val->next = val;
} else {
yyjson_mut_val* prev = ((yyjson_mut_val*)arr->uni.ptr);
yyjson_mut_val* next = prev->next;
prev->next = val;
val->next = next;
}
arr->uni.ptr = val;
return true;
}
return false;
}
yyjson_api_inline bool yyjson_mut_arr_prepend(yyjson_mut_val* arr, yyjson_mut_val* val) {
if (yyjson_likely(yyjson_mut_is_arr(arr) && val)) {
size_t len = unsafe_yyjson_get_len(arr);
unsafe_yyjson_set_len(arr, len + 1);
if (len == 0) {
val->next = val;
arr->uni.ptr = val;
} else {
yyjson_mut_val* prev = ((yyjson_mut_val*)arr->uni.ptr);
yyjson_mut_val* next = prev->next;
prev->next = val;
val->next = next;
}
return true;
}
return false;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_replace(yyjson_mut_val* arr, size_t idx,
yyjson_mut_val* val) {
if (yyjson_likely(yyjson_mut_is_arr(arr) && val)) {
size_t len = unsafe_yyjson_get_len(arr);
if (yyjson_likely(idx < len)) {
if (yyjson_likely(len > 1)) {
yyjson_mut_val* prev = ((yyjson_mut_val*)arr->uni.ptr);
yyjson_mut_val* next = prev->next;
while (idx-- > 0) {
prev = next;
next = next->next;
}
prev->next = val;
val->next = next->next;
if ((void*)next == arr->uni.ptr)
arr->uni.ptr = val;
return next;
} else {
yyjson_mut_val* prev = ((yyjson_mut_val*)arr->uni.ptr);
val->next = val;
arr->uni.ptr = val;
return prev;
}
}
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_remove(yyjson_mut_val* arr, size_t idx) {
if (yyjson_likely(yyjson_mut_is_arr(arr))) {
size_t len = unsafe_yyjson_get_len(arr);
if (yyjson_likely(idx < len)) {
unsafe_yyjson_set_len(arr, len - 1);
if (yyjson_likely(len > 1)) {
yyjson_mut_val* prev = ((yyjson_mut_val*)arr->uni.ptr);
yyjson_mut_val* next = prev->next;
while (idx-- > 0) {
prev = next;
next = next->next;
}
prev->next = next->next;
if ((void*)next == arr->uni.ptr)
arr->uni.ptr = prev;
return next;
} else {
return ((yyjson_mut_val*)arr->uni.ptr);
}
}
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_remove_first(yyjson_mut_val* arr) {
if (yyjson_likely(yyjson_mut_is_arr(arr))) {
size_t len = unsafe_yyjson_get_len(arr);
if (len > 1) {
yyjson_mut_val* prev = ((yyjson_mut_val*)arr->uni.ptr);
yyjson_mut_val* next = prev->next;
prev->next = next->next;
unsafe_yyjson_set_len(arr, len - 1);
return next;
} else if (len == 1) {
yyjson_mut_val* prev = ((yyjson_mut_val*)arr->uni.ptr);
unsafe_yyjson_set_len(arr, 0);
return prev;
}
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_remove_last(yyjson_mut_val* arr) {
if (yyjson_likely(yyjson_mut_is_arr(arr))) {
size_t len = unsafe_yyjson_get_len(arr);
if (yyjson_likely(len > 1)) {
yyjson_mut_val* prev = ((yyjson_mut_val*)arr->uni.ptr);
yyjson_mut_val* next = prev->next;
unsafe_yyjson_set_len(arr, len - 1);
while (--len > 0)
prev = prev->next;
prev->next = next;
next = (yyjson_mut_val*)arr->uni.ptr;
arr->uni.ptr = prev;
return next;
} else if (len == 1) {
yyjson_mut_val* prev = ((yyjson_mut_val*)arr->uni.ptr);
unsafe_yyjson_set_len(arr, 0);
return prev;
}
}
return NULL;
}
yyjson_api_inline bool yyjson_mut_arr_remove_range(yyjson_mut_val* arr, size_t _idx, size_t _len) {
if (yyjson_likely(yyjson_mut_is_arr(arr))) {
yyjson_mut_val *prev, *next;
bool tail_removed;
size_t len = unsafe_yyjson_get_len(arr);
if (yyjson_unlikely(_idx + _len > len))
return false;
if (yyjson_unlikely(_len == 0))
return true;
unsafe_yyjson_set_len(arr, len - _len);
if (yyjson_unlikely(len == _len))
return true;
tail_removed = (_idx + _len == len);
prev = ((yyjson_mut_val*)arr->uni.ptr);
while (_idx-- > 0)
prev = prev->next;
next = prev->next;
while (_len-- > 0)
next = next->next;
prev->next = next;
if (yyjson_unlikely(tail_removed))
arr->uni.ptr = prev;
return true;
}
return false;
}
yyjson_api_inline bool yyjson_mut_arr_clear(yyjson_mut_val* arr) {
if (yyjson_likely(yyjson_mut_is_arr(arr))) {
unsafe_yyjson_set_len(arr, 0);
return true;
}
return false;
}
yyjson_api_inline bool yyjson_mut_arr_rotate(yyjson_mut_val* arr, size_t idx) {
if (yyjson_likely(yyjson_mut_is_arr(arr) && unsafe_yyjson_get_len(arr) > idx)) {
yyjson_mut_val* val = (yyjson_mut_val*)arr->uni.ptr;
while (idx-- > 0)
val = val->next;
arr->uni.ptr = (void*)val;
return true;
}
return false;
}
yyjson_api_inline bool yyjson_mut_arr_add_val(yyjson_mut_val* arr, yyjson_mut_val* val) {
return yyjson_mut_arr_append(arr, val);
}
yyjson_api_inline bool yyjson_mut_arr_add_null(yyjson_mut_doc* doc, yyjson_mut_val* arr) {
if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
yyjson_mut_val* val = yyjson_mut_null(doc);
return yyjson_mut_arr_append(arr, val);
}
return false;
}
yyjson_api_inline bool yyjson_mut_arr_add_true(yyjson_mut_doc* doc, yyjson_mut_val* arr) {
if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
yyjson_mut_val* val = yyjson_mut_true(doc);
return yyjson_mut_arr_append(arr, val);
}
return false;
}
yyjson_api_inline bool yyjson_mut_arr_add_false(yyjson_mut_doc* doc, yyjson_mut_val* arr) {
if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
yyjson_mut_val* val = yyjson_mut_false(doc);
return yyjson_mut_arr_append(arr, val);
}
return false;
}
yyjson_api_inline bool yyjson_mut_arr_add_bool(yyjson_mut_doc* doc, yyjson_mut_val* arr,
bool _val) {
if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
yyjson_mut_val* val = yyjson_mut_bool(doc, _val);
return yyjson_mut_arr_append(arr, val);
}
return false;
}
yyjson_api_inline bool yyjson_mut_arr_add_uint(yyjson_mut_doc* doc, yyjson_mut_val* arr,
uint64_t num) {
if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
yyjson_mut_val* val = yyjson_mut_uint(doc, num);
return yyjson_mut_arr_append(arr, val);
}
return false;
}
yyjson_api_inline bool yyjson_mut_arr_add_sint(yyjson_mut_doc* doc, yyjson_mut_val* arr,
int64_t num) {
if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
yyjson_mut_val* val = yyjson_mut_sint(doc, num);
return yyjson_mut_arr_append(arr, val);
}
return false;
}
yyjson_api_inline bool yyjson_mut_arr_add_int(yyjson_mut_doc* doc, yyjson_mut_val* arr,
int64_t num) {
if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
yyjson_mut_val* val = yyjson_mut_sint(doc, num);
return yyjson_mut_arr_append(arr, val);
}
return false;
}
yyjson_api_inline bool yyjson_mut_arr_add_real(yyjson_mut_doc* doc, yyjson_mut_val* arr,
double num) {
if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
yyjson_mut_val* val = yyjson_mut_real(doc, num);
return yyjson_mut_arr_append(arr, val);
}
return false;
}
yyjson_api_inline bool yyjson_mut_arr_add_str(yyjson_mut_doc* doc, yyjson_mut_val* arr,
const char* str) {
if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
yyjson_mut_val* val = yyjson_mut_str(doc, str);
return yyjson_mut_arr_append(arr, val);
}
return false;
}
yyjson_api_inline bool yyjson_mut_arr_add_strn(yyjson_mut_doc* doc, yyjson_mut_val* arr,
const char* str, size_t len) {
if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
yyjson_mut_val* val = yyjson_mut_strn(doc, str, len);
return yyjson_mut_arr_append(arr, val);
}
return false;
}
yyjson_api_inline bool yyjson_mut_arr_add_strcpy(yyjson_mut_doc* doc, yyjson_mut_val* arr,
const char* str) {
if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
yyjson_mut_val* val = yyjson_mut_strcpy(doc, str);
return yyjson_mut_arr_append(arr, val);
}
return false;
}
yyjson_api_inline bool yyjson_mut_arr_add_strncpy(yyjson_mut_doc* doc, yyjson_mut_val* arr,
const char* str, size_t len) {
if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
yyjson_mut_val* val = yyjson_mut_strncpy(doc, str, len);
return yyjson_mut_arr_append(arr, val);
}
return false;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_add_arr(yyjson_mut_doc* doc, yyjson_mut_val* arr) {
if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
yyjson_mut_val* val = yyjson_mut_arr(doc);
return yyjson_mut_arr_append(arr, val) ? val : NULL;
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_arr_add_obj(yyjson_mut_doc* doc, yyjson_mut_val* arr) {
if (yyjson_likely(doc && yyjson_mut_is_arr(arr))) {
yyjson_mut_val* val = yyjson_mut_obj(doc);
return yyjson_mut_arr_append(arr, val) ? val : NULL;
}
return NULL;
}
yyjson_api_inline size_t yyjson_mut_obj_size(yyjson_mut_val* obj) {
return yyjson_mut_is_obj(obj) ? unsafe_yyjson_get_len(obj) : 0;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_get(yyjson_mut_val* obj, const char* key) {
return yyjson_mut_obj_getn(obj, key, key ? strlen(key) : 0);
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_getn(yyjson_mut_val* obj, const char* _key,
size_t key_len) {
size_t len = yyjson_mut_obj_size(obj);
if (yyjson_likely(len && _key)) {
yyjson_mut_val* key = ((yyjson_mut_val*)obj->uni.ptr)->next->next;
while (len-- > 0) {
if (unsafe_yyjson_equals_strn(key, _key, key_len))
return key->next;
key = key->next->next;
}
}
return NULL;
}
yyjson_api_inline bool yyjson_mut_obj_iter_init(yyjson_mut_val* obj, yyjson_mut_obj_iter* iter) {
if (yyjson_likely(yyjson_mut_is_obj(obj) && iter)) {
iter->idx = 0;
iter->max = unsafe_yyjson_get_len(obj);
iter->cur = iter->max ? (yyjson_mut_val*)obj->uni.ptr : NULL;
iter->pre = NULL;
iter->obj = obj;
return true;
}
if (iter)
memset(iter, 0, sizeof(yyjson_mut_obj_iter));
return false;
}
yyjson_api_inline yyjson_mut_obj_iter yyjson_mut_obj_iter_with(yyjson_mut_val* obj) {
yyjson_mut_obj_iter iter;
yyjson_mut_obj_iter_init(obj, &iter);
return iter;
}
yyjson_api_inline bool yyjson_mut_obj_iter_has_next(yyjson_mut_obj_iter* iter) {
return iter ? iter->idx < iter->max : false;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_iter_next(yyjson_mut_obj_iter* iter) {
if (iter && iter->idx < iter->max) {
yyjson_mut_val* key = iter->cur;
iter->pre = key;
iter->cur = key->next->next;
iter->idx++;
return iter->cur;
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_iter_get_val(yyjson_mut_val* key) {
return key ? key->next : NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_iter_remove(yyjson_mut_obj_iter* iter) {
if (yyjson_likely(iter && 0 < iter->idx && iter->idx <= iter->max)) {
yyjson_mut_val* prev = iter->pre;
yyjson_mut_val* cur = iter->cur;
yyjson_mut_val* next = cur->next->next;
if (yyjson_unlikely(iter->idx == iter->max))
iter->obj->uni.ptr = prev;
iter->idx--;
iter->max--;
unsafe_yyjson_set_len(iter->obj, iter->max);
prev->next->next = next;
iter->cur = prev;
return cur->next;
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_iter_get(yyjson_mut_obj_iter* iter,
const char* key) {
return yyjson_mut_obj_iter_getn(iter, key, key ? strlen(key) : 0);
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_iter_getn(yyjson_mut_obj_iter* iter,
const char* key, size_t key_len) {
if (iter && key) {
size_t idx = 0;
size_t max = iter->max;
yyjson_mut_val *pre, *cur = iter->cur;
while (idx++ < max) {
pre = cur;
cur = cur->next->next;
if (unsafe_yyjson_equals_strn(cur, key, key_len)) {
iter->idx += idx;
if (iter->idx > max)
iter->idx -= max + 1;
iter->pre = pre;
iter->cur = cur;
return cur->next;
}
}
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj(yyjson_mut_doc* doc) {
if (yyjson_likely(doc)) {
yyjson_mut_val* val = unsafe_yyjson_mut_val(doc, 1);
if (yyjson_likely(val)) {
val->tag = YYJSON_TYPE_OBJ | YYJSON_SUBTYPE_NONE;
return val;
}
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_with_str(yyjson_mut_doc* doc, const char** keys,
const char** vals, size_t count) {
if (yyjson_likely(doc && ((count > 0 && keys && vals) || (count == 0)))) {
yyjson_mut_val* obj = unsafe_yyjson_mut_val(doc, 1 + count * 2);
if (yyjson_likely(obj)) {
obj->tag = ((uint64_t)count << YYJSON_TAG_BIT) | YYJSON_TYPE_OBJ;
if (count > 0) {
size_t i;
for (i = 0; i < count; i++) {
yyjson_mut_val* key = obj + (i * 2 + 1);
yyjson_mut_val* val = obj + (i * 2 + 2);
uint64_t key_len = (uint64_t)strlen(keys[i]);
uint64_t val_len = (uint64_t)strlen(vals[i]);
key->tag = (key_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
val->tag = (val_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
key->uni.str = keys[i];
val->uni.str = vals[i];
key->next = val;
val->next = val + 1;
}
obj[count * 2].next = obj + 1;
obj->uni.ptr = obj + (count * 2 - 1);
}
return obj;
}
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_with_kv(yyjson_mut_doc* doc, const char** pairs,
size_t count) {
if (yyjson_likely(doc && ((count > 0 && pairs) || (count == 0)))) {
yyjson_mut_val* obj = unsafe_yyjson_mut_val(doc, 1 + count * 2);
if (yyjson_likely(obj)) {
obj->tag = ((uint64_t)count << YYJSON_TAG_BIT) | YYJSON_TYPE_OBJ;
if (count > 0) {
size_t i;
for (i = 0; i < count; i++) {
yyjson_mut_val* key = obj + (i * 2 + 1);
yyjson_mut_val* val = obj + (i * 2 + 2);
const char* key_str = pairs[i * 2 + 0];
const char* val_str = pairs[i * 2 + 1];
uint64_t key_len = (uint64_t)strlen(key_str);
uint64_t val_len = (uint64_t)strlen(val_str);
key->tag = (key_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
val->tag = (val_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
key->uni.str = key_str;
val->uni.str = val_str;
key->next = val;
val->next = val + 1;
}
obj[count * 2].next = obj + 1;
obj->uni.ptr = obj + (count * 2 - 1);
}
return obj;
}
}
return NULL;
}
yyjson_api_inline void unsafe_yyjson_mut_obj_add(yyjson_mut_val* obj, yyjson_mut_val* key,
yyjson_mut_val* val, size_t len) {
if (yyjson_likely(len)) {
yyjson_mut_val* prev_val = ((yyjson_mut_val*)obj->uni.ptr)->next;
yyjson_mut_val* next_key = prev_val->next;
prev_val->next = key;
val->next = next_key;
} else {
val->next = key;
}
key->next = val;
obj->uni.ptr = (void*)key;
unsafe_yyjson_set_len(obj, len + 1);
}
yyjson_api_inline yyjson_mut_val* unsafe_yyjson_mut_obj_remove(yyjson_mut_val* obj, const char* key,
size_t key_len) {
size_t obj_len = unsafe_yyjson_get_len(obj);
if (obj_len) {
yyjson_mut_val* pre_key = (yyjson_mut_val*)obj->uni.ptr;
yyjson_mut_val* cur_key = pre_key->next->next;
yyjson_mut_val* removed_item = NULL;
size_t i;
for (i = 0; i < obj_len; i++) {
if (unsafe_yyjson_equals_strn(cur_key, key, key_len)) {
if (!removed_item)
removed_item = cur_key->next;
cur_key = cur_key->next->next;
pre_key->next->next = cur_key;
if (i + 1 == obj_len)
obj->uni.ptr = pre_key;
i--;
obj_len--;
} else {
pre_key = cur_key;
cur_key = cur_key->next->next;
}
}
unsafe_yyjson_set_len(obj, obj_len);
return removed_item;
} else {
return NULL;
}
}
yyjson_api_inline bool unsafe_yyjson_mut_obj_replace(yyjson_mut_val* obj, yyjson_mut_val* key,
yyjson_mut_val* val) {
size_t key_len = unsafe_yyjson_get_len(key);
size_t obj_len = unsafe_yyjson_get_len(obj);
if (obj_len) {
yyjson_mut_val* pre_key = (yyjson_mut_val*)obj->uni.ptr;
yyjson_mut_val* cur_key = pre_key->next->next;
size_t i;
for (i = 0; i < obj_len; i++) {
if (unsafe_yyjson_equals_strn(cur_key, key->uni.str, key_len)) {
cur_key->next->tag = val->tag;
cur_key->next->uni.u64 = val->uni.u64;
return true;
} else {
cur_key = cur_key->next->next;
}
}
}
return false;
}
yyjson_api_inline void unsafe_yyjson_mut_obj_rotate(yyjson_mut_val* obj, size_t idx) {
yyjson_mut_val* key = (yyjson_mut_val*)obj->uni.ptr;
while (idx-- > 0)
key = key->next->next;
obj->uni.ptr = (void*)key;
}
yyjson_api_inline bool yyjson_mut_obj_add(yyjson_mut_val* obj, yyjson_mut_val* key,
yyjson_mut_val* val) {
if (yyjson_likely(yyjson_mut_is_obj(obj) && yyjson_mut_is_str(key) && val)) {
unsafe_yyjson_mut_obj_add(obj, key, val, unsafe_yyjson_get_len(obj));
return true;
}
return false;
}
yyjson_api_inline bool yyjson_mut_obj_put(yyjson_mut_val* obj, yyjson_mut_val* key,
yyjson_mut_val* val) {
bool replaced = false;
size_t key_len;
yyjson_mut_obj_iter iter;
yyjson_mut_val* cur_key;
if (yyjson_unlikely(!yyjson_mut_is_obj(obj) || !yyjson_mut_is_str(key)))
return false;
key_len = unsafe_yyjson_get_len(key);
yyjson_mut_obj_iter_init(obj, &iter);
while ((cur_key = yyjson_mut_obj_iter_next(&iter)) != 0) {
if (unsafe_yyjson_equals_strn(cur_key, key->uni.str, key_len)) {
if (!replaced && val) {
replaced = true;
val->next = cur_key->next->next;
cur_key->next = val;
} else {
yyjson_mut_obj_iter_remove(&iter);
}
}
}
if (!replaced && val)
unsafe_yyjson_mut_obj_add(obj, key, val, iter.max);
return true;
}
yyjson_api_inline bool yyjson_mut_obj_insert(yyjson_mut_val* obj, yyjson_mut_val* key,
yyjson_mut_val* val, size_t idx) {
if (yyjson_likely(yyjson_mut_is_obj(obj) && yyjson_mut_is_str(key) && val)) {
size_t len = unsafe_yyjson_get_len(obj);
if (yyjson_likely(len >= idx)) {
if (len > idx) {
void* ptr = obj->uni.ptr;
unsafe_yyjson_mut_obj_rotate(obj, idx);
unsafe_yyjson_mut_obj_add(obj, key, val, len);
obj->uni.ptr = ptr;
} else {
unsafe_yyjson_mut_obj_add(obj, key, val, len);
}
return true;
}
}
return false;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_remove(yyjson_mut_val* obj, yyjson_mut_val* key) {
if (yyjson_likely(yyjson_mut_is_obj(obj) && yyjson_mut_is_str(key))) {
return unsafe_yyjson_mut_obj_remove(obj, key->uni.str, unsafe_yyjson_get_len(key));
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_remove_key(yyjson_mut_val* obj, const char* key) {
if (yyjson_likely(yyjson_mut_is_obj(obj) && key)) {
size_t key_len = strlen(key);
return unsafe_yyjson_mut_obj_remove(obj, key, key_len);
}
return NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_remove_keyn(yyjson_mut_val* obj, const char* key,
size_t key_len) {
if (yyjson_likely(yyjson_mut_is_obj(obj) && key)) {
return unsafe_yyjson_mut_obj_remove(obj, key, key_len);
}
return NULL;
}
yyjson_api_inline bool yyjson_mut_obj_clear(yyjson_mut_val* obj) {
if (yyjson_likely(yyjson_mut_is_obj(obj))) {
unsafe_yyjson_set_len(obj, 0);
return true;
}
return false;
}
yyjson_api_inline bool yyjson_mut_obj_replace(yyjson_mut_val* obj, yyjson_mut_val* key,
yyjson_mut_val* val) {
if (yyjson_likely(yyjson_mut_is_obj(obj) && yyjson_mut_is_str(key) && val)) {
return unsafe_yyjson_mut_obj_replace(obj, key, val);
}
return false;
}
yyjson_api_inline bool yyjson_mut_obj_rotate(yyjson_mut_val* obj, size_t idx) {
if (yyjson_likely(yyjson_mut_is_obj(obj) && unsafe_yyjson_get_len(obj) > idx)) {
unsafe_yyjson_mut_obj_rotate(obj, idx);
return true;
}
return false;
}
#define yyjson_mut_obj_add_func(func) \
if (yyjson_likely(doc && yyjson_mut_is_obj(obj) && _key)) { \
yyjson_mut_val* key = unsafe_yyjson_mut_val(doc, 2); \
if (yyjson_likely(key)) { \
size_t len = unsafe_yyjson_get_len(obj); \
yyjson_mut_val* val = key + 1; \
size_t key_len = strlen(_key); \
bool noesc = unsafe_yyjson_is_str_noesc(_key, key_len); \
key->tag = YYJSON_TYPE_STR; \
key->tag |= noesc ? YYJSON_SUBTYPE_NOESC : YYJSON_SUBTYPE_NONE; \
key->tag |= (uint64_t)strlen(_key) << YYJSON_TAG_BIT; \
key->uni.str = _key; \
func unsafe_yyjson_mut_obj_add(obj, key, val, len); \
return true; \
} \
} \
return false
yyjson_api_inline bool yyjson_mut_obj_add_null(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* _key) {
yyjson_mut_obj_add_func({ val->tag = YYJSON_TYPE_NULL | YYJSON_SUBTYPE_NONE; });
}
yyjson_api_inline bool yyjson_mut_obj_add_true(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* _key) {
yyjson_mut_obj_add_func({ val->tag = YYJSON_TYPE_BOOL | YYJSON_SUBTYPE_TRUE; });
}
yyjson_api_inline bool yyjson_mut_obj_add_false(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* _key) {
yyjson_mut_obj_add_func({ val->tag = YYJSON_TYPE_BOOL | YYJSON_SUBTYPE_FALSE; });
}
yyjson_api_inline bool yyjson_mut_obj_add_bool(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* _key, bool _val) {
yyjson_mut_obj_add_func({
_val = !!_val;
val->tag = YYJSON_TYPE_BOOL | (uint8_t)((uint8_t)(_val) << 3);
});
}
yyjson_api_inline bool yyjson_mut_obj_add_uint(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* _key, uint64_t _val) {
yyjson_mut_obj_add_func({
val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_UINT;
val->uni.u64 = _val;
});
}
yyjson_api_inline bool yyjson_mut_obj_add_sint(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* _key, int64_t _val) {
yyjson_mut_obj_add_func({
val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT;
val->uni.i64 = _val;
});
}
yyjson_api_inline bool yyjson_mut_obj_add_int(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* _key, int64_t _val) {
yyjson_mut_obj_add_func({
val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_SINT;
val->uni.i64 = _val;
});
}
yyjson_api_inline bool yyjson_mut_obj_add_real(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* _key, double _val) {
yyjson_mut_obj_add_func({
val->tag = YYJSON_TYPE_NUM | YYJSON_SUBTYPE_REAL;
val->uni.f64 = _val;
});
}
yyjson_api_inline bool yyjson_mut_obj_add_str(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* _key, const char* _val) {
if (yyjson_unlikely(!_val))
return false;
yyjson_mut_obj_add_func({
size_t val_len = strlen(_val);
bool val_noesc = unsafe_yyjson_is_str_noesc(_val, val_len);
val->tag = ((uint64_t)strlen(_val) << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
val->tag |= val_noesc ? YYJSON_SUBTYPE_NOESC : YYJSON_SUBTYPE_NONE;
val->uni.str = _val;
});
}
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) {
if (yyjson_unlikely(!_val))
return false;
yyjson_mut_obj_add_func({
val->tag = ((uint64_t)_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
val->uni.str = _val;
});
}
yyjson_api_inline bool yyjson_mut_obj_add_strcpy(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* _key, const char* _val) {
if (yyjson_unlikely(!_val))
return false;
yyjson_mut_obj_add_func({
size_t _len = strlen(_val);
val->uni.str = unsafe_yyjson_mut_strncpy(doc, _val, _len);
if (yyjson_unlikely(!val->uni.str))
return false;
val->tag = ((uint64_t)_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
});
}
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) {
if (yyjson_unlikely(!_val))
return false;
yyjson_mut_obj_add_func({
val->uni.str = unsafe_yyjson_mut_strncpy(doc, _val, _len);
if (yyjson_unlikely(!val->uni.str))
return false;
val->tag = ((uint64_t)_len << YYJSON_TAG_BIT) | YYJSON_TYPE_STR;
});
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_add_arr(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* _key) {
yyjson_mut_val* key = yyjson_mut_str(doc, _key);
yyjson_mut_val* val = yyjson_mut_arr(doc);
return yyjson_mut_obj_add(obj, key, val) ? val : NULL;
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_add_obj(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* _key) {
yyjson_mut_val* key = yyjson_mut_str(doc, _key);
yyjson_mut_val* val = yyjson_mut_obj(doc);
return yyjson_mut_obj_add(obj, key, val) ? val : NULL;
}
yyjson_api_inline bool yyjson_mut_obj_add_val(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* _key, yyjson_mut_val* _val) {
if (yyjson_unlikely(!_val))
return false;
yyjson_mut_obj_add_func({ val = _val; });
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_remove_str(yyjson_mut_val* obj, const char* key) {
return yyjson_mut_obj_remove_strn(obj, key, key ? strlen(key) : 0);
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_obj_remove_strn(yyjson_mut_val* obj, const char* _key,
size_t _len) {
if (yyjson_likely(yyjson_mut_is_obj(obj) && _key)) {
yyjson_mut_val* key;
yyjson_mut_obj_iter iter;
yyjson_mut_val* val_removed = NULL;
yyjson_mut_obj_iter_init(obj, &iter);
while ((key = yyjson_mut_obj_iter_next(&iter)) != NULL) {
if (unsafe_yyjson_equals_strn(key, _key, _len)) {
if (!val_removed)
val_removed = key->next;
yyjson_mut_obj_iter_remove(&iter);
}
}
return val_removed;
}
return NULL;
}
yyjson_api_inline bool yyjson_mut_obj_rename_key(yyjson_mut_doc* doc, yyjson_mut_val* obj,
const char* key, const char* new_key) {
if (!key || !new_key)
return false;
return yyjson_mut_obj_rename_keyn(doc, obj, key, strlen(key), new_key, strlen(new_key));
}
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) {
char* cpy_key = NULL;
yyjson_mut_val* old_key;
yyjson_mut_obj_iter iter;
if (!doc || !obj || !key || !new_key)
return false;
yyjson_mut_obj_iter_init(obj, &iter);
while ((old_key = yyjson_mut_obj_iter_next(&iter))) {
if (unsafe_yyjson_equals_strn((void*)old_key, key, len)) {
if (!cpy_key) {
cpy_key = unsafe_yyjson_mut_strncpy(doc, new_key, new_len);
if (!cpy_key)
return false;
}
yyjson_mut_set_strn(old_key, cpy_key, new_len);
}
}
return cpy_key != NULL;
}
#define yyjson_ptr_set_err(_code, _msg) \
do { \
if (err) { \
err->code = YYJSON_PTR_ERR_##_code; \
err->msg = _msg; \
err->pos = 0; \
} \
} while (false)
yyjson_api yyjson_val* unsafe_yyjson_ptr_getx(yyjson_val* val, const char* ptr, size_t len,
yyjson_ptr_err* err);
yyjson_api yyjson_mut_val* unsafe_yyjson_mut_ptr_getx(yyjson_mut_val* val, const char* ptr,
size_t len, yyjson_ptr_ctx* ctx, yyjson_ptr_err* err);
yyjson_api bool unsafe_yyjson_mut_ptr_putx(yyjson_mut_val* val, const char* ptr, size_t len,
yyjson_mut_val* new_val, yyjson_mut_doc* doc, bool create_parent, bool insert_new,
yyjson_ptr_ctx* ctx, yyjson_ptr_err* err);
yyjson_api yyjson_mut_val* unsafe_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);
yyjson_api yyjson_mut_val* unsafe_yyjson_mut_ptr_removex(yyjson_mut_val* val, const char* ptr,
size_t len, yyjson_ptr_ctx* ctx, yyjson_ptr_err* err);
yyjson_api_inline yyjson_val* yyjson_doc_ptr_get(yyjson_doc* doc, const char* ptr) {
if (yyjson_unlikely(!ptr))
return NULL;
return yyjson_doc_ptr_getn(doc, ptr, strlen(ptr));
}
yyjson_api_inline yyjson_val* yyjson_doc_ptr_getn(yyjson_doc* doc, const char* ptr, size_t len) {
return yyjson_doc_ptr_getx(doc, ptr, len, NULL);
}
yyjson_api_inline yyjson_val* yyjson_doc_ptr_getx(yyjson_doc* doc, const char* ptr, size_t len,
yyjson_ptr_err* err) {
yyjson_ptr_set_err(NONE, NULL);
if (yyjson_unlikely(!doc || !ptr)) {
yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
return NULL;
}
if (yyjson_unlikely(!doc->root)) {
yyjson_ptr_set_err(NULL_ROOT, "document's root is NULL");
return NULL;
}
if (yyjson_unlikely(len == 0)) {
return doc->root;
}
if (yyjson_unlikely(*ptr != '/')) {
yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
return NULL;
}
return unsafe_yyjson_ptr_getx(doc->root, ptr, len, err);
}
yyjson_api_inline yyjson_val* yyjson_ptr_get(yyjson_val* val, const char* ptr) {
if (yyjson_unlikely(!ptr))
return NULL;
return yyjson_ptr_getn(val, ptr, strlen(ptr));
}
yyjson_api_inline yyjson_val* yyjson_ptr_getn(yyjson_val* val, const char* ptr, size_t len) {
return yyjson_ptr_getx(val, ptr, len, NULL);
}
yyjson_api_inline yyjson_val* yyjson_ptr_getx(yyjson_val* val, const char* ptr, size_t len,
yyjson_ptr_err* err) {
yyjson_ptr_set_err(NONE, NULL);
if (yyjson_unlikely(!val || !ptr)) {
yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
return NULL;
}
if (yyjson_unlikely(len == 0)) {
return val;
}
if (yyjson_unlikely(*ptr != '/')) {
yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
return NULL;
}
return unsafe_yyjson_ptr_getx(val, ptr, len, err);
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_doc_ptr_get(yyjson_mut_doc* doc, const char* ptr) {
if (!ptr)
return NULL;
return yyjson_mut_doc_ptr_getn(doc, ptr, strlen(ptr));
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_doc_ptr_getn(yyjson_mut_doc* doc, const char* ptr,
size_t len) {
return yyjson_mut_doc_ptr_getx(doc, ptr, len, NULL, NULL);
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_doc_ptr_getx(yyjson_mut_doc* doc, const char* ptr,
size_t len, yyjson_ptr_ctx* ctx, yyjson_ptr_err* err) {
yyjson_ptr_set_err(NONE, NULL);
if (ctx)
memset(ctx, 0, sizeof(*ctx));
if (yyjson_unlikely(!doc || !ptr)) {
yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
return NULL;
}
if (yyjson_unlikely(!doc->root)) {
yyjson_ptr_set_err(NULL_ROOT, "document's root is NULL");
return NULL;
}
if (yyjson_unlikely(len == 0)) {
return doc->root;
}
if (yyjson_unlikely(*ptr != '/')) {
yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
return NULL;
}
return unsafe_yyjson_mut_ptr_getx(doc->root, ptr, len, ctx, err);
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_ptr_get(yyjson_mut_val* val, const char* ptr) {
if (!ptr)
return NULL;
return yyjson_mut_ptr_getn(val, ptr, strlen(ptr));
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_ptr_getn(yyjson_mut_val* val, const char* ptr,
size_t len) {
return yyjson_mut_ptr_getx(val, ptr, len, NULL, NULL);
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_ptr_getx(yyjson_mut_val* val, const char* ptr,
size_t len, yyjson_ptr_ctx* ctx, yyjson_ptr_err* err) {
yyjson_ptr_set_err(NONE, NULL);
if (ctx)
memset(ctx, 0, sizeof(*ctx));
if (yyjson_unlikely(!val || !ptr)) {
yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
return NULL;
}
if (yyjson_unlikely(len == 0)) {
return val;
}
if (yyjson_unlikely(*ptr != '/')) {
yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
return NULL;
}
return unsafe_yyjson_mut_ptr_getx(val, ptr, len, ctx, err);
}
yyjson_api_inline bool yyjson_mut_doc_ptr_add(yyjson_mut_doc* doc, const char* ptr,
yyjson_mut_val* new_val) {
if (yyjson_unlikely(!ptr))
return false;
return yyjson_mut_doc_ptr_addn(doc, ptr, strlen(ptr), new_val);
}
yyjson_api_inline bool yyjson_mut_doc_ptr_addn(yyjson_mut_doc* doc, const char* ptr, size_t len,
yyjson_mut_val* new_val) {
return yyjson_mut_doc_ptr_addx(doc, ptr, len, new_val, true, NULL, NULL);
}
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) {
yyjson_ptr_set_err(NONE, NULL);
if (ctx)
memset(ctx, 0, sizeof(*ctx));
if (yyjson_unlikely(!doc || !ptr || !new_val)) {
yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
return false;
}
if (yyjson_unlikely(len == 0)) {
if (doc->root) {
yyjson_ptr_set_err(SET_ROOT, "cannot set document's root");
return false;
} else {
doc->root = new_val;
return true;
}
}
if (yyjson_unlikely(*ptr != '/')) {
yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
return false;
}
if (yyjson_unlikely(!doc->root && !create_parent)) {
yyjson_ptr_set_err(NULL_ROOT, "document's root is NULL");
return false;
}
if (yyjson_unlikely(!doc->root)) {
yyjson_mut_val* root = yyjson_mut_obj(doc);
if (yyjson_unlikely(!root)) {
yyjson_ptr_set_err(MEMORY_ALLOCATION, "failed to create value");
return false;
}
if (unsafe_yyjson_mut_ptr_putx(root, ptr, len, new_val, doc, create_parent, true, ctx,
err)) {
doc->root = root;
return true;
}
return false;
}
return unsafe_yyjson_mut_ptr_putx(doc->root, ptr, len, new_val, doc, create_parent, true, ctx,
err);
}
yyjson_api_inline bool yyjson_mut_ptr_add(yyjson_mut_val* val, const char* ptr,
yyjson_mut_val* new_val, yyjson_mut_doc* doc) {
if (yyjson_unlikely(!ptr))
return false;
return yyjson_mut_ptr_addn(val, ptr, strlen(ptr), new_val, doc);
}
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) {
return yyjson_mut_ptr_addx(val, ptr, len, new_val, doc, true, NULL, NULL);
}
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) {
yyjson_ptr_set_err(NONE, NULL);
if (ctx)
memset(ctx, 0, sizeof(*ctx));
if (yyjson_unlikely(!val || !ptr || !new_val || !doc)) {
yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
return false;
}
if (yyjson_unlikely(len == 0)) {
yyjson_ptr_set_err(SET_ROOT, "cannot set root");
return false;
}
if (yyjson_unlikely(*ptr != '/')) {
yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
return false;
}
return unsafe_yyjson_mut_ptr_putx(val, ptr, len, new_val, doc, create_parent, true, ctx, err);
}
yyjson_api_inline bool yyjson_mut_doc_ptr_set(yyjson_mut_doc* doc, const char* ptr,
yyjson_mut_val* new_val) {
if (yyjson_unlikely(!ptr))
return false;
return yyjson_mut_doc_ptr_setn(doc, ptr, strlen(ptr), new_val);
}
yyjson_api_inline bool yyjson_mut_doc_ptr_setn(yyjson_mut_doc* doc, const char* ptr, size_t len,
yyjson_mut_val* new_val) {
return yyjson_mut_doc_ptr_setx(doc, ptr, len, new_val, true, NULL, NULL);
}
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) {
yyjson_ptr_set_err(NONE, NULL);
if (ctx)
memset(ctx, 0, sizeof(*ctx));
if (yyjson_unlikely(!doc || !ptr)) {
yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
return false;
}
if (yyjson_unlikely(len == 0)) {
if (ctx)
ctx->old = doc->root;
doc->root = new_val;
return true;
}
if (yyjson_unlikely(*ptr != '/')) {
yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
return false;
}
if (!new_val) {
if (!doc->root) {
yyjson_ptr_set_err(RESOLVE, "JSON pointer cannot be resolved");
return false;
}
return !!unsafe_yyjson_mut_ptr_removex(doc->root, ptr, len, ctx, err);
}
if (yyjson_unlikely(!doc->root && !create_parent)) {
yyjson_ptr_set_err(NULL_ROOT, "document's root is NULL");
return false;
}
if (yyjson_unlikely(!doc->root)) {
yyjson_mut_val* root = yyjson_mut_obj(doc);
if (yyjson_unlikely(!root)) {
yyjson_ptr_set_err(MEMORY_ALLOCATION, "failed to create value");
return false;
}
if (unsafe_yyjson_mut_ptr_putx(root, ptr, len, new_val, doc, create_parent, false, ctx,
err)) {
doc->root = root;
return true;
}
return false;
}
return unsafe_yyjson_mut_ptr_putx(doc->root, ptr, len, new_val, doc, create_parent, false, ctx,
err);
}
yyjson_api_inline bool yyjson_mut_ptr_set(yyjson_mut_val* val, const char* ptr,
yyjson_mut_val* new_val, yyjson_mut_doc* doc) {
if (yyjson_unlikely(!ptr))
return false;
return yyjson_mut_ptr_setn(val, ptr, strlen(ptr), new_val, doc);
}
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) {
return yyjson_mut_ptr_setx(val, ptr, len, new_val, doc, true, NULL, NULL);
}
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) {
yyjson_ptr_set_err(NONE, NULL);
if (ctx)
memset(ctx, 0, sizeof(*ctx));
if (yyjson_unlikely(!val || !ptr || !doc)) {
yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
return false;
}
if (yyjson_unlikely(len == 0)) {
yyjson_ptr_set_err(SET_ROOT, "cannot set root");
return false;
}
if (yyjson_unlikely(*ptr != '/')) {
yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
return false;
}
if (!new_val) {
return !!unsafe_yyjson_mut_ptr_removex(val, ptr, len, ctx, err);
}
return unsafe_yyjson_mut_ptr_putx(val, ptr, len, new_val, doc, create_parent, false, ctx, err);
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_doc_ptr_replace(yyjson_mut_doc* doc, const char* ptr,
yyjson_mut_val* new_val) {
if (!ptr)
return NULL;
return yyjson_mut_doc_ptr_replacen(doc, ptr, strlen(ptr), new_val);
}
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) {
return yyjson_mut_doc_ptr_replacex(doc, ptr, len, new_val, NULL, NULL);
}
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) {
yyjson_ptr_set_err(NONE, NULL);
if (ctx)
memset(ctx, 0, sizeof(*ctx));
if (yyjson_unlikely(!doc || !ptr || !new_val)) {
yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
return NULL;
}
if (yyjson_unlikely(len == 0)) {
yyjson_mut_val* root = doc->root;
if (yyjson_unlikely(!root)) {
yyjson_ptr_set_err(RESOLVE, "JSON pointer cannot be resolved");
return NULL;
}
if (ctx)
ctx->old = root;
doc->root = new_val;
return root;
}
if (yyjson_unlikely(!doc->root)) {
yyjson_ptr_set_err(NULL_ROOT, "document's root is NULL");
return NULL;
}
if (yyjson_unlikely(*ptr != '/')) {
yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
return NULL;
}
return unsafe_yyjson_mut_ptr_replacex(doc->root, ptr, len, new_val, ctx, err);
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_ptr_replace(yyjson_mut_val* val, const char* ptr,
yyjson_mut_val* new_val) {
if (!ptr)
return NULL;
return yyjson_mut_ptr_replacen(val, ptr, strlen(ptr), new_val);
}
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) {
return yyjson_mut_ptr_replacex(val, ptr, len, new_val, NULL, NULL);
}
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) {
yyjson_ptr_set_err(NONE, NULL);
if (ctx)
memset(ctx, 0, sizeof(*ctx));
if (yyjson_unlikely(!val || !ptr || !new_val)) {
yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
return NULL;
}
if (yyjson_unlikely(len == 0)) {
yyjson_ptr_set_err(SET_ROOT, "cannot set root");
return NULL;
}
if (yyjson_unlikely(*ptr != '/')) {
yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
return NULL;
}
return unsafe_yyjson_mut_ptr_replacex(val, ptr, len, new_val, ctx, err);
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_doc_ptr_remove(yyjson_mut_doc* doc, const char* ptr) {
if (!ptr)
return NULL;
return yyjson_mut_doc_ptr_removen(doc, ptr, strlen(ptr));
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_doc_ptr_removen(yyjson_mut_doc* doc, const char* ptr,
size_t len) {
return yyjson_mut_doc_ptr_removex(doc, ptr, len, NULL, NULL);
}
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) {
yyjson_ptr_set_err(NONE, NULL);
if (ctx)
memset(ctx, 0, sizeof(*ctx));
if (yyjson_unlikely(!doc || !ptr)) {
yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
return NULL;
}
if (yyjson_unlikely(!doc->root)) {
yyjson_ptr_set_err(NULL_ROOT, "document's root is NULL");
return NULL;
}
if (yyjson_unlikely(len == 0)) {
yyjson_mut_val* root = doc->root;
if (ctx)
ctx->old = root;
doc->root = NULL;
return root;
}
if (yyjson_unlikely(*ptr != '/')) {
yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
return NULL;
}
return unsafe_yyjson_mut_ptr_removex(doc->root, ptr, len, ctx, err);
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_ptr_remove(yyjson_mut_val* val, const char* ptr) {
if (!ptr)
return NULL;
return yyjson_mut_ptr_removen(val, ptr, strlen(ptr));
}
yyjson_api_inline yyjson_mut_val* yyjson_mut_ptr_removen(yyjson_mut_val* val, const char* ptr,
size_t len) {
return yyjson_mut_ptr_removex(val, ptr, len, NULL, NULL);
}
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) {
yyjson_ptr_set_err(NONE, NULL);
if (ctx)
memset(ctx, 0, sizeof(*ctx));
if (yyjson_unlikely(!val || !ptr)) {
yyjson_ptr_set_err(PARAMETER, "input parameter is NULL");
return NULL;
}
if (yyjson_unlikely(len == 0)) {
yyjson_ptr_set_err(SET_ROOT, "cannot set root");
return NULL;
}
if (yyjson_unlikely(*ptr != '/')) {
yyjson_ptr_set_err(SYNTAX, "no prefix '/'");
return NULL;
}
return unsafe_yyjson_mut_ptr_removex(val, ptr, len, ctx, err);
}
yyjson_api_inline bool yyjson_ptr_ctx_append(yyjson_ptr_ctx* ctx, yyjson_mut_val* key,
yyjson_mut_val* val) {
yyjson_mut_val *ctn, *pre_key, *pre_val, *cur_key, *cur_val;
if (!ctx || !ctx->ctn || !val)
return false;
ctn = ctx->ctn;
if (yyjson_mut_is_obj(ctn)) {
if (!key)
return false;
key->next = val;
pre_key = ctx->pre;
if (unsafe_yyjson_get_len(ctn) == 0) {
val->next = key;
ctn->uni.ptr = key;
ctx->pre = key;
} else if (!pre_key) {
pre_key = (yyjson_mut_val*)ctn->uni.ptr;
pre_val = pre_key->next;
val->next = pre_val->next;
pre_val->next = key;
ctn->uni.ptr = key;
ctx->pre = pre_key;
} else {
cur_key = pre_key->next->next;
cur_val = cur_key->next;
val->next = cur_val->next;
cur_val->next = key;
if (ctn->uni.ptr == cur_key)
ctn->uni.ptr = key;
ctx->pre = cur_key;
}
} else {
pre_val = ctx->pre;
if (unsafe_yyjson_get_len(ctn) == 0) {
val->next = val;
ctn->uni.ptr = val;
ctx->pre = val;
} else if (!pre_val) {
pre_val = (yyjson_mut_val*)ctn->uni.ptr;
val->next = pre_val->next;
pre_val->next = val;
ctn->uni.ptr = val;
ctx->pre = pre_val;
} else {
cur_val = pre_val->next;
val->next = cur_val->next;
cur_val->next = val;
if (ctn->uni.ptr == cur_val)
ctn->uni.ptr = val;
ctx->pre = cur_val;
}
}
unsafe_yyjson_inc_len(ctn);
return true;
}
yyjson_api_inline bool yyjson_ptr_ctx_replace(yyjson_ptr_ctx* ctx, yyjson_mut_val* val) {
yyjson_mut_val *ctn, *pre_key, *cur_key, *pre_val, *cur_val;
if (!ctx || !ctx->ctn || !ctx->pre || !val)
return false;
ctn = ctx->ctn;
if (yyjson_mut_is_obj(ctn)) {
pre_key = ctx->pre;
pre_val = pre_key->next;
cur_key = pre_val->next;
cur_val = cur_key->next;
cur_key->next = val;
val->next = cur_val->next;
ctx->old = cur_val;
} else {
pre_val = ctx->pre;
cur_val = pre_val->next;
if (pre_val != cur_val) {
val->next = cur_val->next;
pre_val->next = val;
if (ctn->uni.ptr == cur_val)
ctn->uni.ptr = val;
} else {
val->next = val;
ctn->uni.ptr = val;
ctx->pre = val;
}
ctx->old = cur_val;
}
return true;
}
yyjson_api_inline bool yyjson_ptr_ctx_remove(yyjson_ptr_ctx* ctx) {
yyjson_mut_val *ctn, *pre_key, *pre_val, *cur_key, *cur_val;
size_t len;
if (!ctx || !ctx->ctn || !ctx->pre)
return false;
ctn = ctx->ctn;
if (yyjson_mut_is_obj(ctn)) {
pre_key = ctx->pre;
pre_val = pre_key->next;
cur_key = pre_val->next;
cur_val = cur_key->next;
pre_val->next = cur_val->next;
if (ctn->uni.ptr == cur_key)
ctn->uni.ptr = pre_key;
ctx->pre = NULL;
ctx->old = cur_val;
} else {
pre_val = ctx->pre;
cur_val = pre_val->next;
pre_val->next = cur_val->next;
if (ctn->uni.ptr == cur_val)
ctn->uni.ptr = pre_val;
ctx->pre = NULL;
ctx->old = cur_val;
}
len = unsafe_yyjson_get_len(ctn) - 1;
if (len == 0)
ctn->uni.ptr = NULL;
unsafe_yyjson_set_len(ctn, len);
return true;
}
#undef yyjson_ptr_set_err
yyjson_api_inline bool yyjson_ptr_get_bool(yyjson_val* root, const char* ptr, bool* value) {
yyjson_val* val = yyjson_ptr_get(root, ptr);
if (value && yyjson_is_bool(val)) {
*value = unsafe_yyjson_get_bool(val);
return true;
} else {
return false;
}
}
yyjson_api_inline bool yyjson_ptr_get_uint(yyjson_val* root, const char* ptr, uint64_t* value) {
yyjson_val* val = yyjson_ptr_get(root, ptr);
if (value && val) {
uint64_t ret = val->uni.u64;
if (unsafe_yyjson_is_uint(val) || (unsafe_yyjson_is_sint(val) && !(ret >> 63))) {
*value = ret;
return true;
}
}
return false;
}
yyjson_api_inline bool yyjson_ptr_get_sint(yyjson_val* root, const char* ptr, int64_t* value) {
yyjson_val* val = yyjson_ptr_get(root, ptr);
if (value && val) {
int64_t ret = val->uni.i64;
if (unsafe_yyjson_is_sint(val) || (unsafe_yyjson_is_uint(val) && ret >= 0)) {
*value = ret;
return true;
}
}
return false;
}
yyjson_api_inline bool yyjson_ptr_get_real(yyjson_val* root, const char* ptr, double* value) {
yyjson_val* val = yyjson_ptr_get(root, ptr);
if (value && yyjson_is_real(val)) {
*value = unsafe_yyjson_get_real(val);
return true;
} else {
return false;
}
}
yyjson_api_inline bool yyjson_ptr_get_num(yyjson_val* root, const char* ptr, double* value) {
yyjson_val* val = yyjson_ptr_get(root, ptr);
if (value && yyjson_is_num(val)) {
*value = unsafe_yyjson_get_num(val);
return true;
} else {
return false;
}
}
yyjson_api_inline bool yyjson_ptr_get_str(yyjson_val* root, const char* ptr, const char** value) {
yyjson_val* val = yyjson_ptr_get(root, ptr);
if (value && yyjson_is_str(val)) {
*value = unsafe_yyjson_get_str(val);
return true;
} else {
return false;
}
}
yyjson_deprecated("renamed to yyjson_doc_ptr_get")
yyjson_api_inline yyjson_val* yyjson_doc_get_pointer(yyjson_doc* doc, const char* ptr) {
return yyjson_doc_ptr_get(doc, ptr);
}
yyjson_deprecated("renamed to yyjson_doc_ptr_getn") yyjson_api_inline
yyjson_val* yyjson_doc_get_pointern(yyjson_doc* doc, const char* ptr, size_t len) {
return yyjson_doc_ptr_getn(doc, ptr, len);
}
yyjson_deprecated("renamed to yyjson_mut_doc_ptr_get") yyjson_api_inline
yyjson_mut_val* yyjson_mut_doc_get_pointer(yyjson_mut_doc* doc, const char* ptr) {
return yyjson_mut_doc_ptr_get(doc, ptr);
}
yyjson_deprecated("renamed to yyjson_mut_doc_ptr_getn") yyjson_api_inline
yyjson_mut_val* yyjson_mut_doc_get_pointern(yyjson_mut_doc* doc, const char* ptr, size_t len) {
return yyjson_mut_doc_ptr_getn(doc, ptr, len);
}
yyjson_deprecated("renamed to yyjson_ptr_get") yyjson_api_inline yyjson_val* yyjson_get_pointer(
yyjson_val* val, const char* ptr) {
return yyjson_ptr_get(val, ptr);
}
yyjson_deprecated("renamed to yyjson_ptr_getn") yyjson_api_inline yyjson_val* yyjson_get_pointern(
yyjson_val* val, const char* ptr, size_t len) {
return yyjson_ptr_getn(val, ptr, len);
}
yyjson_deprecated("renamed to yyjson_mut_ptr_get")
yyjson_api_inline yyjson_mut_val* yyjson_mut_get_pointer(yyjson_mut_val* val, const char* ptr) {
return yyjson_mut_ptr_get(val, ptr);
}
yyjson_deprecated("renamed to yyjson_mut_ptr_getn") yyjson_api_inline
yyjson_mut_val* yyjson_mut_get_pointern(yyjson_mut_val* val, const char* ptr, size_t len) {
return yyjson_mut_ptr_getn(val, ptr, len);
}
yyjson_deprecated("renamed to unsafe_yyjson_ptr_getn") yyjson_api_inline
yyjson_val* unsafe_yyjson_get_pointer(yyjson_val* val, const char* ptr, size_t len) {
yyjson_ptr_err err;
return unsafe_yyjson_ptr_getx(val, ptr, len, &err);
}
yyjson_deprecated("renamed to unsafe_yyjson_mut_ptr_getx")
yyjson_api_inline yyjson_mut_val* unsafe_yyjson_mut_get_pointer(yyjson_mut_val* val,
const char* ptr, size_t len) {
yyjson_ptr_err err;
return unsafe_yyjson_mut_ptr_getx(val, ptr, len, NULL, &err);
}
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif
#elif defined(_MSC_VER)
#pragma warning(pop)
#endif
#ifdef __cplusplus
}
#endif
#endif