lept_json的学习之API

lept_json的学习之API

这一节就整理一下所有的api


先从整个JSON开始

Parse

用户只能用到parse,像parse_value、parse_whitespace之类就属于内部函数了

int lept_parse(lept_value& v, const char* json){
	lept_context c;
	int ret;
	assert(&v != NULL);
	c.json = json;
	c.stack = NULL;//初始化堆栈
	c.size =c.top = 0;//初识化栈容量和栈顶
	lept_init(v);
	lept_parse_whitespace(c);
	if ((ret = lept_parse_value(c, v)) == LEPT_PARSE_OK) {
		lept_parse_whitespace(c);
		if (*(c.json) != '\0') {
			v.type = LEPT_NULL;
			ret = LEPT_PARSE_ROOT_NOT_SINGULAR;
		}
	}
	assert(c.top == 0);//判断栈顶元素是否为0(即栈中所有数据成功弹出
	free(c.stack);//释放栈
	return ret;
}

Stringify

char* lept_stringify(const lept_value& v, size_t length) {
	lept_context c;
	assert(&v != NULL);
	c.stack = (char*)malloc(c.size = LEPT_PARSE_STRINGIFY_INIT_SIZE);
	c.top = 0;
	lept_stringify_value(c, v);
	if (length)
		length = c.top;
	PUTC(c, '\0');
	return c.stack;
}

Free(JSON)

内存释放也是api,可以给用户使用,让用户在内存管理这一块可以更加确定一块内存的使用与否。

void lept_free (lept_value & v) {
	size_t i;
	assert(&v != NULL);
	switch (v.type) {
	case LEPT_STRING:
		free(v.u.m_str.s);
		break;
	case LEPT_ARRAY:
		for (i = 0; i < v.u.m_arr.size; i++)
			lept_free(v.u.m_arr.e[i]);
		free(v.u.m_arr.e);
		break;
	case LEPT_OBJECT:
		for (i = 0; i < v.u.m_obj.size; i++) {
			free(v.u.m_obj.m[i].k);
			lept_free(v.u.m_obj.m[i].v);
		}
		free(v.u.m_obj.m);
		break;
	default: break;
	}
	v.type = LEPT_NULL;
}

Tool

两值是否相等?相等则返回1,不相等则返回0

size_t lept_find_object_index(const lept_value& v, const char* key, size_t klen);//前向声明
int lept_is_equal(const lept_value& lhs, const lept_value& rhs) {
	size_t i;
	assert(&lhs != NULL && &rhs != NULL);
	if (lhs.type != rhs.type)
		return 0;
	switch (lhs.type) {
	case LEPT_STRING:
		return lhs.u.m_str.len == rhs.u.m_str.len &&
			memcmp(lhs.u.m_str.s, rhs.u.m_str.s, lhs.u.m_str.len) == 0;
	case LEPT_NUMBER:
		return lhs.u.m_num == rhs.u.m_num;
	case LEPT_ARRAY:
		if (lhs.u.m_arr.size != rhs.u.m_arr.size)
			return 0;
		for (i = 0; i < lhs.u.m_arr.size; i++)
			if (!lept_is_equal(lhs.u.m_arr.e[i], rhs.u.m_arr.e[i]))
				return 0;
		return 1;
	case LEPT_OBJECT://对象的键值是无序的,所以不能像array那样逐个比对
		if (lhs.u.m_obj.size != rhs.u.m_obj.size)
			return 0;
		for (i = 0; i < lhs.u.m_obj.size; i++) {
			if (lept_find_object_index(rhs, lhs.u.m_obj.m[i].k, lhs.u.m_obj.m[i].klen) == LEPT_KEY_NOT_EXIST)
				return 0;
			if (!lept_is_equal(lhs.u.m_obj.m[i].v, rhs.u.m_obj.m[i].v))
				return 0;
		}
		return 1;
	default:
		return 1;
	}
}

将一个值赋值给另一个值

void lept_copy(lept_value& dst, const lept_value& src)
{
	size_t i;
	assert(&src != NULL && &dst != NULL && &src != &dst);
	switch (src.type) {
	case LEPT_STRING:
		lept_set_string(dst, src.u.m_str.s, src.u.m_str.len);
		break;
	case LEPT_ARRAY:
		lept_set_array(dst, src.u.m_arr.size);
		for (i = 0; i < src.u.m_arr.size; i++) {
			lept_copy(dst.u.m_arr.e[i], src.u.m_arr.e[i]);
		}
		dst.u.m_arr.size = src.u.m_arr.size;
		break;
	case LEPT_OBJECT:
		lept_set_object(dst, src.u.m_obj.size);

		for (i = 0; i < src.u.m_obj.size; i++) {
			//k
			lept_value& val = lept_set_object_value(dst, src.u.m_obj.m[i].k, src.u.m_obj.m[i].klen);
			//v
			lept_copy(val, src.u.m_obj.m[i].v);
		}
		dst.u.m_obj.size = src.u.m_obj.size;
		break;
	default:
		lept_free(dst);
		memcpy(&dst, &src, sizeof(lept_value));
		break;
	}
}

