lept_json.cpp文件
1 #include"pch.h"
2 /*#ifdef WIN32
3 #define _CRTDBG_MAP_ALLOC
4 #include <stdlib.h>
5 #include <crtdbg.h>
6 #endif*/
7
8 #include "leptjson.h"
9 #include<string>
10 #include <assert.h> /* assert() */
11 #include <stdlib.h> /* NULL */
12
13 #ifndef LEPT_PARSE_STACK_INIT_SIZE
14 #define LEPT_PARSE_STACK_INIT_SIZE 256
15 #endif //const int LEPT_PARSE_STACK_INIT_SIZE = 256;
16 //判断json值第一个字符是否是json六种类型中的一种正确的开头,如果是,字符后移一位
17 //do while 可以避免宏在应用中的一些错误
18 #define EXPECT(c, ch) do { assert(*c->json == (ch)); c->json++; } while(0)
19 #define PUTC(c, ch) do { *(char*)lept_context_push(c, sizeof(char)) = (ch); } while(0)
20
21 //一句要解析的json值内容
22 typedef struct {
23 const char* json;
24 char* stack;
25 size_t size, top; //size是容量,top是现存量
26 }lept_context;
27
28 //入栈和出栈都返回数据起始的位置,即你入栈数据的起始位置
29 //为什么要返回这个位置呢?因为你要插入数据,你这里操作的是字节。
30 //我们预想这样插入数据char *x=&CHAR; lept_context_push(&c,size)=x;
31 static void* lept_context_push(lept_context* c, size_t size) {
32 void* ret;
33 assert(size > 0);
34 //初始化容量以及扩容
35 if (c->top + size >= c->size) {
36 if (c->size == 0)
37 c->size = LEPT_PARSE_STACK_INIT_SIZE;
38 while (c->top + size >= c->size)
39 c->size += c->size >> 1; /* c->size * 1.5 */
40 c->stack = (char*)realloc(c->stack, c->size);
41 }
42 ret = c->stack + c->top;
43 c->top += size;
44 return ret;
45 }
46
47 static void* lept_context_pop(lept_context* c, size_t size) {
48 assert(c->top >= size);
49 return c->stack + (c->top -= size);
50 }
51
52 //去除空白符,一个json值得构成如:whitespace value whitespace。如果尾空白还有字符就是非单数,我们认为非法
53 static void lept_parse_whitespace(lept_context* c) {
54 const char *p = c->json;
55 while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')
56 p++;
57 c->json = p;
58 }
59
60 //解析null类型
61 static int lept_parse_null(lept_context* c, lept_value* v) {
62 EXPECT(c, 'n');
63 if (c->json[0] != 'u' || c->json[1] != 'l' || c->json[2] != 'l')
64 return LEPT_PARSE_INVALID_VALUE;
65 c->json += 3;
66 v->type = LEPT_NULL;
67 return LEPT_PARSE_OK;
68 }
69
70 //解析false类型
71 static int lept_parse_false(lept_context* c, lept_value* v) {
72 EXPECT(c, 'f');
73 if (c->json[0] != 'a' || c->json[1] != 'l' || c->json[2] != 's' || c->json[3] != 'e')
74 return LEPT_PARSE_INVALID_VALUE;
75 c->json += 4;
76 v->type = LEPT_FALSE;
77 return LEPT_PARSE_OK;
78 }
79 //解析true类型
80 static int lept_parse_true(lept_context* c, lept_value* v) {
81 EXPECT(c, 't');
82 if (c->json[0] != 'r' || c->json[1] != 'u' || c->json[2] != 'e')
83 return LEPT_PARSE_INVALID_VALUE;
84 c->json += 3;
85 v->type = LEPT_TRUE;
86 return LEPT_PARSE_OK;
87 }
88
89 //重构合并 lept_parse_null()、lept_parse_false()、lept_parse_true
90 //我们来总结一下这三个函数的共同工作步骤:
91 //1.使用断言,判断首字符是否为某个类型的起始字符
92 //2.判断后续字符串是否是在类型下的完整性
93 //3.设置该json值的类型
94 //为确保断言的使用合理性,我们在lept_parse_value函数中保证在首字符下才选择使用(两次判断仅是确保断言保证的安全性)
95 //实际上可以只是用assert即可
96 static int lept_parse_literal(lept_context* c, lept_value* v, const char* literal, lept_type type) {
97 EXPECT(c, literal[0]);
98 size_t i;
99 //'\0'结束循环
100 for (i = 0; literal[i + 1]; i++) {
101 if (c->json[i] != literal[i + 1])
102 return LEPT_PARSE_INVALID_VALUE;
103 }
104 c->json += i;
105 v->type = type;
106 return LEPT_PARSE_OK;
107 }
108
109 //解析数据类型
110 //实际上,0123和+123应该是不允许的值但是strtod()允许了
111 //把字符串转换成double类型是一件复杂的事情,可以查阅更多的资料了解
112 #define isdigit1to9(c) ((c>='1') && (c<='9'))
113 static int lept_parse_number(lept_context* c, lept_value* v) {
114 const char *temp = c->json;
115 //校验一些json值得错误,因为有些值在strtod()函数中可以正确解析成double类型,但是是我们所不允许的
116 // (-) digits(多字符下首字符不为0) ((.) (digits)) e or E digits
117 //首先判断是否有 '-',后续判断拒绝了'+'情况
118 if (*temp == '-')
119 temp++;
120 //如果仅仅是一个0我们就跳过
121 if (*temp == '0')
122 temp++;
123 else {
124 if (!isdigit1to9(*temp)) return LEPT_PARSE_INVALID_VALUE;
125 for (temp++; isdigit(*temp); temp++);
126 }
127 if (*temp == '.') {
128 temp++;
129 if (!isdigit(*temp)) return LEPT_PARSE_INVALID_VALUE;
130 for (temp++; isdigit(*temp); temp++);
131 }
132 if (*temp == 'e' || *temp == 'E') {
133 temp++;
134 if (*temp == '+' || *temp == '-') temp++;
135 if (!isdigit(*temp)) return LEPT_PARSE_INVALID_VALUE;
136 for (temp++; isdigit(*temp); temp++);
137 }
138 errno = 0;
139 //浮点值对应于str成功的内容。如果转换后的值超出相应返回类型的范围,
140 //则发生范围错误,并返回HUGE_VAL,HUGE_VALF或HUGE_VALL。如果无法执行转换,则返回'0'。
141 //详细可查阅strtod()使用说明
142 //C库宏ERANGE 表示一个范围错误,它在输入参数超出数学函数定义的范围时发生,errno被设置为ERANGE。
143 //http://c.biancheng.net/c/errno/ errno可以检测库函数调用是否成功
144 if (errno == ERANGE && (v->u.n == HUGE_VAL || v->u.n == -HUGE_VAL))
145 return LEPT_PARSE_NUMBER_TOO_BIG;
146 v->u.n = strtod(c->json, NULL);
147 v->type = LEPT_NUMBER;
148 c->json = temp;
149 return LEPT_PARSE_OK;
150 }
151
152 //该函数解决了对四位16进制字符串转换为十进制unsigned的问题
153 //这是一个非常高效的做法
154 /*具体的算法如下
155 15FA
156 1 -> 0001
157 5 -> 0101
158 F -> 1111
159 A -> 1010
160 15FA -> 0001 0101 1111 1010
161 每四位二进制数表示一位16进制数
162 我最后的结果相当于每次在后面增加四位二进制位
163 于是先左移四位后用|运算
164 0000 0000 |= 0000 0001 = 0000 0001
165 0001 0000 |= 0000 0101 = 0001 0101
166 0001 0101 0000 |= 0000 0000 1111 =0001 0101 1111
167 0000 0001 0101 1111 |= 0000 0000 0000 0000 1010 = 0001 0101 1111 1010
168 */
169 static const char* lept_parse_hex4(const char* p, unsigned* u) {
170 int i;
171 *u = 0;
172 for (i = 0; i < 4; i++) {
173 char ch = *p++;
174 *u <<= 4;
175 if (ch >= '0' && ch <= '9') *u |= ch - '0';
176 else if (ch >= 'A' && ch <= 'F') *u |= ch - ('A' - 10);
177 else if (ch >= 'a' && ch <= 'f') *u |= ch - ('a' - 10);
178 else return NULL;
179 }
180 return p;
181 }
182
183 /*
184 假设 u=0xc8
185 0xC0 | ((u >> 6) & 0xFF)
186 11001000 >> 6 = 00000011
187 11000000(使其加前缀) | ( 00000011 & 11111111 )
188 11000000 | 00000011 = 11000011
189
190 0x80 | ( u & 0x3F)
191 10000000 | ( 11001000 & 00111111 )
192 10000000 | 00001000 = 10001000
193
194 我们分析一下这个过程:
195 我们人工步骤应该是这样的:
196 1.添足码点位数
197 0800> 0xc8 >007F 于是分为两个字节 两个字节是11个码点位
198 原本是:11001000 添加之后:00011001000
199 2.二进位分组
200 字节1应该是5位码点(因为你要添三位前缀) ,字节2应该是6位码点
201 字节1:00011 字节2:001000
202 3.添加前缀
203 字节1:11000011 字节2:10001000
204
205 于是你可以总结如下:
206 对字节的操作:右移了6位(>>)等同与分组了字节,字节2&运算00111111(相当于把前5个码点置0)也是起到分组的效果,
207 再利用11000000 |运算之,可以保留字节1的前提下添加前缀。
208 &0xFF实际上不起任何作用,为了让编译器不警告转型截断数据而已。
209 */
210 //详细分组处理情况,可以查维基百科UTF-8关于用四位16进制表示字符的部分
211 static void lept_encode_utf8(lept_context* c, unsigned u) {
212 if (u <= 0x7F)
213 PUTC(c, u & 0xFF);
214 else if (u <= 0x7FF) {
215 PUTC(c, 0xC0 | ((u >> 6) & 0xFF));
216 PUTC(c, 0x80 | (u & 0x3F));
217 }
218 else if (u <= 0xFFFF) {
219 PUTC(c, 0xE0 | ((u >> 12) & 0xFF));
220 PUTC(c, 0x80 | ((u >> 6) & 0x3F));
221 PUTC(c, 0x80 | (u & 0x3F));
222 }
223 else {
224 assert(u <= 0x10FFFF);
225 PUTC(c, 0xF0 | ((u >> 18) & 0xFF));
226 PUTC(c, 0x80 | ((u >> 12) & 0x3F));
227 PUTC(c, 0x80 | ((u >> 6) & 0x3F));
228 PUTC(c, 0x80 | (u & 0x3F));
229 }
230 }
231
232 #define STRING_ERROR(ret) do { c->top = head; return ret; } while(0)
233
234 //解析string
235 #if 0
236 static int lept_parse_string(lept_context* c, lept_value* v) {
237 size_t head = c->top, len;
238 unsigned u, u2;
239 const char* p;
240 EXPECT(c, '\"');
241 p = c->json;
242 for (;;) {
243 char ch = *p++;
244 /*
245 简述这个switch的工作原理
246 假设一个字符串" \"xx\\tx\" "
247 注意json中\t 在c字符串中要表示为\\t
248 \"要用 \\\\"表示
249 在json值中如果是表示一个\,那么就要用\\\\表示
250 EXPECT后移了一位相当于把第一个"处理了,然后依次入栈
251 如果遇到转义字符即\\分支,处理之,假设没有找到合适的转义字符,返回表示转义错误的值
252 实际上正确的解析是这样的" (EXPEC处理)\" (PUTC处理)xx (case\\处理)\\t (PUTC处理)x
253 (case\"处理)\" (case\0处理)(暗含一个\0结束符)"
254 这里就可以理解先遇到\"和先遇到\0的处理方式
255 如果返回了表示解析错误的值,记得把栈顶设置回原来的位置
256 实际上你有可能会怀疑,栈顶回到了原来的位置难道里面的数据(之前已经进栈但是解析证实错误的)
257 就不存在了吗?实际上我们根本不用管它们,因为free会帮我们解决的,我们要的是top必须回到原来的位置
258 否则就是栈顶的位置改变,而实际上不需要改变,然后本身字节段的部分,下一次解析自然会覆盖掉上一次的数据
259 实际上c->top=head完成了删除栈内元素的工作
260 */
261 switch (ch) {
262 case '\"':
263 len = c->top - head;
264 lept_set_string(v, (const char*)lept_context_pop(c, len), len);
265 c->json = p;
266 return LEPT_PARSE_OK;
267 case '\\':
268 switch (*p++) {
269 case '\"': PUTC(c, '\"'); break;
270 case '\\': PUTC(c, '\\'); break;
271 case '/': PUTC(c, '/'); break;
272 case 'b': PUTC(c, '\b'); break;
273 case 'f': PUTC(c, '\f'); break;
274 case 'n': PUTC(c, '\n'); break;
275 case 'r': PUTC(c, '\r'); break;
276 case 't': PUTC(c, '\t'); break;
277 case 'u':
278 if (!(p = lept_parse_hex4(p, &u)))
279 STRING_ERROR(LEPT_PARSE_INVALID_UNICODE_HEX);
280 //如果四位16进制数在代理对的范围内就要处理它了
281 //详细可以查阅相关资料
282 if (u >= 0xD800 && u <= 0xDBFF) {
283 if (*p++ != '\\')
284 STRING_ERROR(LEPT_PARSE_INVALID_UNICODE_SURROGATE);
285 if (*p++ != 'u')
286 STRING_ERROR(LEPT_PARSE_INVALID_UNICODE_SURROGATE);
287 if (!(p = lept_parse_hex4(p, &u2)))
288 STRING_ERROR(LEPT_PARSE_INVALID_UNICODE_HEX);
289 if (u2 < 0xDC00 || u2 > 0xDFFF)
290 STRING_ERROR(LEPT_PARSE_INVALID_UNICODE_SURROGATE);
291 u = (((u - 0xD800) << 10) | (u2 - 0xDC00)) + 0x10000;
292 }
293 lept_encode_utf8(c, u);
294 break;
295 default:
296 STRING_ERROR(LEPT_PARSE_INVALID_STRING_ESCAPE);
297 }
298 break;
299 case '\0':
300 STRING_ERROR(LEPT_PARSE_MISS_QUOTATION_MARK);
301 default:
302 if ((unsigned char)ch < 0x20)
303 STRING_ERROR(LEPT_PARSE_INVALID_STRING_CHAR);
304 PUTC(c, ch);
305 }
306 }
307 }
308 #endif
309
310 //重构string,让解析string和set_string两个步骤分开
311 //这样便于我们在解析对象的时候,对键值的解析
312 //解析string
313 static int lept_parse_string_raw(lept_context* c, char** str, size_t* len) {
314 size_t head = c->top;
315 unsigned u, u2;
316 const char* p;
317 EXPECT(c, '\"');
318 p = c->json;
319 for (;;) {
320 char ch = *p++;
321 switch (ch) {
322 case '\"':
323 *len = c->top - head;
324 //我们把出栈内容保存在了*str,而不是直接调用lept_set_string
325 *str = (char *)lept_context_pop(c, *len);
326 c->json = p;
327 return LEPT_PARSE_OK;
328 case '\\':
329 switch (*p++) {
330 case '\"': PUTC(c, '\"'); break;
331 case '\\': PUTC(c, '\\'); break;
332 case '/': PUTC(c, '/'); break;
333 case 'b': PUTC(c, '\b'); break;
334 case 'f': PUTC(c, '\f'); break;
335 case 'n': PUTC(c, '\n'); break;
336 case 'r': PUTC(c, '\r'); break;
337 case 't': PUTC(c, '\t'); break;
338 case 'u':
339 if (!(p = lept_parse_hex4(p, &u)))
340 STRING_ERROR(LEPT_PARSE_INVALID_UNICODE_HEX);
341 //如果四位16进制数在代理对的范围内就要处理它了
342 //详细可以查阅相关资料
343 if (u >= 0xD800 && u <= 0xDBFF) {
344 if (*p++ != '\\')
345 STRING_ERROR(LEPT_PARSE_INVALID_UNICODE_SURROGATE);
346 if (*p++ != 'u')
347 STRING_ERROR(LEPT_PARSE_INVALID_UNICODE_SURROGATE);
348 if (!(p = lept_parse_hex4(p, &u2)))
349 STRING_ERROR(LEPT_PARSE_INVALID_UNICODE_HEX);
350 if (u2 < 0xDC00 || u2 > 0xDFFF)
351 STRING_ERROR(LEPT_PARSE_INVALID_UNICODE_SURROGATE);
352 u = (((u - 0xD800) << 10) | (u2 - 0xDC00)) + 0x10000;
353 }
354 lept_encode_utf8(c, u);
355 break;
356 default:
357 STRING_ERROR(LEPT_PARSE_INVALID_STRING_ESCAPE);
358 }
359 break;
360 case '\0':
361 STRING_ERROR(LEPT_PARSE_MISS_QUOTATION_MARK);
362 default:
363 if ((unsigned char)ch < 0x20)
364 STRING_ERROR(LEPT_PARSE_INVALID_STRING_CHAR);
365 PUTC(c, ch);
366 }
367 }
368
369 }
370
371 //parse string and set string
372 static int lept_parse_string(lept_context* c, lept_value* v) {
373 int ret;
374 char* s;
375 size_t len;
376 if ((ret = lept_parse_string_raw(c, &s, &len)) == LEPT_PARSE_OK)
377 lept_set_string(v, s, len);
378 return ret;
379 }
380
381
382
383 //解析数组
384 /*
385 [“a,b,c”,[1,2],3]
386
387 从[开始后移一位,
388 遇到”,我们用lept_parse函数判断应该调用哪个具体的解析函数,
389 遇到 , 后移一位,
390 遇到[后移一位按数组解析,注意遇到]只是解决了上层数组的一个元素解析而已
391 遇到] 代表解析正确
392
393 要处理的两个问题,
394 [1,] 这是不允许的
395 [1 这也是不允许的
396 */
397 static int lept_parse_value(lept_context* c, lept_value* v);/*前向声明*/
398 static int lept_parse_array(lept_context* c, lept_value* v) {
399 size_t i, size = 0;
400 int ret;
401 EXPECT(c, '[');
402 //元素与左中括号之间可能会有空格,这是允许的
403 lept_parse_whitespace(c);
404 if (*c->json == ']') {
405 c->json++;
406 v->type = LEPT_ARRAY;
407 v->u.a.size = 0;
408 v->u.a.e = NULL;
409 return LEPT_PARSE_OK;
410 }
411 for (;;) {
412 //创建一个临时lept_value用于存放数组元素进行压栈
413 lept_value e;
414 lept_init(&e);
415 //解析第一个数组元素
416 if ((ret = lept_parse_value(c, &e)) != LEPT_PARSE_OK)
417 break;
418 //解析完成后,将这个lept_value压栈
419 //e=lept_context_push(c,sizeof(lept_value)); 这样操作是不可以的,类比vector扩容后,内部指针失效
420 memcpy(lept_context_push(c, sizeof(lept_value)), &e, sizeof(lept_value));
421 size++;
422 //元素与逗号之间可能会有空格,这是允许的
423 lept_parse_whitespace(c);
424 //处理一个元素后,遇到逗号就跳过
425 if (*c->json == ',') {
426 c->json++;
427 //逗号之前有空格也是允许的
428 lept_parse_whitespace(c);
429 }
430 //一旦解析完全,我们就把三个lept_value*类型的元素从栈里面压出来,复制到v的数组中(v->a.e)
431 else if (*c->json == ']') {
432 c->json++;
433 v->type = LEPT_ARRAY;
434 v->u.a.size = size;
435 size *= sizeof(lept_value);
436 memcpy(v->u.a.e = (lept_value*)malloc(size), lept_context_pop(c, size), size);
437 return LEPT_PARSE_OK;
438 }
439 else {
440 ret = LEPT_PARSE_MISS_COMMA_OR_SQUARE_BRACKET;
441 break;
442 }
443 }
444 /* Pop and free values on the stack */
445 for (i = 0; i < size; i++)
446 lept_free((lept_value*)lept_context_pop(c, sizeof(lept_value)));
447 return ret;
448 }
449
450 //解析对象
451 static int lept_parse_object(lept_context* c, lept_value* v) {
452 size_t i, size;
453 lept_member m;
454 int ret;
455 EXPECT(c, '{');
456 lept_parse_whitespace(c);
457 if (*c->json == '}') {
458 c->json++;
459 v->type = LEPT_OBJECT;
460 v->u.o.m = 0;
461 v->u.o.size = 0;
462 return LEPT_PARSE_OK;
463 }
464 m.k = NULL;
465 size = 0;
466 for (;;) {
467 char* str;
468 lept_init(&m.v);
469 /* parse key */
470 if (*c->json != '"') {
471 ret = LEPT_PARSE_MISS_KEY;
472 break;
473 }
474 if ((ret = lept_parse_string_raw(c, &str, &m.klen)) != LEPT_PARSE_OK)
475 break;
476 memcpy(m.k = (char*)malloc(m.klen + 1), str, m.klen);
477 m.k[m.klen] = '\0';
478 /* parse ws colon ws */
479 lept_parse_whitespace(c);
480 if (*c->json != ':') {
481 ret = LEPT_PARSE_MISS_COLON;
482 break;
483 }
484 c->json++;
485 lept_parse_whitespace(c);
486 /* parse value */
487 if ((ret = lept_parse_value(c, &m.v)) != LEPT_PARSE_OK)
488 break;
489 memcpy(lept_context_push(c, sizeof(lept_member)), &m, sizeof(lept_member));
490 size++;
491 m.k = NULL; /* ownership is transferred to member on stack */
492 /* parse ws [comma | right-curly-brace] ws */
493 lept_parse_whitespace(c);
494 if (*c->json == ',') {
495 c->json++;
496 lept_parse_whitespace(c);
497 }
498 else if (*c->json == '}') {
499 size_t s = sizeof(lept_member) * size;
500 c->json++;
501 v->type = LEPT_OBJECT;
502 v->u.o.size = size;
503 memcpy(v->u.o.m = (lept_member*)malloc(s), lept_context_pop(c, s), s);
504 return LEPT_PARSE_OK;
505 }
506 else {
507 ret = LEPT_PARSE_MISS_COMMA_OR_CURLY_BRACKET;
508 break;
509 }
510 }
511 /* Pop and free members on the stack */
512 free(m.k);
513 for (i = 0; i < size; i++) {
514 lept_member* m = (lept_member*)lept_context_pop(c, sizeof(lept_member));
515 free(m->k);
516 lept_free(&m->v);
517 }
518 v->type = LEPT_NULL;
519 return ret;
520 }
521
522
523 static int lept_parse_value(lept_context* c, lept_value* v) {
524 switch (*c->json) {
525 case 't': return lept_parse_literal(c, v, "true", LEPT_TRUE);
526 case 'f': return lept_parse_literal(c, v, "false", LEPT_FALSE);
527 case 'n': return lept_parse_literal(c, v, "null", LEPT_NULL);
528 default: return lept_parse_number(c, v);
529 case '"': return lept_parse_string(c, v);
530 case '[': return lept_parse_array(c, v);
531 case'{':return lept_parse_object(c, v);
532 case '\0': return LEPT_PARSE_EXPECT_VALUE;
533 }
534 }
535 /*
536 static int lept_parse_value(lept_context* c, lept_value* v) {
537 switch (*c->json) {
538 case 'n': return lept_parse_null(c, v);
539 case'f': return lept_parse_false(c, v);
540 case't': return lept_parse_true(c, v);
541 case '\0': return LEPT_PARSE_EXPECT_VALUE;
542 default: return LEPT_PARSE_INVALID_VALUE;
543 }
544 }
545 */
546
547 //解析函数,注意处理尾空白
548 int lept_parse(lept_value* v, const char* json) {
549 lept_context c;
550 assert(v != NULL);
551 c.json = json;
552 c.stack = NULL;
553 c.size = c.top = 0;
554 v->type = LEPT_NULL;
555 lept_parse_whitespace(&c);
556 int ret = lept_parse_value(&c, v);
557 if (ret == LEPT_PARSE_OK) {
558 lept_parse_whitespace(&c);
559 if (*c.json != '\0')
560 return LEPT_PARSE_ROOT_NOT_SINGULAR;
561 }
562 assert(c.top == 0);
563 free(c.stack);
564 return ret;
565 }
566
567 //释放空间
568 void lept_free(lept_value* v) {
569 size_t i;
570 assert(v != NULL);
571 switch (v->type) {
572 case LEPT_STRING:
573 free(v->u.s.s);
574 break;
575 case LEPT_ARRAY:
576 for (i = 0; i < v->u.a.size; i++)
577 lept_free(&v->u.a.e[i]);
578 free(v->u.a.e);
579 break;
580 case LEPT_OBJECT:
581 for (i = 0; i < v->u.o.size; i++) {
582 free(v->u.o.m[i].k);
583 lept_free(&v->u.o.m[i].v);
584 }
585 free(v->u.o.m);
586 break;
587 default: break;
588 }
589 v->type = LEPT_NULL;
590 }
591
592 //为了确保API使用者使用了正确的类型,我们用断言保证
593 //获取json值得类型
594 lept_type lept_get_type(const lept_value* v) {
595 assert(v != NULL);
596 return v->type;
597 }
598
599
600 //读取和写入boolea类型
601 int lept_get_boolean(const lept_value* v) {
602 assert(v != NULL && (v->type == LEPT_TRUE || v->type == LEPT_FALSE));
603 return v->type == LEPT_TRUE;
604 }
605
606 void lept_set_boolean(lept_value* v, int b) {
607 lept_free(v);
608 v->type = b ? LEPT_TRUE : LEPT_FALSE;
609 }
610
611 //读取和写入数值类型
612 double lept_get_number(const lept_value* v) {
613 assert(v != NULL && v->type == LEPT_NUMBER);
614 return v->u.n;
615 }
616
617 void lept_set_number(lept_value* v, double n) {
618 lept_free(v);
619 v->u.n = n;
620 v->type = LEPT_NUMBER;
621 }
622
623 //读取和写入string类型
624 const char* lept_get_string(const lept_value* v) {
625 assert(v != NULL && v->type == LEPT_STRING);
626 return v->u.s.s;
627 }
628
629 size_t lept_get_string_length(const lept_value* v) {
630 assert(v != NULL && v->type == LEPT_STRING);
631 return v->u.s.len;
632 }
633
634 //设置一个值为字符串
635 void lept_set_string(lept_value* v, const char* s, size_t len) {
636 assert(v != NULL && (s != NULL || len == 0));
637 lept_free(v);
638 v->u.s.s = (char*)malloc(len + 1);
639 memcpy(v->u.s.s, s, len);
640 v->u.s.s[len] = '\0';
641 v->u.s.len = len;
642 v->type = LEPT_STRING;
643 }
644
645 //获取数组类型值的数组大小
646 size_t lept_get_array_size(const lept_value* v) {
647 assert(v != NULL && v->type == LEPT_ARRAY);
648 return v->u.a.size;
649 }
650
651 //获取数组类型元素的值
652 lept_value* lept_get_array_element(const lept_value* v, size_t index) {
653 assert(v != NULL && v->type == LEPT_ARRAY);
654 return &v->u.a.e[index];
655 }
656
657 //获取对象类型相关
658 size_t lept_get_object_size(const lept_value* v) {
659 assert(v != NULL && v->type == LEPT_OBJECT);
660 return v->u.o.size;
661 }
662
663 const char* lept_get_object_key(const lept_value* v, size_t index) {
664 assert(v != NULL && v->type == LEPT_OBJECT);
665 assert(index < v->u.o.size);
666 return v->u.o.m[index].k;
667 }
668
669 size_t lept_get_object_key_length(const lept_value* v, size_t index) {
670 assert(v != NULL && v->type == LEPT_OBJECT);
671 assert(index < v->u.o.size);
672 return v->u.o.m[index].klen;
673 }
674
675 lept_value* lept_get_object_value(const lept_value* v, size_t index) {
676 assert(v != NULL && v->type == LEPT_OBJECT);
677 assert(index < v->u.o.size);
678 return &v->u.o.m[index].v;
679 }