json库实现笔记

经验

1.单元测试非常非常重要!!一定要熟悉单元测试的写法,以及尽可能多的寻找更多可能的测试样例
2.在适当的地方加assert有助于寻找定位出程序的bug
3.注意解析number时的各种边界条件和特殊值的检验,根据json的number语言标准判断每一种特殊情况,支持这一步最重要的一点就是写好单元测试,测试每一种边界条件和特殊值,下面给出部分边界条件和特殊值。

json库

0.总览:

解析的时候是将数据先放入临时的存储空间lept_context,
当解析字符串,数组,对象等时,无法事先知道需要多少空间,所以需要动态的存储空间来存储临时,使用自定义的栈来存储

1.解析null,true,false

2.解析number

3.解析字符串

1) json格式下的字符串与普通字符串

json格式下的字符串与普通字符串的区别如下:

	TEST_STRING("Hello\nWorld", "\"Hello\\nWorld\"");
	TEST_STRING("\" \\ / \b \f \n \r \t", "\"\\\" \\\\ \\/ \\b \\f \\n \\r \\t\"");

上述两个测试用例中,左边为普通字符串,右边为将普通字符串传换成的JSON字符串

4.解析unicode码

1) 16进制数转10进制数的小技巧

当将16进制数转为10进制数时,例如const char str[] = “1234”,最先想到的方法一定是

str[0]*pow(16,3)+str[1]*pow(16,2)+str[2]*pow(16,1)+str[3];

其实也可以通过位运算来方便简洁的求解,

	int u=0;
	for (int i = 0; i < 4; i++)
	{
		*u <<= 4;
		char tmp = *p++;
		if ('0' <= tmp&&tmp <= '9')
			*u |= (tmp - '0');
		else if ('A' <= tmp&&tmp <= 'F')
			*u |= (tmp - 'A' + 10);
		else if ('a' <= tmp&&tmp <= 'f')
			*u |= (tmp - 'a' + 10);
		else
			return NULL;
	}

5.解析数组

1)malloc进阶
memcpy(v->u.a.e = (lept_value*)malloc(size), lept_context_pop(c, size), size);
2)

6.解析对象

1)很重要的一点:对于函数的封装的思考:

int lept_parse_value(lept_context* c, lept_value* v)

对于上述函数,对于传入的v,该函数保证了以下:
无论传入的v是刚创建分配的新的lept_value对象,或者是已经使用过的“脏”的lept_value对象,lept_parse_value函数都能进行正确的解析过程,什么是正确的解析过程呢,先看lept_value的定义:

struct lept_value {
	union {
		struct { lept_member* m; size_t size; }o;   /* object: members, member count */
		struct { lept_value* e; size_t size; }a;    /* array:  elements, element count */
		struct { char* s; size_t len; }s;           /* string: null-terminated string, string length */
		double n;                                   /* number */
	}u;
	lept_type type;
};

如果lept_value 存储的是number对象,那么可以用新的number对象直接覆盖旧的number对象,这里没有涉及动态内存的分配,所以比较容易处理,但是如果lept_value 存储的是string对象等,因为s中带有动态内存的分配,所以必须先调用对应的free函数来释放空间,然后再调用malloc分配新的空间,然后再进行相应的赋值操作。所以该函数正常完成之后,v是一个“脏”的lept_value对象。在最后的最后需要释放其中可能存在的动态内存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值