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