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