将一个值移动到目标容器

void lept_move(lept_value& dst, lept_value& src)
{
	assert(&dst != NULL && &src != NULL && &src != &dst);
	lept_free(dst);
	memcpy(&dst, &src, sizeof(lept_value));
	lept_init(src);
}

交换两个值

void lept_swap(lept_value& lhs, lept_value& rhs)
{
	assert(&lhs != NULL && &rhs != NULL);
	if (&lhs != &rhs) {
		lept_value temp;
		memcpy(&temp, &lhs, sizeof(lept_value));
		memcpy(&lhs, &rhs, sizeof(lept_value));
		memcpy(&rhs, &temp, sizeof(lept_value));
	}
}

NULL类型

#define lept_set_null(v) lept_free(v)

对的,null的api其实就是free

BOOL类型

int lept_get_boolean(const lept_value& v)
{
	assert(&v != NULL && (v.type == LEPT_TRUE || v.type == LEPT_FALSE));
	return v.type == LEPT_TRUE;
}
void lept_set_boolean(lept_value& v, int b)
{
	lept_free(v);
	v.type = b ? LEPT_TRUE : LEPT_FALSE;
}

NUMBER类型

double lept_get_number(const lept_value& v)
{
	assert(&v != NULL);
	assert(v.type == LEPT_NUMBER);
	return v.u.m_num;
}
void lept_set_number(lept_value& v, double n)//唐铭德独自完成(但做错了
{
	lept_free(v);
	v.u.m_num = n;
	v.type = LEPT_NUMBER;
}

STRING类型

const char* lept_get_string(const lept_value& v) {
	assert(&v != NULL && v.type == LEPT_STRING);
	return v.u.m_str.s;
}
size_t lept_get_string_length(const lept_value& v) {
	assert(&v != NULL && v.type == LEPT_STRING);
	return v.u.m_str.len;
}
//设置字符串,将v的s置为输入字符串值和输入字符串长度
void lept_set_string(lept_value& v, const char* s, size_t len) {
	assert(&v != NULL && (s != NULL || len == 0));//数据类型不为空,且字符串不为空或长度为0
	lept_free(v);                                //先释放v的string 内存
	v.u.m_str.s = (char*)malloc(len + 1);   //重新分配内存
	memcpy(v.u.m_str.s, s, len);            //内存值copy过去
	v.u.m_str.s[len] = '\0';                //字符串尾置为空字符
	v.u.m_str.len = len;                    //字符串长赋值
	v.type = LEPT_STRING;               //类型改为string类
}

ARRAY类型

