JSON / JSON5 操作
可用性:两个变体(Full / Tiny)均支持。
OnePath 内置一组 JSON/JSON5 解析与操作 API(onepath_json.h)。该 API 可在不启动任何 OnePath 会话的情况下使用,适合配置处理、消息体编解码等场景。
一、设计要点
- 独立:不依赖 OnePath 会话,可单独使用 JSON 解析和操作。
- JSON5 兼容:支持注释(
//、/* */)、尾逗号等 JSON5 超集特性。 - 层级路径:用
/分隔对象键,[N]访问数组索引。 - 所有权清晰:
onepath_json_parse()在堆上分配,onepath_json_free()释放。
二、快速开始
c
#include <onepath.h> /* 自动包含 onepath_json.h */
int main(void) {
/* 解析 JSON5 字符串 */
const char *input = "{/* config */ \"host\": \"example.com\", \"port\": 8080}";
onepath_json_t *doc = onepath_json_parse(input, 0);
if (!doc) { printf("parse error\n"); return 1; }
/* 查询 */
onepath_json_val_t v;
onepath_json_get(doc, "host", &v);
printf("host = %.*s\n", (int)v.str_len, v.str);
/* 修改 */
onepath_json_set(doc, "port", "9090");
/* 序列化 */
char *buf = NULL; size_t len = 0;
onepath_json_dump(doc, &buf, &len);
printf("result: %s\n", buf);
free(buf);
onepath_json_free(doc);
return 0;
}配套示例程序 onepath_json_demo 给出完整可运行版本。
三、API 参考
生命周期
| 函数 | 说明 |
|---|---|
onepath_json_t *onepath_json_parse(str, len) | 解析 JSON/JSON5 字符串。len=0 时自动 strlen。失败返回 NULL |
void onepath_json_free(json) | 释放句柄,NULL 安全 |
查询
| 函数 | 说明 |
|---|---|
int onepath_json_get(json, path, &out) | 按层级路径获取值。路径不存在返回 ONEPATH_JSON_ENOTFND |
修改
| 函数 | 说明 |
|---|---|
int onepath_json_set(json, path, json_value) | 在指定路径设置值。value 须为合法 JSON 字符串 |
int onepath_json_delete(json, path) | 删除路径上的值 |
序列化
| 函数 | 说明 |
|---|---|
int onepath_json_dump(json, &buf, &len) | 紧凑输出。buf 由调用者 free() |
int onepath_json_dump_pretty(json, &buf, &len, indent) | 美化输出。indent=2 缩进两个空格 |
错误信息
| 函数 | 说明 |
|---|---|
const char *onepath_json_strerror(err) | 错误码转可读字符串 |
四、路径语法
c
/* 对象键 */
onepath_json_get(doc, "server", &v); // 顶层键 "server"
onepath_json_get(doc, "nested/key", &v); // 嵌套键 nested → key
onepath_json_get(doc, "/nested/key", &v); // 等价, 前导 / 可选
/* 数组索引 */
onepath_json_get(doc, "tags[0]", &v); // 数组第 0 个元素
onepath_json_get(doc, "tags[1]/sub", &v); // 数组元素中的对象键五、结果类型 onepath_json_val_t
| type 常量 | 值 | 有效字段 |
|---|---|---|
ONEPATH_JSON_TYPE_NULL | 0 | — |
ONEPATH_JSON_TYPE_BOOL | 1 | bool_val |
ONEPATH_JSON_TYPE_INT | 2 | i64_val |
ONEPATH_JSON_TYPE_UINT | 3 | u64_val |
ONEPATH_JSON_TYPE_REAL | 4 | real_val |
ONEPATH_JSON_TYPE_STR | 5 | str, str_len |
ONEPATH_JSON_TYPE_ARR | 6 | —(复合类型) |
ONEPATH_JSON_TYPE_OBJ | 7 | —(复合类型) |
整数类型
正整数字面量被解析为 UINT(type=3),负整数为 INT(type=2)。用户代码应同时检查两种类型。
六、错误码
| 错误码 | 值 | 说明 |
|---|---|---|
ONEPATH_JSON_OK | 0 | 成功 |
ONEPATH_JSON_EPARSE | -1 | JSON/JSON5 解析错误 |
ONEPATH_JSON_EPATH | -2 | 路径语法错误 |
ONEPATH_JSON_ENOTFND | -3 | 键或索引不存在 |
ONEPATH_JSON_ENOMEM | -4 | 内存不足 |
ONEPATH_JSON_ETYPE | -5 | 类型不匹配 |
七、限制与注意事项
- 性能:当前实现对每个 set/delete 操作在可变文档上执行,适合配置处理和小型文档。
- 数值类型:不区分 int/uint 字面量(正数 → UINT,负数 → INT)。
- JSON5 子集:支持注释和尾逗号,不支持单引号字符串和十六进制数字。
- 线程安全:API 非线程安全,多线程需用户自行加锁。