本文へ移動
cccskills
無料GitHub で公開

yyjson

High-performance C JSON parsing, creation, and modification with yyjson.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md8.2 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

yyjson Usage Guide

Single-header ANSI C (yyjson.h + yyjson.c). Two data models: immutable (yyjson_doc/yyjson_val) and mutable (yyjson_mut_doc/yyjson_mut_val). Free the doc to free all values. Arrays/objects are linked lists; index/key lookup is O(n) — prefer iterators.

Project Notes

  • The bundled copy is in src/ext/yyjson (currently 0.12.0). The build option lc_yyjson_use_xrepo switches to the xmake-repo package.
  • Luisa code commonly supplies a custom yyjson_alc that forwards to luisa::detail::allocator_allocate/reallocate/deallocate with 16-byte alignment.
  • yyjson_write() / yyjson_mut_write() / yyjson_val_write() allocate their output string with the default allocator. Use the _opts variants and pass an allocator if the output must use the same allocator as the document.
  • The bundled target compiles yyjson.c with /utf-8 on MSVC.

Read JSON

yyjson_doc *doc = yyjson_read(json, len, 0);
yyjson_doc *doc = yyjson_read_file("path", 0, NULL, &err);
yyjson_doc *doc = yyjson_read_opts((char*)dat, len, flg, alc, &err);
yyjson_doc *doc = yyjson_read_fp(fp, flg, alc, &err);

// Incremental
yyjson_incr_state *s = yyjson_incr_new(buf, len, flg, alc);
yyjson_doc *doc = yyjson_incr_read(s, read_len, &err);
yyjson_incr_free(s);

Read flags: YYJSON_READ_NOFLAG (RFC 8259), ALLOW_COMMENTS, ALLOW_TRAILING_COMMAS, ALLOW_INF_AND_NAN, ALLOW_INVALID_UNICODE, NUMBER_AS_RAW, BIGNUM_AS_RAW (overridden by NUMBER_AS_RAW), ALLOW_BOM, ALLOW_EXT_NUMBER, ALLOW_EXT_ESCAPE, ALLOW_EXT_WHITESPACE, ALLOW_SINGLE_QUOTED_STR, ALLOW_UNQUOTED_KEY, INSITU (modify input buffer; pad with YYJSON_PADDING_SIZE zeros), STOP_WHEN_DONE (NDJSON), JSON5.

Error: yyjson_read_err err; → err.code, err.msg, err.pos. yyjson_locate_pos(dat, len, err.pos, &line, &col, &chr) for line/col.

Access Values

yyjson_val *root = yyjson_doc_get_root(doc);

// Type checks
yyjson_is_null(v)  yyjson_is_bool(v)  yyjson_is_uint(v)  yyjson_is_sint(v)
yyjson_is_int(v)   yyjson_is_real(v)  yyjson_is_num(v)   yyjson_is_str(v)
yyjson_is_arr(v)   yyjson_is_obj(v)   yyjson_is_raw(v)

// Getters
bool b = yyjson_get_bool(v);          uint64_t u = yyjson_get_uint(v);
int64_t s = yyjson_get_sint(v);       int i = yyjson_get_int(v);
double d = yyjson_get_real(v);        const char *str = yyjson_get_str(v);
size_t len = yyjson_get_len(v);       const char *raw = yyjson_get_raw(v);

// Array (linear by index)
size_t sz = yyjson_arr_size(arr);
yyjson_val *v = yyjson_arr_get(arr, idx);
yyjson_val *v = yyjson_arr_get_first(arr) / yyjson_arr_get_last(arr);

// Object (linear by key)
size_t sz = yyjson_obj_size(obj);
yyjson_val *v = yyjson_obj_get(obj, "key");
yyjson_val *v = yyjson_obj_getn(obj, "key", key_len);

// String compare
yyjson_equals_str(v, "abc");  yyjson_equals_strn(v, "abc", 3);

Iterate

// Array
yyjson_val *v;
yyjson_arr_iter iter = yyjson_arr_iter_with(arr);
while ((v = yyjson_arr_iter_next(&iter))) { }
// Macro:
yyjson_arr_foreach(arr, idx, max, v) { }