size_t lept_get_array_size(const lept_value& v)
{
	assert(&v != NULL);
	assert(v.type == LEPT_ARRAY);
	return v.u.m_arr.size;
}
size_t lept_get_array_capacity(const lept_value& v)
{
	assert(&v != NULL && v.type == LEPT_ARRAY);
	return v.u.m_arr.capacity;
}
void lept_reserve_array(lept_value& v, size_t capacity)
{
	assert(&v != NULL && v.type == LEPT_ARRAY);
	if (v.u.m_arr.capacity < capacity) {
		v.u.m_arr.capacity = capacity;
		v.u.m_arr.e = (lept_value*)realloc(v.u.m_arr.e, capacity * sizeof(lept_value));
	}
}
void lept_shrink_array(lept_value& v)
{
	assert(&v != NULL && v.type == LEPT_ARRAY);
	if (v.u.m_arr.capacity > v.u.m_arr.size) {
		v.u.m_arr.capacity = v.u.m_arr.size;
		v.u.m_arr.e = (lept_value*)realloc(v.u.m_arr.e, v.u.m_arr.capacity * sizeof(lept_value));
	}
}
lept_value& lept_pushback_array_element(lept_value& v)
{
	assert(&v != NULL && v.type == LEPT_ARRAY);
	if (v.u.m_arr.size == v.u.m_arr.capacity)
		lept_reserve_array(v, v.u.m_arr.capacity == 0 ? 1 : v.u.m_arr.capacity * 2);
	lept_init(v.u.m_arr.e[v.u.m_arr.size]);
	return v.u.m_arr.e[v.u.m_arr.size++];
}
void lept_popback_array_element(lept_value& v)
{
	assert(&v != NULL && v.type == LEPT_ARRAY && v.u.m_arr.size > 0);
	lept_free(v.u.m_arr.e[--v.u.m_arr.size]);
}
lept_value& lept_insert_array_element(lept_value& v, size_t index)
{
	assert(&v != NULL && v.type == LEPT_ARRAY && index <= v.u.m_arr.size);
	if (v.u.m_arr.size == v.u.m_arr.capacity)
		lept_reserve_array(v, v.u.m_arr.capacity == 0 ? 1 : (v.u.m_arr.capacity << 1)); //扩容为原来一倍
	memcpy(&v.u.m_arr.e[index + 1], &v.u.m_arr.e[index], (v.u.m_arr.size - index) * sizeof(lept_value));
	lept_init(v.u.m_arr.e[index]);
	v.u.m_arr.size++;
	return v.u.m_arr.e[index];
}
void lept_erase_array_element(lept_value& v, size_t index, size_t count)
{
	assert(&v != NULL && v.type == LEPT_ARRAY && index + count <= v.u.m_arr.size);
	size_t i;
	for (i = index; i < index + count; i++) {
		lept_free(v.u.m_arr.e[i]);
	}
	memcpy( v.u.m_arr.e + index,
			v.u.m_arr.e + index + count,
		   (v.u.m_arr.size - index - count) * sizeof(lept_value));
	for (i = v.u.m_arr.size - count; i < v.u.m_arr.size; i++)
		lept_init(v.u.m_arr.e[i]);
	v.u.m_arr.size -= count;
}
void lept_clear_array(lept_value& v)
{
	assert(&v != NULL && v.type == LEPT_ARRAY);
	size_t i;
	for (i = 0; i < v.u.m_arr.size; i++) {
		lept_free(v.u.m_arr.e[i]);
	}
	v.u.m_arr.size = 0;
}
lept_value& lept_get_array_element(const lept_value& v, size_t index) //返回数组中第index个元素
{
	assert(&v != NULL);
	assert(v.type == LEPT_ARRAY);
	assert(index < v.u.m_arr.size);
	return v.u.m_arr.e[index];
}
void lept_set_array(lept_value& v, size_t capacity)
{
	assert(&v != NULL);
	lept_free(v);
	v.type = LEPT_ARRAY;
	v.u.m_arr.size = 0;
	v.u.m_arr.capacity = capacity;
	v.u.m_arr.e = capacity > 0 ? (lept_value*)malloc(capacity * sizeof(lept_value)) : NULL;
}

array中的reserve和shrink也都是为了方便用户内存管理

OBJECT类型

void lept_set_object(lept_value& v, size_t capacity)
{
	assert(&v != NULL);
	lept_free(v);
	v.type = LEPT_OBJECT;
	v.u.m_obj.size = 0;
	v.u.m_obj.capacity = capacity;
	v.u.m_obj.m = capacity > 0 ? (lept_member*)malloc(capacity * sizeof(lept_member)) : NULL;
}

size_t lept_get_object_size(const lept_value& v)
{
	assert(&v != NULL );
	assert(v.type == LEPT_OBJECT);
	return v.u.m_obj.size;
}
size_t lept_get_object_capacity(const lept_value& v)
{
	assert(&v != NULL );
	assert(v.type == LEPT_OBJECT);
	return v.u.m_obj.capacity;
}
const char* lept_get_object_key(const lept_value& v, size_t index)
{
	assert(&v != NULL );
	assert( v.type == LEPT_OBJECT);
	assert(index < v.u.m_obj.size);
	return v.u.m_obj.m[index].k;
}
size_t lept_get_object_key_length(const lept_value& v, size_t index)
{
	assert(&v != NULL);
	assert(v.type == LEPT_OBJECT);
	assert(index < v.u.m_obj.size);
	return v.u.m_obj.m[index].klen;
}
lept_value& lept_get_object_value(const lept_value& v, size_t index)
{
	assert(&v != NULL);
	assert(v.type == LEPT_OBJECT);
	assert(index < v.u.m_obj.size);
	return v.u.m_obj.m[index].v;
}

