Jansson API 介绍

原文链接:jansson api 接口


用c语言数据结构描述的jansson数据类型,这数据类型用来表示这个JSON值的类型:
json_t
这个数据类型在数据库中用来表示所有的JSON值。该结构有该JSON值的类型和该值的引用计数组成。json_t的对象总是通过指针使用的。jansson提供用于查询JSON值类型、操作引用计数以及构造和操作不同类型值的API接口。

JSON值类型:
JSON定义了以下类型:
JSON_OBJECT : 对象
JSON_ARRAY: 数组
JSON_STRING: 字符串
JSON_INTEGER: 整型数字
JSON_REAL: 实型数字
JSON_TRUE: bool真
JSON_FALSE: bool假
JSON_NULL: 空
int json_typeof(const json_t *json) 返回json值的类,参数json不能为空(NULL)

json_is_object (const json_t *json)
json_is_array(const json_t *json)
json_is_string(const json_t *json)
json_is_integer(const json_t *json)
json_is_real(const json_t *json)¶
json_is_true(const json_t *json)
json_is_false(const json_t *json)
json_is_null(const json_t *json)
以上函数用于判断json值的类型,若是给的类型则返回真,否则返回假,参数json为空指针也返回假

json_is_number(const json_t *json)
若json值为JSON_INTEGER或JSON_REAL类型返回真,否则返回假,参数json为空指针也返回假
json_is_boolean(const json_t *json)
若json值为JSON_TRUE或JSON_FALSE类型返回真,否则返回假,参数json为空指针也返回假

引用计数(reference count):
引用计数用于跟踪某个值是否仍在使用。创建值时,其引用计数设置为1。如果保留对某个值的引用(例如,将某个值存储在某个位置以供以后使用),则该值的引用计数将递增,当不再需要该值时,该引用计数将递减。当引用计数降至零时,就没有剩余的引用,并且可以销毁该值。

json_t *json_incref(json_t *json)
增加json的引用计数(参数json不能为空)、
void json_decref(json_t *json)
减少json的引用计数。一旦调用 json_decref将引用计数减至0,该json值就被销毁,并且不能再次使用。

创建新的JSON值的函数将引用计数设置为1,这些函数返回一个引用计数。其他返回一个已存在的JSON值的函数通常不会增加引用计数的值,因此在使用这些函数时必须调用json_incref函数来增加引用计数的值。一旦不需要该JSON值,就应该调用json_decref函数来释放引用计数。
通常接受JSON值作为参数的函数,都需要根据需要增加或者减少引用计数的值。但是函数名带有_new或者函数名后缀为_new的,在调用函数后,会自行增加或减少引用计数。
例如下列创建一个数组JSON,并且向该数组型JSON追加一个整数型JSON

  json_t *array, *integer;
    array = json_array();
    integer = json_integer(42);
    json_array_append(array, integer);
    json_decref(integer);

 
 
  • 1
  • 2
  • 3
  • 4
  • 5

此处需要自行调用json_decref来释放integer的引用计数

json_t *array = json_array();
json_array_append_new(array, json_integer(42));

 
 
  • 1
  • 2

用户不必显式释放对整数值的引用,因为json_array_append_new()在将值附加到数组时会窃取引用(即自动处理JSON参数的引用计数)

循环引用:
当一个对象型或数组型JSON直接或间接插入到其自己内部时,就会创建一个循环引用。

json_t *obj = json_object();
json_object_set(obj, "foo", obj);

 
 
  • 1
  • 2

这是直接循环引用,Jansson将拒绝执行此操作,json_object_set()(以及对象和数组的所有其他此类函数)将返回错误状态。间接循环无法检测,但是是危险的。

json_t *arr1 = json_array(), *arr2 = json_array();
json_array_append(arr1, arr2);
json_array_append(arr2, arr1);

 
 
  • 1
  • 2
  • 3

在本例中,数组arr2包含在数组arr1中,反之亦然。如果不影响性能,Jansson就无法检查这种间接循环引用,因此由用户来避免它们。
如果创建了循环引用,则json_decref()无法释放值所消耗的内存。引用计数永远不会降为零,因为值会保持彼此的引用。此外,尝试使用任何编码函数对值进行编码都将失败。编码器检测循环引用并返回错误状态。