// Object
yyjson_val *k, *v;
yyjson_obj_iter iter = yyjson_obj_iter_with(obj);
while ((k = yyjson_obj_iter_next(&iter))) { v = yyjson_obj_iter_get_val(k); }
// Macro:
yyjson_obj_foreach(obj, idx, max, k, v) { }

Mutable: use yyjson_mut_ prefix. Inside mutable iter: yyjson_mut_arr_iter_remove(&iter) / yyjson_mut_obj_iter_remove(&iter).

Create / Modify JSON

yyjson_mut_doc *doc = yyjson_mut_doc_new(alc);
yyjson_mut_val *root = yyjson_mut_obj(doc);  // or yyjson_mut_arr(doc)
yyjson_mut_doc_set_root(doc, root);

// Scalars
yyjson_mut_null(doc)  yyjson_mut_bool(doc, true)
yyjson_mut_uint(doc, 123)  yyjson_mut_sint(doc, -123)  yyjson_mut_int(doc, 123)
yyjson_mut_real(doc, 1.5)  yyjson_mut_str(doc, "hello")       // refs caller's string
yyjson_mut_strcpy(doc, "hello")                                // copies into doc
yyjson_mut_strn(doc, "hello", 5)  yyjson_mut_strncpy(doc, "hello", 5)  // n-variants

// Array
yyjson_mut_arr_append(arr, val)  yyjson_mut_arr_prepend(arr, val)
yyjson_mut_arr_insert(arr, val, idx)  yyjson_mut_arr_replace(arr, idx, val)
yyjson_mut_arr_remove(arr, idx)  yyjson_mut_arr_remove_first/last(arr)  yyjson_mut_arr_clear(arr)
// Convenience: yyjson_mut_arr_add_int(doc, arr, 42) / _add_str / _add_arr / _add_obj
// From C array: yyjson_mut_arr_with_sint32(doc, nums, 3)

// Object
yyjson_mut_obj_add(obj, key, val)      // allows duplicates
yyjson_mut_obj_put(obj, key, val)      // removes existing first (O(n))
yyjson_mut_obj_remove(obj, key)  yyjson_mut_obj_clear(obj)
// Convenience: yyjson_mut_obj_add_str/int/arr/obj(doc, obj, "key", ...)
yyjson_mut_obj_remove_str(obj, "key")  yyjson_mut_obj_rename_key(doc, obj, "old", "new")

Important: A yyjson_mut_val can only be added to one container.

Immutable ↔ Mutable

yyjson_mut_doc *mdoc = yyjson_doc_mut_copy(idoc, alc);
yyjson_mut_val *mval = yyjson_val_mut_copy(mdoc, ival);
yyjson_doc *idoc = yyjson_mut_doc_imut_copy(mdoc, alc);

Write JSON

char *json = yyjson_write(doc, flg, &len);      free(json);
char *json = yyjson_mut_write(mdoc, flg, &len); free(json);
char *json = yyjson_val_write(val, flg, &len);   free(json);    // per-value
yyjson_write_file("out.json", doc, flg, alc, &err);
yyjson_mut_write_file("out.json", mdoc, flg, alc, &err);
yyjson_write_fp(fp, doc, flg, alc, &err);
size_t n = yyjson_write_buf(buf, buf_len, doc, flg, &err);

Write flags: YYJSON_WRITE_NOFLAG (minified), PRETTY (4-space), PRETTY_TWO_SPACES, ESCAPE_UNICODE, ESCAPE_SLASHES, ALLOW_INF_AND_NAN, INF_AND_NAN_AS_NULL, ALLOW_INVALID_UNICODE, LOWERCASE_HEX, NEWLINE_AT_END, FP_TO_FLOAT, FP_TO_FIXED(prec) (1..15).

JSON Pointer / Patch (RFC 6901/6902/7386)

// Query
yyjson_val *v = yyjson_doc_ptr_get(doc, "/users/0/name");

// Modify (mutable)
yyjson_mut_doc_ptr_set(doc, "/a", yyjson_mut_int(doc, 9));
yyjson_mut_doc_ptr_add(doc, "/b/-", val);    // "-" appends to array
yyjson_mut_doc_ptr_remove(doc, "/b");

// Error variants: _getx takes yyjson_ptr_err; _setx/_addx/_removex take yyjson_ptr_ctx + yyjson_ptr_err

