本帖最后由 vsfopen 于 2018-8-3 08:44 编辑
坐标:https://gitee.com/versaloon/vsf_open/blob/master/vsf/component/tool/json
极简方式实现,不使用中间结构,不是用动态分配,不使用递归,不使用全局变量。
RAM只使用堆栈,做大堆栈使用的函数是vsfjson_set_number,使用68字节堆栈(4字节返回值和64字节字符串缓冲)。
支持json解析和json生成
json生成时候,数据保存接口由用户定义
资源按需分配,比如解析json的时候,如果没有调用vsfjson_get_number,编译器就可以优化去掉浮点数的部分。
目前代码vsfjson.c为391字节,不过刚刚写好,兼容性还没做太多测试,并且以后会增加一些其他API。
demo:
static int usrapp_json_write_str(void *param, char *ch, int len)
{
struct vsf_transaction_buffer_t *buf = (struct vsf_transaction_buffer_t *)param;
if (buf->buffer.buffer != NULL)
{
if ((buf->buffer.size - buf->position) >= len)
{
memcpy(&buf->buffer.buffer[buf->position], ch, len);
buf->position += len;
return 0;
}
}
return -1;
}
void usrapp_json_test(void)
{
const char *json = "{\"obj\":{\"arr\":[0.01, 1.01],\"str\":\"abcd\"},\"uuid\":\"012376545672184\"}";
double double_value;
char buff[128];
int len;
char *result = vsfjson_get(json, "/obj/str");
if (result != NULL)
{
len = vsfjson_get_string(result, NULL, 0);
if (len < sizeof(buff))
{
vsfjson_get_string(result, buff, len);
}
}
result = vsfjson_get(json, "obj");
if (result != NULL)
{
result = vsfjson_get(result, "str");
if (result != NULL)
{
len = vsfjson_get_string(result, NULL, 0);
if (len < sizeof(buff))
{
vsfjson_get_string(result, buff, len);
}
}
}
result = vsfjson_get(json, "obj/arr/0");
if (result != NULL)
{
len = vsfjson_get_number(result, &double_value);
}
/* "{
"key0":1.0,
"key1":true,
"key2":["123", 4.56],
"key3":null
}
*/
struct vsfjson_constructor_t c;
struct vsf_transaction_buffer_t buf = { NULL, 0 };
do
{
if (buf.buffer.size)
{
if (buf.buffer.size < sizeof(buff))
{
buf.buffer.buffer = (uint8_t *)buff;
buf.position = 0;
vsfjson_constructor_init(&c, &buf, usrapp_json_write_str);
}
else
break;
}
else
{
vsfjson_constructor_init(&c, NULL, NULL);
}
vsfjson_set_object(&c, NULL,
{
vsfjson_set_number(&c, "key0", 1.0);
vsfjson_set_boolean(&c, "key1", true);
vsfjson_set_array(&c, "key2",
{
vsfjson_set_string(&c, NULL, "123");
vsfjson_set_number(&c, NULL, 4.67);
});
vsfjson_set_null(&c, "key3");
});
if (!c.write_str)
buf.buffer.size = c.len + 1;
else
c.write_str(c.param, "\0", 1);
} while (!buf.buffer.buffer);
}
API:
1. char *vsfjson_get(const char *json, const char *key);
从json字符串后,或者指定的key的值,key可以用路径的方式表示,比如"/obj/arr/2"(obj需要是object,arr需要是array)。
2. enum vsfjson_type_t vsfjson_enumerate_start(struct vsfjson_enumerator_t *e, const char *json);
vsfjson_enumerate_start用于枚举指定的json,只对array和object有效。struct vsfjson_enumerator_t为枚举器。
3. char *vsfjson_enumerate_next(struct vsfjson_enumerator_t *e);
枚举array或者object的时候,用来得到下一个值。
4. enum vsfjson_type_t vsfjson_get_type(const char *json);
得到json的类型,比如object、array、number、string等等。
5. int vsfjson_get_string(const char *json, char *result, int len);
对于string类型的json,读取字符串的值,并且返回长度。如果result为NULL,可以返回保存字符串需要的长度。
6. int vsfjson_get_number(const char *json, double *result);
对于number类型的json,读取double类型的值。
7. int vsfjson_get_boolean(const char *json, bool *result);
对于boolean类型的json,读取bool类型的值。
8. void vsfjson_constructor_init(struct vsfjson_constructor_t *c, void *param, int (*write_str)(void *, char *, int));
初始化struct vsfjson_constructor_t构造器,并且指定写数据的用户回调,如果用户回调设置为NULL的话,则用来计算生成的json数据长度。
9. vsfjson_set_object(c, key, member);
json构造器中,加入指定key的object,member要使用闭包的方式。比如:
vsfjson_set_object(&c, "KEY0",
{
vsfjson_set_boolean(&c, "enabled", true);
});
如果key参数为NULL的话,则生成不带名字的object(一般其他的成员,都写在一个不带名字的object内)。
10. vsfjson_set_array(c, key, member);
类似vsfjson_set_object,不过这里member里的成员,都必须不带key。
11. int vsfjson_set_string(struct vsfjson_constructor_t *c, char *key, char *value);
json构造器中,加入string。生成"key":"value"
12. int vsfjson_set_number(struct vsfjson_constructor_t *c, char *key, double value);
json构造器中,加入number。生成"key":double(value)
13. int vsfjson_set_boolean(struct vsfjson_constructor_t *c, char *key, bool value);
json构造器中,加入boolean。生成"key":true/false
14. int vsfjson_set_null(struct vsfjson_constructor_t *c, char *key);
json构造器中,加入null。生成"key":null
|