TRUE ,FALSE and Null
这些值是作为个体使用的,因此这些函数每次都返回相同的值
json_t *json_true(void)
返回ftrue型JSON,新的引用计数

json_t *json_false(void)¶
返回false型JSON,新的引用计数

json_t *json_null(void)
返回null型JSON,新的引用计数 .

string
jansson使用UTF-8作为字符编码。所有JSON字符串必须是有效的UTF-8(或ASCII,因为它是UTF-8的子集)。使用普通的以空结尾的C字符串,因此JSON字符串不能包含嵌入的空字符
**json_t json_string(const char value)
返回新的JSON型的字符串,或出错时返回空值。参数必须是有效的UTF-8编码的Unicode字符串

**json_t json_string_nocheck(const char value)
类似于json_string不检查该值是否为有效的UTF-8。仅当您确定确实如此时才使用此函数

const char *json_string_value(const json_t *string)
返回一个以null结尾的utf-8编码的字符串的指针,如果不是字符串型json则返回null
返回值只读,不能修改也不能释放。只要引用计数没有降到0,返回值一直有效

int json_string_set(const json_t *string, const char *value)
将string型的关联值设置为value的内容,value的内容必须是有效的UTF-8编码的Unicode字符串,成功返回0,失败返回-1或error

int json_string_set_nocheck(const json_t *string, const char *value) 不验证value的内容格式

Number(整型和浮点型)
json_int_t
这是用于存储JSON整数值的C类型。它表示系统上可用的最宽整数类型。实际上,如果编译器支持它,那么它只是一个long long的typedef,否则就是long.
通常,您可以安全地使用int代替json_int_t,而隐式C整数转换处理其余的部分。只有当您知道需要完整的64位范围时,才应该显式地使用json_int_t。
JSON_INTEGER_IS_LONG_LONG是个预处理器,如果json_int_t是long long型其值为1,如果json-int_t代表long型,则其值为0

JSON_INTEGER_FORMAT
json_int_t在print的输出格式,要用双引号括起来,例子:

json_int_t x = 123123123;
printf("x is %" JSON_INTEGER_FORMAT "\n", x);

 
 
  • 1
  • 2

json_t *json_integer(json_int_t value)
以value值新建一个inter型json,成功返回一个新的integer型json,失败返回空

json_int_t json_integer_value(const json_t *integer)
返回integer型json的关联值, 如果参数类型不对返回0.

int json_integer_set(const json_t *integer, json_int_t value)
设置integer的关联值为value. Returns 0 on success and -1 if integer is not a JSON integer.

json_t *json_real(double value)
Return value: New reference.
Returns a new JSON real, or NULL on error.

double json_real_value(const json_t *real)
Returns the associated value of real, or 0.0 if real is not a JSON real.

int json_real_set(const json_t *real, double value)
Sets the associated value of real to value. Returns 0 on success and -1 if real is not a JSON real.

double json_number_value(const json_t *json)
返回integer型或real型json的关联值, cast to double regardless of the actual type. If json is neither JSON real nor JSON integer, 0.0 is returned.

Array
数组型json是其他json值的有序集合
json_t *json_array(void)
创建一个新的array型json,数组为空,失败返回空指针

size_t json_array_size(const json_t *array)
返回数组中元素的个数,NULL或者非array型数组返回0

json_t *json_array_get(const json_t *array, size_t index)
返回json数组中第index元素

int json_array_set(json_t *array, size_t index, json_t *value)
将array型数组的第index元素设置为value,成功返回1,失败返回0

int json_array_set_new(json_t *array, size_t index, json_t *value)
与 json_array_set类似,但是调用后会对value的引用计数减一(适用于:value为新建的json并且被调用后不再使用)

int json_array_append(json_t *array, json_t *value)
将value追加至array的尾部,array的长度加一,成功返回0,失败返回-1

int json_array_append_new(json_t *array, json_t *value)
与 json_array_append类似,但是调用后会对value的引用计数减一(适用于:value为新建的json并且被调用后不再使用)

int json_array_insert(json_t *array, size_t index, json_t *value)
在index位置处插入数据