// Patch
yyjson_mut_val *out = yyjson_patch(doc, orig, patch, &err);     // RFC 6902
yyjson_mut_val *out = yyjson_merge_patch(doc, orig, patch);     // RFC 7386

Memory Allocator

// Stack allocator
char buf[128*1024];
yyjson_alc alc; yyjson_alc_pool_init(&alc, buf, sizeof(buf));
yyjson_doc *doc = yyjson_read_opts(dat, len, 0, &alc, NULL);

// Dynamic
yyjson_alc *alc = yyjson_alc_dyn_new();
// ...
yyjson_alc_dyn_free(alc);

// Custom (malloc/realloc/free signatures match yyjson_alc)
yyjson_alc MY_ALC = { my_malloc, my_realloc, my_free, NULL };

A custom allocator applies to the document and its values. The output string from yyjson_write() / yyjson_mut_write() / yyjson_val_write() uses the default allocator; use the _opts variants to route it through the same allocator.

Number & Compile-time

// Per-value output format (mutable)
yyjson_mut_set_fp_to_float(val, true);
yyjson_mut_set_fp_to_fixed(val, 6);

Compile-time defines: YYJSON_DISABLE_READER, YYJSON_DISABLE_WRITER, YYJSON_DISABLE_INCR_READER, YYJSON_DISABLE_UTILS (Pointer/Patch), YYJSON_DISABLE_FAST_FP_CONV, YYJSON_DISABLE_NON_STANDARD, YYJSON_DISABLE_UTF8_VALIDATION, YYJSON_DISABLE_UNALIGNED_MEMORY_ACCESS. YYJSON_READER_DEPTH_LIMIT.

Null Safety

All APIs null-check inputs — safe to chain: yyjson_get_str(yyjson_obj_get(root, "key")) returns NULL if missing. For hot loops, unsafe_ prefix skips checks: unsafe_yyjson_is_str(k), unsafe_yyjson_get_uint(v).

Common Pattern: Read → Modify → Write

yyjson_doc *idoc = yyjson_read_file("in.json", 0, NULL, NULL);
yyjson_mut_doc *doc = yyjson_doc_mut_copy(idoc, NULL);
yyjson_mut_val *root = yyjson_mut_doc_get_root(doc);

yyjson_mut_val *k, *v;
yyjson_mut_obj_iter iter = yyjson_mut_obj_iter_with(root);
while ((k = yyjson_mut_obj_iter_next(&iter))) {
    v = yyjson_mut_obj_iter_get_val(k);
    if (yyjson_mut_is_null(v)) yyjson_mut_obj_iter_remove(&iter);
}

yyjson_mut_write_file("out.json", doc, YYJSON_WRITE_PRETTY, NULL, NULL);
yyjson_doc_free(idoc);
yyjson_mut_doc_free(doc);

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

ast

無料

Manual AST construction with FunctionBuilder for kernels and callables without DSL sugar.

日本語の概要は準備中です。原文の説明を表示しています。

LuisaGroup/LuisaCompute1,0532026年10月11日 更新

Backend plugin architecture, DeviceInterface, dynamic loading, and command encoding.

日本語の概要は準備中です。原文の説明を表示しています。

LuisaGroup/LuisaCompute1,0532026年10月11日 更新

cmake

無料

CMake build options, custom functions, and backend patterns for LuisaCompute.

日本語の概要は準備中です。原文の説明を表示しています。

LuisaGroup/LuisaCompute1,0532026年10月11日 更新

cpp-style

無料

C++ naming, formatting, static analysis, and RTTI rules for LuisaCompute.

日本語の概要は準備中です。原文の説明を表示しています。

LuisaGroup/LuisaCompute1,0532026年10月11日 更新

debug

無料

Debug crashes and test failures via stack-traces, host/device logging, and DSL buffer inspection.

日本語の概要は準備中です。原文の説明を表示しています。

LuisaGroup/LuisaCompute1,0532026年10月11日 更新

git

無料

Show uncommitted changes and commit history via git. Use when: (1) inspecting what changed in a file before committing, (2) checking diff of tracked/new/deleted files, (3) reviewing a specific commit's changes, (4) listing files changed in a commit.

日本語の概要は準備中です。原文の説明を表示しています。

LuisaGroup/LuisaCompute1,0532026年10月11日 更新

LuisaGroup のスキルをすべて見る

このスキルの問題を報告する