coreJSON
? coreJSON是FreeRTOS中的一个组件库,它coreJSON库提供了一个解析器,该解析器支持密钥查找,同时严格执行标准ECMA-404:JSON数据交换标准)。该库是用C语言编写的,旨在符合ISO C90和MISRA C:2012它具有显示安全内存使用且没有堆分配的证明,使其适用于物联网微控制器,但也完全可移植到其他平台。
源码下载: coreJSON库可以在FreeRTOS/FreeRTOS-Plus/Source/coreJSON目录中的FreeRTOS主下载中找到。
内存占用情况
? coreJSON 库使用内部堆栈来跟踪 JSON 文档中的嵌套结构。堆栈在单个函数调用的持续时间内存在;它不会被保留。堆栈大小可以通过定义宏JSON_MAX_DEPTH来指定,该宏默认为 32 级。每个级别消耗一个字节。
coreJSON使用方式
? 在coreJSON中主要有以下几个API:
JSONStatus_t JSON_Validate( const char * buf,size_t max );
JSON_Search( buf, max, query, queryLength, outValue, outValueLength )
JSONStatus_t JSON_Iterate( const char * buf, size_t max,
size_t * start,
size_t * next,
JSONPair_t * outPair );
下面主要讲解JSON_Search和JSON_Iterate这两个函数的使用方法
JSON_Search:
原型:
#define JSON_Search( buf, max, query, queryLength, outValue, outValueLength ) \
JSON_SearchT( buf, max, query, queryLength, outValue, outValueLength, NULL )
参数:
buf: 要搜索的解释缓冲区
max: 解释缓冲区的大小
query: 要搜索的对象键和数组索引
queryLength: 键值长度
outValue:一个指针 用来接收找到的值的地址
outValueLength:一个指针,用来接收找到的值的长度
返回:
#JSONSuccess 查询被匹配并且值输出;
#JSONNullParameter 指针参数为NULL;
#JSONBadParameter 如果查询为空,或者分隔符之后的部分为空,或者max为0,或者索引太大而不 能转换为32位整数;。
#JSONNotFound 查询没有匹配
note:最大嵌套深度可以通过定义宏JSON_MAX_DEPTH来指定,默认值是32。
JSON_Search()执行验证,但在找到匹配的键及其值时候就停止寻找。
- 在json中不包含数组时,例如:{“foo”:“abc”,“bar”:{“foo”:“xyz”}}
JSONStatus_t result;
char buffer[] = "{\"foo\":\"abc\",\"bar\":{\"foo\":\"xyz\"}}";
size_t bufferLength = sizeof( buffer ) - 1;
char query[] = "bar.foo";
size_t queryLength = sizeof( query ) - 1;
char * value;
size_t valueLength;
result = JSON_Validate( buffer, bufferLength );
if( result == JSONSuccess )
{
result = JSON_Search( buffer, bufferLength, query, queryLength,
&value, &valueLength );
if( result == JSONSuccess )
{
char save = value[ valueLength ];
value[ valueLength ] = '\0';
printf( "Found: %s -> %s\n", query, value );
value[ valueLength ] = save;
}
}
- JSON数据中带有数据,例如:"{“results”:[{“location”:{“id”:“WT3Q0FW9ZJ3Q”,“name”:“武汉”,“country”:“CN”,“path”:“武汉,武汉,湖北,中国”,“timezone”:“Asia/Shanghai”,“timezone_offset”:"+08:00"},“now”:{“text”:“小雨”,“code”:“13”,“temperature”:“4”},“last_update”:“2022-01-22T17:47:52+08:00”}]}"
JSONStatus_t result;
char buffer[] = "{\"results\":[{\"location\":{\"id\":\"WT3Q0FW9ZJ3Q\",\"name\"\:\"武汉\",\"country\":\"CN\",\"path\":\"武汉,武汉,湖北,中国\",\"timezone\":\"Asia/Shanghai\",\"timezone_offset\":\"+08:00\"},\"now\":{\"text\":\"小雨\",\"code\":\"13\",\"temperature\":\"4\"},\"last_update\":\"2022-01-22T17:47:52+08:00\"}]}";
size_t bufferLength = sizeof(buffer) - 1;
char query[] = "results.[0].now";
size_t queryLength = sizeof(query) - 1;
char *value;
size_t valueLength;
result = JSON_Validate(buf, len);
if( result == JSONSuccess)
{
result = JSON_Search(buffer, bufferLength, query, queryLength,
&value, &valueLength);
if( result == JSONSuccess)
{
char save = value[valueLength];
value[valueLength] = '\0';
printf("Found: %s %d-> %s\n", query, valueLength,value);
value[valueLength] = save;
}
}
JSON_Iterate
原型:
JSONStatus_t JSON_Iterate( const char * buf,
size_t max,
size_t * start,
size_t * next,
JSONPair_t * outPair );
参数:
buf:要搜索的解析缓冲区
max:解析缓冲区的长度
start:集合开始时的索引
next : 在其上寻找下一个值的索引
outPair:接收下一个键值对的指针
返回值:
JSONSuccess:有值输出
JSONIllegalDocument:解析缓冲区不包含集合
JSONNotFound :如果集合中没有其他值
note:
这个函数需要一个有效的JSON文档; 首先运行JSON_Validate()。
对于一个对象,outPair结构将引用一个键及其值。
对于一个数组,只有值将被引用(例如,outPair,key将为NULL)。
Example:
static char * json_types[] =
{
"invalid",
"string",
"number",
"true",
"false",
"null",
"object",
"array"
};
void show( const char * json,
size_t length )
{
size_t start = 0, next = 0;
JSONPair_t pair = { 0 };
JSONStatus_t result;
result = JSON_Validate( json, length );
if( result == JSONSuccess )
{
result = JSON_Iterate( json, length, &start, &next, &pair );
}
while( result == JSONSuccess )
{
if( pair.key != NULL )
{
printf( "key: %.*s\t", ( int ) pair.keyLength, pair.key );
}
printf( "value: (%s) %.*s\n", json_types[ pair.jsonType ],
( int ) pair.valueLength, pair.value );
result = JSON_Iterate( json, length, &start, &next, &pair );
}
}
|