int json_array_insert_new(json_t *array, size_t index, json_t *value)
与 json_array_append类似,但是调用后会对value的引用计数减一(适用于:value为新建的json并且被调用后不再使用)

int json_array_remove(json_t *array, size_t index)
删除index位置处的数据,并且被删除数据的引用计数减一

int json_array_clear(json_t *array)
清空所有元素,并且每个元素的引用计数减一

int json_array_extend(json_t *array, json_t *other_array)
将array的所有元素追到other_array数组的尾部,成功返回0 失败返回-1

Object
object型的json是典型的键值对,其中,键值是Unicode字符串,值是任意类型json值
json_t *json_object(void)
新建一个空的object型json,失败返回NULL,引用计数置一

size_t json_object_size(const json_t *object)
返回object中键值对(元素)的个数,如果参数不是object型json返回0

json_t *json_object_get(const json_t *object, const char *key)
获取与键值key对应的值(任意json),如果没有定位到相应的键值key返回null.

int json_object_set(json_t *object, const char *key, json_t *value)
在object中设置键值对,如果object中键值key本来就存在覆盖原来的值(json型),如果键值key不存在就插入新的键值对.键值必须是有效的以null结尾的UTF-8编码的Unicode字符串。 成功返回0,失败返回-1

int json_object_set_nocheck(json_t *object, const char *key, json_t *value)
类似于json_object_set,不检查key是否为符合标准的utf-8格式

int json_object_set_new(json_t *object, const char *key, json_t *value)
与 json_object_set类似,但是调用后会对value的引用计数减一(适用于:value为新建的json并且被调用后不再使用)

int json_object_set_new_nocheck(json_t *object, const char *key, json_t *value)
与 json_object_set_nocheck类似,但是调用后会对value的引用计数减一(适用于:value为新建的json并且被调用后不再使用)

int json_object_del(json_t *object, const char *key)
如果键值key存在,则删除键值key对应的value,并且value的引用计数减一,成功返回0,失败返回-1

int json_object_clear(json_t *object)
删除object所有的键值对,并且每个键值对的value的引用计数减一,成功返回0,失败返回-1

int json_object_update(json_t *object, json_t *other)
用other的键值对更新object的键值对,并且重写已存在的键值对,成功返回0,失败返回-1

接下来的函数实现对象的迭代协议,可以遍历对象中的所有键值对,键值对的返回没有特定的顺序,因为依赖于哈希表内部的排序实现机制。
void *json_object_iter(json_t *object)
Returns an opaque iterator which can be used to iterate over all key-value pairs in object, or NULL if object is empty.
返回一个可以遍历对象中所有键值对的迭代器,对象空则返回null

void *json_object_iter_at(json_t *object, const char *key)
返回与key相同的键值对的迭代器,如果key不存在,则返回null,如果key恰好是哈希表的第一个键,则向前迭代到对象的末尾会生成对象所有的键值对

void *json_object_iter_next(json_t *object, void *iter)
Returns an iterator pointing to the next key-value pair in object after iter, or NULL if the whole object has been iterated through.
返回指向下一个键值对的迭代器,如果整个对象已经被迭代器遍历,则返回空指针。

const char *json_object_iter_key(void *iter)
从迭代器iter中取出相应的键值

json_t *json_object_iter_value(void *iter)
从迭代器iter中取出相应的value

int json_object_iter_set(json_t *object, void *iter, json_t *value)
Set the value of the key-value pair in object, that is pointed to by iter, to value.
将迭代器iter所指向的键值对的值,改为value,键值保存不变

int json_object_iter_set_new(json_t *object, void *iter, json_t *value)
与 json_object_iter_set类似,但是调用后会对value的引用计数减一(适用于:value为新建的json并且被调用后不再使用)
迭代器使用例子:

 /* obj is a JSON object */
