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