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 }

猜你喜欢

转载自www.cnblogs.com/Royzzzzz/p/12789861.html
cpp