const char *key;
json_t *value;
void *iter = json_object_iter(obj);
while(iter)
{
    key = json_object_iter_key(iter);
    value = json_object_iter_value(iter);
    /* use key and value ... */
    iter = json_object_iter_next(obj, iter);
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

错误打印
jansson用一个结构体json_error_t向用户传递错误信息
char text[]:错误信息,如果错误信息不看获得则为空字符串
char source[] : 错误的来源
int line :错误发生在第几行
int column :错误发生的列
size_t position :从输入开始的字节数位置。这对于调试Unicode编码问题很有用。

错误结构体使用例子:

int main() {
    json_t *json;
    json_error_t error;
    json = json_load_file("/path/to/file.json", 0, &error);
    if(!json) {
        /* the error variable contains error information */
    }
    ...
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

注意:如果调用成功(即json!=null),错误内容不会被指定。所有函数的错误指针可以赋值为空,此时不会返回错误信息。

编码
本节介绍可用于将值编码为JSON的函数。默认情况下,只能直接对对象和数组进行编码,因为它们是JSON文本的唯一有效根值。要对任何JSON值进行编码,请使用JSON_ENCODE_ANY_flag(见下文)。
默认情况下,json输出没有换行符,并且数组和对象元素之间使用空格使得输出可读。这个行为可以通过下午的JSON_INDENT和JSON-COMPACT标志改变。换行符永远附加到json数据编码的尾部。
每个函数都接受一个标志参数,该参数控制数据编码方式的某些方面。它的默认值是0。下面的宏可以一起操作以获取标志。
JSON_INDENT(n)
漂亮的打印结果,在数组以及对象元素之间使用换行符,并且缩进n个空格。n的取值范围为0到30.如果不使用JSON_INDENT或者n的值为0,在数组和对象元素间不会插入换行符。

JSON_COMPACT
这个标志使能紧凑表示,数组和对象元素间的分隔符设置为",",对象元素键值与value值间的分隔符为":"。

JSON_ENSURE_ASCII
如果使用这个标志,则保证输出中只包含ASCII字符。

JSON_SORT_KEYS
如果使用这个标志,则输出中所有对象的键值对按照键值key排序。

JSON_PRESERVE_ORDER
如果使用此标志,则输出中的对象键将按它们首次插入对象时的顺序排序。例如,对JSON文本进行解码,然后使用此标志进行编码,可以保留对象键的顺序。

JSON_ENCODE_ANY
指定这个标志,使得可以对任何json值进行编码。没有这个标志,只有对象和数组json可以将自己的根值传给编码函数,进行编码。
注意:编码任何类型值在某些场景是可用的,但是一般不鼓励这么做,因为这违背了RFC4627严格的兼容性。如果你想使用这个标志,就不要期望能和其他json系统有互操作性。甚至jansson自己都没有办法解码根植不是对象或数组的json文本。

以下函数实现实际的json编码。结果是UTF8格式
char *json_dumps(const json_t *root, size_t flags)
以字符串形式返回root代表的json数据,错误返回空。flag如上所示。返回值必须使用free()函数进行释放。

int json_dumpf(const json_t *root, FILE *output, size_t flags)
将root代表的json输出到指定的输出文件流,标志如上所述。成功时返回0,错误时返回-1。如果发生错误,则可能已将某些内容写入输出。在这种情况下,输出是未定义的,很可能不是有效的JSON。

int json_dump_file(const json_t *json, const char *path, size_t flags)
将root代表的json输出到指定路径的文件。如果路径已经存在,文件内容将会被覆盖,成功返回0,失败返回-1

json_dump_callback_t
调用 json_dump_callback()函数

typedef int (*json_dump_callback_t)(const char *buffer, size_t size, void *data);
buffer指向一个包含输出块的缓存区,size是缓存区的长度,data与json_dump_callback()函数传递过来的参数一致。
错误返回-1并且停止编码过程,成功返回0

int json_dump_callback(const json_t *json, json_dump_callback_t callback, void *data, size_t flags)
重复调用回调函数,每次传递root代表json的数据块。成功返回0,失败返回-1

译码
本节介绍用于将json文本译码成满足jansson规范的json数据的函数。json规范要求json文本是序列化的数组或者序列化的对象,并且以下函数也要满足该要求。也就是说,要被译码的json文本的最高层必须是数组或者对象。

Each function takes a flags parameter that can be used to control the behavior of the decoder. Its default value is 0. The following macros can be ORed together to obtain flags.
每个函数接受一个flag参数,该参数用于控制解码器的行为。它的默认值为0。以下宏可以获取标志。

JSON_REJECT_DUPLICATES
如果输入文本中的任何object型json含有重复的key,则发出解码错误信号。没有这个标志,键值最后出现所对应的值编码到结果中。key的相同性检查是逐字节检查的,没有特别的Unicode比较算法

JSON_DISABLE_EOF_CHECK
默认情况下,解码器希望它的整个输入都是一个有效的json文本,如果在有效的json输入之后含有其他的数据则会报一个错误。若设置这个标志,解码器将在解码一个有效数组或者对象json后停止,从而忽略json文本之后其他的数据。

以下函数展示了json实际的解码过程。
json_t *json_loads(const char *input, size_t flags, json_error_t *error)
解码input所指的json字符串,并返回它所包含的数组型json或者对象型json,失败返null并且error中填充错误信息。标志如上所述。

json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error)
对长度为buflen的json字符串缓冲区进行解码,并返回它所包含的数组型json或对象型json,或者返回空的错误,在这种情况下,错误中会填充有关错误的信息。这类似于json_loads(),只是字符串不需要以空结尾。标志如上所述。

json_t *json_loadf(FILE *input, size_t flags, json_error_t *error)
解码input输入流中的JSON文本并返回它包含的数组型json或对象型json。或者返回空的错误,在这种情况下,错误中会填充有关错误的信息。
此函数将开始从输入文件所在的任何位置读取输入,而不尝试首先查找。如果发生错误,文件位置将不确定。成功后,文件位置将位于eof,除非使用了json_disable_eof_check标志。在这种情况下,文件位置将位于JSON输入中最后一个]或之后的第一个字符。这允许多次对同一个文件对象调用json_Loadf(),前提是输入由连续的json文本组成,可能由空格分隔。

