Deps: update yyjson

This commit is contained in:
李通洲
2023-09-13 09:41:57 +08:00
parent 9b72971dc9
commit c400261a11
4 changed files with 298 additions and 84 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"home": "https://github.com/ibireme/yyjson",
"license": "MIT ( embed in source )",
"version": "5e3b26d2659287d31e2f8e10f95f95feb7e5ab3a",
"version": "d50c9564b6cb22e0b24751941abcd36ad254cff8",
"author": "ibireme"
}
+215 -49
View File
@@ -307,6 +307,9 @@ uint32_t yyjson_version(void) {
#define YYJSON_MUT_DOC_VAL_POOL_INIT_SIZE (0x10 * sizeof(yyjson_mut_val))
#define YYJSON_MUT_DOC_VAL_POOL_MAX_SIZE (0x1000000 * sizeof(yyjson_mut_val))
/* The minimum size of the dynamic allocator's chunk. */
#define YYJSON_ALC_DYN_MIN_SIZE 0x1000
/* Default value for compile-time options. */
#ifndef YYJSON_DISABLE_READER
#define YYJSON_DISABLE_READER 0
@@ -966,6 +969,15 @@ static const yyjson_alc YYJSON_DEFAULT_ALC = {
NULL
};
/*==============================================================================
* Null Memory Allocator
*
* This allocator is just a placeholder to ensure that the internal
* malloc/realloc/free function pointers are not null.
*============================================================================*/
static void *null_malloc(void *ctx, usize size) {
return NULL;
}
@@ -989,29 +1001,37 @@ static const yyjson_alc YYJSON_NULL_ALC = {
/*==============================================================================
* Pool Memory Allocator
* This is a simple memory allocator that uses linked list memory chunk.
* The following code will be executed only when the library user creates
* this allocator manually.
*
* This allocator is initialized with a fixed-size buffer.
* The buffer is split into multiple memory chunks for memory allocation.
*============================================================================*/
/** chunk header */
/** memory chunk header */
typedef struct pool_chunk {
usize size; /* chunk memory size (include chunk header) */
struct pool_chunk *next;
usize size; /* chunk memory size, include chunk header */
struct pool_chunk *next; /* linked list, nullable */
/* char mem[]; flexible array member */
} pool_chunk;
/** ctx header */
/** allocator ctx header */
typedef struct pool_ctx {
usize size; /* total memory size (include ctx header) */
pool_chunk *free_list;
usize size; /* total memory size, include ctx header */
pool_chunk *free_list; /* linked list, nullable */
/* pool_chunk chunks[]; flexible array member */
} pool_ctx;
/** align up the input size to chunk size */
static_inline void pool_size_align(usize *size) {
*size = size_align_up(*size, sizeof(pool_chunk)) + sizeof(pool_chunk);
}
static void *pool_malloc(void *ctx_ptr, usize size) {
/* assert(size != 0) */
pool_ctx *ctx = (pool_ctx *)ctx_ptr;
pool_chunk *next, *prev = NULL, *cur = ctx->free_list;
if (unlikely(size == 0 || size >= ctx->size)) return NULL;
size = size_align_up(size, sizeof(pool_chunk)) + sizeof(pool_chunk);
if (unlikely(size >= ctx->size)) return NULL;
pool_size_align(&size);
while (cur) {
if (cur->size < size) {
@@ -1038,6 +1058,7 @@ static void *pool_malloc(void *ctx_ptr, usize size) {
}
static void pool_free(void *ctx_ptr, void *ptr) {
/* assert(ptr != NULL) */
pool_ctx *ctx = (pool_ctx *)ctx_ptr;
pool_chunk *cur = ((pool_chunk *)ptr) - 1;
pool_chunk *prev = NULL, *next = ctx->free_list;
@@ -1064,25 +1085,15 @@ static void pool_free(void *ctx_ptr, void *ptr) {
static void *pool_realloc(void *ctx_ptr, void *ptr,
usize old_size, usize size) {
/* assert(ptr != NULL && size != 0 && old_size < size) */
pool_ctx *ctx = (pool_ctx *)ctx_ptr;
pool_chunk *cur = ((pool_chunk *)ptr) - 1, *prev, *next, *tmp;
usize free_size;
void *new_ptr;
if (unlikely(size == 0 || size >= ctx->size)) return NULL;
size = size_align_up(size, sizeof(pool_chunk)) + sizeof(pool_chunk);
/* reduce size */
if (unlikely(size <= cur->size)) {
free_size = cur->size - size;
if (free_size >= sizeof(pool_chunk) * 2) {
tmp = (pool_chunk *)(void *)((u8 *)cur + cur->size - free_size);
tmp->size = free_size;
pool_free(ctx_ptr, (void *)(tmp + 1));
cur->size -= free_size;
}
return ptr;
}
/* check size */
if (unlikely(size >= ctx->size)) return NULL;
pool_size_align(&old_size);
pool_size_align(&size);
if (unlikely(old_size == size)) return ptr;
/* find next and prev chunk */
prev = NULL;
@@ -1092,10 +1103,9 @@ static void *pool_realloc(void *ctx_ptr, void *ptr,
next = next->next;
}
/* merge to higher chunk if they are contiguous */
if ((u8 *)cur + cur->size == (u8 *)next &&
cur->size + next->size >= size) {
free_size = cur->size + next->size - size;
if ((u8 *)cur + cur->size == (u8 *)next && cur->size + next->size >= size) {
/* merge to higher chunk if they are contiguous */
usize free_size = cur->size + next->size - size;
if (free_size > sizeof(pool_chunk) * 2) {
tmp = (pool_chunk *)(void *)((u8 *)cur + size);
if (prev) prev->next = tmp;
@@ -1109,15 +1119,15 @@ static void *pool_realloc(void *ctx_ptr, void *ptr,
cur->size += next->size;
}
return ptr;
} else {
/* fallback to malloc and memcpy */
void *new_ptr = pool_malloc(ctx_ptr, size - sizeof(pool_chunk));
if (new_ptr) {
memcpy(new_ptr, ptr, cur->size - sizeof(pool_chunk));
pool_free(ctx_ptr, ptr);
}
return new_ptr;
}
/* fallback to malloc and memcpy */
new_ptr = pool_malloc(ctx_ptr, size - sizeof(pool_chunk));
if (new_ptr) {
memcpy(new_ptr, ptr, cur->size - sizeof(pool_chunk));
pool_free(ctx_ptr, ptr);
}
return new_ptr;
}
bool yyjson_alc_pool_init(yyjson_alc *alc, void *buf, usize size) {
@@ -1147,6 +1157,161 @@ bool yyjson_alc_pool_init(yyjson_alc *alc, void *buf, usize size) {
/*==============================================================================
* Dynamic Memory Allocator
*
* This allocator allocates memory on demand and does not immediately release
* unused memory. Instead, it places the unused memory into a freelist for
* potential reuse in the future. It is only when the entire allocator is
* destroyed that all previously allocated memory is released at once.
*============================================================================*/
/** memory chunk header */
typedef struct dyn_chunk {
usize size; /* chunk size, include header */
struct dyn_chunk *next;
/* char mem[]; flexible array member */
} dyn_chunk;
/** allocator ctx header */
typedef struct {
dyn_chunk free_list; /* dummy header, sorted from small to large */
dyn_chunk used_list; /* dummy header */
} dyn_ctx;
/** align up the input size to chunk size */
static_inline bool dyn_size_align(usize *size) {
usize alc_size = *size + sizeof(dyn_chunk);
alc_size = size_align_up(alc_size, YYJSON_ALC_DYN_MIN_SIZE);
if (unlikely(alc_size < *size)) return false; /* overflow */
*size = alc_size;
return true;
}
/** remove a chunk from list (the chunk must already be in the list) */
static_inline void dyn_chunk_list_remove(dyn_chunk *list, dyn_chunk *chunk) {
dyn_chunk *prev = list, *cur;
for (cur = prev->next; cur; cur = cur->next) {
if (cur == chunk) {
prev->next = cur->next;
cur->next = NULL;
return;
}
prev = cur;
}
}
/** add a chunk to list header (the chunk must not be in the list) */
static_inline void dyn_chunk_list_add(dyn_chunk *list, dyn_chunk *chunk) {
chunk->next = list->next;
list->next = chunk;
}
static void *dyn_malloc(void *ctx_ptr, usize size) {
/* assert(size != 0) */
const yyjson_alc def = YYJSON_DEFAULT_ALC;
dyn_ctx *ctx = (dyn_ctx *)ctx_ptr;
dyn_chunk *chunk, *prev, *next;
if (unlikely(!dyn_size_align(&size))) return NULL;
/* freelist is empty, create new chunk */
if (!ctx->free_list.next) {
chunk = (dyn_chunk *)def.malloc(def.ctx, size);
if (unlikely(!chunk)) return NULL;
chunk->size = size;
chunk->next = NULL;
dyn_chunk_list_add(&ctx->used_list, chunk);
return (void *)(chunk + 1);
}
/* find a large enough chunk, or resize the largest chunk */
prev = &ctx->free_list;
while (true) {
chunk = prev->next;
if (chunk->size >= size) { /* enough size, reuse this chunk */
prev->next = chunk->next;
dyn_chunk_list_add(&ctx->used_list, chunk);
return (void *)(chunk + 1);
}
if (!chunk->next) { /* resize the largest chunk */
chunk = (dyn_chunk *)def.realloc(def.ctx, chunk, chunk->size, size);
if (unlikely(!chunk)) return NULL;
prev->next = NULL;
chunk->size = size;
dyn_chunk_list_add(&ctx->used_list, chunk);
return (void *)(chunk + 1);
}
prev = chunk;
}
}
static void *dyn_realloc(void *ctx_ptr, void *ptr,
usize old_size, usize size) {
/* assert(ptr != NULL && size != 0 && old_size < size) */
const yyjson_alc def = YYJSON_DEFAULT_ALC;
dyn_ctx *ctx = (dyn_ctx *)ctx_ptr;
dyn_chunk *prev, *next, *new_chunk;
dyn_chunk *chunk = (dyn_chunk *)ptr - 1;
if (unlikely(!dyn_size_align(&size))) return NULL;
if (chunk->size >= size) return ptr;
dyn_chunk_list_remove(&ctx->used_list, chunk);
new_chunk = (dyn_chunk *)def.realloc(def.ctx, chunk, chunk->size, size);
if (likely(new_chunk)) {
new_chunk->size = size;
chunk = new_chunk;
}
dyn_chunk_list_add(&ctx->used_list, chunk);
return new_chunk ? (void *)(new_chunk + 1) : NULL;
}
static void dyn_free(void *ctx_ptr, void *ptr) {
/* assert(ptr != NULL) */
dyn_ctx *ctx = (dyn_ctx *)ctx_ptr;
dyn_chunk *chunk = (dyn_chunk *)ptr - 1, *prev;
dyn_chunk_list_remove(&ctx->used_list, chunk);
for (prev = &ctx->free_list; prev; prev = prev->next) {
if (!prev->next || prev->next->size >= chunk->size) {
chunk->next = prev->next;
prev->next = chunk;
break;
}
}
}
yyjson_alc *yyjson_alc_dyn_new(void) {
const yyjson_alc def = YYJSON_DEFAULT_ALC;
usize hdr_len = sizeof(yyjson_alc) + sizeof(dyn_ctx);
yyjson_alc *alc = (yyjson_alc *)def.malloc(def.ctx, hdr_len);
dyn_ctx *ctx = (dyn_ctx *)(void *)(alc + 1);
if (unlikely(!alc)) return NULL;
alc->malloc = dyn_malloc;
alc->realloc = dyn_realloc;
alc->free = dyn_free;
alc->ctx = alc + 1;
memset(ctx, 0, sizeof(*ctx));
return alc;
}
void yyjson_alc_dyn_free(yyjson_alc *alc) {
const yyjson_alc def = YYJSON_DEFAULT_ALC;
dyn_ctx *ctx = (dyn_ctx *)(void *)(alc + 1);
dyn_chunk *chunk, *next;
if (unlikely(!alc)) return;
for (chunk = ctx->free_list.next; chunk; chunk = next) {
next = chunk->next;
def.free(def.ctx, chunk);
}
for (chunk = ctx->used_list.next; chunk; chunk = next) {
next = chunk->next;
def.free(def.ctx, chunk);
}
def.free(def.ctx, alc);
}
/*==============================================================================
* JSON document and value
*============================================================================*/
@@ -1305,7 +1470,6 @@ yyjson_mut_val *yyjson_val_mut_copy(yyjson_mut_doc *m_doc,
We copy them to another contiguous memory as mutable values,
then reconnect the mutable values with the original relationship.
*/
usize i_vals_len;
yyjson_mut_val *m_vals, *m_val;
yyjson_val *i_val, *i_end;
@@ -1375,7 +1539,6 @@ static yyjson_mut_val *unsafe_yyjson_mut_val_mut_copy(yyjson_mut_doc *m_doc,
second to last item, which needs to be linked to the last item to close the
circle.
*/
yyjson_mut_val *m_val = unsafe_yyjson_mut_val(m_doc, 1);
if (unlikely(!m_val)) return NULL;
m_val->tag = m_vals->tag;
@@ -1540,12 +1703,13 @@ static_inline bool unsafe_yyjson_num_equals(void *lhs, void *rhs) {
yyjson_val_uni *runi = &((yyjson_val *)rhs)->uni;
yyjson_subtype lt = unsafe_yyjson_get_subtype(lhs);
yyjson_subtype rt = unsafe_yyjson_get_subtype(rhs);
if (lt == rt)
return luni->u64 == runi->u64;
if (lt == YYJSON_SUBTYPE_SINT && rt == YYJSON_SUBTYPE_UINT)
if (lt == rt) return luni->u64 == runi->u64;
if (lt == YYJSON_SUBTYPE_SINT && rt == YYJSON_SUBTYPE_UINT) {
return luni->i64 >= 0 && luni->u64 == runi->u64;
if (lt == YYJSON_SUBTYPE_UINT && rt == YYJSON_SUBTYPE_SINT)
}
if (lt == YYJSON_SUBTYPE_UINT && rt == YYJSON_SUBTYPE_SINT) {
return runi->i64 >= 0 && luni->u64 == runi->u64;
}
return false;
}
@@ -1571,8 +1735,8 @@ bool unsafe_yyjson_equals(yyjson_val *lhs, yyjson_val *rhs) {
while (len-- > 0) {
rhs = yyjson_obj_iter_getn(&iter, lhs->uni.str,
unsafe_yyjson_get_len(lhs));
if (!rhs || !unsafe_yyjson_equals(lhs + 1, rhs))
return false;
if (!rhs) return false;
if (!unsafe_yyjson_equals(lhs + 1, rhs)) return false;
lhs = unsafe_yyjson_get_next(lhs + 1);
}
}
@@ -1626,8 +1790,8 @@ bool unsafe_yyjson_mut_equals(yyjson_mut_val *lhs, yyjson_mut_val *rhs) {
while (len-- > 0) {
rhs = yyjson_mut_obj_iter_getn(&iter, lhs->uni.str,
unsafe_yyjson_get_len(lhs));
if (!rhs || !unsafe_yyjson_mut_equals(lhs->next, rhs))
return false;
if (!rhs) return false;
if (!unsafe_yyjson_mut_equals(lhs->next, rhs)) return false;
lhs = lhs->next->next;
}
}
@@ -2506,6 +2670,7 @@ yyjson_mut_val *yyjson_merge_patch(yyjson_mut_doc *doc,
builder = yyjson_mut_obj(doc);
if (unlikely(!builder)) return NULL;
memset(&local_orig, 0, sizeof(local_orig));
if (!yyjson_is_obj(orig)) {
orig = &local_orig;
orig->tag = builder->tag;
@@ -2557,6 +2722,7 @@ yyjson_mut_val *yyjson_mut_merge_patch(yyjson_mut_doc *doc,
builder = yyjson_mut_obj(doc);
if (unlikely(!builder)) return NULL;
memset(&local_orig, 0, sizeof(local_orig));
if (!yyjson_mut_is_obj(orig)) {
orig = &local_orig;
orig->tag = builder->tag;
+82 -18
View File
@@ -635,11 +635,11 @@ typedef struct yyjson_alc {
function, but the amount of memory required to write a JSON cannot be directly
calculated.
This is not a general-purpose allocator. If used to read multiple JSON
documents and only some of them are released, it may cause memory
fragmentation, leading to performance degradation and memory waste. Therefore,
it is recommended to use this allocator only for reading or writing a single
JSON document.
This is not a general-purpose allocator. It is designed to handle a single JSON
data at a time. If it is used for overly complex memory tasks, such as parsing
multiple JSON documents using the same allocator but releasing only a few of
them, it may cause memory fragmentation, resulting in performance degradation
and memory waste.
@param alc The allocator to be initialized.
If this parameter is NULL, the function will fail and return false.
@@ -662,9 +662,31 @@ typedef struct yyjson_alc {
yyjson_doc *doc = yyjson_read_opts(json, strlen(json), 0, &alc, NULL);
// the memory of `doc` is on the stack
@endcode
@warning This Allocator is not thread-safe.
*/
yyjson_api bool yyjson_alc_pool_init(yyjson_alc *alc, void *buf, size_t size);
/**
A dynamic allocator.
This allocator has a similar usage to the pool allocator above. However, when
there is not enough memory, this allocator will dynamically request more memory
using libc's `malloc` function, and frees it all at once when it is destroyed.
@return A new dynamic allocator, or NULL if memory allocation failed.
@note The returned value should be freed with `yyjson_alc_dyn_free()`.
@warning This Allocator is not thread-safe.
*/
yyjson_api yyjson_alc *yyjson_alc_dyn_new(void);
/**
Free a dynamic allocator which is created by `yyjson_alc_dyn_new()`.
@param alc The dynamic allocator to be destroyed.
*/
yyjson_api void yyjson_alc_dyn_free(yyjson_alc *alc);
/*==============================================================================
@@ -3556,7 +3578,7 @@ yyjson_api_inline bool yyjson_mut_obj_rotate(yyjson_mut_val *obj,
The `key` should be a null-terminated UTF-8 string.
This function allows duplicated key in one object.
@warning The key string are not copied, you should keep the string
@warning The key string is not copied, you should keep the string
unmodified for the lifetime of this JSON document. */
yyjson_api_inline bool yyjson_mut_obj_add_null(yyjson_mut_doc *doc,
yyjson_mut_val *obj,
@@ -3566,7 +3588,7 @@ yyjson_api_inline bool yyjson_mut_obj_add_null(yyjson_mut_doc *doc,
The `key` should be a null-terminated UTF-8 string.
This function allows duplicated key in one object.
@warning The key string are not copied, you should keep the string
@warning The key string is not copied, you should keep the string
unmodified for the lifetime of this JSON document. */
yyjson_api_inline bool yyjson_mut_obj_add_true(yyjson_mut_doc *doc,
yyjson_mut_val *obj,
@@ -3576,7 +3598,7 @@ yyjson_api_inline bool yyjson_mut_obj_add_true(yyjson_mut_doc *doc,
The `key` should be a null-terminated UTF-8 string.
This function allows duplicated key in one object.
@warning The key string are not copied, you should keep the string
@warning The key string is not copied, you should keep the string
unmodified for the lifetime of this JSON document. */
yyjson_api_inline bool yyjson_mut_obj_add_false(yyjson_mut_doc *doc,
yyjson_mut_val *obj,
@@ -3586,7 +3608,7 @@ yyjson_api_inline bool yyjson_mut_obj_add_false(yyjson_mut_doc *doc,
The `key` should be a null-terminated UTF-8 string.
This function allows duplicated key in one object.
@warning The key string are not copied, you should keep the string
@warning The key string is not copied, you should keep the string
unmodified for the lifetime of this JSON document. */
yyjson_api_inline bool yyjson_mut_obj_add_bool(yyjson_mut_doc *doc,
yyjson_mut_val *obj,
@@ -3596,7 +3618,7 @@ yyjson_api_inline bool yyjson_mut_obj_add_bool(yyjson_mut_doc *doc,
The `key` should be a null-terminated UTF-8 string.
This function allows duplicated key in one object.
@warning The key string are not copied, you should keep the string
@warning The key string is not copied, you should keep the string
unmodified for the lifetime of this JSON document. */
yyjson_api_inline bool yyjson_mut_obj_add_uint(yyjson_mut_doc *doc,
yyjson_mut_val *obj,
@@ -3606,7 +3628,7 @@ yyjson_api_inline bool yyjson_mut_obj_add_uint(yyjson_mut_doc *doc,
The `key` should be a null-terminated UTF-8 string.
This function allows duplicated key in one object.
@warning The key string are not copied, you should keep the string
@warning The key string is not copied, you should keep the string
unmodified for the lifetime of this JSON document. */
yyjson_api_inline bool yyjson_mut_obj_add_sint(yyjson_mut_doc *doc,
yyjson_mut_val *obj,
@@ -3616,7 +3638,7 @@ yyjson_api_inline bool yyjson_mut_obj_add_sint(yyjson_mut_doc *doc,
The `key` should be a null-terminated UTF-8 string.
This function allows duplicated key in one object.
@warning The key string are not copied, you should keep the string
@warning The key string is not copied, you should keep the string
unmodified for the lifetime of this JSON document. */
yyjson_api_inline bool yyjson_mut_obj_add_int(yyjson_mut_doc *doc,
yyjson_mut_val *obj,
@@ -3626,7 +3648,7 @@ yyjson_api_inline bool yyjson_mut_obj_add_int(yyjson_mut_doc *doc,
The `key` should be a null-terminated UTF-8 string.
This function allows duplicated key in one object.
@warning The key string are not copied, you should keep the string
@warning The key string is not copied, you should keep the string
unmodified for the lifetime of this JSON document. */
yyjson_api_inline bool yyjson_mut_obj_add_real(yyjson_mut_doc *doc,
yyjson_mut_val *obj,
@@ -3636,7 +3658,7 @@ yyjson_api_inline bool yyjson_mut_obj_add_real(yyjson_mut_doc *doc,
The `key` and `val` should be null-terminated UTF-8 strings.
This function allows duplicated key in one object.
@warning The key/value string are not copied, you should keep these strings
@warning The key/value strings are not copied, you should keep these strings
unmodified for the lifetime of this JSON document. */
yyjson_api_inline bool yyjson_mut_obj_add_str(yyjson_mut_doc *doc,
yyjson_mut_val *obj,
@@ -3648,7 +3670,7 @@ yyjson_api_inline bool yyjson_mut_obj_add_str(yyjson_mut_doc *doc,
The `len` should be the length of the `val`, in bytes.
This function allows duplicated key in one object.
@warning The key/value string are not copied, you should keep these strings
@warning The key/value strings are not copied, you should keep these strings
unmodified for the lifetime of this JSON document. */
yyjson_api_inline bool yyjson_mut_obj_add_strn(yyjson_mut_doc *doc,
yyjson_mut_val *obj,
@@ -3660,7 +3682,7 @@ yyjson_api_inline bool yyjson_mut_obj_add_strn(yyjson_mut_doc *doc,
The value string is copied.
This function allows duplicated key in one object.
@warning The key string are not copied, you should keep the string
@warning The key string is not copied, you should keep the string
unmodified for the lifetime of this JSON document. */
yyjson_api_inline bool yyjson_mut_obj_add_strcpy(yyjson_mut_doc *doc,
yyjson_mut_val *obj,
@@ -3673,18 +3695,44 @@ yyjson_api_inline bool yyjson_mut_obj_add_strcpy(yyjson_mut_doc *doc,
The `len` should be the length of the `val`, in bytes.
This function allows duplicated key in one object.
@warning The key/value string are not copied, you should keep these strings
@warning The key/value strings are not copied, you should keep these strings
unmodified for the lifetime of this JSON document. */
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);
/**
Creates and adds a new array to the target object.
The `key` should be a null-terminated UTF-8 string.
This function allows duplicated key in one object.
@warning The key string is not copied, you should keep these strings
unmodified for the lifetime of this JSON document.
@return The new array, or NULL on error.
*/
yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_add_arr(yyjson_mut_doc *doc,
yyjson_mut_val *obj,
const char *key);
/**
Creates and adds a new object to the target object.
The `key` should be a null-terminated UTF-8 string.
This function allows duplicated key in one object.
@warning The key string is not copied, you should keep these strings
unmodified for the lifetime of this JSON document.
@return The new object, or NULL on error.
*/
yyjson_api_inline yyjson_mut_val *yyjson_mut_obj_add_obj(yyjson_mut_doc *doc,
yyjson_mut_val *obj,
const char *key);
/** Adds a JSON value at the end of the object.
The `key` should be a null-terminated UTF-8 string.
This function allows duplicated key in one object.
@warning The key string are not copied, you should keep the string
@warning The key string is not copied, you should keep the string
unmodified for the lifetime of this JSON document. */
yyjson_api_inline bool yyjson_mut_obj_add_val(yyjson_mut_doc *doc,
yyjson_mut_val *obj,
@@ -6920,6 +6968,22 @@ yyjson_api_inline bool yyjson_mut_obj_add_strncpy(yyjson_mut_doc *doc,
});
}
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,
-16
View File
@@ -21,19 +21,3 @@ yyjson_api_inline bool yyjson_mut_arr_add_strbuf(yyjson_mut_doc *doc,
const FFstrbuf* buf) {
return yyjson_mut_arr_add_strncpy(doc, obj, buf->chars, buf->length);
}
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* newObj = yyjson_mut_obj(doc);
yyjson_mut_obj_add_val(doc, obj, _key, newObj);
return newObj;
}
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* newArr = yyjson_mut_arr(doc);
yyjson_mut_obj_add_val(doc, obj, _key, newArr);
return newArr;
}