size_t lept_find_object_index(const lept_value& v, const char* key, size_t klen)//知道key值和长度查index
{
	size_t i;
	assert(&v != NULL && v.type == LEPT_OBJECT && key != NULL);
	for (i = 0; i < v.u.m_obj.size; i++)
		if (v.u.m_obj.m[i].klen == klen && memcmp(v.u.m_obj.m[i].k, key, klen) == 0)
			return i;
	return LEPT_KEY_NOT_EXIST;
}

lept_value& lept_find_object_value(lept_value& v, const char* key, size_t klen) {
	assert(&v != NULL);
	assert(key != NULL);
	assert(klen != 0);
	size_t index = lept_find_object_index(v, key, klen);
	assert(index != LEPT_KEY_NOT_EXIST);
	return v.u.m_obj.m[index].v;
}
lept_value& lept_set_object_value(lept_value& v, const char* key, size_t klen)
{
	assert(&v != NULL && v.type == LEPT_OBJECT && key != NULL);
	size_t i,index;
	index = lept_find_object_index(v, key, klen);
	if (index != LEPT_KEY_NOT_EXIST)
		return v.u.m_obj.m[index].v;
	//key not exist, then we make room and init
	if (v.u.m_obj.size == v.u.m_obj.capacity) {
		lept_reserve_object(v, v.u.m_obj.capacity == 0 ? 1 : (v.u.m_obj.capacity << 1));
	}
	i = v.u.m_obj.size;
	v.u.m_obj.m[i].k = (char*)malloc((klen + 1));
	memcpy(v.u.m_obj.m[i].k, key, klen);
	v.u.m_obj.m[i].k[klen] = '\0';
	v.u.m_obj.m[i].klen = klen;
	lept_init(v.u.m_obj.m[i].v);
	v.u.m_obj.size++;
	return v.u.m_obj.m[i].v;
}
void lept_remove_object_value(lept_value& v, size_t index)
{
	assert(&v != NULL && v.type == LEPT_OBJECT && index < v.u.m_obj.size);
	free(v.u.m_obj.m[index].k);
	lept_free(v.u.m_obj.m[index].v);
	memcpy(v.u.m_obj.m + index, v.u.m_obj.m + index + 1, (v.u.m_obj.size - index - 1) * sizeof(lept_member));
	v.u.m_obj.m[--v.u.m_obj.size].k = NULL;
	v.u.m_obj.m[v.u.m_obj.size].klen = 0;
	lept_init(v.u.m_obj.m[v.u.m_obj.size].v);
}
void lept_reserve_object(lept_value& v, size_t capacity)
{
	assert(&v != NULL && v.type == LEPT_OBJECT);
	if (v.u.m_obj.capacity < capacity) {
		v.u.m_obj.capacity = capacity;
		v.u.m_obj.m = (lept_member*)realloc(v.u.m_obj.m, capacity * sizeof(lept_member));
	}
}
void lept_shrink_object(lept_value& v)
{
	assert(&v != NULL &&  v.type == LEPT_OBJECT);
	if (v.u.m_obj.capacity > v.u.m_obj.size) {
		v.u.m_obj.capacity = v.u.m_obj.size;
		v.u.m_obj.m = (lept_member*)realloc(v.u.m_obj.m, v.u.m_obj.capacity * sizeof(lept_value));
	}
}
void lept_clear_object(lept_value& v)
{
	assert(&v != NULL && v.type == LEPT_OBJECT);
	size_t i;
	for (i = 0; i < v.u.m_obj.size; i++) {
		free(v.u.m_obj.m[i].k);
		v.u.m_obj.m[i].k = NULL;
		v.u.m_obj.m[i].klen = 0;
		lept_free(v.u.m_obj.m[i].v);
	}
	v.u.m_obj.size = 0;
}

英语好的话,这些接口应该是不需要注释也能看懂的。
当然还有这些api的单元测试,叶老师一再强调:

为贯彻 TDD,先写测试:

那么整个json的复习就到这里,虽然从讲解上来讲我可能什么都每讲,不过大致的过程我就这样再过一遍。


总结

那么整个JSON项目到这里就差不多结束了,吧。
(Github上叶老师的第9章还没有完成,但整体上已经全部讲完了)
我的下一个项目是红黑树。
在学习红黑树的实现的过程中,也会将数据结构整个复习一遍。以上。


lept_json Github:https://github.com/miloyip/json-tutorial

本人流星画魂第八次在csdn上做笔记,有什么错误或者是需要改进的地方请即时提出
我只是一个对编程感兴趣的人,但懒得要死,学得又不认真,希望读者能骂就骂两句,真的太懒了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值