json_t *json_load_file(const char *path, size_t flags, json_error_t *error)
解码文件路径中的JSON文本并返回它所包含的数组或对象,或者返回出错时为空,在这种情况下,错误中会填充有关错误的信息。标志如上所述。

构造 Values
本节介绍有助于创建或者打包复杂json值的函数,尤其是嵌套的对象和数组型json。值的构建是基于格式化字符串的,该字符串用于告诉函数有关预期参数的信息。

例如,格式化字符串"i"指定单个整数值,而格式化字符串"[ssb]“或等效的”[s,s,b]"指定一个数组值,其中还有2个字符串元素和一个布尔值。
/* Create the JSON integer 42 */创建一个整型json,其值赋值为42
json_pack(“i”, 42);

/* Create the JSON array [“foo”, “bar”, true] */创建array型json[“foo”,“bar”,true]
json_pack("[ssb]", “foo”, “bar”, 1);
Here’s the full list of format characters. The type in parentheses denotes the resulting JSON type, and the type in brackets (if any) denotes the C type that is expected as the corresponding argument.
这里是格式化字符的完整列表,括号中的类型表示生成的json类型,中括号里的类型(如果有)表示预期作为相应参数的c类型

s (string) [const char *]
将以null结尾的utf-8字符串转换为字符串型json

n (null).
输出一个空值json,不需要任何参数

b (boolean) [int]
将一个c int值转换为布尔值型json。零装换为假,非零转换为真。

i (integer) [int]
将一个c int值转换为整型json

I (integer) [json_int_t]
将一个c json_int_t值转换为整型json

f (real) [double]
将一个c double值转换为实型json
o (any value) [json_t *]
按照原样输出任意给定的json值。如果将该json值添加到数组或对象中,容器会窃取传递给哦参数值的引用计数

O (any value) [json_t *]
和o类似,但是参数的引用计数是递增的。如果您打包到一个数组或对象中,并希望将O使用的JSON值的引用保留给您自己,那么这很有用

[fmt] (array)
使用内部格式字符串中的内容生成一个数组型json,fmt可能包括对象和数组,即支持递归值的生成

{fmt} (object)
使用内部格式字符串fmt中的内容生成一个对象json。第一和第三个等格式字符串代表一个键值,必须是字符串类型(因为对象的键值总是字符串)。第二、第四等格式字符串代表一个json值。可以是任意值(对象或数组等),因此支持递归值的生成。

