|
这几天使用了一下JSON在STM32103平台上的使用,还是很好用的,在此记录下。 JSON是啥我也不总结了,就是直观的看起来是一个有格式的字符串,看起来非常清楚明白,有点像Python中的dicitionary的意思,实际使用的过程中主要就是“打包”和“解析”。下面直接来代码。 - char * Status_to_cJSON( char * cJSONROOM, ROBOStatus_TypeDef status)//传入一个变量的指针,这里cJSONROOM是一个全局变量(一个提前规定大小的字符数组),用来存放转换之后的JSON字符串
" l- I; k# X* \ C
& h& C+ S1 q. s* \; L- {* k8 c7 V: Y4 }% P! }0 V b: J
) Z! F/ T* t& r" Z: e- char *result;0 V M3 z# [, T; d) T
- * N3 |5 U, `7 E+ k% P" ?
- cJSON *root,*subroot;//新建两个cJSON的对象指针
# S. n3 N* T" j& |& p - 9 E1 X, r; i7 P
- root=cJSON_CreateObject();//创建一个机器人状态的JSON对象
; ? ^$ s' c D8 G! m: F - : z; K4 F! u9 s& I V
- subroot=cJSON_CreateObject();//subroot是下面的一个嵌入对象
5 Y2 B E% C# X) { - 7 I9 u! C8 I$ G* X
- cJSON_AddStringToObject(subroot,"RunStatus",status.RunStatus);//将status.RunStatus的值赋值到subroot下面一个叫RunStatus的变量。
; E6 X6 {" `! l1 j, W# Z
8 M/ t" s7 [6 ~# m' ?$ f( T& s( S; ~" n- cJSON_AddStringToObject(subroot,"CurrentTime",status.CurrentTime);
7 R7 `) P& y9 J' E; N/ U - 4 U Q3 q! g2 E7 {' m a; g0 x9 k
- //同上9 u$ [2 W% j: g0 O& `8 T
6 z& H5 u$ @2 r0 D3 M8 g! K0 u- cJSON_AddNumberToObject(subroot,"CurrentPosition",status.CurrentPositiont);5 V! R" ~9 M0 Q
- Y: h& t. I$ t- //将位置信息赋值到subroot下面一个叫CurrentPosition的变量,注意此处为Number类型" j2 H: D' u) u( m& |0 r" t5 O
- 1 A' ]$ h8 K; J( [- y* Y; n. S
- cJSON_AddNumberToObject(subroot,"CurrentSpeed",status.CurrentSpeed);
% j3 b/ a: k* G6 z+ @
& N; u# A4 r3 \: F' [5 j$ |6 J- cJSON_AddNumberToObject(subroot,"RunningCount",status.RunningCount);& c1 x: t+ ~) h( M! y& n+ s# U
- ) [+ Q5 Z( w7 l8 R$ h J3 h
- cJSON_AddNumberToObject(subroot,"CurrentTemp",status.CurrentTemp);- x4 t2 u4 W& {7 `* ^
' I- Z8 H+ K: ~7 N3 i- _- cJSON_AddNumberToObject(subroot,"CurrentVoltage",status.CurrentVoltage);3 U% Q$ F/ e+ T& {8 m" T
. J9 f1 J. L8 l, w, H- cJSON_AddNumberToObject(subroot,"CurrentAmp",status.CurrentAmp);$ v4 A9 c# ]) F- b3 D4 G
; l- W, J3 ~( y; d# \- cJSON_AddNumberToObject(subroot,"CurrentDir",status.CurrentDir);) B' h5 F, t. p+ P% c" {/ y9 _
; q, k$ g2 k$ I7 }, ~- cJSON_AddNumberToObject(subroot,"ControlSystemEnergy",status.ControlSystemEnergy); G) @% j. |, q; B3 j8 m3 R
1 T+ H9 v0 U" O- J g H- cJSON_AddNumberToObject(subroot,"DynamicSystemEnergy",status.DynamicSystemEnergy);5 E/ Z3 u0 T/ D% s+ }# F
- $ k: T$ j) C+ a H4 O
- cJSON_AddItemToObject(root, "RobotStatus", subroot);8 ]9 e0 O" h, M$ l% ?
# n& Q( s/ G/ C( O- result=cJSON_PrintUnformatted(root);//生成JSONC字符串,注意可以用cJSON_Print()格式的,就是人眼看着好看一点,就是有点占用存储空间. d0 v0 G, c& R+ O/ R$ v# P
. [6 `/ J4 w8 A% ~- strcpy(cJSONROOM,result);//将转换的结果字符串赋值给传入的全局变量
! I+ E: S% e4 a T - ' r, r. ^/ L" P( l9 a( F" {
- cJSON_Delete(root);//最后将root根节点删除
/ e* S! i$ @/ w$ e$ ?+ @
9 E) B" F+ H6 e! g B# l: O- myfree(result);//释放result的空间,必须要有,要不然内存里会失去一段空间,最后系统崩溃- W8 k, r1 E( V3 E
' Z5 d' }: l; a% N; o- return cJSONROOM;//不要指望着返回一个局部变量的地址,这是非常危险的,因为函数调用完毕后这个地址指向的内容就消失了。所以这个函数在设计的时候返回了一个全局变量的地址。
+ P: p. Q3 R) v+ i, N5 K3 ~& U
8 C$ s& [( o V: r% {1 A, ^- }
复制代码注意:malloc在STM32平台上使用的时候需要改动一下,关于内存操作的改动见下面的代码。使用字符数组会提高程序的可靠性,之前一直用字符指针,可能没有用好,中途会挂掉,后来发现提前建立一个数组,在这段空间进行数据的操作还是比较稳定的。 - #include "malloc.h"
. C( i" h+ F+ y( z# J! A
7 o" n5 `/ T0 _" |% L- //内存池(4字节对齐)
( q; F& {# V+ Z* P - __align(4) u8 membase[MEM_MAX_SIZE]; //内部SRAM内存池' ]) F" M5 {8 n) l
- //内存管理表
# z3 e, @0 \/ ~4 G* E, ? - u16 memmapbase[MEM_ALLOC_TABLE_SIZE]; //内部SRAM内存池MAP7 @& S, z' L0 m8 Q# S
- //内存管理参数) N$ ?/ f: ~0 ^% x* p, n* q4 O
- const u32 memtblsize = MEM_ALLOC_TABLE_SIZE; //内存表大小
5 l- q1 A$ n* Q& L- } - const u32 memblksize = MEM_BLOCK_SIZE; //内存分块大小9 J9 J0 |& w: ?0 F) ?7 G, D/ P
- const u32 memsize = MEM_MAX_SIZE; //内存总大小$ c9 u( p" |' I5 U. }! d. J9 H
. Q( ] F m; h# z1 S
* E' u; @ R: S' _9 B4 B& N0 d- //内存管理控制器
7 e- g1 s, g+ E% [2 d - struct _m_mallco_dev mallco_dev=
- I) V* m# F1 N8 w$ x - {
; d7 }% H# z6 k9 @3 V( Z& J - mem_init, //内存初始化1 N1 ^+ n* R& \/ \9 q6 P
- mem_perused, //内存使用率! G7 P# A( N4 ~! E, Q6 y1 `
- membase, //内存池
# c1 ~8 I$ }- l1 l7 A - memmapbase, //内存管理状态表' y5 ^0 H& h3 X2 c) s* Y6 L% X
- 0, //内存管理未就绪
% u9 G8 U" a7 R - };$ y! G) k. T9 u4 v |4 Q7 ~- z
- ; s5 c; g% T. T, b0 L
- //复制内存
! a5 h* V6 d( v {2 J - //*des:目的地址
7 G$ r& ?4 I ?. h3 J - //*src:源地址
3 b- E& T. n9 q" m1 g - //n:需要复制的内存长度(字节为单位)
/ n2 N) p+ p+ C - void mymemcpy(void *des,void *src,u32 n)
6 F9 V, e- x3 r - {9 H/ x! c* W( f p" Z& d7 \
- u8 *xdes=des;
* i4 n% D' ]- ~3 @ - u8 *xsrc=src;- N4 \& ^0 t* b9 |( G% A( q2 `: T
- while(n--)*xdes++=*xsrc++;
; D) J$ J: q9 M1 K0 ] - }" v! D; E* X; b+ V
- ; U2 V& }# Z, A$ y
- //设置内存
' A Q( {3 u8 n: c. v3 H# n - //*s:内存首地址8 ^$ }: e' j4 Y+ _1 t! ]9 R# L
- //c :要设置的值) E8 e- C7 R& Y/ c
- //count:需要设置的内存大小(字节为单位)
* l# ~' H0 f; ^- C) T7 J - void mymemset(void *s,u8 c,u32 count)" ?0 M6 U: ^3 p8 \
- {$ \! N" _" s8 U* K& Y! [
- u8 *xs = s;' z' J3 p* Y! `- q4 E( y
- while(count--)*xs++=c;
( C0 I5 F. x0 p* {* R - }
. K4 [7 b }; B6 [( @; Q% y& V, ]5 r - " \6 C+ U- `/ |$ o( f" J8 t$ B
- //内存管理初始化
+ r6 H. E, R2 z# o& x0 q - //memx:所属内存块
* y! t) a- q: S* u M - void mem_init(void)
* y& v. B) k- E0 x - {
J% H: O6 c; [8 P - mymemset(mallco_dev.memmap, 0,memtblsize*2);//内存状态表数据清零( A9 E$ t" `5 L7 ?3 g' `$ w9 `
- mymemset(mallco_dev.membase, 0,memsize); //内存池所有数据清零- v. b) p! X: _% ?; y( r) f0 E
- mallco_dev.memrdy=1; //内存管理初始化OK" E2 L% ~( \+ m) h! S0 H
- }
^# U. K$ t8 F - 6 g0 k. [/ q( h( u9 {
- //获取内存使用率! w& ]( ^9 k6 U" }
- //memx:所属内存块! h7 b$ i( v4 M5 V' E: ?7 i
- //返回值:使用率(0~100)! M' Y( U. z1 ?) X A( V
- u8 mem_perused(void)- r. v8 l7 n8 P7 f; T! @6 g5 n4 o
- {7 N& E3 Z& I+ w9 o& j
- u32 used=0;
7 s! l4 u2 T2 o8 b( |/ ] - u32 i;. t) C K" |# o
- for(i=0;i<memtblsize;i++), }* r2 l9 U6 _* F
- {
9 w) A" d! ]$ P( M, O* Z( ? - if(mallco_dev.memmap[i])used++;' v( ]0 M$ [0 P4 H
- }7 W$ @ ?9 b- F) c/ ~5 u! [9 G. A+ j) n* G
- return (used*100)/(memtblsize);
& v+ a0 v2 {: D- I/ u - }
" S7 x, P. Y: p, \
+ a, }( R3 n7 C6 C3 d- //内存分配(内部调用)
6 b, g3 q% i6 \& q - //memx:所属内存块% C0 D3 s# j/ t4 j& l" ]
- //size:要分配的内存大小(字节)) G N; ^0 y. H# A
- //返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址& s! A% U6 x7 f' ?0 f8 n8 Z
- u32 mem_malloc(u32 size)
$ u+ N8 w' H% Y7 c! p1 u# E - {
- T& T' v/ ?+ X0 n7 J - signed long offset=0;
. R4 I5 w. e' {% ~3 ~ - u16 nmemb; //需要的内存块数
( s/ f8 r4 f- D& B; M - u16 cmemb=0;//连续空内存块数8 F# N( W6 V/ }' @ t6 D2 l/ y
- u32 i;# x2 m- h5 J3 H
- if(!mallco_dev.memrdy)mallco_dev.init();//未初始化,先执行初始化- L) r3 b7 z6 }2 ^2 Z0 x
- if(size==0)return 0XFFFFFFFF;//不需要分配8 F ?9 }1 L; ~5 R# d0 A& x# g
+ K8 @) T/ K+ g: w0 w) `. F2 Z3 L2 m- nmemb=size/memblksize; //获取需要分配的连续内存块数# \7 ]: ^# y9 |3 G% o+ p+ z3 |
- if(size%memblksize)nmemb++;
* [+ d6 a4 L2 }) h: z - for(offset=memtblsize-1;offset>=0;offset--)//搜索整个内存控制区( ?& X% I5 D* s$ A+ v% D% C& z% ]
- {
2 @3 U- C5 w* @ - if(!mallco_dev.memmap[offset])cmemb++;//连续空内存块数增加
! ~; f+ j2 @: D2 Y% Y% j - else cmemb=0; //连续内存块清零
" B4 f& d q- g+ C2 K! B4 p5 Z - if(cmemb==nmemb) //找到了连续nmemb个空内存块' i0 F$ @3 ^5 q. ?; \, s0 B
- {
3 F! Q1 ]# }' {( K0 W) A/ k - for(i=0;i<nmemb;i++) //标注内存块非空
- I9 g0 K: l0 [* b! I) f& P9 G1 C - {- o5 D/ f8 b9 b6 ] ]7 m
- mallco_dev.memmap[offset+i]=nmemb;
* V# G8 |' i0 M, T; u8 W7 w2 a$ C - }. }) x1 p) |; C$ A: L5 ]( Y
- return (offset*memblksize);//返回偏移地址
! a! K3 b- u! ~+ L: ~ - }8 R) h# n( T: f: U! J3 x
- }
h( j3 z! D, L1 b1 x - return 0XFFFFFFFF;//未找到符合分配条件的内存块, W" n8 {# d( s
- }' _! \; A5 e. D4 ?
0 y0 l* W0 s1 Y3 S% u! j- //释放内存(内部调用)
% I+ w \4 e* ]8 a U - //memx:所属内存块3 ?1 G5 `5 B/ O! s' S
- //offset:内存地址偏移4 q: I7 R k3 S$ V
- //返回值:0,释放成功;1,释放失败;
- w( L/ k3 _0 i, C& m& r" e$ X - u8 mem_free(u32 offset)5 d, |* ^0 \1 W
- {& e0 Z Q9 g5 k- D d2 |, S
- int i;, I i. u1 v4 g3 [* @7 t0 h/ a
- if(!mallco_dev.memrdy)//未初始化,先执行初始化! L" g& l; l% e5 K/ j( c
- {4 z3 }, J. h4 b& Z8 r
- mallco_dev.init();
5 @; }6 M+ u) m: C6 x, m# i - return 1;//未初始化" u( b1 i& N1 i
- }. ?; ?5 U8 Y% q+ q7 B, p
- if(offset<memsize)//偏移在内存池内.! p8 O- ?; a; [6 [: d) |
- {: K: m, w8 a7 y4 q- X% E
- int index=offset/memblksize; //偏移所在内存块号码! i: s% g7 O( P$ [
- int nmemb=mallco_dev.memmap[index]; //内存块数量: H6 `- j- E) c3 ]1 q, Z% M6 k" j: V
- for(i=0;i<nmemb;i++) //内存块清零2 W2 H/ ?& z5 Q2 C( e3 L' Y
- {8 ?' v# t/ e" z
- mallco_dev.memmap[index+i]=0;$ w$ g+ `1 ?+ `! B
- }! C0 m; ~; A) b9 X; k/ t2 h2 s
- return 0;) k% k( t. S$ K
- }else return 2;//偏移超区了., t( @7 ^, L* g/ h
- }: s5 d* l: z) A+ U
z# ]; Y1 [" Z& ?/ ~ ]8 A0 \- //释放内存(外部调用)
& w) D4 I. {% U, Y C5 m' [8 g - //memx:所属内存块0 A% f$ ^0 J, c4 C, X9 m( R8 m
- //ptr:内存首地址
7 j" Y" S4 c, A, W2 L) h; K - void myfree(void *ptr)% i0 \$ {- Z' N. R, `2 K: K7 B
- { ^/ v4 w. }* K& t/ w, c
- u32 offset;
. T' r2 U) @% C# R - if(ptr==NULL)return;//地址为0.
5 l2 l9 ^7 c# Z5 B3 i2 f - offset=(u32)ptr-(u32)mallco_dev.membase;
: d% }2 {* g& E0 W/ w& x* ^' r# n - mem_free(offset);//释放内存/ Y) l- A2 S, c, _: x0 N
- }
/ T2 R9 `5 i5 t9 x
- @" T q1 c2 u: W- //分配内存(外部调用)
- k! W& I* ?1 H' P4 X$ }/ C - //memx:所属内存块
# q, D& n% T: |5 z& W, p' V - //size:内存大小(字节)2 j: ?9 v" S2 ]) ?- I/ @* S/ {
- //返回值:分配到的内存首地址.
2 `8 |) F' g$ t - void *mymalloc(u32 size)
+ n# [# O$ }, ^' v$ `, A. c - {2 r- S6 e$ M+ b( b- Y
- u32 offset;
5 ^' v/ L; [# ~% j ]/ G3 S - offset=mem_malloc(size);* J3 a( {) r: B/ ?
- if(offset==0XFFFFFFFF)return NULL;& z, b9 e: V V2 u" U V
- else return (void*)((u32)mallco_dev.membase+offset);3 D4 T1 \! F& H, N
- }8 }# B+ v- S( G# `# O" |& n
- + R G5 f t, O2 _6 O: Q$ {
- //重新分配内存(外部调用)
1 K$ U8 n+ q% X! l - //memx:所属内存块
3 N. T; n2 Z/ b3 I - //*ptr:旧内存首地址
+ H. a+ w* R( ~% I9 Q8 ] - //size:要分配的内存大小(字节)
1 W3 v1 ]& O( } - //返回值:新分配到的内存首地址.6 O/ R3 n# `% m) @9 d; ~ N
- void *myrealloc(void *ptr,u32 size)
. f5 |2 M% x; p, [3 e0 d - {9 ~! N- q3 D9 u7 Z) n2 V: ]- z
- u32 offset;
( K; p. L M+ M- W: } D | - offset=mem_malloc(size);+ Y3 s# y2 s/ l6 @5 Y
- if(offset==0XFFFFFFFF)return NULL;6 |& O2 I) d3 @) e) s# A' A, h2 w
- else
9 b6 B: p8 m/ y3 M5 ` - {7 u( d; u* Q: [) a8 k8 C
- mymemcpy((void*)((u32)mallco_dev.membase+offset),ptr,size); //拷贝旧内存内容到新内存
9 f4 W/ G; ]0 ], N - myfree(ptr); //释放旧内存( a+ U+ s1 U! b! j6 T" i
- return (void*)((u32)mallco_dev.membase+offset); //返回新内存首地址
9 d9 r( k/ c. X) \5 A8 D, \ - }
/ i( ?6 G* X I" h% w - }
复制代码malloc.h内容如下: - #ifndef __MALLOC_H
# l0 R( n6 l3 d9 h - #define __MALLOC_H' v0 s: b( s, d7 g9 ?
- #include "stm32f10x.h"
+ g% u# `8 {9 H
, O4 E4 T, w! @2 F. m- #ifndef NULL
1 r8 I. }1 u- I9 J; d - #define NULL 0& H( R9 h+ {. ^0 i
- #endif
/ p- ]" j5 J8 Q0 G, ^ - % C8 v0 ^3 f8 z& ` k
- #define MEM_BLOCK_SIZE 32 //内存块大小为32字节5 Q& J* _3 L- a& ~- j
- #define MEM_MAX_SIZE 16*1024 //最大管理内存 2K8 C& c- g$ O: u1 C, h+ F4 p
- #define MEM_ALLOC_TABLE_SIZE MEM_MAX_SIZE/MEM_BLOCK_SIZE //内存表大小
; t. y D* S# D# Y% `
/ q+ F4 p( L1 p9 W4 u! c% j2 R- //内存管理控制器! l5 o, n: t) x6 B3 G/ I ?: A) z9 P
- struct _m_mallco_dev( u+ j7 |1 O! ?3 } D8 q; d
- {* k% |$ T6 b5 i: W
- void (*init)(void); //初始化
4 R$ z3 ?6 a, o( p; I; \' B - u8 (*perused)(void); //内存使用率
) @5 C" f/ l( E' E - u8 *membase; //内存池
, s1 |% T* i/ ]! n$ R0 P" w - u16 *memmap; //内存管理状态表1 w I1 W% z) u7 w/ m' o) c, t ^" G
- u8 memrdy; //内存管理是否就绪
, O1 a* e9 c5 h, Q4 |: t9 C* W) } - };7 ~/ o+ ? T+ u' C" n) e* f- W" Y
- & t9 L% {/ S$ U. O
- extern struct _m_mallco_dev mallco_dev; //在mallco.c里面定义
. t& n3 F1 @# W6 |
& l3 C) q; f& ~$ Z; h6 q' Z- void mymemset(void *s,u8 c,u32 count); //设置内存) w/ l; p4 Q. L: a1 ]
- void mymemcpy(void *des,void *src,u32 n);//复制内存
* K# R4 B$ E( h- f6 w+ V
3 I* t+ N8 W8 G- void mem_init(void); //内存管理初始化函数
2 {6 P, G( O+ R$ b, G - u32 mem_malloc(u32 size); //内存分配
: j S9 w7 b4 `% x' p @ - u8 mem_free(u32 offset); //内存释放
: i. N) `" ?/ Z9 y2 s4 h6 ~ - u8 mem_perused(void); //获得内存使用率
4 N: e; _1 l5 q- R, p. b* V - ////////////////////////////////////////////////////////////////////////////////
\ b! f4 N6 C, u5 ] r - //用户调用函数
8 ^; C! p6 p! R3 E/ ` - void myfree(void *ptr); //内存释放
# g% c5 X1 t# }2 f - void *mymalloc(u32 size); //内存分配
* D+ q+ _) l) y+ B* ?! |. z" r7 @+ { - void *myrealloc(void *ptr,u32 size);//重新分配内存+ f7 q y3 K {# R3 N: S/ D2 v8 m% Q$ }
- #endif
复制代码cJSON.c的内容也全在下面 - 1 /*: G* n: l5 a, `5 R
- 2 Copyright (c) 2009 Dave Gamble
5 [, f0 U+ M% @0 ? - 3
; K3 }% u8 m/ s. s - 4 Permission is hereby granted, free of charge, to any person obtaining a copy
* L0 T, C. ~- G% H6 s; c - 5 of this software and associated documentation files (the "Software"), to deal) q6 s9 [* q$ _
- 6 in the Software without restriction, including without limitation the rights& K7 s, {) C7 X: V
- 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
! E% ^+ [& d: Z/ F. X - 8 copies of the Software, and to permit persons to whom the Software is4 |2 t8 d4 n: s6 z
- 9 furnished to do so, subject to the following conditions:
0 V6 \/ W! n+ \& H& w - 10
4 \0 y9 P; Y( a2 S - 11 The above copyright notice and this permission notice shall be included in
3 R: a" Q/ E7 Q3 |7 C - 12 all copies or substantial portions of the Software.
+ S. N% R. q4 d/ B% I: w - 13
' a: L i' U3 i) w - 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR7 L2 U, [" h6 ~. Z" [5 w
- 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,. @- R( H# s4 _# E4 _% a
- 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE$ }* N! H7 t$ ]. e- P# |% `
- 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER' Y# m4 C. H1 W0 B2 _
- 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,! r/ q; X' M; }+ C9 N- _" a
- 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN9 D# E9 {! \( v; J
- 20 THE SOFTWARE.5 p6 q5 g" B# S- ]! h/ M
- 21 */
& \7 M+ q" C6 O: U% C - 22
D2 b6 Y: Q- ~- n# Z+ c - 23 /* cJSON */! q/ ?9 M, p4 v' A* E' e! X6 L* v
- 24 /* JSON parser in C. */( t% z" j# `3 L+ _7 x+ Y
- 25
. Y0 H1 d6 j J2 q4 l' ^ - 26 #include <string.h>
, x1 \8 s$ s5 d5 r% H" j - 27 #include <stdio.h>
$ U- ^/ R& w/ G' t' R( z) }) X - 28 #include <math.h>
, r: l" E5 f, ?3 g4 K/ a o* |( B& D - 29 #include <stdlib.h>' ?" c: k; y: Y3 H- K: ~9 G7 c* n j
- 30 #include <float.h>: ^7 S: Z0 d) |7 N6 W- n) H6 n% [; e
- 31 #include <limits.h>
8 ~/ s' p$ k8 l) D8 m5 |2 P - 32 #include <ctype.h>. [& f5 R* |0 Z0 n) E! a, e3 F
- 33 #include "cJSON.h"
" M; x) f5 a+ {7 O - 34
/ l9 [# r8 d' O! M0 @! ~' w - 35 #include "malloc.h"
, W4 V) \4 l) ]7 f$ e5 a8 Q - 36 % K+ E4 B a3 _- R9 G
- 37 static const char *ep;
3 s( R: r4 j( f3 X/ n8 Y/ K; _: z, d - 38 7 ~& S: x$ t# W' y: w, H% R
- 39 const char *cJSON_GetErrorPtr(void) {return ep;}' d; y$ }- R3 s/ s
- 40
# C C u! _8 ~3 o6 U - 41 static int cJSON_strcasecmp(const char *s1,const char *s2)# m2 z' e" I# C% E$ V' q0 L; G
- 42 {# [& o0 w# O- ~/ c4 j: S8 g `2 }# M# z
- 43 if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
* ?2 _$ M/ J9 o! u0 k3 w6 n - 44 for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;/ K% S: |0 O0 ]3 i
- 45 return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);" V% Q, _3 \! ?1 A
- 46 }
1 F5 T4 H' k- S - 47
4 V' {2 {- B7 t' J7 r, S - 48 static void *(*cJSON_malloc)(size_t sz) = mymalloc;+ ~" P% C! q$ @ n) N
- 49 static void (*cJSON_free)(void *ptr) = myfree;
, W x' Q& x3 }) `7 s! o9 G" w - 50
! {0 J, Q( }6 y# c - 51 static char* cJSON_strdup(const char* str)* g. m/ H1 [- b
- 52 {
4 i: N% P2 ?: L0 m |! ~, \& v - 53 size_t len;+ J+ t6 f& O* G( y5 y' b
- 54 char* copy;; ?9 J0 u; A5 U, R/ |7 U# f4 S4 a
- 55
9 I5 z2 U' U. I - 56 len = strlen(str) + 1;& i6 S1 M. h" J- ]5 b( {( z
- 57 if (!(copy = (char*)cJSON_malloc(len))) return 0;+ ]* f; r/ F2 s0 T+ p( c# a- h& a
- 58 memcpy(copy,str,len);! P5 h- X3 b) m
- 59 return copy;- T: w0 Z3 N8 @. V- o# z4 F" |# R p
- 60 }# [1 S4 K2 ^, a# k6 X) G
- 61 0 D6 G/ E0 ]5 J( N
- 62 void cJSON_InitHooks(cJSON_Hooks* hooks)
6 H: K3 \8 p. K! K. f( v - 63 {
- D+ r/ n, F" A- y- E - 64 if (!hooks) { /* Reset hooks */
+ p; O( T4 A6 { G9 K* Y - 65 cJSON_malloc = malloc;
& S9 k2 I' B; @/ e; O - 66 cJSON_free = free;
% x" L( s# a# \8 B+ F. H" c* ^ - 67 return;' Q$ E% r' d. [5 `6 J+ S
- 68 }. \3 q. f% a$ X4 ^; e
- 69
" K8 O6 c( V1 ^! [" R# i% v - 70 cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;" M' M2 j0 O) I9 C
- 71 cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
( H: p1 g$ M$ v; \7 h t6 i7 p - 72 }* K- b# X5 j6 O! c! H+ Y+ r
- 73
- Z3 ~+ g, M1 ?9 k1 T% u% p' W* t2 ^ - 74 /* Internal constructor. */' F7 Y5 H5 _4 _, ~! b3 o# k
- 75 static cJSON *cJSON_New_Item(void)
0 L- _/ @/ o" P; R2 W - 76 { v% x' q$ n' @ f1 N, ]0 e
- 77 cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));7 D' k. o+ t8 O1 w4 g6 i
- 78 if (node) memset(node,0,sizeof(cJSON));
) q$ v) `# _' f2 a V - 79 return node; @. i4 L+ C" n. r# G/ y
- 80 }
: N& o7 k0 e& j, p - 81 $ u& M4 T% O: M( l0 m
- 82 /* Delete a cJSON structure. */) o' V+ r/ `4 d' N+ l
- 83 void cJSON_Delete(cJSON *c)
9 x# a5 ?) s0 G0 w% g" c3 t' Q - 84 {
) k( ]' c3 E i5 x$ s( S7 D - 85 cJSON *next;. ? E! O# d+ K3 }7 l" e& |8 G C
- 86 while (c)
5 q+ e: k* f) `2 g: |3 c - 87 {
2 z7 ^& `- t9 c1 l8 S! I P9 T& T6 S" u - 88 next=c->next;
* X; J1 q4 K" @. { - 89 if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
3 k' @! S- Z. w' O2 u - 90 if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
" l) k, L& a U0 @. r - 91 if (c->string) cJSON_free(c->string); e3 ]. H8 \$ R# I, a; v2 ]' Z2 T8 n( A
- 92 cJSON_free(c);+ I) c( u0 ?* o6 ^/ |9 z, n
- 93 c=next;/ ~# @1 d5 C# y' F7 U6 H
- 94 }
6 f; k5 a0 E, `8 D - 95 }: [2 F+ L* Z: R# _ w
- 96 v/ v$ A2 d$ ^* R9 h1 K
- 97 /* Parse the input text to generate a number, and populate the result into item. */
5 Y- W% e" Y' Y K - 98 static const char *parse_number(cJSON *item,const char *num)
' s$ P0 [) [* b+ C2 j - 99 {0 x4 m3 X; H `+ b7 B
- 100 double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;3 i+ N4 J/ N% T$ l/ Q
- 101
I4 V9 c/ }. y1 b' y* r( q# o* C3 t - 102 if (*num=='-') sign=-1,num++; /* Has sign? */
. A' A8 p% _/ Y7 n# _ - 103 if (*num=='0') num++; /* is zero */ h3 }& L8 }0 r. f" H
- 104 if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
! z8 f K2 T. {' K' |& ?* S - 105 if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
9 |8 [5 _* r3 `- W! E - 106 if (*num=='e' || *num=='E') /* Exponent? */3 ^+ z% i2 g- q' a
- 107 { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
$ _3 [* _/ ^# s - 108 while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */# g2 |+ n8 W% x. O8 Z7 M; K
- 109 }
7 b! O1 A5 R4 {$ k, u8 ? - 110 8 w. T9 _! z1 ^7 g# B
- 111 n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */# O: s0 q- R0 t& G
- 112
/ m4 p& Q0 P1 A - 113 item->valuedouble=n;; |$ v3 L* r# N# L& L4 V
- 114 item->valueint=(int)n;
& M, E4 d; G# n1 l5 D - 115 item->type=cJSON_Number;
0 Y8 H: ]( V& I* e) U5 f0 ~: y - 116 return num;, ]! D3 _6 f j. @) h5 l
- 117 }2 J' O5 @( b7 |
- 118 ( L( O+ {/ C' Z- M
- 119 /* Render the number nicely from the given item into a string. */- ?) Y0 l' ?) ^# T* k, [
- 120 static char *print_number(cJSON *item)- J F( f) ^6 r j$ u, W1 N
- 121 {2 Z p% Y: c2 Q. ^( s
- 122 char *str;
: u, o3 Q) e5 ^. a1 u5 q - 123 double d=item->valuedouble;
( \) m( v, T. m8 h# Y- r8 e - 124 if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)3 ^3 d& G" I3 R7 ^
- 125 {% A/ g; H3 C5 ~( j. ^
- 126 str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */1 c* F$ W4 R9 y: l" |7 s
- 127 if (str) sprintf(str,"%d",item->valueint);
) ?2 D$ ?2 p& O" ~. Y1 p. B I - 128 }* _" q% l; ]- q- T; B D3 }5 f
- 129 else
) A8 P1 n- T x - 130 {
: r4 n$ b$ ^" e2 E' P8 t2 A - 131 str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */0 w, G) A3 @8 B
- 132 if (str)
. o4 E9 f5 q+ W$ v0 k4 b$ z - 133 {
7 w' S; m) B2 Y, n- o - 134 if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);
* e8 ?! m4 t) C+ s/ G4 I; f0 t" g - 135 else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);: R2 p" a8 |2 F5 p/ T
- 136 else sprintf(str,"%f",d);. ?) F7 s: ]6 M: d$ ^1 w
- 137 }
1 O; H! E2 @! D- D( r6 w( A u$ Q - 138 }
' Y1 R( J6 o( {$ L( z# s) Y - 139 return str; p2 [+ B L" W7 q" f; j1 }/ K
- 140 }
" V' k6 ^8 u Y - 141
; { }4 |* O, ]9 Q - 142 static unsigned parse_hex4(const char *str)
5 f( s& _+ e" S# }! l - 143 {
9 N9 S$ y8 {$ M: U ?) [) |" A - 144 unsigned h=0;1 }8 M4 v% z8 j$ _4 M4 w
- 145 if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
! `' {, q9 C( q G$ J& v - 146 h=h<<4;str++;: ~+ ]5 ]+ u" s# F1 n
- 147 if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
( R3 @, X9 [; O% L- C9 h. ~/ Y - 148 h=h<<4;str++;
: y3 W& [ f: h5 ]* p - 149 if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
& ^7 [! E) i! J3 X& N - 150 h=h<<4;str++;; W% l5 X, W# ?* v+ s% ^7 Q8 k
- 151 if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;! f; U- X5 ^5 M7 D- u4 M
- 152 return h;7 W" Z* C' p- k& a+ v v! N
- 153 }) s: A% M% w; {7 \/ i% f( W( ~
- 154 3 C( C5 c) y+ T1 Y
- 155 /* Parse the input text into an unescaped cstring, and populate item. */
- g. |% [/ b- G$ T( w - 156 static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };8 [) x* W$ b9 x9 ?8 J
- 157 static const char *parse_string(cJSON *item,const char *str)
( ]- {/ V/ r9 N( r - 158 {& I. N( k8 @! Q0 \3 b: Q' X9 i
- 159 const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
+ T# A5 N' B$ }9 h - 160 if (*str!='"') {ep=str;return 0;} /* not a string! */
& t9 [" m) F2 I! X. O - 161 " }! ^2 Q$ T* z% [9 c
- 162 while (*ptr!='"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
- l: \6 f- [7 Z7 ~& Q" h$ U - 163 7 I1 b3 I6 V/ @. X, R; C
- 164 out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */ F$ e+ S* }6 W: y' _" p
- 165 if (!out) return 0;
3 [( x. W3 x+ {" _3 e1 U - 166
o9 [( M1 ]' b2 L; I& i& n7 n - 167 ptr=str+1;ptr2=out;
# q3 D# ~ x5 S# E - 168 while (*ptr!='"' && *ptr)2 \7 g0 \. P" V' M3 w# v
- 169 {
' ^! m# |$ i, u! b - 170 if (*ptr!='\\') *ptr2++=*ptr++;
6 u7 A+ q# O: @/ C4 B. k, K - 171 else
! _5 `9 H/ ^. A& { - 172 {) p3 ]% t! t6 F* X
- 173 ptr++;
6 X$ x; Q: R5 g2 k. p7 e' }& j/ H/ T - 174 switch (*ptr)$ }1 m7 K: b, x( ^4 f
- 175 {+ v) q7 N v' c6 Y" U0 z3 T
- 176 case 'b': *ptr2++='\b'; break;
5 y8 p$ z) i; ^$ k/ U4 D - 177 case 'f': *ptr2++='\f'; break;
2 D& @. \+ a1 `# R; F6 F - 178 case 'n': *ptr2++='\n'; break;0 j% z1 U8 A8 h7 U
- 179 case 'r': *ptr2++='\r'; break;
) E, J P; W9 n: H - 180 case 't': *ptr2++='\t'; break;8 d+ O! t# ^$ p/ [8 [
- 181 case 'u': /* transcode utf16 to utf8. */
. L. K: ^( O* w; }# v" i - 182 uc=parse_hex4(ptr+1);ptr+=4; /* get the unicode char. */
6 C- S# f( m% {1 T8 F9 [ - 183 " x% s' P( p" R0 x
- 184 if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */: l4 J1 I) s% [: C
- 185 . c1 r# t9 \1 B4 y8 p: f) u$ m' K
- 186 if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */% G' U2 r" k$ ~: n3 @+ h9 |
- 187 {, l g' w [& L/ j# E
- 188 if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */
5 u/ c3 u* ~1 D( Q* V& q- b$ ] - 189 uc2=parse_hex4(ptr+3);ptr+=6;( x, O( g& R+ S+ h
- 190 if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */+ G7 i8 G7 Z) h6 c
- 191 uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));2 B. }+ ]% d! L( \+ X, U: e
- 192 }
+ p+ N- ~1 Z7 R5 V% ^ - 193 - v: f) O+ e0 ?4 C& ^3 @
- 194 len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len; p+ Q n" y0 U9 z7 |. D! s
- 195 : y2 Y4 h, M5 w
- 196 switch (len) {, f6 b9 f4 ?, @. d, [4 A0 Q
- 197 case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;( x b4 T! \) S7 K. a
- 198 case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
( z; i- v1 V; M% [2 G% Y7 C+ z: a - 199 case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
- c' C' P4 u" u - 200 case 1: *--ptr2 =(uc | firstByteMark[len]);# k+ o( j6 \7 ]9 o! s6 s
- 201 }
' S" j( e0 E1 @4 ^9 p- \/ D - 202 ptr2+=len;( [# G; a) k/ A' C
- 203 break;7 S; K! e2 l- @ t' c
- 204 default: *ptr2++=*ptr; break;
5 O# h# t# u. ]# X/ S- L2 w - 205 }% [5 ]) A8 G: q3 n r( l7 e
- 206 ptr++;
x7 L9 M" E4 M- R ~% w( x - 207 }& b, v/ z5 G7 n5 C
- 208 }+ k6 E: D) y; u- t& U
- 209 *ptr2=0;
3 A; C9 h# T9 n" T. W: G - 210 if (*ptr=='"') ptr++;
( ^/ i( d M+ U" s* S$ A4 [: E" m - 211 item->valuestring=out;
( \6 B/ c; d' ^" x2 x: I( D3 p+ A - 212 item->type=cJSON_String;8 ~9 i; ^* R9 t/ p$ @
- 213 return ptr;
& r# N/ q8 y2 ^9 W# ]" i - 214 }5 m0 u9 k# z, ]! `1 ^* h; q
- 215 ) \; L3 t$ X- U8 w( A1 E5 Y1 |
- 216 /* Render the cstring provided to an escaped version that can be printed. */' P: }8 z8 Y* X1 f
- 217 static char *print_string_ptr(const char *str)# e M, C( y9 A$ F
- 218 {, i# W& l$ K8 {+ _
- 219 const char *ptr;char *ptr2,*out;int len=0;unsigned char token;. V4 R8 _) x e+ S) E* Q: T2 g' W
- 220 5 b. R' ^+ H$ {1 L/ W
- 221 if (!str) return cJSON_strdup("");9 [2 W/ J+ A9 n
- 222 ptr=str;while ((token=*ptr) && ++len) {if (strchr(""\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
4 ~! U& z0 z8 K+ Y - 223
1 G) B2 |1 F* @5 U5 c5 p! R' `; e - 224 out=(char*)cJSON_malloc(len+3);6 ~( t. N# ?! C; w7 f. W1 h$ p
- 225 if (!out) return 0;, H6 X$ v0 T6 T4 Y
- 226
8 Q* v$ c$ v3 D# h9 R7 @$ g - 227 ptr2=out;ptr=str;
# n$ L0 H: [" g( t+ g' l - 228 *ptr2++='"';
- [3 `6 y1 W% L& F+ j( z - 229 while (*ptr); q( C# o) m5 \ U" R5 `
- 230 {6 P1 V& L& a- ~6 U# O1 w4 E, X
- 231 if ((unsigned char)*ptr>31 && *ptr!='"' && *ptr!='\\') *ptr2++=*ptr++;
7 T; ~ N- T- O( }3 v& x - 232 else0 @- Q/ D, A& z! J* v8 {( N
- 233 {# \ k8 L1 c% _# k* c1 m2 K4 u3 F
- 234 *ptr2++='\\';. O1 W6 @2 P! K) ?( V; V! b
- 235 switch (token=*ptr++)
6 A/ T& \7 y/ z! D C; E8 k/ ]8 _ - 236 {
1 H* W4 c3 e' C% v3 r/ Z - 237 case '\\': *ptr2++='\\'; break;% S3 j- w% G# A
- 238 case '"': *ptr2++='"'; break;; e# s+ P! O0 @! ^$ s$ g9 o
- 239 case '\b': *ptr2++='b'; break;
- P0 W; r3 x4 J* p7 S. b. O' @ - 240 case '\f': *ptr2++='f'; break;
X6 w; w5 g+ G! h* X3 h. M - 241 case '\n': *ptr2++='n'; break;+ s/ [% x+ D+ R" l$ e
- 242 case '\r': *ptr2++='r'; break;5 m4 J7 G' ^( O* ?& J
- 243 case '\t': *ptr2++='t'; break;0 J, @/ E/ C: Z5 [
- 244 default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */
P2 ~$ b& y$ Q4 K; N2 W - 245 }, ?. N2 ^1 _" L7 L7 Y
- 246 }
' F/ h3 W C: F& v - 247 }
l1 G) H+ G% K) Z2 M5 V: n - 248 *ptr2++='"';*ptr2++=0;* `. o7 Y9 v% S' J1 b2 y% k3 @" u
- 249 return out;* b7 b' S, p: J) @* } n+ X t3 C" I
- 250 }
0 f" e; P+ ?4 k* G2 r* l - 251 /* Invote print_string_ptr (which is useful) on an item. */
* i' d; o' C, W! t) G: Z - 252 static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
v9 b Q5 V3 Z6 \: O& ?, T - 253
% n0 j, C* H; d7 a! ^9 I0 h - 254 /* Predeclare these prototypes. */
1 P1 p. S" S/ H( a1 F. A - 255 static const char *parse_value(cJSON *item,const char *value);
: E2 N" ?& K# U! ~ - 256 static char *print_value(cJSON *item,int depth,int fmt);3 B/ t: \$ z3 s+ [$ S4 ]0 f
- 257 static const char *parse_array(cJSON *item,const char *value);
) z: X) F5 D( a - 258 static char *print_array(cJSON *item,int depth,int fmt);; Z. k0 h' K6 K( y7 e$ `& X. I
- 259 static const char *parse_object(cJSON *item,const char *value);% Y7 A3 [6 D3 o$ i2 p$ M
- 260 static char *print_object(cJSON *item,int depth,int fmt);
) e: J1 G N1 v1 G K - 261 2 Z( m8 o, a( m: T! r, s+ m+ N
- 262 /* Utility to jump whitespace and cr/lf */
% r% M; m4 y/ t, } - 263 static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
' P2 H. w( h; `% H - 264 3 k" q7 w4 B( @& o( B/ q* d$ c
- 265 /* Parse an object - create a new root, and populate. */0 G( }1 h F9 W! Y9 v* H! q- r
- 266 cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
% }( P- o; f- m6 p0 F - 267 {7 B+ W ~/ W) Y9 y
- 268 const char *end=0;4 u) K7 t8 T6 s1 V+ c. r: l! L/ `
- 269 cJSON *c=cJSON_New_Item();: v) W: z x8 C) q
- 270 ep=0;
/ |' X. N/ M- u! Y. Z" t: V - 271 if (!c) return 0; /* memory fail */8 E2 D# P, u* T4 i! R5 [
- 272 , p1 T7 g4 x" }! m- C
- 273 end=parse_value(c,skip(value));# e! @' R" F# ~% P3 p
- 274 if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */
" n) f, s) o) H/ j9 J' _4 y7 ?: _' Y - 275 4 ^: P: k7 W6 m4 ~+ q. V1 {! t
- 276 /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */0 v; U3 o/ z' d- |& y
- 277 if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}}6 u6 g! H2 B# }7 D8 Y( U& U
- 278 if (return_parse_end) *return_parse_end=end;
* J, e9 @! t3 @ - 279 return c;
, c- r. q3 Q' z s7 }1 A: n - 280 }
6 `, x" _( {7 u \! A - 281 /* Default options for cJSON_Parse */
: C1 _! Y$ v4 a! M7 U0 L' g1 w- R; a - 282 cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);}
9 W; f: C- y2 {% s1 }/ K - 283
5 W* y' v; J2 ?4 ?3 e% @( q1 M. ` - 284 /* Render a cJSON item/entity/structure to text. */' e6 V) r4 p& e8 B- v4 c4 r
- 285 char *cJSON_Print(cJSON *item) {return print_value(item,0,1);}# I0 n, D: k+ Q1 ]; A& j
- 286 char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);}
5 c3 s+ o# @8 S2 [ - 287
. b. D2 ]; {. D q0 Q. x0 f - 288 /* Parser core - when encountering text, process appropriately. */6 D1 k' `. e% x/ M+ o
- 289 static const char *parse_value(cJSON *item,const char *value)0 O0 l1 J0 K# A( \( [0 R
- 290 {' ?& x( o! }' r" a# C
- 291 if (!value) return 0; /* Fail on null. *// w" @0 t' X6 ]" E& Y n
- 292 if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }/ }( k+ O& j/ K5 a/ m$ z
- 293 if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }. i1 U; R1 b$ ^, x" b+ r
- 294 if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
1 s5 d4 y8 w) N9 x! z" N - 295 if (*value=='"') { return parse_string(item,value); }8 U3 A/ Z. ^! ` h
- 296 if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }5 |6 A# _. \. A; p$ _& o/ v' d( c& [
- 297 if (*value=='[') { return parse_array(item,value); }- ]1 G/ U) P9 t+ j$ ?! A: n
- 298 if (*value=='{') { return parse_object(item,value); }
2 D4 p& R, H( {/ J% t6 H - 299 . h' P3 f4 [# x( _& L
- 300 ep=value;return 0; /* failure. */
! x& j, {' A/ \4 [7 A' g - 301 }
' ~) n0 ?, L& _9 \+ `0 J ]& W. p - 302
" }1 q$ I! f- `% j1 q' q: B+ @* D - 303 /* Render a value to text. */
) J; K8 j" P5 [+ T - 304 static char *print_value(cJSON *item,int depth,int fmt)
# H* k/ T+ i* d- ?1 M - 305 {8 X. }& o& `; U* a Z# ^0 g
- 306 char *out=0;7 ^9 T! O$ C! K& m! B
- 307 if (!item) return 0;& Z; C3 [& c: W
- 308 switch ((item->type)&255)
1 S5 ]0 U+ |9 i9 @ - 309 {0 \8 R" C* C$ f' I/ |1 ]
- 310 case cJSON_NULL: out=cJSON_strdup("null"); break;
5 P9 y4 t- I" z! }7 `5 A- R! J' H - 311 case cJSON_False: out=cJSON_strdup("false");break;
% C: W: K; l2 d. [: D+ V7 [ - 312 case cJSON_True: out=cJSON_strdup("true"); break;/ Y- i/ M( G+ z( X* Q
- 313 case cJSON_Number: out=print_number(item);break;
2 W: L$ U' N `# r- |$ ^) F6 J6 P% h - 314 case cJSON_String: out=print_string(item);break;
" F- b( u; ?# G) A3 _: U' s( k \ - 315 case cJSON_Array: out=print_array(item,depth,fmt);break;$ `' A; F1 y- w8 T7 w# l
- 316 case cJSON_Object: out=print_object(item,depth,fmt);break;
) N" l$ @3 e0 ^. t# @9 H - 317 }
- {7 T/ W1 C( t2 y2 o4 X - 318 return out;
' n ]; O4 s4 E& { - 319 } q$ D" q7 {) K% }0 U
- 320 3 P- _0 _& t+ v+ R
- 321 /* Build an array from input text. */
0 e9 O) ?: A" H' N! u: T - 322 static const char *parse_array(cJSON *item,const char *value)
& b6 w; _' H, q+ x& e1 M' Z0 y: p - 323 {
3 G4 u9 w3 N- H+ _4 Q - 324 cJSON *child;2 }7 G/ j4 A' g+ s% i! O. k7 T
- 325 if (*value!='[') {ep=value;return 0;} /* not an array! */
# n5 S6 {3 ~! X( V9 \. | - 326
0 r: ]4 G2 Z. N2 a - 327 item->type=cJSON_Array;
9 q0 b! ~& \ }( A/ q/ B1 Z - 328 value=skip(value+1);5 b* f; R6 c2 }% F7 H1 b! K5 W
- 329 if (*value==']') return value+1; /* empty array. */
1 \* r8 N$ ]9 _: B - 330
( U* [) f: k, W8 s - 331 item->child=child=cJSON_New_Item();; g) W* y6 K! M6 S
- 332 if (!item->child) return 0; /* memory fail */
# O- Y, Z+ z, j4 Z0 [. N- { - 333 value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */( c: w n( O2 N1 C1 M
- 334 if (!value) return 0;+ g/ s6 D) y, r: L% t
- 335
, ?) \/ {( ]# c4 A; U) a - 336 while (*value==',')4 p. o" p9 I- l) Z
- 337 {1 M7 C' \% ?; h- J6 c
- 338 cJSON *new_item;; F8 B, S) ]% C$ w# _
- 339 if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
- Y( {! J8 t3 F N+ t - 340 child->next=new_item;new_item->prev=child;child=new_item;
' l' V' T1 R2 I/ e# C - 341 value=skip(parse_value(child,skip(value+1)));
/ c W5 b) ~( I Z, ? - 342 if (!value) return 0; /* memory fail */1 F. J. N$ @ }
- 343 }
0 x& [% O5 P% N, L - 344 3 p1 N7 E1 i# s+ Q {
- 345 if (*value==']') return value+1; /* end of array */$ i8 G6 I7 ~6 B# t2 z; N3 ~; c
- 346 ep=value;return 0; /* malformed. */
" n. ?# Y% n8 }& Y% @! \! U/ l& ]: W! ^5 J - 347 }
' R. Y; }4 h# T) u! } - 348
1 X7 W2 E- L9 t4 g3 H; r& Y - 349 /* Render an array to text */
6 a& y! C: ~6 ~3 U5 P - 350 static char *print_array(cJSON *item,int depth,int fmt), C0 \1 G7 |5 |' m
- 351 {# a; e0 V: q4 d; e
- 352 char **entries;
4 t/ `7 Y; G( H3 n9 t. A! n3 V - 353 char *out=0,*ptr,*ret;int len=5;6 q6 V, w5 S/ C1 X7 t# Y t- U; J
- 354 cJSON *child=item->child;6 L( f% R) y' x& O4 C* \- V* U2 Z
- 355 int numentries=0,i=0,fail=0;
. z6 { ~7 N4 w G( H1 i5 ?% G( l - 356 1 c' ]4 h3 W% {, {9 {# N3 f2 H+ m3 E
- 357 /* How many entries in the array? */* L, Z/ f7 X" K( U
- 358 while (child) numentries++,child=child->next;
& |/ x9 m( c3 Q1 W4 z. E - 359 /* Explicitly handle numentries==0 */
1 y! x P3 p; b5 {: H) X - 360 if (!numentries)
0 K0 |, K4 `* ~9 o! e - 361 {- T9 `; }8 @. W6 w) f# @1 A& @- I
- 362 out=(char*)cJSON_malloc(3);7 @: q* Q; \+ o2 y5 j) n) @
- 363 if (out) strcpy(out,"[]");& {/ Q1 Y3 z, y* e0 O T; G6 q
- 364 return out;
1 d- I `# M+ O g R6 m - 365 }; [8 O& z- [% T6 Z/ ~ S
- 366 /* Allocate an array to hold the values for each */
6 d: M& Q+ o0 T; ~+ M$ q7 e - 367 entries=(char**)cJSON_malloc(numentries*sizeof(char*));
2 q7 m/ y4 e$ K, D4 b( ?. Z - 368 if (!entries) return 0;0 u9 K) s0 G3 E2 f8 L
- 369 memset(entries,0,numentries*sizeof(char*));( F( L) M0 r/ M9 [& y: a
- 370 /* Retrieve all the results: */
5 U& s7 q: b2 O/ l! \9 k - 371 child=item->child;' ?9 r$ s5 v3 l
- 372 while (child && !fail)7 ?1 b2 Y) F) }) X8 P& u
- 373 {
4 O: N2 c% R7 n. }1 J) R+ e( } - 374 ret=print_value(child,depth+1,fmt);
4 e; ? |0 B# K4 o( K9 e - 375 entries[i++]=ret;
1 p+ o! q0 D5 P2 Z) `5 U - 376 if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
+ h& f2 S4 j& m- q. ? v - 377 child=child->next;3 ^# @- z( n* V v" H9 G% T
- 378 }) l$ H7 O/ S Y- a
- 379 ]( G0 d$ [, |. }
- 380 /* If we didn't fail, try to malloc the output string */2 Q: E" y* v M7 _0 ^% [
- 381 if (!fail) out=(char*)cJSON_malloc(len);
7 @+ v- r! K2 I2 E7 ~3 d4 | - 382 /* If that fails, we fail. */
4 t( \: S& U- H3 M - 383 if (!out) fail=1;
' u. x! j4 K! o& @4 F" L% g - 384
# v% ?6 s* G8 I0 s0 M( W3 y7 V( b - 385 /* Handle failure. */( M$ f* I E4 D
- 386 if (fail)7 F; M [6 j' a5 I {( Y M# E! B+ d
- 387 {/ x" e9 p0 l2 R- [
- 388 for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
5 u, p1 t% H6 e& v5 y7 L - 389 cJSON_free(entries);
& k# q) n$ E' t2 f# C( U' x" i - 390 return 0;
N& n& K0 u! b. X$ r2 X% x - 391 }. a- U/ u) m0 G. ~1 L# V
- 392 * X1 W/ X7 n6 l7 O* ^
- 393 /* Compose the output array. */' h+ z5 G4 u! i, q: Z
- 394 *out='[';
% I) a. V0 N' U" Y" n - 395 ptr=out+1;*ptr=0;
8 a B% O4 J9 O - 396 for (i=0;i<numentries;i++)# s9 `3 k, @# r+ B3 p: k7 v" J
- 397 {
# R/ Q+ _4 X6 y( y, m, | - 398 strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
3 t% s7 ]+ ~/ [ - 399 if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
7 f$ |) @4 I: _- D+ C/ G - 400 cJSON_free(entries[i]);
6 [( {% S+ {4 |8 Q - 401 }
; f) B: H; S1 A- [6 H9 @. O - 402 cJSON_free(entries);' f( o$ F; N/ {
- 403 *ptr++=']';*ptr++=0;
4 U4 a! ^3 S$ w+ m9 D& }8 P, c w - 404 return out;
8 h# q$ \" _5 C2 v3 N - 405 }
6 K. f: Z: M% N: V0 h; B9 h - 406
: N4 P$ P* N' Y9 h+ ]* j - 407 /* Build an object from the text. */9 m, I( K( Q+ r( H/ i
- 408 static const char *parse_object(cJSON *item,const char *value)
' V$ M3 S u$ S. d - 409 {
9 q# @" ^- M' K/ @* S) {+ G0 v - 410 cJSON *child;
5 `; C% P6 E0 Y - 411 if (*value!='{') {ep=value;return 0;} /* not an object! */8 M% w: N- w( f" y5 p) v4 {
- 412
# N8 M* m0 P) @# b4 e E0 m; d - 413 item->type=cJSON_Object;
6 \* C6 m" E9 o8 Z - 414 value=skip(value+1);
9 w! G' g; n0 u" {5 W" [$ ~. W D - 415 if (*value=='}') return value+1; /* empty array. */4 s5 k' u7 F. A6 E- Q* f
- 416 : J6 j$ S/ G. r1 u" S1 y
- 417 item->child=child=cJSON_New_Item();
2 e! x% ~1 r" L% o6 p9 G. z - 418 if (!item->child) return 0;% V m3 e6 v7 Y& L' @1 M
- 419 value=skip(parse_string(child,skip(value)));
* c/ f3 b- P% u3 U1 Z. n - 420 if (!value) return 0;& |8 ?- l; ~% x0 ~4 o* `: S
- 421 child->string=child->valuestring;child->valuestring=0;
/ R8 y8 V0 | Y1 v+ W: a, Z' f - 422 if (*value!=':') {ep=value;return 0;} /* fail! */
) ], U7 ^& ]3 @6 k: C6 n8 h - 423 value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */* b7 p+ t4 {7 s# n
- 424 if (!value) return 0;
& d5 P) }8 H* ?/ y) ]( v - 425 5 J9 Z5 P/ G! E4 E* G
- 426 while (*value==',')" R" p% _: N# e8 E1 D! r( t4 ~
- 427 {/ f3 ?3 i" j/ e
- 428 cJSON *new_item;
4 M& d+ `, {1 [! E - 429 if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */) I! X$ W: V; }; s6 \, X* g
- 430 child->next=new_item;new_item->prev=child;child=new_item;
. x) K: p4 ^9 w" |! u - 431 value=skip(parse_string(child,skip(value+1)));) }1 x" P6 Y+ \
- 432 if (!value) return 0;
: c8 x. l% |9 _6 @ U - 433 child->string=child->valuestring;child->valuestring=0;
: \+ `% u a. q O$ N - 434 if (*value!=':') {ep=value;return 0;} /* fail! */
5 ~3 c1 N6 Y6 D _6 H - 435 value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */! z# b" y5 J5 B: O; L
- 436 if (!value) return 0;
/ h: o5 `# u/ O3 E - 437 }! z3 g' S' ?* [! A
- 438 + j7 V7 r$ z7 u( i
- 439 if (*value=='}') return value+1; /* end of array */2 t! I u6 O. T) o4 p. R
- 440 ep=value;return 0; /* malformed. */1 U8 c& }! n9 X8 q, B. P- a J, d
- 441 }
7 G5 f+ }& l- O: i2 i' G. X2 T: X - 442 / X& E: i" `8 x C; U% J
- 443 /* Render an object to text. */% i! h3 \$ h1 p6 _4 @) V& z: j5 b
- 444 static char *print_object(cJSON *item,int depth,int fmt)
0 }2 o/ A8 q9 } - 445 {
- g% d( E9 C; ?2 u9 z. b8 W$ n - 446 char **entries=0,**names=0;
: j/ `4 o) m/ A+ ~, Z - 447 char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
8 F/ A6 e& C$ m0 }! S8 Y - 448 cJSON *child=item->child;" T- F% l+ l. P5 | Z& T1 l
- 449 int numentries=0,fail=0;0 G0 C( H, M2 E
- 450 /* Count the number of entries. */
$ g5 g9 b0 Y5 l3 S- q1 m5 d7 t7 d7 M - 451 while (child) numentries++,child=child->next;7 N6 L+ P$ J0 G4 I' ]
- 452 /* Explicitly handle empty object case */
7 v# M8 s" l% f - 453 if (!numentries)# K3 f x6 C& a' W
- 454 {
+ [- n9 w/ o4 r: n" h x8 A - 455 out=(char*)cJSON_malloc(fmt?depth+4:3);
9 g% p9 ~' I7 G$ O. c - 456 if (!out) return 0;
3 i& p' B( Z* k* x1 _) O' X - 457 ptr=out;*ptr++='{';
$ ~# Z4 R) m8 p8 R0 |# m - 458 if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';}
) F$ g1 p" ~0 w7 m7 e3 l - 459 *ptr++='}';*ptr++=0;3 l9 L6 O- y" y9 R
- 460 return out;
8 d0 |3 ]7 f" L" E, P4 E - 461 }& b7 H# ?* S0 i. b
- 462 /* Allocate space for the names and the objects */# M M' O6 ~! D3 R/ w5 _6 K
- 463 entries=(char**)cJSON_malloc(numentries*sizeof(char*));; ^7 e& m5 j, w, k* n* Y
- 464 if (!entries) return 0;
+ m% Z1 m. l. i2 ^: M7 S3 g/ B v - 465 names=(char**)cJSON_malloc(numentries*sizeof(char*));
& h4 R" X! b) I: Z; f3 A! s# i/ C - 466 if (!names) {cJSON_free(entries);return 0;}6 Z; Z W- u* w3 K( K% k
- 467 memset(entries,0,sizeof(char*)*numentries);, B" k1 @( d' Q# q: t- P" K1 y+ u. [. @
- 468 memset(names,0,sizeof(char*)*numentries);) c& P8 w# B. F7 l, F B7 L( i
- 469
' w; u* d) I8 s3 P2 k% ]8 g* t+ f - 470 /* Collect all the results into our arrays: */7 H0 c4 ^8 U8 q1 g! q7 L2 W
- 471 child=item->child;depth++;if (fmt) len+=depth;9 D% c6 ?( h# u. L( X/ W! L
- 472 while (child)
" x) {; }8 o8 Y8 p* C; v7 M - 473 {
- l7 m2 Z4 O- v! ^$ w - 474 names[i]=str=print_string_ptr(child->string); k' G; r+ f6 u2 W# `( |3 S( Y* @1 i
- 475 entries[i++]=ret=print_value(child,depth,fmt);
& |. Q' `* r D" s' l3 M3 r3 r9 { - 476 if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;8 p3 E9 H% ~9 J0 W; }
- 477 child=child->next;# H4 J( W+ ]' D& {) @
- 478 }% K- g, r- l6 A+ U4 M1 G. h: }, I
- 479
2 P; j5 @% r4 m. X6 n( n: e8 I - 480 /* Try to allocate the output string */
3 ^! V1 w9 K' }0 P4 l B0 Y - 481 if (!fail) out=(char*)cJSON_malloc(len);
9 r8 C& Y, @4 v# C - 482 if (!out) fail=1;
6 A% |. L T7 n+ w2 ` - 483 Y5 r0 n; U) d N. p F: N
- 484 /* Handle failure */
* {+ E- R/ v4 [8 ^" Z/ [& F% f - 485 if (fail)6 G$ I5 _) D4 y+ @" U: {. n5 u
- 486 {
6 [/ U4 ^* ?; d( w1 p7 m- t" e3 @ - 487 for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}" @' j5 o1 J& T& L! h; g
- 488 cJSON_free(names);cJSON_free(entries);/ K6 v+ M: D* F. d
- 489 return 0;
% f3 x8 ~9 F( B; V ~& _ - 490 }8 m; m/ ]0 N+ L0 r1 _
- 491
( P8 x L9 i% T: J8 I) G# ~; ]2 `5 A - 492 /* Compose the output: */
T* f5 K- H7 V+ @& y5 p5 C3 R( ] - 493 *out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;% v7 H. b& c' t0 p% D6 E" u0 f
- 494 for (i=0;i<numentries;i++)
3 w& z' l4 [& @7 X - 495 {# B h. I! N! q) A+ a
- 496 if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
) \! ~9 X, z7 ]$ x0 [# e' U. D- S+ r - 497 strcpy(ptr,names[i]);ptr+=strlen(names[i]);
* a3 M* T [2 a9 A5 K4 M - 498 *ptr++=':';if (fmt) *ptr++='\t';
1 a6 z2 @1 l! g8 `' A& [# c - 499 strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
3 ]' B( T7 m$ x# A/ e; q - 500 if (i!=numentries-1) *ptr++=',';
& C. O" {! M `5 {, d% k% H: k" N - 501 if (fmt) *ptr++='\n';*ptr=0;
& G% U+ k! N0 z" j i2 K5 K& \" K- @ - 502 cJSON_free(names[i]);cJSON_free(entries[i]);4 P& A. A9 z% S* q3 J5 k5 X; g" S& b) p, \
- 503 }
0 M' z9 h4 M7 B: |7 R# L - 504
' k8 \1 d9 t2 }- Z - 505 cJSON_free(names);cJSON_free(entries);% f' A8 d9 c( N% T: E% H9 }
- 506 if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';7 v" O: A1 A Z. _$ V. a
- 507 *ptr++='}';*ptr++=0;0 Z9 \! [$ ^5 D, d
- 508 return out; 8 C+ x4 i# g; n' A2 {8 C
- 509 }
, A! F( B0 p- }9 y* A2 a5 u# b9 ` - 510
( x0 Y. u e. p - 511 /* Get Array size/item / object item. */
6 [$ B8 y- D# _* o, ]- b - 512 int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}0 n- |+ B7 d! D: L4 ?/ N4 L
- 513 cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;}
: m8 i B5 V7 @7 P0 O9 v6 G* J2 d - 514 cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}. m4 I: [3 X1 H/ x( v
- 515 ( n7 N- ?& N- D! j
- 516 /* Utility for array list handling. */2 |: T7 j" V& i4 @ t
- 517 static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}% m# ~5 g B* c& R, q s: h& S
- 518 /* Utility for handling references. */
" N+ j( R. y+ g7 Y5 q) k - 519 static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;mymemcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
$ u0 A0 P: k' j' g9 ? - 520
) L$ P( T& q9 L% Q; p' V; W0 N2 Y - 521 /* Add item to array/object. */
: f+ }8 X7 @' Y: N - 522 void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}4 v f- ?: k/ F; s, W! l1 ~
- 523 void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}! F+ u- |( e' H; I% r
- 524 void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));}( y: u" g; B0 `3 S2 _: q1 B' y* X& y
- 525 void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));}' X/ d- M" L S9 D" ^0 R
- 526
% c0 O/ F5 u2 C$ Q, k+ u- R2 U - 527 cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
; w5 G$ x* @9 g6 }) o3 g3 K/ Q - 528 if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}: n& O" ?5 m% e1 J) ^
- 529 void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}* j# Y+ ^/ n! H: D" |
- 530 cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}: Y2 x. R& e" R
- 531 void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}) y! C- t% Y6 C. E7 H
- 532
8 `) F1 a8 H7 H/ ^, n2 X6 e - 533 /* Replace array/object items with new ones. */9 s. l3 r3 S1 b) F3 C, b4 }6 ^. ]
- 534 void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
" t4 J; U3 S$ A! x/ W/ U% _ - 535 newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;: g, T4 F* S6 w( g* Y* C/ q; |7 N1 F" R
- 536 if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
+ l+ [' ^- K2 `! h" R1 T - 537 void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}" L: l/ G: X. I6 |1 i: g8 y; ^# X; y
- 538
- i' p5 A7 t, v8 {0 W7 Z) M( s - 539 /* Create basic types: */
. z, H1 z! c8 q v. V% t; g - 540 cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
- z5 e! f* }9 x+ _! F/ Q - 541 cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}3 t& F- J! ^6 ]: {' Y
- 542 cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}- o$ c- ~9 e5 w: ~! l: A" g' l
- 543 cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}1 E/ q! O( n/ T5 a3 k/ [ f
- 544 cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
: b; e8 J7 U4 A! }9 c7 I* L K1 X. U - 545 cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
2 A" L1 n8 d: `2 z0 \5 y - 546 cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
4 {8 e- f/ H( b1 D7 B& B$ a( w - 547 cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
7 D/ @7 G [4 T2 V9 B# }0 `& X - 548
8 `) Q/ z* ^ j# s' h5 M* L& M+ [7 j - 549 /* Create Arrays: */! ?3 S% N7 [6 z
- 550 cJSON *cJSON_CreateIntArray(const int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}" f, Q4 [- y2 b4 }. s
- 551 cJSON *cJSON_CreateFloatArray(const float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}: k3 ]4 [) J5 p. s5 A" K
- 552 cJSON *cJSON_CreateDoubleArray(const double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
2 z3 J) _1 ?) v - 553 cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
$ C* T2 f" [3 f% m9 @# E - 554
8 Y3 Q3 T/ A7 M* ^5 Y9 n - 555 /* Duplication */
* K/ u8 O @1 S8 u - 556 cJSON *cJSON_Duplicate(cJSON *item,int recurse)5 U7 g2 @5 c4 J9 S0 H( N; e# u
- 557 {0 i$ d- ]/ j [9 p- R
- 558 cJSON *newitem,*cptr,*nptr=0,*newchild;
9 h$ ?" v3 I# V7 x% k - 559 /* Bail on bad ptr */
" x+ M0 H/ b# t7 S9 w1 W9 R' ~0 x - 560 if (!item) return 0;
' l; @9 Q8 u: ^2 o8 J - 561 /* Create new item */
- U* M n! P/ h& u# Q# \ - 562 newitem=cJSON_New_Item();
( w# ^! h# d( B" O# {; y# v - 563 if (!newitem) return 0;
9 M% b% e! Z ^9 i - 564 /* Copy over all vars */9 |. [ v V5 y0 |) F
- 565 newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;$ Z3 P, z9 v2 j' `5 `! a4 @* X: I
- 566 if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}}( ^0 M$ r! b Z9 a
- 567 if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}}
8 H3 j7 ]% E K7 a, U7 J; ] - 568 /* If non-recursive, then we're done! */# _3 g' m! y0 Z
- 569 if (!recurse) return newitem;/ R& ]. C' L+ e" ^
- 570 /* Walk the ->next chain for the child. */
2 d) a( M h5 I& V. w$ o9 K4 q/ L- S4 d - 571 cptr=item->child;
4 L+ m0 @, {) ]! s& N - 572 while (cptr)1 \% m4 W& l1 {( }8 N
- 573 {
, e, J( |" w$ r - 574 newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */$ |+ ]4 b% y" S7 Z" h7 I. @1 M
- 575 if (!newchild) {cJSON_Delete(newitem);return 0;}
8 z ~3 k( g+ Q$ u - 576 if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */
& U* D0 s4 F2 X2 h6 s3 k' q5 N" K - 577 else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */
+ F5 n8 F5 ?4 Y, y4 ` - 578 cptr=cptr->next;
" y& T$ U: F8 ?+ D1 e - 579 }7 G$ F# u* x5 M8 Q! V
- 580 return newitem; B& P1 @2 y5 D
- 581 }8 v2 G! F, K/ W8 y K6 I
- 582 / s6 `& J* F! O4 v& f6 f6 S
- 583 void cJSON_Minify(char *json)8 C3 N( s g) N1 Q3 I, M9 E" R; \
- 584 { }0 o# \; z9 n8 z, g/ E" b p. v
- 585 char *into=json;
) C+ d: N, K7 f0 F - 586 while (*json)& ?. w0 [' ~0 k9 B' X; W% o/ j
- 587 {
" F0 k1 A) B R, [9 | - 588 if (*json==' ') json++;9 x/ I, y M% T& c/ _
- 589 else if (*json=='\t') json++; // Whitespace characters.$ b) M# v' s: j: w A) [8 A# N6 M
- 590 else if (*json=='\r') json++;
3 V @: a# \" e. K( x - 591 else if (*json=='\n') json++;
8 L+ U- q( U# ]: R2 \+ k2 v+ p - 592 else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; // double-slash comments, to end of line.
" k. I, f6 {7 ?. |6 u+ I; j5 l - 593 else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} // multiline comments.0 Z8 e/ M- k6 T# |, Q0 n6 J2 P
- 594 else if (*json=='"'){*into++=*json++;while (*json && *json!='"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} // string literals, which are " sensitive.
/ W! k/ ?% N3 m; Y2 T. j# [ - 595 else *into++=*json++; // All other characters.
( n! m5 q2 _1 U" ]+ e& v* i - 596 }* _& G6 @4 C& i, W
- 597 *into=0; // and null-terminate.
# z3 y; ~ H) Y5 { - 598 }cJSON.h内容如下
; O3 H5 a9 f' E: s - 1 /*0 ^" I3 M, V/ b+ {1 W
- 2 Copyright (c) 2009 Dave Gamble0 W8 a& u* M# A p2 ^. K
- 3
# J. D; h3 |3 i# D6 Q! S7 ^ - 4 Permission is hereby granted, free of charge, to any person obtaining a copy% c$ T! M5 {4 F9 J" M, w' V7 _$ N1 h
- 5 of this software and associated documentation files (the "Software"), to deal$ V, z" E% D! ^! r' N
- 6 in the Software without restriction, including without limitation the rights
4 c! L2 j/ e- p L5 Y - 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2 a# R R; g, |3 C4 j1 L# ?; V1 x - 8 copies of the Software, and to permit persons to whom the Software is
& g9 E2 \! F) t3 U9 q& i, ^ - 9 furnished to do so, subject to the following conditions:0 e2 H' p8 ]7 h
- 10
8 }9 M7 `3 E0 N" w - 11 The above copyright notice and this permission notice shall be included in
^/ f7 i" F8 T/ m( E+ L. A - 12 all copies or substantial portions of the Software.
) q. s6 q+ h, _. K4 P" m: e - 13 - n" X0 m& Y% a
- 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9 T) I: Z& `0 b) E" \ - 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,' a7 ] y* @7 q/ w
- 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE" E/ o) ?. F g" }1 `7 r/ @
- 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER6 K, g' q, I8 q1 ], r1 y/ H7 P
- 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, x% V1 v4 P; l# ^
- 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2 Z% E+ d# u& A - 20 THE SOFTWARE.
5 y/ H7 o1 A! y$ d( Q$ n+ Y7 v - 21 */ i* t) E4 R* y, Z% s! z
- 22
" @( _5 C% ?+ a1 A. J. U, Z - 23 #ifndef cJSON__h* C- ~! g5 B, e
- 24 #define cJSON__h# J8 N' I2 g( r F( Z3 E
- 25 7 F$ o. t6 ?1 r+ x9 O$ b
- 26 #include <stddef.h>4 k: U) K' ]& z8 t |. i, Y
- 27
7 B2 T( O' D) a6 w& v$ V5 e - 28 #ifdef __cplusplus
; a3 ~+ r1 ~% ^ - 29 extern "C"% E$ Q3 T; ~3 y- E
- 30 {4 u* d: g! J3 A# h+ ~' R
- 31 #endif+ X5 ?5 {; c" E
- 32
+ g3 R5 Q+ `, B. o0 O4 s: ] - 33 /* cJSON Types: */
! C! E3 o2 m/ a' l6 d - 34 #define cJSON_False 0/ n3 N: g8 ?/ y% ` E' ]
- 35 #define cJSON_True 1
) T6 q! V2 U4 K# D# w- j0 |$ c - 36 #define cJSON_NULL 29 g D. g) Y$ g* p7 n
- 37 #define cJSON_Number 3
3 S% u5 z: T5 ?# A& o. f - 38 #define cJSON_String 4
. f l* r: r. A: \; e- p& N - 39 #define cJSON_Array 5
- j8 c3 i- G( Q3 R: Q4 y - 40 #define cJSON_Object 6
1 Z/ L6 C# q' E0 K - 41
# C- F$ T$ @# C5 u0 k1 Q3 ~3 Q - 42 #define cJSON_IsReference 256
" Y# ]% D, }+ }* {) x1 { - 43 4 F% Y& ~% Y( i0 t
- 44 /* The cJSON structure: */
# K' |, t, s! f- }: l5 N - 45 typedef struct cJSON {
! |: t% S; ^: K - 46 struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
& z w0 ~: E2 t% z3 k - 47 struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
) D1 v& X, Q* }8 L( c - 48 9 I; V6 M3 e# O6 A
- 49 int type; /* The type of the item, as above. */- v; L) S* p- r4 C
- 50
0 B' m6 H9 A5 h8 n1 O - 51 char *valuestring; /* The item's string, if type==cJSON_String */& O) b: ?% ?* E; L! Z& c0 r/ j
- 52 int valueint; /* The item's number, if type==cJSON_Number */
% u& ~# q( b3 d - 53 double valuedouble; /* The item's number, if type==cJSON_Number */
8 R X8 T( K( [! _7 x+ L - 54 ) @$ u. m6 A" M* T/ E' X
- 55 char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
! S' ]3 Z- E: s0 ^7 A: \ - 56 } cJSON;
3 t0 w6 C& ]% z9 `$ N3 B4 h - 57
7 @ B- {9 ]2 H/ n1 Y" T% `- K - 58 * ^- ?3 R# ~$ l2 n0 w! ~8 r
- 59 + k2 C" K3 l. e, B% z i3 T1 l
- 60 typedef struct cJSON_Hooks {$ Y' x& e+ a8 |5 X! u
- 61 void *(*malloc_fn)(size_t sz);
" H2 h/ n- k; e- x7 b - 62 void (*free_fn)(void *ptr);
! _; W+ F) B3 ~9 x+ Z - 63 } cJSON_Hooks;
" c2 m3 X) b7 }' o - 64 % A( Y3 l b- @3 ?# a% c7 C& J
- 65 /* Supply malloc, realloc and free functions to cJSON */; U+ [% v( h1 b5 c7 h& V
- 66 extern void cJSON_InitHooks(cJSON_Hooks* hooks);; u5 g( c; C( s; f% H: x- c
- 67
" ?# @( p$ C+ U - 68 7 i( n: r4 L3 {. n3 P. N- m
- 69 /* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
3 x7 D* S, b( V+ C+ _/ j/ Q* Y( F - 70 extern cJSON *cJSON_Parse(const char *value);2 _2 ?/ e. Z9 M
- 71 /* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */# D& P" ^5 n0 Y J: z( F5 |
- 72 extern char *cJSON_Print(cJSON *item);3 M5 ^; y! ^; `* c5 S4 s; S3 h
- 73 /* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
2 V# r3 f4 [! N4 v3 v: R6 z - 74 extern char *cJSON_PrintUnformatted(cJSON *item);
" q2 e3 z; M, e% g* j* k& V! M - 75 /* Delete a cJSON entity and all subentities. */
3 Z6 y; F/ h8 V: x8 U - 76 extern void cJSON_Delete(cJSON *c);
( N/ i2 N9 D! D$ M) [3 q - 77
/ h+ c4 y" N' y0 I6 }) d - 78 /* Returns the number of items in an array (or object). */. X. ], v5 u, u$ R- D1 X
- 79 extern int cJSON_GetArraySize(cJSON *array);
& `2 g9 ]/ }+ h' T/ B1 {+ o4 r0 w - 80 /* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. *// p2 T1 m" A; a1 L# i/ c, N
- 81 extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);9 y9 E! d( Z1 C+ L
- 82 /* Get item "string" from object. Case insensitive. */ k6 v- G7 [! m) l
- 83 extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);0 _8 g# }1 A; ]
- 84
8 z; u3 q0 K1 [ - 85 /* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */" t7 n2 v- A2 L; x+ ?* U+ z8 G/ A* B' d
- 86 extern const char *cJSON_GetErrorPtr(void);
* j1 `9 R6 H, @3 r1 b. o) J - 87
5 |2 u1 U, }3 s6 ~ - 88 /* These calls create a cJSON item of the appropriate type. */
. ]' ?5 }9 U1 w+ A - 89 extern cJSON *cJSON_CreateNull(void);# j! M& a0 f( t
- 90 extern cJSON *cJSON_CreateTrue(void);2 ?' Q; b5 k* `, C, C4 z
- 91 extern cJSON *cJSON_CreateFalse(void);2 b) }8 f: k. _/ q: f2 A& R% H6 j7 o4 n
- 92 extern cJSON *cJSON_CreateBool(int b);
# A9 k) q4 n2 B - 93 extern cJSON *cJSON_CreateNumber(double num);
; I9 q" m8 ?, ` - 94 extern cJSON *cJSON_CreateString(const char *string);
8 \1 r4 A% C7 H, }' ?& K; F - 95 extern cJSON *cJSON_CreateArray(void);+ ^6 [/ E* x1 s3 r
- 96 extern cJSON *cJSON_CreateObject(void);
1 j, n0 c+ m) r2 Y - 97 - f; u# e8 F) h% c
- 98 /* These utilities create an Array of count items. */, e1 d/ [8 I6 c% z# y# ?+ m
- 99 extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
1 P# c4 j' r, P - 100 extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
. v8 s) S9 f2 r+ T8 H) R - 101 extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
4 j( h! j( s% f! o) R2 u" s$ ]7 P - 102 extern cJSON *cJSON_CreateStringArray(const char **strings,int count);2 s4 r* \ V; d P2 x8 A, x0 {
- 103
* F% L7 ?, t- X* `. q4 X - 104 /* Append item to the specified array/object. */. F1 V# {& |6 O" [+ W
- 105 extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
! h2 y7 {7 s5 d" M' Q" ? - 106 extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
4 r! l: Y% B" T- } - 107 /* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */9 Y: x8 s5 _8 x' E/ i
- 108 extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
8 ~; A. B# L, ?* {0 P: z# y5 _/ x# d - 109 extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);/ B% Q w7 A8 A9 A
- 110 7 W6 I0 W0 P2 X
- 111 /* Remove/Detatch items from Arrays/Objects. */! u' Z. R& \0 X0 F% v9 R" g+ T
- 112 extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);1 ^! y& S+ d* H4 b2 `" G& P8 R* i
- 113 extern void cJSON_DeleteItemFromArray(cJSON *array,int which);+ N* b; H; Y" A# r
- 114 extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);3 k8 {% F! E B3 B
- 115 extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
! B1 s% q1 S. ^ - 116
: R. M: @7 F H: U1 k) I - 117 /* Update array items. *// f! H- t) b$ o+ L4 o
- 118 extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
0 [: ?3 S0 G, _6 G - 119 extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
3 ?- X# g, _2 [8 H) g" [ P0 i - 120 * c4 k' x( G5 B/ Q& ~& m2 F/ m
- 121 /* Duplicate a cJSON item */
$ v# \( v/ G" M9 Y+ c8 n, l - 122 extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);" \% @ v# u! D7 Y* M
- 123 /* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will4 Z( U _2 |) a
- 124 need to be released. With recurse!=0, it will duplicate any children connected to the item., j5 P6 h7 q( B0 M2 C8 g
- 125 The item->next and ->prev pointers are always zero on return from Duplicate. */: G& z+ _/ |' ?* ^: p' x ^
- 126
0 N+ p7 q' B# b1 J - 127 /* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */" `, B( q9 e- P8 m8 v8 E! ]
- 128 extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);8 e% f. ~( E! I. m' q
- 129 0 l m+ E5 X& I6 ^: r
- 130 extern void cJSON_Minify(char *json);
' B# \& z$ F2 Y* F2 k( k - 131
* ?& l* _. N( i7 H9 j- ? - 132 /* Macros for creating things quickly. */; X1 @5 f( B/ O1 G2 K* Y
- 133 #define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())# W* x, w. ]3 r7 F g
- 134 #define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())1 Y* u7 R/ d- F2 v# l: y l9 d
- 135 #define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())! E3 ~& S. h w& F" M$ ], ^- i
- 136 #define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))# t6 O: U1 s+ i5 V
- 137 #define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
3 c+ e+ ]1 c9 r3 N% d - 138 #define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
* s2 a+ D" ^5 n& }! r0 q - 139
6 f. L% i/ _; @% C7 S - 140 /* When assigning an integer value, it needs to be propagated to valuedouble too. */
. U, |. m V# \# z- S" L) i - 141 #define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))# d4 `2 p5 ?* V. E* S" R
- 142
6 N9 F: e* u% |, \; H - 143 #ifdef __cplusplus
% f5 j2 E8 I+ M& s - 144 }. W$ X \& V9 A7 }, i
- 145 #endif
. F* I1 _; r; O - 146 8 a$ J/ }: n- Z( y" y8 O7 D5 t2 k
- 147 #endif
复制代码- /*, G2 _6 _! j1 K l" m5 O9 Z
- Copyright (c) 2009 Dave Gamble' l8 h8 J% D1 ^8 t1 I9 c
) W( |) P4 Z3 A( l! x- Permission is hereby granted, free of charge, to any person obtaining a copy
/ K8 Z- n/ c9 I, j; L& z; H0 T( g - of this software and associated documentation files (the "Software"), to deal/ r! I$ E) Z. |$ w) `
- in the Software without restriction, including without limitation the rights2 p) z' ^( T* b5 |( n
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell/ n. z$ ], i# |( J# v; _0 n& p( z
- copies of the Software, and to permit persons to whom the Software is# r5 ]( m+ u4 I" [ K
- furnished to do so, subject to the following conditions:
% h" i* v$ J# m5 L e - $ v( m# x- L# v# y; `) q
- The above copyright notice and this permission notice shall be included in- f' b1 ^: v0 B* v, s a
- all copies or substantial portions of the Software.( j! A1 G) B0 E2 J, W
- / l& C# f" A0 |: K8 V, {
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR6 k& v( z- \4 i1 s/ U. G# Y' q
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY," _" D4 C/ G4 f: z/ V
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4 M) j' c. |# { - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
! j1 C, ~: J: w' p; i( {# t0 A3 F0 j6 f - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,; C( I" a2 I; R6 a5 p+ Q
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN, ]& ?7 n% U1 l. p+ H
- THE SOFTWARE., D Y3 `- t2 M+ K5 ^) W {9 ~
- */' o- u: r" O* e: Y( B
: ^( P6 o# L* O+ @ P# g- #ifndef cJSON__h2 ?/ V2 a0 u4 U
- #define cJSON__h
- U1 q# G0 p% ~3 z - $ G3 i* v& K& w, T
- #include <stddef.h>
2 a- p% }% L9 F, m) V K - " r9 R0 _9 g& B9 v' R' t
- #ifdef __cplusplus. h8 G# ~# v: p9 d0 J9 p
- extern "C"
& Q+ \, u7 N% e7 Q/ f1 C - {$ { n6 b0 i; s0 E; ]' \, N$ A
- #endif
, H& X+ E; M7 H/ F! } Z% C, F+ l
3 h- t, C! D3 I- /* cJSON Types: */
5 ?. B* g4 I/ U# V+ A3 k; ~: H - #define cJSON_False 0. u9 y3 ?& d: m0 d# v; U5 ~' r6 w
- #define cJSON_True 19 T! E: P* A9 N- i0 x
- #define cJSON_NULL 2
" Q4 e0 \# p3 a - #define cJSON_Number 3
& L- t1 W, R/ \4 T - #define cJSON_String 4& X- A# n5 r; i: M' x
- #define cJSON_Array 5
+ v6 X) L( n% h: {! H8 L5 ~" Y$ n - #define cJSON_Object 6) [% O |' l3 C1 [; H
5 H/ ^, L e4 q$ } b& G6 I, b- #define cJSON_IsReference 256
- E. G9 o0 ^+ K" s- J+ _& y3 ?
' ]- M# L+ ` M4 S( i- /* The cJSON structure: */
/ b3 h3 F: f. l7 u+ l. s - typedef struct cJSON {5 |/ q* E/ Y7 W* z W
- struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */3 X* V8 j, }7 |- `& C; M
- struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */; Y) c% T& P6 |# w
+ Y6 s: K* c3 g' p; a+ j- int type; /* The type of the item, as above. */! ^' Q8 L0 D/ \8 s+ s
- , h& B! W1 e, _6 Y5 {$ G2 {
- char *valuestring; /* The item's string, if type==cJSON_String */$ G$ [) T" W! d: v- B. S: z
- int valueint; /* The item's number, if type==cJSON_Number */
0 m3 F6 g# T; _4 u- a' J - double valuedouble; /* The item's number, if type==cJSON_Number */
: K" G3 N+ a e% [- H0 ~; W- E6 E
, `% y% W* k; W& V& v1 D6 z- char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
. R3 f6 g. {1 w9 M- Z0 q1 J - } cJSON;
8 M; M! V& T/ e - 7 V% a8 w( [1 ]- }; _
- - j+ w2 @4 k' C7 H0 u5 u U
4 y2 B3 `4 x! I, \( U& q' W- typedef struct cJSON_Hooks {
7 o4 b' e7 U- v4 f2 z - void *(*malloc_fn)(size_t sz);+ V9 W$ c1 V. V; Z8 v
- void (*free_fn)(void *ptr);- d6 y* U* E! `5 l# ~
- } cJSON_Hooks;
+ [) `: R) f3 @8 k/ {# V5 D; W6 A/ b
/ e, `7 d' D% o5 S5 }& p; O- /* Supply malloc, realloc and free functions to cJSON */
' q3 G: a9 q/ ^1 F - extern void cJSON_InitHooks(cJSON_Hooks* hooks);
8 [5 A1 v! L2 w
* A V- O6 B9 D. r
! u: c6 @. F8 G" |- /* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */: a" O( x3 c6 ^- @3 l" G* `* o
- extern cJSON *cJSON_Parse(const char *value);
& g6 W; g: ]( K* v/ U - /* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
{3 W2 U) f+ X( P - extern char *cJSON_Print(cJSON *item);
! f' k. K* m6 y# H - /* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
) n; c" H+ _- [* O; e, m$ N4 B) J! Z - extern char *cJSON_PrintUnformatted(cJSON *item);$ z" V' s- e/ j6 j+ r8 h
- /* Delete a cJSON entity and all subentities. */4 L ~* o8 {1 `' t$ u8 [
- extern void cJSON_Delete(cJSON *c);
' K! @' Y" C! h( I2 r( U6 }1 a% z
9 u! w4 u$ E: L7 W, I+ R! p* h6 x- /* Returns the number of items in an array (or object). */
, u0 l- B3 Z5 N5 U* F: L8 ~. H$ Y+ S - extern int cJSON_GetArraySize(cJSON *array);
/ c9 D1 g7 [6 U& j% @- q! { - /* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */* ^+ H* [8 K8 R& ]. i
- extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);- w. N/ d+ F: L3 t% r7 T
- /* Get item "string" from object. Case insensitive. */
. Q- R0 T# K8 |8 S, Q - extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
4 z. A/ O. e V; Y/ ?3 F
1 E# S$ q k* L' h2 B% b9 B- /* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
( {) S+ L+ y. z- |, T" S - extern const char *cJSON_GetErrorPtr(void);9 s: h, W3 H% a0 w$ a& v: O7 ~9 s
; }. L1 X" q1 N! P$ M, V( w/ K) t- /* These calls create a cJSON item of the appropriate type. */
' F" J, c' W/ W& b - extern cJSON *cJSON_CreateNull(void);& W5 g. U7 K. R. I& Z
- extern cJSON *cJSON_CreateTrue(void);8 q* x- ~: j1 e) r* U% C# J$ p Q
- extern cJSON *cJSON_CreateFalse(void);
- J$ P, k2 B1 _! w* J" o - extern cJSON *cJSON_CreateBool(int b);
4 ?% Q& e9 u! v5 ^ - extern cJSON *cJSON_CreateNumber(double num);
! e! v6 R2 [ a, h0 {; f - extern cJSON *cJSON_CreateString(const char *string);# d# `. @" q- }% u7 Y8 ~
- extern cJSON *cJSON_CreateArray(void);
; G1 {8 v) }; h: K+ i0 D4 A+ E2 L - extern cJSON *cJSON_CreateObject(void);+ j3 Q, T0 D6 w$ K" V5 G3 h
- 9 d! _3 f' v% x- M
- /* These utilities create an Array of count items. *// e: ]5 O+ S/ Y. `9 E& B
- extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);2 a5 y( u6 `. A
- extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count); N0 r" X0 l0 P7 O3 @
- extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
4 Z9 t3 M: K! K/ d9 z+ D* ` - extern cJSON *cJSON_CreateStringArray(const char **strings,int count);" S7 r7 {4 J* m% q; f% C0 i
- ; C. d+ t. O9 ^$ R% K
- /* Append item to the specified array/object. */
2 {: J& W: H" @; \; H - extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
( k5 {' e# |- o% H* J - extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
# U8 N% P9 h+ g$ F0 v! F$ U - /* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */" i, L8 q( Q7 J. v% ^9 V
- extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
/ `, m/ t& Q4 k, G! L) ] - extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
1 N3 G* t# L- J. J - " u) b# ^+ q" S* V
- /* Remove/Detatch items from Arrays/Objects. */
2 Z; x1 T Z6 j, @. @* n( G: c( y - extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
" P7 Y. g* G$ |+ j& I$ ~ - extern void cJSON_DeleteItemFromArray(cJSON *array,int which);. o* ~7 U/ \2 w9 \0 z9 ?6 `! L
- extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);9 P# w& K3 A8 z# n) J- f4 u- H
- extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
% m9 ?$ U7 g9 T! M5 m- k
_! D y1 \+ x3 p2 O- /* Update array items. */
) n7 c4 T" ?3 a. f% e, v4 i - extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);: b8 a/ P" z. c6 p* a
- extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
2 r$ k/ a# @; K" `6 M) I
5 X) @/ _, y {8 D. {0 {- /* Duplicate a cJSON item */4 R+ G7 ^* L* }2 ^
- extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
; L) p8 G# Z9 t0 t - /* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will9 X0 n2 z* U0 C: P5 q) D
- need to be released. With recurse!=0, it will duplicate any children connected to the item.
# H2 A- x9 l3 {5 J# { - The item->next and ->prev pointers are always zero on return from Duplicate. */
3 H$ W1 x/ W# D n& I - ( `: H8 m8 H; |* r" P! m: d
- /* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */9 C# L; ] {; W6 B: A' r9 `% N* r
- extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);
4 O$ _/ l0 @6 W! c# u9 X4 B - 7 b- w7 ^; r8 E# ]7 \- `1 z/ Q
- extern void cJSON_Minify(char *json);* \/ e& W# i% r. r4 N2 R
+ l9 D X' G' S( Z- /* Macros for creating things quickly. */8 b6 \8 C: O& Y! ]. o: t/ v1 j6 g. k( g* C
- #define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
+ ^4 _4 [& o' l {% V# y) q - #define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
! y% R+ `6 F7 f, ^% h4 i- z - #define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())3 |# Q0 U; T# |6 @4 J* L* G; W
- #define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
! s ?% \) l: b' U9 N& d! q" m, u - #define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))/ p C0 v9 b3 v- G, ^) F/ o8 e% S
- #define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
. y0 C, Z+ Q; g$ h; Y4 _ c
6 D( X$ k* i2 M, S- /* When assigning an integer value, it needs to be propagated to valuedouble too. */- S; D/ T& k1 Z7 x
- #define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))
( A$ ~ B! e# c6 c- o# r1 _$ h/ E
2 |1 P' n* d* _" M0 Z$ W, `- #ifdef __cplusplus6 P, b3 T- a1 }5 J$ T! r* W, s8 W
- }% M+ f! E+ t. t2 {' V
- #endif
+ x/ G* \& }2 U$ o+ n. |+ ? - 0 o6 o" s9 p" H' h! ]6 c: }' K
- #endif
复制代码下面是JSON数据的解析部分,简单说来就是对号入座。 - /**************************************************************************8 z4 J. y {: Z" V7 x! p. o8 U
- 函数功能:JSON字符串解析,按照命令格式,解析出上位机发送的命令
& i- I0 ~) I% U" ~+ t - 入口参数:JSON格式的字符串,
8 b3 \1 a3 Y4 w - 返回 值:指令类型- d0 s. _5 v2 |- |( l
- 注 意:从服务器的socket得到的字符串是加密了的字符串,需要首先解密后才能放入此函数9 X0 ?9 U/ _* P! @( x) U
- **************************************************************************/
' |* _* A! N. C1 l6 T1 o( y - CommandType GetCommandFromServer(char * JsonDataFromSocket)" Q& h3 n2 m, P. C) u$ e# c
- {- f4 T& {; ]5 U3 P& m" p
& w+ X8 d0 y7 e- // ROBOCmd_TypeDef cmd;//使用的时候用全部结构体代替
) L2 d: ]+ e7 Y1 o* r
3 l3 W& s( _, M* J- r1 N7 Z _- // Hello_Ack_TypeDef hello_ack;//使用的时候用全局接头体代替
, m) \" `* d' C5 Q5 V3 ^1 e+ C ? - CommandType cmdtype;
$ A+ {" a9 h% f - RobotJSON_CMD_TypeDef json_cmd;( x0 M+ v0 F' ^2 Q
- HelloJSON_Ack_TypeDef json_ack; P* [7 G. V2 b @( L
8 L9 ~# X$ S- s0 m" M- cJSON *root,*command_root;
) `* B0 T4 D" X: O. ~) k - 4 a4 v7 S1 q2 [' c
- root = cJSON_Parse(JsonDataFromSocket); //实例化JSON对象(静态对象)* E) t* q* U7 A
- if(!root)# w0 S+ o0 U& ?8 r
- {' D. p6 _; x/ ?9 F
- //printf("get cJSON faild !\n");2 v# [) l$ O8 N# |& G G) N
- cmdtype=NOCOMMAND;//如果没有,就直接返回0* R) S! s7 _- q/ ~) w' h8 C8 L
- }
9 q2 _9 O4 G5 v8 B. p; ~ - else
, R* a% ?% W/ p" T k# l: F+ X7 r: b& f - {( |) T( T) s1 O9 c
- command_root = cJSON_GetObjectItem(root, "RobotCommand"); //取RobotCommand键值对+ w& e; J7 h G$ K
- if(!command_root)
0 p' n" x |& o/ f' d - {
i, }& A& ~% j3 R - //printf("No RobotCommand !\n");( o0 r5 z- `/ B4 Q
- " t* V. R; z* H2 d1 w) G
- command_root = cJSON_GetObjectItem(root, "HelloACK"); //取hellACK键值对1 X4 \ g" j/ I4 E4 u( c
- if(!command_root)
6 l; K3 B' M1 L# o% H+ o% @- v - {
0 \! R9 E( E# t - //将函数的返回值改下 既不是RobotCommand也不是HelloACK的情况就返回0, ?2 r- Y* G7 Y' y! ]
- cmdtype=NOCOMMAND;//如果没有,就直接返回00 W7 f0 \% W; h: G9 M- t6 O
- }( [- d9 h# _2 r7 m4 G( Y
- else{
: ?! _7 c& L6 `; f& o - 3 u, n0 l: I! E$ \. a
$ u g9 ?* x% _5 `$ L- R: r- json_ack.ID = cJSON_GetObjectItem(command_root,"ID");
( |% ^2 s9 E6 I7 [0 {4 E8 _) V - if(!json_ack.ID)
5 I3 N. i M$ @) K. ] - {
7 ? q6 b3 E* D - cmdtype=NOCOMMAND;//如果没有,就直接返回0- \$ P$ Q/ w3 j5 n$ S( [+ m
- }
% n U6 V& e8 |: [% ~) K* h - else. S6 M: a9 N4 J
- {5 i4 d5 a# j5 Q! S2 Y% N
- strcpy(Ack_From_Server.ID,json_ack.ID->valuestring);
$ l" G0 s1 _8 y - }# S' {" j* `+ M. D
- json_ack.Time = cJSON_GetObjectItem(command_root,"Time");
0 h/ H5 a# X8 V2 S - if(!json_ack.Time)
( X1 l6 v9 A; Q' ] - {
7 r- n2 |# }) q. m - cmdtype=NOCOMMAND;//如果没有,就直接返回0
0 ]# b4 ?, i5 B+ d1 P+ Y. w - }# A1 t, p5 s8 v! F' _8 g
- else
. k4 E+ C9 H' V - {
3 w; }# v2 P, F! u) S - strcpy(Ack_From_Server.Time,json_ack.Time->valuestring);
* m6 J- b' l) o# v$ T J - }
, t6 {0 J5 o. a9 h; Q& F
! |' C3 x9 M) H! m6 T0 z- cmdtype=HELLO_ACK;//如果没有,就直接返回0
2 x! ?: c; q1 b2 S+ T - }
! L7 ]/ S8 P* d0 E - }" b+ a- `7 I7 x& Z5 B
- else9 p. H- ?$ w. L+ q
- {
5 V6 ~. T! Y0 _$ l% _, P
7 ?1 V9 m( ^" z( N- //运动命令& F z; m$ h& R- b5 r. J
- json_cmd.Command =cJSON_GetObjectItem(command_root,"Command");! w0 A8 X, C8 R/ u: N5 d8 W
- if(!json_cmd.Command). T" M# U* P2 Q+ H+ g0 U
- {! K7 {- a6 z! h* ^9 P
- //printf("no Command!\n");
7 {/ `- k) k! C m; S0 o7 i - //cmdtype=NOCOMMAND;//如果没有,就直接返回0
" u ]* p9 I: A N; Q4 s - }
# t3 Q6 M8 H% M; k( @1 G9 ^ - else
* I' i# f: ~$ k3 @ - {
) m" V; c6 o3 Q - //printf("Command is %s\r\n", robocmd.Command->valuestring);" a" C5 _- H+ M" E
- strcpy(Cmd_From_Server.Command,json_cmd.Command->valuestring);" P0 H6 q4 X1 { y
- //此时应该发送对应命令的OK程序,Set或者Auto或者。。。具体见协议
( ]! B+ h. g' y: f- d# s2 g9 a - ; E3 J, A" m5 _/ w) Y
- }
$ ?; q: B" e! k5 @ - //速度指令
1 @1 n. p @6 D% ` - json_cmd.Speed=cJSON_GetObjectItem(command_root,"Speed");
1 i2 X4 k$ Z( C) V - if(!json_cmd.Speed)
9 t4 Y# M8 n: F - {
$ x$ G% G- d- T - //printf("no Speed!\n");
- D6 D8 k8 o& I: y) X+ B - // cmdtype=NOCOMMAND;//如果没有,就直接返回0
: r F+ _9 f+ `' F* w6 h6 G+ G8 m - }
, Z& [: x- M+ @9 C - else
0 h7 ^! T* b9 S% _" M: a - {
0 @: L* X, f& G8 ^ - //printf("Speed is %d\r\n", json_cmd.Speed->valueint);5 M: f M L I0 @! h% J+ m
- Cmd_From_Server.Speed=json_cmd.Speed->valueint;
4 ?) h9 E2 L* d' [: C* z - }+ l. c5 l" U8 _* X5 H: Q$ V8 B+ z
' t1 ~! ` |, Q0 v4 l- //运行次数
; N7 B& b9 C; s7 `3 l - json_cmd.RunCount = cJSON_GetObjectItem(command_root,"RunCount");) c' y$ m: ^+ z' u- i& M( @9 I
- if(!json_cmd.RunCount), w% n: r2 u6 g
- {
, m( J4 O3 w) z# X - //printf("no RunCount!\n");
# q8 X, m+ g) Z3 m" k - // cmdtype=NOCOMMAND;//如果没有,就直接返回0 ]: F( H }5 I8 |
- }( A: l2 n4 b! c/ a8 u1 W
- else! s7 ?! E( D& ?' x7 I# e
- {
; [6 U1 Q% s4 O2 R0 `3 M( s1 w - //printf("RunCount is %d\r\n",json_cmd.RunCount->valueint);' y+ y5 _* [ k
- Cmd_From_Server.RunCount=json_cmd.RunCount->valueint;# e8 T$ j+ M3 B
- }
5 F1 N1 b2 Q2 k. h/ N% p - //开始位置
4 ]& H% U* u: V8 e* _$ S) S% W - json_cmd.StartPosition = cJSON_GetObjectItem(command_root,"StartPosition");1 X+ d9 z8 w4 H4 p' {
- if(!json_cmd.StartPosition)
0 A0 v" z' _6 Q) @ - {
9 a- b& k m3 ^) f' f - //printf("no StartPosition!\n");; H6 L, r/ i7 a2 f2 p; |8 t
- // cmdtype=NOCOMMAND;//如果没有,就直接返回0% ?6 f) J9 V* r! J2 g0 K! d
- }
! p0 x/ X6 }1 O& M, M# K - else& v5 b( G& T# e! h
- {& \' f8 E6 G8 o
- //printf("StartPosition is %d\r\n",json_cmd.StartPosition->valueint);
0 Z1 y! U$ e; q! ~9 z - Cmd_From_Server.StartPosition=json_cmd.StartPosition->valueint;
5 S& i8 z# B7 x' _ - }- z. m3 A# n1 ^6 w1 z
- //结束位置
$ |3 F9 `0 W, s+ q% l8 V. i7 J1 ` - json_cmd.EndPosition = cJSON_GetObjectItem(command_root,"EndPosition");
9 r' `# s2 \, j J - if(!json_cmd.EndPosition)
- d& ^* u- X/ W4 c l - {* A+ l0 R/ N. v; ?- M( t) p- J
- //printf("no EndPosition!\n");
% ]; Q1 e$ C# f j. e - // cmdtype=NOCOMMAND;//如果没有,就直接返回0
4 n% P# @% e' F/ Q5 m7 M - }8 z+ Z& z' d( D, y% W! l
- else
/ N, G7 W% W. f8 D5 Y0 I! M9 O - {
. c: @2 `) w9 s. A6 h - //printf("EndPosition is %d\r\n",json_cmd.EndPosition->valueint);& @1 Z: P9 ?6 d: w1 Q) o4 [; B
- Cmd_From_Server.EndPosition=json_cmd.EndPosition->valueint;' m6 V9 {$ }# X# H
- }
" |: {, \. W( b - //目标位置TargetPosition
2 ]1 x* t) t6 \6 ^ - json_cmd.TargetPosition = cJSON_GetObjectItem(command_root,"TargetPosition");2 ^: v) U/ M# i% ?8 S Z& _
- if(!json_cmd.TargetPosition)
% T! l4 I! t% ^! c - { F. y% {, N, b: M6 c3 W* \# I
- //printf("no TargetPosition!\n");7 X/ |0 A* I1 F) e, m
- // cmdtype=NOCOMMAND;//如果没有,就直接返回0# R' j" S: {, M g# O, O9 e
- }
& o$ @9 c( `# f3 V% U8 [8 E; n' a - else
; L1 R1 V# J0 Q" w2 V5 Z& e - {. b. h( F) V, Q, ~
- //printf("TargetPosition is %d\r\n",json_cmd.TargetPosition->valueint);
2 e+ V# j6 n; @7 Y1 y+ _ - Cmd_From_Server.TargetPosition=json_cmd.TargetPosition->valueint;8 \, x0 t; S: [0 P
- }
# }$ x8 l+ c4 w6 n
$ ~" A* B+ x; h- //*工作模式WorkMode;6 t. }5 A: ~0 |; F' l
- json_cmd.WorkMode= cJSON_GetObjectItem(command_root,"WorkMode");% V. A! ~. n0 ]- a
- if(!json_cmd.WorkMode)% }/ |+ v3 K$ Y5 Z" t& A( h1 N
- {" M0 ~9 V% J7 ?* m9 [
- //printf("no WorkMode!\n");' K1 Z( Y* }. K8 C/ k9 c8 a8 k. e
- // cmdtype=NOCOMMAND;//如果没有,就直接返回03 R0 P V& F8 u; w# P6 T& A
- }" w i# ]+ [* n/ P1 m) S
- else$ _' [ ~4 g3 ~2 V% Y' {4 D
- {+ }# ?( Z, o% ~! }. G5 H
- //printf("WorkMode is %s\r\n",json_cmd.WorkMode->valuestring);
# I, {$ y. t8 S3 V$ d# H7 c2 w - strcpy(Cmd_From_Server.WorkMode,json_cmd.WorkMode->valuestring);
/ E' p% p' o- P# s4 O3 U( B - }& n" `: f: t' |( k- {
- //step
- I1 w0 g& z+ Y6 g' E" l! z1 } - json_cmd.Step= cJSON_GetObjectItem(command_root,"Step");+ g7 O/ q$ I4 |1 m" J' w1 j ?! Q
- if(!json_cmd.Step)- r0 }( h3 Z3 q* t. g) R% A
- {
# L- Z' e2 w: s: n - //printf("no Step!\n");" }: @1 p2 U ? d* d
- // cmdtype=NOCOMMAND;//如果没有,就直接返回09 U9 \) N6 ]) s6 g, X/ @
- }6 i4 Y2 N) y! `
- else- x) g8 A7 s* @" j3 z; s# V5 O
- {
4 x: M7 K I2 y4 x& l; r5 }( m - //printf("Step is %d\r\n",json_cmd.Step->valueint);
( s$ X" K. m, I* s- p - Cmd_From_Server.Step=json_cmd.Step->valueint;
" i. x$ P2 K* M/ t! B - }2 X; c1 {& ~+ ^ J$ s
- 3 x0 d- l( Z6 O# \& U% }
- 6 ^$ ]0 Q# M( f
- cmdtype= COMMAND;
+ J; E: F4 m) k1 X1 g' b - % e$ T1 T6 D6 O1 V' w4 _
- }, B1 O- d* l: c+ ?9 e
- }
! k7 ~- ~" \+ l - ( Z5 R4 w: p1 E6 N2 i( |- }
- cJSON_Delete(root);
. D5 g% K9 x( _* X; @/ z/ U
7 R( R2 k+ T$ g. [7 P- return cmdtype;8 R! S/ C G! A% G1 g
- }
复制代码
9 K, n' ]5 ]" K. r0 ~& e) R4 I2 R) L- |, g) H0 F2 }9 d. Q
|