json-c-0.9库解析
来源:互联网 发布:淘宝店铺托管协议 编辑:程序博客网 时间:2024/06/04 18:04
json-c-0.9库解析
- 预备知识
- linux内核哈希表hlist
项目中使用json格式字符串进行进程间通信,使用json-c-0.9库进行字符串解析和设置,现将json-c-0.9库进行说明,欢迎指正~~
1. 编译
- ./configure CC= –host= –prefix=PATH
指定编译器、主机类型、安装路径(绝对路径),默认路径/usr/local - make && make install
修改config.h.in屏蔽#undef malloc 和 #undef realloc后执行,
这样json就已经安装成功。 - -std=c99 -I/PATH/incldue/json -L/PATH/lib -ljson
在程序中使用json的api只需要在编译程序时添加以上信息
例如这样编译库中test1.c:
gcc test1.c -o test1 -std=c99 -I/PATH/incldue/json -L/PATH/lib -ljson
2. 数据结构(data structures)
比较重要的数据结构:
1. struct json_object
struct json_object{ enum json_type o_type; //json对象类型 json_object_delete_fn *_delete; //free json对象 json_object_to_json_string_fn *_to_json_string; //转换json对象为json格式的字符串 int _ref_count; //json对象引用计数,初始化为1 struct printbuf *_pb; //存储json对象转换后的字符串内存区域地址 union data { boolean c_boolean; //boolean类型json对象的数值 double c_double; //double类型json对象的数值 int c_int; //int类型json对象的数值 struct lh_table *c_object; //存储object类型json对象的hash_table地址 struct array_list *c_array; //存储array类型json对象的字符串数组地址 char *c_string; //存储string类型json对象的地址 } o;};
2. struct json_tokener
struct json_tokener{ char *str; struct printbuf *pb; //用于分类存储待解析字符串的buffer int depth; //结构体成员stack的depth int is_double; //value是double or int int st_pos; //string中某字符的position,string包括:null,true,false,unicode int char_offset; //某字符在待解析字符串中的offset ptrdiff_t err; //字符串解析出错代码 unsigned int ucs_char; //unicode的值 char quote_char; //存储引号" struct json_tokener_srec stack[JSON_TOKENER_MAX_DEPTH]; //存储待解析字符串中所有的json对象};
3. struct json_object 和 struct json_tokener 的成员struct printbuf定义如下,定义一个buffer,用于存储字符串;
struct printbuf { char *buf; int bpos; //buf中已经使用的数量 int size; //buf的size};
4. struct json_tokener 的成员struct json_tokener_srec定义如下,定义一个stack,用于存储不同类型object对象;
struct json_tokener_srec{ enum json_tokener_state state, saved_state; struct json_object *obj; //暂未使用 struct json_object *current; char *obj_field_name; //object某一个field的name};
3. 文件(files)
获取json-c-0.9.tar.gz解压后,包含的源码文件如图,下面内容大致介绍文件的主要代码:
json_object.c
定义json对象的操作函数,包括新建、删除、转换、添加等函数;1. json_object_new()/json_object_to_json_string()/json_object_generic_delete() 三个函数分别new一个json对象/转换json对象为json格式的字符串/删除json对象,相当于父类。
json_object_new()实现:
static struct json_object* json_object_new(enum json_type o_type) { struct json_object *jso; jso = (struct json_object*)calloc(sizeof(struct json_object), 1); //new一个json_object对象,并赋值 if(!jso) return NULL; jso->o_type = o_type; jso->_ref_count = 1; jso->_delete = &json_object_generic_delete; ... return jso; }
json_object_to_json_string()实现
const char* json_object_to_json_string(struct json_object *jso) { if(!jso) return "null"; if(!jso->_pb) { if(!(jso->_pb = printbuf_new())) return NULL; } else { printbuf_reset(jso->_pb);//如果存在,则复位存储json对象转换后的字符串的内存区域,否则new一个新区域 } if(jso->_to_json_string(jso, jso->_pb) < 0) return NULL; //依据传入的json对象(struct json_object *jso), //jso->_to_json_string(jso, jso->_pb)调用相应的json_object_**_to_json_string()函数 return jso->_pb->buf; }
json_object_generic_delete()实现
static void json_object_generic_delete(struct json_object* jso) { ... printbuf_free(jso->_pb); free(jso); }
2. json_object_new_**()/json_object_**_to_json_string()/json_object_**_delete() 三个系列函数分别new一个“子类”的json对象/转换“子类”的json对象为json格式的字符串/删除“子类”的json对象; 其中的“子类”的json对象包括boolean、double、int、object、array、string等类型;
以object类型json对象为例:
json_object_new_**()实现
struct json_object* json_object_new_object(void) { struct json_object *jso = json_object_new(json_type_object); if(!jso) return NULL; jso->_delete = &json_object_object_delete; //在json_object_new()基础上填充._to_json_string、.o.c_object方法, jso->_to_json_string = &json_object_object_to_json_string; //并覆写._delete方法 jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES, NULL, &json_object_lh_entry_free); return jso; }
json_object_**_to_json_string()实现
static int json_object_object_to_json_string(struct json_object* jso, struct printbuf *pb) { int i=0; struct json_object_iter iter; sprintbuf(pb, "{"); //object类型json对象的json格式字符串开始 /* CAW: scope operator to make ANSI correctness */ /* CAW: switched to json_object_object_foreachC which uses an iterator struct */ json_object_object_foreachC(jso, iter) { //遍历json对象所有的key和value if(i) sprintbuf(pb, ","); sprintbuf(pb, " \""); json_escape_str(pb, iter.key); sprintbuf(pb, "\": "); if(iter.val == NULL) sprintbuf(pb, "null"); else iter.val->_to_json_string(iter.val, pb); //依据json对象(iter.val),选择相应的json_object_**_to_json_string() i++; } return sprintbuf(pb, " }"); //object类型json对象的json格式字符串结束 }
json_object_**_delete()实现
static void json_object_object_delete(struct json_object* jso) { lh_table_free(jso->o.c_object); //free hash_table json_object_generic_delete(jso); //free json对象 }
3. json_object_get()/json_object_put() 增加json对象引用计数/减少json对象引用计数
4. json_object_object_add()/json_object_object_get()/json_object_object_del() 添加一个feild到object类型的json对象/从object类型的json对象获取一个feild/删除object类型的json对象中一个feild
5. json_object_array_add()/json_object_array_put_idx()/json_object_array_get_idx() 添加一个element(json对象)到array类型的json对象尾部/添加一个element到array类型的json对象的 某个位置/获取array类型的json对象的某个位置的element
- json_tokener.c
定义解析字符串为json对象函数以及两个重要的宏POP_CHAR(dest, tok)和ADVANCE_CHAR(str, tok)
POP_CHAR(dest, tok)
#define POP_CHAR(dest, tok) \(((tok)->char_offset == len) ? \ (((tok)->depth == 0 && state == json_tokener_state_eatws && saved_state == json_tokener_state_finish) ? \ (((tok)->err = json_tokener_success), 0) \ : \ (((tok)->err = json_tokener_continue), 0) \ ) : \ (((dest) = *str), 1) \ ) //将字符*str赋值给dest,并返回1;当到达字符串结尾(tok->char_offset == len)时检查depth、state和saved_state,设置tok->err,并返回0
ADVANCE_CHAR(str, tok)
#define ADVANCE_CHAR(str, tok) \ ( ++(str), ((tok)->char_offset)++, c) //遍历字符串str,同步递增tok->char_offset,并返回字符c //和POP_CHAR(c, tok)一起使用,实现对字符串str的字符进行遍历,并设置遍历的结果状态(tok->err)
定义的函数包括新建/删除json_tokener对象函数json_tokener_new()/json_tokener_free(),以及解析函数json_tokener_parse**();其中json_tokener_parse_ex()函数很重要,此函数通过state和saved_state两个状态控制函数流程,state和saved_state 取下面枚举值;
enum json_tokener_state { json_tokener_state_eatws, //ew json_tokener_state_start, //st json_tokener_state_finish, //fi ... json_tokener_state_string, //str json_tokener_state_string_escape, //str_esc json_tokener_state_escape_unicode, //uni ... json_tokener_state_array, //arr json_tokener_state_array_add, //arr_a json_tokener_state_array_sep, //arr_s json_tokener_state_object_field_start, //ofs json_tokener_state_object_field, //of json_tokener_state_object_field_end, //ofe json_tokener_state_object_value, //ov json_tokener_state_object_value_add, //ova json_tokener_state_object_sep //os};
json_tokener_parse_ex() 函数可以解析boolean、double、int、object、array、string等类型的json对象,以object类型的json对象的解析过程为例,说明解析流程(重点介绍解析过程中state和saved_state 转换过程,详细流程查看源码)
linkhash.c
这个文件中函数用于处理存储object类型json对象的hash_table,包括新建hash_table函数lh_table_new()/lh_**_table_new(),删除hash_table
函数lh_table_free(),添加record到hash_table函数lh_table_insert(),删除record函数lh_table_delete()/lh_table_delete_entry(),查找record
函数lh_table_lookup()/lh_table_lookup_entry();
关于hash_table的知识请参考预备知识 : linux内核哈希表hlist;arraylist.c
这个文件中函数用于处理存储array类型json对象的arraylist,包括新建arraylist函数array_list_new(),删除arraylist函数array_list_free(),
添加元素到arraylist函数array_list_add()/array_list_put_idx(),查找元素函数array_list_get_idx();debug.c
定义不等等级的日志输出函数以及对应的宏,MC_DEBUG()/mc_debug()/..;printbuf.c
定义内存操作函数,新建函数printbuf_new(),内存拷贝函数printbuf_memappend()等;json_util.c
定义从文件读取字符串解析为json对象函数json_object_from_file()和将json对象转化为json格式字符串写入文件函数json_object_to_file();
4. json格式通信的收发流程
- 接收:
read()(读取字符串数据)
–> json_tokener_parse()(从字符串数据中解析json对象)
–> json_object_get_*()(从json对象中获取数据value,如int、double、string、array、object等) - 发送:
json_object_new_*()(生成json对象)
–> json_object_object_add()/json_object_array_add()/json_object_to_json_string().. (往json对象添加数据并转换字符串数据)
–> write()(发送字符串数据)
5. 举例
项目中使用json格式字符串进行进程间通信,流程如下:
读取进程间通信数据(字符串) –> 解析出json对象 –> 处理json对象 –> … –> 生成json对象并添加数据 –> 转换json对象为json格式字符串并发送
6. 小结
本文简绍项目中使用的json-c-0.9库解析、处理json格式字符串的实现流程,并简单说明使用json-c-0.9进行通信的原理,欢迎指正和讨论^_^。
疑问
- json_object.h 30~38行的定义有什么用?
printbuf、lh_table、… 这些结构体在别的地方已经定义,再次定义的作用是什么..
/* forward structure definitions */ typedef int boolean; typedef struct printbuf printbuf; typedef struct lh_table lh_table; typedef struct array_list array_list; typedef struct json_object json_object; typedef struct json_object_iter json_object_iter; typedef struct json_tokener json_tokener;
- json-c-0.9库解析
- C#,Json解析,Json遍历
- json-c-0.9解析出错位置查看
- Json解析 - c语言库libJsonParser
- JSON解析类(C#)
- JSON解析类(C#)
- c#,js解析json
- C语言解析JSON
- c语言解析json
- 【C++】Json解析
- c语言解析json
- c json解析jansson
- c#、js解析json
- C++JSON解析器
- cJSON库(构建json与解析json字符串)-c语言
- cJSON库(构建json与解析json字符串)-c语言
- cJSON库(构建json与解析json字符串)-c语言
- cJSON库(构建json与解析json字符串)-c语言
- winForm 读取Web.config 包含(xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0")
- WordPress出现循环重定向解决办法
- 帮助新手理解MVC,可以看看,思维导图原件可以找我
- 弹窗关闭
- Make file 函数
- json-c-0.9库解析
- quagga关于vpnv4的配置
- Tomcat内存设置详解
- gdx camera详解
- Lists
- 《Linux内核设计与实现》读书笔记(二)- 内核开发的准备
- 自动化测试软件分类
- 几行代码实现RPC框架
- 20170119总结