以下函数是完成构造json值的api接口
json_t *json_pack(const char *fmt, …)
根据格式字符串fmt构建一个新的json值。对于每个格式字符(除了{}[]n),都需要一个参数来构建相应的json值。失败返回空

json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, …)
json_t *json_vpack_ex(json_error_t *error, size_t flags, const char *fmt, va_list ap)
和json_pack类似,但在发生错误地情况下,如果错误不为空,则会将错误消息写入error,flag参数当前未使用,应该被设置为0

例子:

/* Build an empty JSON object */
json_pack("{}");
/* Build the JSON object {"foo": 42, "bar": 7} */
json_pack("{sisi}", "foo", 42, "bar", 7);
/* Like above, ':', ',' and whitespace are ignored */
json_pack("{s:i, s:i}", "foo", 42, "bar", 7);
/* Build the JSON array [[1, 2], {"cool": true}] */
json_pack("[[i,i],{s:b}]", 1, 2, "cool", 1);

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

分析和验证值
本节介绍了有助于验证复杂值并从中提取或解包数据的函数。与构建值一样,这也是基于格式字符串的。

在解包json时,将检查格式字符串中指定的类型来匹配json值。这就是过程的验证部分。除此之外,解包函数也将检查数组和对象的所有项是否已解包。这个检查可以用格式字符来启动。或者使用JSON_STRICT标志。

这是格式字符的完整列表。括号中的类型表示JSON类型,中括号里的类型(如果有)表示应该传递内容c类型的地址。

s (string) [const char *]
将一个字符串型json转换为以null结尾的utf-8字符串指针。结果字符串是通过内部使用json_string_value()提取的。因此只要还有对相应字符串json的引用,该字符串json就一直存在。

n (null)
什么也不提取

b (boolean) [int]
将一个布尔值型json转化为一个c int,true转换为1,假转换为0

i (integer) [int]
将一个整型json转换为c int

I (integer) [json_int_t]
将一个整型json转换为c json_int_t

f (real) [double]
将一个实型json转换为double

F (integer or real) [double]
将一个数型json(整型或实型)转换为double

o (any value) [json_t *]
Store a JSON value with no conversion to a json_t pointer.

O (any value) [json_t *]
Like O, but the JSON value’s reference count is incremented.

[fmt] (array)
根据内部格式字符串转换JSON数组中的每个项。fmt可以包含对象和数组,即支持递归值提取。

{fmt} (object)
根据内部格式字符串fmt转换JSON对象中的每个项。第一个、第三个等格式字符表示一个键,必须是字符串。解包函数的相应参数读取为对象键。第二个、第四个等格式字符表示一个值,并作为相应的参数写入给定的地址。注意,其他每一个参数都是从中读出来的,其他每一个都是写出来的。
fmt可以包含对象和数组作为值,即支持递归值提取。

!
此特殊格式字符用于检查是否按值访问所有对象和数组项。它必须作为右括号或大括号之前的最后一个格式字符出现在数组或对象中。要全局启用检查,请使用json_strict un解包标志。

这个特殊格式的字符是与!相反作用的。如果使用json_strict标志,* 可用于禁用每个值的严格检查。它必须作为右括号或大括号之前的最后一个格式字符出现在数组或对象中。

以下函数构成分析和验证API:
int json_unpack(json_t *root, const char *fmt, …)
根据格式字符串fmt验证并解包json根植,成功返回0,失败返回0

int json_unpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, …)
int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, va_list ap)
根据格式字符串fmt验证并解包json根植,错误信息写入错误指针error,标志用来控制解包行为

注意:
所有解包函数的第一参数是json_t *root而不是const json_t *root,因为,使用O格式字符会增加根或者某些从根可达json值的引用计数。另外,o字符格式可以照样提取json值,并且可以修改可从根访问的json值的结构或内容

如果不使用O和o格式字符,那么这些函数使用时,将const json_t变量强制转换json_t是完全安全的。

T解包标志如下所示:
JSON_STRICT
启用额外的验证步骤,检查是否已解包所有对象和数组项。这相当于附加格式字符!到每个数组和对象格式字符串的结尾。

