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