概述
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库解析json-c-0.9库解析的全部内容,希望文章能够帮你解决json-c-0.9库解析json-c-0.9库解析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复