JSON_VALIDATE_ONLY
不提取任何数据,只是根据给定的格式字符串验证json的值
注意,对象的键值必须在格式字符串之后指定

例子:

/* root is the JSON integer 42 */
int myint;
json_unpack(root, "i", &myint);
assert(myint == 42);
/* root is the JSON object {"foo": "bar", "quux": true} */
const char *str;
int boolean;
json_unpack(root, "{s:s, s:b}", "foo", &str, "quux", &boolean);
assert(strcmp(str, "bar") == 0 && boolean == 1);
/* root is the JSON array [[1, 2], {"baz": null} */
json_error_t error;
json_unpack_ex(root, &error, JSON_VALIDATE_ONLY, "[[i,i], {s:n}]", "baz");
/* returns 0 for validation success, nothing is extracted */
/* root is the JSON array [1, 2, 3, 4, 5] */
int myint1, myint2;
json_unpack(root, "[ii!]", &myint1, &myint2);
/* returns -1 for failed validation */

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

相等比较
通常,无法使用运算符来测试两个JSON值是否相等。用运算符表示的相等表示两个JSON指针指向完全相同的JSON值。然而,两个JSON值不仅可以是完全相同的值,而且“内容”也是相等的:

两个整型或实型json值,如果包含的数值相等则它们相等,不过,实型json值绝不等于整型json值
如果包含的utf-8字符串逐字节比较相等,则两个字符串是相等的。
如果两个数组的元素数目相同,并且第一个数组中的每个元素等于第二个数组中的相应元素,则两个数组相等。
如果两个对象的键完全相同,并且第一个对象中每个键的值等于第二个对象中相应键的值,则两个对象相等。(即键值对需要相等)
两个真、假或空值没有“内容”,因此如果它们的类型相同,它们就相等。(因为这些值是单件的,所以实际上可以用==来测试它们的相等性。)

以下函数用来比较两个json值是否相等
int json_equal(json_t *value1, json_t *value2)
相等返回1 ,不相等返回0,如果两个参数空也返回0

拷贝
由于引用计数,传递JSON值不需要复制它们。但有时需要一个新的JSON值副本。例如,如果您需要修改一个数组,但之后仍然想使用原始数组,那么您应该首先复制它

jansson支持两种复制:浅拷贝和深拷贝。这些方法之间只有数组型json和对象json有区别。浅拷贝仅拷贝第一级(根级)json值(数组或对象),并在拷贝的值中使用相同的子值。深度拷贝会生成子值的新副本。此外,所有子值都以递归方式进行深度拷贝

json_t *json_copy(json_t *value)
浅拷贝,返回新json值的指针.,失败返回空

json_t *json_deep_copy(json_t *value)
深拷贝,返回新json值的指针.,失败返回空

自定义内存分配
默认情况下,Jansson使用malloc()和free()进行内存分配。如果需要自定义行为,可以重写这些函数。

json_malloc_t
带有malloc()签名的函数指针的typedef
typedef void *(*json_malloc_t)(size_t);

json_free_t
带有free()签名的函数指针的typedef
typedef void (*json_free_t)(void *);

void json_set_alloc_funcs(json_malloc_t malloc_fn, json_free_t free_fn)
使用malloc_fn代替malloc(),使用free_fn代替free()。必须在任何其他Jansson的API函数之前调用此函数(类似声明),以确保所有内存操作使用相同的函数。

、例子:
Use the Boehm’s conservative garbage collector for memory operations:

json_set_alloc_funcs(GC_malloc, GC_free);
释放后再将所有内存清零,则允许在JSON结构中存储敏感数据(例如密码或加密密钥):

static void *secure_malloc(size_t size)
{
    /* Store the memory area size in the beginning of the block */
    void *ptr = malloc(size + 8);
    *((size_t *)ptr) = size;
    return ptr + 8;
}
static void secure_free(void *ptr)
{
    size_t size; 
    ptr -= 8;
    size = *((size_t *)ptr); 
    guaranteed_memset(ptr, 0, size);
    free(ptr);
}
int main()
{
    json_set_alloc_funcs(secure_malloc, secure_free);
    /* ... */
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值