STM32-cJSON库的打包和解析
这几天使用了一下JSON在STM32103平台上的使用,还是很好用的,在此记录下。
JSON是啥我也不总结了,就是直观的看起来是一个有格式的字符串,看起来非常清楚明白,有点像Python中的dicitionary的意思,键值对,详细的可以看此链接http://www.cnblogs.com/catgatp/p/6380030.html。实际使用的过程中主要就是“打包”和“解析”。下面直接来代码。
char * Status_to_cJSON( char * cJSONROOM, ROBOStatus_TypeDef status)//传入一个变量的指针,这里cJSONROOM是一个全局变量(一个提前规定大小的字符数组),用来存放转换之后的JSON字符串 { char *result; cJSON *root,*subroot;//新建两个cJSON的对象指针 root=cJSON_CreateObject();//创建一个机器人状态的JSON对象 subroot=cJSON_CreateObject();//subroot是下面的一个嵌入对象 cJSON_AddStringToObject(subroot,"RunStatus",status.RunStatus);//将status.RunStatus的值赋值到subroot下面一个叫RunStatus的变量。 cJSON_AddStringToObject(subroot,"CurrentTime",status.CurrentTime); //同上 cJSON_AddNumberToObject(subroot,"CurrentPosition",status.CurrentPositiont); //将位置信息赋值到subroot下面一个叫CurrentPosition的变量,注意此处为Number类型 cJSON_AddNumberToObject(subroot,"CurrentSpeed",status.CurrentSpeed); cJSON_AddNumberToObject(subroot,"RunningCount",status.RunningCount); cJSON_AddNumberToObject(subroot,"CurrentTemp",status.CurrentTemp); cJSON_AddNumberToObject(subroot,"CurrentVoltage",status.CurrentVoltage); cJSON_AddNumberToObject(subroot,"CurrentAmp",status.CurrentAmp); cJSON_AddNumberToObject(subroot,"CurrentDir",status.CurrentDir); cJSON_AddNumberToObject(subroot,"ControlSystemEnergy",status.ControlSystemEnergy); cJSON_AddNumberToObject(subroot,"DynamicSystemEnergy",status.DynamicSystemEnergy); cJSON_AddItemToObject(root, "RobotStatus", subroot); result=cJSON_PrintUnformatted(root);//生成JSONC字符串,注意可以用cJSON_Print()格式的,就是人眼看着好看一点,就是有点占用存储空间 strcpy(cJSONROOM,result);//将转换的结果字符串赋值给传入的全局变量 cJSON_Delete(root);//最后将root根节点删除 myfree(result);//释放result的空间,必须要有,要不然内存里会失去一段空间,最后系统崩溃 return cJSONROOM;//不要指望着返回一个局部变量的地址,这是非常危险的,因为函数调用完毕后这个地址指向的内容就消失了。所以这个函数在设计的时候返回了一个全局变量的地址。 }
注意:malloc在STM32平台上使用的时候需要改动一下,关于内存操作的改动见下面的代码。使用字符数组会提高程序的可靠性,之前一直用字符指针,可能没有用好,中途会挂掉,后来发现提前建立一个数组,在这段空间进行数据的操作还是比较稳定的。
#include "malloc.h" //内存池(4字节对齐)
__align() u8 membase[MEM_MAX_SIZE]; //内部SRAM内存池
//内存管理表
u16 memmapbase[MEM_ALLOC_TABLE_SIZE]; //内部SRAM内存池MAP
//内存管理参数
const u32 memtblsize = MEM_ALLOC_TABLE_SIZE; //内存表大小
const u32 memblksize = MEM_BLOCK_SIZE; //内存分块大小
const u32 memsize = MEM_MAX_SIZE; //内存总大小 //内存管理控制器
struct _m_mallco_dev mallco_dev=
{
mem_init, //内存初始化
mem_perused, //内存使用率
membase, //内存池
memmapbase, //内存管理状态表
, //内存管理未就绪
}; //复制内存
//*des:目的地址
//*src:源地址
//n:需要复制的内存长度(字节为单位)
void mymemcpy(void *des,void *src,u32 n)
{
u8 *xdes=des;
u8 *xsrc=src;
while(n--)*xdes++=*xsrc++;
} //设置内存
//*s:内存首地址
//c :要设置的值
//count:需要设置的内存大小(字节为单位)
void mymemset(void *s,u8 c,u32 count)
{
u8 *xs = s;
while(count--)*xs++=c;
} //内存管理初始化
//memx:所属内存块
void mem_init(void)
{
mymemset(mallco_dev.memmap, ,memtblsize*);//内存状态表数据清零
mymemset(mallco_dev.membase, ,memsize); //内存池所有数据清零
mallco_dev.memrdy=; //内存管理初始化OK
} //获取内存使用率
//memx:所属内存块
//返回值:使用率(0~100)
u8 mem_perused(void)
{
u32 used=;
u32 i;
for(i=;i<memtblsize;i++)
{
if(mallco_dev.memmap[i])used++;
}
return (used*)/(memtblsize);
} //内存分配(内部调用)
//memx:所属内存块
//size:要分配的内存大小(字节)
//返回值:0XFFFFFFFF,代表错误;其他,内存偏移地址
u32 mem_malloc(u32 size)
{
signed long offset=;
u16 nmemb; //需要的内存块数
u16 cmemb=;//连续空内存块数
u32 i;
if(!mallco_dev.memrdy)mallco_dev.init();//未初始化,先执行初始化
if(size==)return 0XFFFFFFFF;//不需要分配 nmemb=size/memblksize; //获取需要分配的连续内存块数
if(size%memblksize)nmemb++;
for(offset=memtblsize-;offset>=;offset--)//搜索整个内存控制区
{
if(!mallco_dev.memmap[offset])cmemb++;//连续空内存块数增加
else cmemb=; //连续内存块清零
if(cmemb==nmemb) //找到了连续nmemb个空内存块
{
for(i=;i<nmemb;i++) //标注内存块非空
{
mallco_dev.memmap[offset+i]=nmemb;
}
return (offset*memblksize);//返回偏移地址
}
}
return 0XFFFFFFFF;//未找到符合分配条件的内存块
} //释放内存(内部调用)
//memx:所属内存块
//offset:内存地址偏移
//返回值:0,释放成功;1,释放失败;
u8 mem_free(u32 offset)
{
int i;
if(!mallco_dev.memrdy)//未初始化,先执行初始化
{
mallco_dev.init();
return ;//未初始化
}
if(offset<memsize)//偏移在内存池内.
{
int index=offset/memblksize; //偏移所在内存块号码
int nmemb=mallco_dev.memmap[index]; //内存块数量
for(i=;i<nmemb;i++) //内存块清零
{
mallco_dev.memmap[index+i]=;
}
return ;
}else return ;//偏移超区了.
} //释放内存(外部调用)
//memx:所属内存块
//ptr:内存首地址
void myfree(void *ptr)
{
u32 offset;
if(ptr==NULL)return;//地址为0.
offset=(u32)ptr-(u32)mallco_dev.membase;
mem_free(offset);//释放内存
} //分配内存(外部调用)
//memx:所属内存块
//size:内存大小(字节)
//返回值:分配到的内存首地址.
void *mymalloc(u32 size)
{
u32 offset;
offset=mem_malloc(size);
if(offset==0XFFFFFFFF)return NULL;
else return (void*)((u32)mallco_dev.membase+offset);
} //重新分配内存(外部调用)
//memx:所属内存块
//*ptr:旧内存首地址
//size:要分配的内存大小(字节)
//返回值:新分配到的内存首地址.
void *myrealloc(void *ptr,u32 size)
{
u32 offset;
offset=mem_malloc(size);
if(offset==0XFFFFFFFF)return NULL;
else
{
mymemcpy((void*)((u32)mallco_dev.membase+offset),ptr,size); //拷贝旧内存内容到新内存
myfree(ptr); //释放旧内存
return (void*)((u32)mallco_dev.membase+offset); //返回新内存首地址
}
}
malloc.h内容如下:
#ifndef __MALLOC_H
#define __MALLOC_H
#include "stm32f10x.h" #ifndef NULL
#define NULL 0
#endif #define MEM_BLOCK_SIZE 32 //内存块大小为32字节
#define MEM_MAX_SIZE 16*1024 //最大管理内存 2K
#define MEM_ALLOC_TABLE_SIZE MEM_MAX_SIZE/MEM_BLOCK_SIZE //内存表大小 //内存管理控制器
struct _m_mallco_dev
{
void (*init)(void); //初始化
u8 (*perused)(void); //内存使用率
u8 *membase; //内存池
u16 *memmap; //内存管理状态表
u8 memrdy; //内存管理是否就绪
}; extern struct _m_mallco_dev mallco_dev; //在mallco.c里面定义 void mymemset(void *s,u8 c,u32 count); //设置内存
void mymemcpy(void *des,void *src,u32 n);//复制内存 void mem_init(void); //内存管理初始化函数
u32 mem_malloc(u32 size); //内存分配
u8 mem_free(u32 offset); //内存释放
u8 mem_perused(void); //获得内存使用率
////////////////////////////////////////////////////////////////////////////////
//用户调用函数
void myfree(void *ptr); //内存释放
void *mymalloc(u32 size); //内存分配
void *myrealloc(void *ptr,u32 size);//重新分配内存
#endif
cJSON.c的内容也全在下面
/*
Copyright (c) 2009 Dave Gamble Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/ /* cJSON */
/* JSON parser in C. */ #include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <float.h>
#include <limits.h>
#include <ctype.h>
#include "cJSON.h" #include "malloc.h" static const char *ep; const char *cJSON_GetErrorPtr(void) {return ep;} static int cJSON_strcasecmp(const char *s1,const char *s2)
{
if (!s1) return (s1==s2)?:;if (!s2) return ;
for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == ) return ;
return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
} static void *(*cJSON_malloc)(size_t sz) = mymalloc;
static void (*cJSON_free)(void *ptr) = myfree; static char* cJSON_strdup(const char* str)
{
size_t len;
char* copy; len = strlen(str) + ;
if (!(copy = (char*)cJSON_malloc(len))) return ;
memcpy(copy,str,len);
return copy;
} void cJSON_InitHooks(cJSON_Hooks* hooks)
{
if (!hooks) { /* Reset hooks */
cJSON_malloc = malloc;
cJSON_free = free;
return;
} cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
} /* Internal constructor. */
static cJSON *cJSON_New_Item(void)
{
cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
if (node) memset(node,,sizeof(cJSON));
return node;
} /* Delete a cJSON structure. */
void cJSON_Delete(cJSON *c)
{
cJSON *next;
while (c)
{
next=c->next;
if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
if (c->string) cJSON_free(c->string);
cJSON_free(c);
c=next;
}
} /* Parse the input text to generate a number, and populate the result into item. */
static const char *parse_number(cJSON *item,const char *num)
{
double n=,sign=,scale=;int subscale=,signsubscale=; if (*num=='-') sign=-,num++; /* Has sign? */
if (*num=='') num++; /* is zero */
if (*num>='' && *num<='') do n=(n*10.0)+(*num++ -''); while (*num>='' && *num<=''); /* Number? */
if (*num=='.' && num[]>='' && num[]<='') {num++; do n=(n*10.0)+(*num++ -''),scale--; while (*num>='' && *num<='');} /* Fractional part? */
if (*num=='e' || *num=='E') /* Exponent? */
{ num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-,num++; /* With sign? */
while (*num>='' && *num<='') subscale=(subscale*)+(*num++ - ''); /* Number? */
} n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */ item->valuedouble=n;
item->valueint=(int)n;
item->type=cJSON_Number;
return num;
} /* Render the number nicely from the given item into a string. */
static char *print_number(cJSON *item)
{
char *str;
double d=item->valuedouble;
if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
{
str=(char*)cJSON_malloc(); /* 2^64+1 can be represented in 21 chars. */
if (str) sprintf(str,"%d",item->valueint);
}
else
{
str=(char*)cJSON_malloc(); /* This is a nice tradeoff. */
if (str)
{
if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);
else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
else sprintf(str,"%f",d);
}
}
return str;
} static unsigned parse_hex4(const char *str)
{
unsigned h=;
if (*str>='' && *str<='') h+=(*str)-''; else if (*str>='A' && *str<='F') h+=+(*str)-'A'; else if (*str>='a' && *str<='f') h+=+(*str)-'a'; else return ;
h=h<<;str++;
if (*str>='' && *str<='') h+=(*str)-''; else if (*str>='A' && *str<='F') h+=+(*str)-'A'; else if (*str>='a' && *str<='f') h+=+(*str)-'a'; else return ;
h=h<<;str++;
if (*str>='' && *str<='') h+=(*str)-''; else if (*str>='A' && *str<='F') h+=+(*str)-'A'; else if (*str>='a' && *str<='f') h+=+(*str)-'a'; else return ;
h=h<<;str++;
if (*str>='' && *str<='') h+=(*str)-''; else if (*str>='A' && *str<='F') h+=+(*str)-'A'; else if (*str>='a' && *str<='f') h+=+(*str)-'a'; else return ;
return h;
} /* Parse the input text into an unescaped cstring, and populate item. */
static const unsigned char firstByteMark[] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
static const char *parse_string(cJSON *item,const char *str)
{
const char *ptr=str+;char *ptr2;char *out;int len=;unsigned uc,uc2;
if (*str!='\"') {ep=str;return ;} /* not a string! */ while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */ out=(char*)cJSON_malloc(len+); /* This is how long we need for the string, roughly. */
if (!out) return ; ptr=str+;ptr2=out;
while (*ptr!='\"' && *ptr)
{
if (*ptr!='\\') *ptr2++=*ptr++;
else
{
ptr++;
switch (*ptr)
{
case 'b': *ptr2++='\b'; break;
case 'f': *ptr2++='\f'; break;
case 'n': *ptr2++='\n'; break;
case 'r': *ptr2++='\r'; break;
case 't': *ptr2++='\t'; break;
case 'u': /* transcode utf16 to utf8. */
uc=parse_hex4(ptr+);ptr+=; /* get the unicode char. */ if ((uc>=0xDC00 && uc<=0xDFFF) || uc==) break; /* check for invalid. */ if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */
{
if (ptr[]!='\\' || ptr[]!='u') break; /* missing second-half of surrogate. */
uc2=parse_hex4(ptr+);ptr+=;
if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */
uc=0x10000 + (((uc&0x3FF)<<) | (uc2&0x3FF));
} len=;if (uc<0x80) len=;else if (uc<0x800) len=;else if (uc<0x10000) len=; ptr2+=len; switch (len) {
case : *--ptr2 =((uc | 0x80) & 0xBF); uc >>= ;
case : *--ptr2 =((uc | 0x80) & 0xBF); uc >>= ;
case : *--ptr2 =((uc | 0x80) & 0xBF); uc >>= ;
case : *--ptr2 =(uc | firstByteMark[len]);
}
ptr2+=len;
break;
default: *ptr2++=*ptr; break;
}
ptr++;
}
}
*ptr2=;
if (*ptr=='\"') ptr++;
item->valuestring=out;
item->type=cJSON_String;
return ptr;
} /* Render the cstring provided to an escaped version that can be printed. */
static char *print_string_ptr(const char *str)
{
const char *ptr;char *ptr2,*out;int len=;unsigned char token; if (!str) return cJSON_strdup("");
ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<) len+=;ptr++;} out=(char*)cJSON_malloc(len+);
if (!out) return ; ptr2=out;ptr=str;
*ptr2++='\"';
while (*ptr)
{
if ((unsigned char)*ptr> && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
else
{
*ptr2++='\\';
switch (token=*ptr++)
{
case '\\': *ptr2++='\\'; break;
case '\"': *ptr2++='\"'; break;
case '\b': *ptr2++='b'; break;
case '\f': *ptr2++='f'; break;
case '\n': *ptr2++='n'; break;
case '\r': *ptr2++='r'; break;
case '\t': *ptr2++='t'; break;
default: sprintf(ptr2,"u%04x",token);ptr2+=; break; /* escape and print */
}
}
}
*ptr2++='\"';*ptr2++=;
return out;
}
/* Invote print_string_ptr (which is useful) on an item. */
static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);} /* Predeclare these prototypes. */
static const char *parse_value(cJSON *item,const char *value);
static char *print_value(cJSON *item,int depth,int fmt);
static const char *parse_array(cJSON *item,const char *value);
static char *print_array(cJSON *item,int depth,int fmt);
static const char *parse_object(cJSON *item,const char *value);
static char *print_object(cJSON *item,int depth,int fmt); /* Utility to jump whitespace and cr/lf */
static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=) in++; return in;} /* Parse an object - create a new root, and populate. */
cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
{
const char *end=;
cJSON *c=cJSON_New_Item();
ep=;
if (!c) return ; /* memory fail */ end=parse_value(c,skip(value));
if (!end) {cJSON_Delete(c);return ;} /* parse failure. ep is set. */ /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return ;}}
if (return_parse_end) *return_parse_end=end;
return c;
}
/* Default options for cJSON_Parse */
cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,,);} /* Render a cJSON item/entity/structure to text. */
char *cJSON_Print(cJSON *item) {return print_value(item,,);}
char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,,);} /* Parser core - when encountering text, process appropriately. */
static const char *parse_value(cJSON *item,const char *value)
{
if (!value) return ; /* Fail on null. */
if (!strncmp(value,"null",)) { item->type=cJSON_NULL; return value+; }
if (!strncmp(value,"false",)) { item->type=cJSON_False; return value+; }
if (!strncmp(value,"true",)) { item->type=cJSON_True; item->valueint=; return value+; }
if (*value=='\"') { return parse_string(item,value); }
if (*value=='-' || (*value>='' && *value<='')) { return parse_number(item,value); }
if (*value=='[') { return parse_array(item,value); }
if (*value=='{') { return parse_object(item,value); } ep=value;return ; /* failure. */
} /* Render a value to text. */
static char *print_value(cJSON *item,int depth,int fmt)
{
char *out=;
if (!item) return ;
switch ((item->type)&)
{
case cJSON_NULL: out=cJSON_strdup("null"); break;
case cJSON_False: out=cJSON_strdup("false");break;
case cJSON_True: out=cJSON_strdup("true"); break;
case cJSON_Number: out=print_number(item);break;
case cJSON_String: out=print_string(item);break;
case cJSON_Array: out=print_array(item,depth,fmt);break;
case cJSON_Object: out=print_object(item,depth,fmt);break;
}
return out;
} /* Build an array from input text. */
static const char *parse_array(cJSON *item,const char *value)
{
cJSON *child;
if (*value!='[') {ep=value;return ;} /* not an array! */ item->type=cJSON_Array;
value=skip(value+);
if (*value==']') return value+; /* empty array. */ item->child=child=cJSON_New_Item();
if (!item->child) return ; /* memory fail */
value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
if (!value) return ; while (*value==',')
{
cJSON *new_item;
if (!(new_item=cJSON_New_Item())) return ; /* memory fail */
child->next=new_item;new_item->prev=child;child=new_item;
value=skip(parse_value(child,skip(value+)));
if (!value) return ; /* memory fail */
} if (*value==']') return value+; /* end of array */
ep=value;return ; /* malformed. */
} /* Render an array to text */
static char *print_array(cJSON *item,int depth,int fmt)
{
char **entries;
char *out=,*ptr,*ret;int len=;
cJSON *child=item->child;
int numentries=,i=,fail=; /* How many entries in the array? */
while (child) numentries++,child=child->next;
/* Explicitly handle numentries==0 */
if (!numentries)
{
out=(char*)cJSON_malloc();
if (out) strcpy(out,"[]");
return out;
}
/* Allocate an array to hold the values for each */
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
if (!entries) return ;
memset(entries,,numentries*sizeof(char*));
/* Retrieve all the results: */
child=item->child;
while (child && !fail)
{
ret=print_value(child,depth+,fmt);
entries[i++]=ret;
if (ret) len+=strlen(ret)++(fmt?:); else fail=;
child=child->next;
} /* If we didn't fail, try to malloc the output string */
if (!fail) out=(char*)cJSON_malloc(len);
/* If that fails, we fail. */
if (!out) fail=; /* Handle failure. */
if (fail)
{
for (i=;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
cJSON_free(entries);
return ;
} /* Compose the output array. */
*out='[';
ptr=out+;*ptr=;
for (i=;i<numentries;i++)
{
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
if (i!=numentries-) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=;}
cJSON_free(entries[i]);
}
cJSON_free(entries);
*ptr++=']';*ptr++=;
return out;
} /* Build an object from the text. */
static const char *parse_object(cJSON *item,const char *value)
{
cJSON *child;
if (*value!='{') {ep=value;return ;} /* not an object! */ item->type=cJSON_Object;
value=skip(value+);
if (*value=='}') return value+; /* empty array. */ item->child=child=cJSON_New_Item();
if (!item->child) return ;
value=skip(parse_string(child,skip(value)));
if (!value) return ;
child->string=child->valuestring;child->valuestring=;
if (*value!=':') {ep=value;return ;} /* fail! */
value=skip(parse_value(child,skip(value+))); /* skip any spacing, get the value. */
if (!value) return ; while (*value==',')
{
cJSON *new_item;
if (!(new_item=cJSON_New_Item())) return ; /* memory fail */
child->next=new_item;new_item->prev=child;child=new_item;
value=skip(parse_string(child,skip(value+)));
if (!value) return ;
child->string=child->valuestring;child->valuestring=;
if (*value!=':') {ep=value;return ;} /* fail! */
value=skip(parse_value(child,skip(value+))); /* skip any spacing, get the value. */
if (!value) return ;
} if (*value=='}') return value+; /* end of array */
ep=value;return ; /* malformed. */
} /* Render an object to text. */
static char *print_object(cJSON *item,int depth,int fmt)
{
char **entries=,**names=;
char *out=,*ptr,*ret,*str;int len=,i=,j;
cJSON *child=item->child;
int numentries=,fail=;
/* Count the number of entries. */
while (child) numentries++,child=child->next;
/* Explicitly handle empty object case */
if (!numentries)
{
out=(char*)cJSON_malloc(fmt?depth+:);
if (!out) return ;
ptr=out;*ptr++='{';
if (fmt) {*ptr++='\n';for (i=;i<depth-;i++) *ptr++='\t';}
*ptr++='}';*ptr++=;
return out;
}
/* Allocate space for the names and the objects */
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
if (!entries) return ;
names=(char**)cJSON_malloc(numentries*sizeof(char*));
if (!names) {cJSON_free(entries);return ;}
memset(entries,,sizeof(char*)*numentries);
memset(names,,sizeof(char*)*numentries); /* Collect all the results into our arrays: */
child=item->child;depth++;if (fmt) len+=depth;
while (child)
{
names[i]=str=print_string_ptr(child->string);
entries[i++]=ret=print_value(child,depth,fmt);
if (str && ret) len+=strlen(ret)+strlen(str)++(fmt?+depth:); else fail=;
child=child->next;
} /* Try to allocate the output string */
if (!fail) out=(char*)cJSON_malloc(len);
if (!out) fail=; /* Handle failure */
if (fail)
{
for (i=;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
cJSON_free(names);cJSON_free(entries);
return ;
} /* Compose the output: */
*out='{';ptr=out+;if (fmt)*ptr++='\n';*ptr=;
for (i=;i<numentries;i++)
{
if (fmt) for (j=;j<depth;j++) *ptr++='\t';
strcpy(ptr,names[i]);ptr+=strlen(names[i]);
*ptr++=':';if (fmt) *ptr++='\t';
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
if (i!=numentries-) *ptr++=',';
if (fmt) *ptr++='\n';*ptr=;
cJSON_free(names[i]);cJSON_free(entries[i]);
} cJSON_free(names);cJSON_free(entries);
if (fmt) for (i=;i<depth-;i++) *ptr++='\t';
*ptr++='}';*ptr++=;
return out;
} /* Get Array size/item / object item. */
int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=;while(c)i++,c=c->next;return i;}
cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>) item--,c=c->next; return c;}
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;} /* Utility for array list handling. */
static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
/* Utility for handling references. */
static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return ;mymemcpy(ref,item,sizeof(cJSON));ref->string=;ref->type|=cJSON_IsReference;ref->next=ref->prev=;return ref;} /* Add item to array/object. */
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);}}
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);}
void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));}
void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));} cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>) c=c->next,which--;if (!c) return ;
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=;return c;}
void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return ;}
void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));} /* Replace array/object items with new ones. */
void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>) c=c->next,which--;if (!c) return;
newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=;cJSON_Delete(c);}
void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=;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);}} /* Create basic types: */
cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
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;}
cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;} /* Create Arrays: */
cJSON *cJSON_CreateIntArray(const int *numbers,int count) {int i;cJSON *n=,*p=,*a=cJSON_CreateArray();for(i=;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateFloatArray(const float *numbers,int count) {int i;cJSON *n=,*p=,*a=cJSON_CreateArray();for(i=;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateDoubleArray(const double *numbers,int count) {int i;cJSON *n=,*p=,*a=cJSON_CreateArray();for(i=;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=,*p=,*a=cJSON_CreateArray();for(i=;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;} /* Duplication */
cJSON *cJSON_Duplicate(cJSON *item,int recurse)
{
cJSON *newitem,*cptr,*nptr=,*newchild;
/* Bail on bad ptr */
if (!item) return ;
/* Create new item */
newitem=cJSON_New_Item();
if (!newitem) return ;
/* Copy over all vars */
newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;
if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return ;}}
if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return ;}}
/* If non-recursive, then we're done! */
if (!recurse) return newitem;
/* Walk the ->next chain for the child. */
cptr=item->child;
while (cptr)
{
newchild=cJSON_Duplicate(cptr,); /* Duplicate (with recurse) each item in the ->next chain */
if (!newchild) {cJSON_Delete(newitem);return ;}
if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */
else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */
cptr=cptr->next;
}
return newitem;
} void cJSON_Minify(char *json)
{
char *into=json;
while (*json)
{
if (*json==' ') json++;
else if (*json=='\t') json++; // Whitespace characters.
else if (*json=='\r') json++;
else if (*json=='\n') json++;
else if (*json=='/' && json[]=='/') while (*json && *json!='\n') json++; // double-slash comments, to end of line.
else if (*json=='/' && json[]=='*') {while (*json && !(*json=='*' && json[]=='/')) json++;json+=;} // multiline comments.
else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} // string literals, which are \" sensitive.
else *into++=*json++; // All other characters.
}
*into=; // and null-terminate.
} cJSON.h内容如下
/*
Copyright (c) 2009 Dave Gamble Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/ #ifndef cJSON__h
#define cJSON__h #include <stddef.h> #ifdef __cplusplus
extern "C"
{
#endif /* cJSON Types: */
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3
#define cJSON_String 4
#define cJSON_Array 5
#define cJSON_Object 6 #define cJSON_IsReference 256 /* The cJSON structure: */
typedef struct cJSON {
struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ int type; /* The type of the item, as above. */ char *valuestring; /* The item's string, if type==cJSON_String */
int valueint; /* The item's number, if type==cJSON_Number */
double valuedouble; /* The item's number, if type==cJSON_Number */ char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON; typedef struct cJSON_Hooks {
void *(*malloc_fn)(size_t sz);
void (*free_fn)(void *ptr);
} cJSON_Hooks; /* Supply malloc, realloc and free functions to cJSON */
extern void cJSON_InitHooks(cJSON_Hooks* hooks); /* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
extern cJSON *cJSON_Parse(const char *value);
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
extern char *cJSON_Print(cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
extern char *cJSON_PrintUnformatted(cJSON *item);
/* Delete a cJSON entity and all subentities. */
extern void cJSON_Delete(cJSON *c); /* Returns the number of items in an array (or object). */
extern int cJSON_GetArraySize(cJSON *array);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
/* Get item "string" from object. Case insensitive. */
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string); /* 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. */
extern const char *cJSON_GetErrorPtr(void); /* These calls create a cJSON item of the appropriate type. */
extern cJSON *cJSON_CreateNull(void);
extern cJSON *cJSON_CreateTrue(void);
extern cJSON *cJSON_CreateFalse(void);
extern cJSON *cJSON_CreateBool(int b);
extern cJSON *cJSON_CreateNumber(double num);
extern cJSON *cJSON_CreateString(const char *string);
extern cJSON *cJSON_CreateArray(void);
extern cJSON *cJSON_CreateObject(void); /* These utilities create an Array of count items. */
extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
extern cJSON *cJSON_CreateStringArray(const char **strings,int count); /* Append item to the specified array/object. */
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
/* 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. */
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item); /* Remove/Detatch items from Arrays/Objects. */
extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string); /* Update array items. */
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); /* Duplicate a cJSON item */
extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
need to be released. With recurse!=0, it will duplicate any children connected to the item.
The item->next and ->prev pointers are always zero on return from Duplicate. */ /* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated); extern void cJSON_Minify(char *json); /* Macros for creating things quickly. */
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) /* When assigning an integer value, it needs to be propagated to valuedouble too. */
#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val)) #ifdef __cplusplus
}
#endif #endif
下面是JSON数据的解析部分,简单说来就是对号入座。
/**************************************************************************
函数功能:JSON字符串解析,按照命令格式,解析出上位机发送的命令
入口参数:JSON格式的字符串,
返回 值:指令类型
注 意:从服务器的socket得到的字符串是加密了的字符串,需要首先解密后才能放入此函数
**************************************************************************/
CommandType GetCommandFromServer(char * JsonDataFromSocket)
{ // ROBOCmd_TypeDef cmd;//使用的时候用全部结构体代替 // Hello_Ack_TypeDef hello_ack;//使用的时候用全局接头体代替
CommandType cmdtype;
RobotJSON_CMD_TypeDef json_cmd;
HelloJSON_Ack_TypeDef json_ack; cJSON *root,*command_root; root = cJSON_Parse(JsonDataFromSocket); //实例化JSON对象(静态对象)
if(!root)
{
//printf("get cJSON faild !\n");
cmdtype=NOCOMMAND;//如果没有,就直接返回0
}
else
{
command_root = cJSON_GetObjectItem(root, "RobotCommand"); //取RobotCommand键值对
if(!command_root)
{
//printf("No RobotCommand !\n"); command_root = cJSON_GetObjectItem(root, "HelloACK"); //取hellACK键值对
if(!command_root)
{
//将函数的返回值改下 既不是RobotCommand也不是HelloACK的情况就返回0
cmdtype=NOCOMMAND;//如果没有,就直接返回0
}
else{ json_ack.ID = cJSON_GetObjectItem(command_root,"ID");
if(!json_ack.ID)
{
cmdtype=NOCOMMAND;//如果没有,就直接返回0
}
else
{
strcpy(Ack_From_Server.ID,json_ack.ID->valuestring);
}
json_ack.Time = cJSON_GetObjectItem(command_root,"Time");
if(!json_ack.Time)
{
cmdtype=NOCOMMAND;//如果没有,就直接返回0
}
else
{
strcpy(Ack_From_Server.Time,json_ack.Time->valuestring);
} cmdtype=HELLO_ACK;//如果没有,就直接返回0
}
}
else
{ //运动命令
json_cmd.Command =cJSON_GetObjectItem(command_root,"Command");
if(!json_cmd.Command)
{
//printf("no Command!\n");
//cmdtype=NOCOMMAND;//如果没有,就直接返回0
}
else
{
//printf("Command is %s\r\n", robocmd.Command->valuestring);
strcpy(Cmd_From_Server.Command,json_cmd.Command->valuestring);
//此时应该发送对应命令的OK程序,Set或者Auto或者。。。具体见协议 }
//速度指令
json_cmd.Speed=cJSON_GetObjectItem(command_root,"Speed");
if(!json_cmd.Speed)
{
//printf("no Speed!\n");
// cmdtype=NOCOMMAND;//如果没有,就直接返回0
}
else
{
//printf("Speed is %d\r\n", json_cmd.Speed->valueint);
Cmd_From_Server.Speed=json_cmd.Speed->valueint;
} //运行次数
json_cmd.RunCount = cJSON_GetObjectItem(command_root,"RunCount");
if(!json_cmd.RunCount)
{
//printf("no RunCount!\n");
// cmdtype=NOCOMMAND;//如果没有,就直接返回0
}
else
{
//printf("RunCount is %d\r\n",json_cmd.RunCount->valueint);
Cmd_From_Server.RunCount=json_cmd.RunCount->valueint;
}
//开始位置
json_cmd.StartPosition = cJSON_GetObjectItem(command_root,"StartPosition");
if(!json_cmd.StartPosition)
{
//printf("no StartPosition!\n");
// cmdtype=NOCOMMAND;//如果没有,就直接返回0
}
else
{
//printf("StartPosition is %d\r\n",json_cmd.StartPosition->valueint);
Cmd_From_Server.StartPosition=json_cmd.StartPosition->valueint;
}
//结束位置
json_cmd.EndPosition = cJSON_GetObjectItem(command_root,"EndPosition");
if(!json_cmd.EndPosition)
{
//printf("no EndPosition!\n");
// cmdtype=NOCOMMAND;//如果没有,就直接返回0
}
else
{
//printf("EndPosition is %d\r\n",json_cmd.EndPosition->valueint);
Cmd_From_Server.EndPosition=json_cmd.EndPosition->valueint;
}
//目标位置TargetPosition
json_cmd.TargetPosition = cJSON_GetObjectItem(command_root,"TargetPosition");
if(!json_cmd.TargetPosition)
{
//printf("no TargetPosition!\n");
// cmdtype=NOCOMMAND;//如果没有,就直接返回0
}
else
{
//printf("TargetPosition is %d\r\n",json_cmd.TargetPosition->valueint);
Cmd_From_Server.TargetPosition=json_cmd.TargetPosition->valueint;
} //*工作模式WorkMode;
json_cmd.WorkMode= cJSON_GetObjectItem(command_root,"WorkMode");
if(!json_cmd.WorkMode)
{
//printf("no WorkMode!\n");
// cmdtype=NOCOMMAND;//如果没有,就直接返回0
}
else
{
//printf("WorkMode is %s\r\n",json_cmd.WorkMode->valuestring);
strcpy(Cmd_From_Server.WorkMode,json_cmd.WorkMode->valuestring);
}
//step
json_cmd.Step= cJSON_GetObjectItem(command_root,"Step");
if(!json_cmd.Step)
{
//printf("no Step!\n");
// cmdtype=NOCOMMAND;//如果没有,就直接返回0
}
else
{
//printf("Step is %d\r\n",json_cmd.Step->valueint);
Cmd_From_Server.Step=json_cmd.Step->valueint;
} cmdtype= COMMAND; }
} cJSON_Delete(root); return cmdtype;
}
STM32-cJSON库的打包和解析的更多相关文章
- C语言cJSON库的使用,解析json数据格式
C语言cJSON库的使用,解析json数据格式 摘自:https://www.cnblogs.com/piaoyang/p/9274925.html 对于c语言来说是没有字典这样的结构的,所以对于解析 ...
- [置顶] cJSON库(构建json与解析json字符串)-c语言
一.c语言获取json中的数据. 1.先要有cJOSN库,两个文件分别是cJSON.c和cJSON.h. 2.感性认识 char * json = "{ \"json\" ...
- 使用cJSON库解析JSON
cJSON库的下载 cJSON是一个基于C的JSON解析库,这个库非常简单,只有cJSON.c和cJSON.h两个文件,支持JSON的解析和封装,需要调用时,只需要#include "cJS ...
- 使用cJSON库解析和构建JSON字符串
使用cJSON库解析和构建JSON字符串 前言 其实之前的两篇博文已经介绍了json格式和如何使用cJSON库来解析JSON: 使用cJSON库解析JSON JSON简介 当时在MCU平台上使用时,会 ...
- 【源码分析】cJSON库学习
cJSON库是什么? cJSON是一个轻量级的json解析库.使用起来非常简单,整个库非常地简洁,核心功能的实现都在cJSON.c文件,非常适合阅读源代码来学习C语言.最近读完这个库的源码,分享自己收 ...
- cJSON 库的使用和优化
部门的产品使用自己公司研发的系统,嵌入式web服务器移植的是goahead2.5的,服务器和前端使用JSON交互,移植的cJSON库,所以这段时间对JSON的使用做个简单的笔记,cJSON.h提供出来 ...
- 使用CJSON库实现XML与JSON格式的相互转化
之前完成了一个两个平台对接的项目.由于这两个平台一个是使用json格式的数据,一个是使用xml格式的数据,要实现它们二者的对接就涉及到这两个数据格式的转化,在查阅相关资料的时候发现了这个CJSON库, ...
- STM32标准库GPIO操作
STM32标准库GPIO操作 STM32任何外围设备的使用都分为两部分:初始化和使用.体现在代码上就是:(1)有一个初始化函数(2)main函数中的使用 1.初始化GPIO 初始化GPIO函数代码: ...
- cJSON库的简单介绍及使用
转载:http://www.cnblogs.com/liunianshiwei/p/6087596.html JSON 语法是 JavaScript 对象表示法语法的子集.数据在键/值对中:数据由逗号 ...
随机推荐
- cmdb部署
参考资料:https://github.com/guohongze/adminset 基础安装说明:1.基本要求:centos 7.2(1511) django 1.9.8(兼容Django1.11) ...
- 轻松测试 logstash 的配置文件
配置文件本身非常脆弱!所以修改配置文件自然会引入部署失败的风险.如果能够对配置文件进行自动化测试将会极大的降低这种风险.本文将介绍一个可以自动化测试 logstash 配置文件的工具,让大家可以像写单 ...
- 对于for循环中使用let或var时,i的作用域范围的记录
在for循环中使用let时,结果如下 for内部定义的i在循环结束后不会覆盖外部的i 在for循环中使用var,且不控制i的作用域时,结果如下 第一个for循环内部定义的i并不会创建,而是直接使用外部 ...
- Python——匿名函数
一.定义: 是指一类无需定义标识符(函数名)的函数或子程序 二.语法格式: lambda 参数:表达式 三.注意事项: lambda 函数可以接收任意多个参数 (包括可选参数) 并且返回单个表达式的值 ...
- Promise学习笔记
Promise对象 Promise 表示一个异步操作的最终结果,与之进行交互的方式主要是 then 方法,该方法注册了两个回调函数,用于接收 promise 的终值或本 promise 不能执行的原因 ...
- 【题解】放球游戏A
题目描述 校园里在上活动课,Red和Blue两位小朋友在玩一种游戏,他俩在一排N个格子里,自左到右地轮流放小球,每个格子只能放一个小球.每个人一次只能放1至5个球,最后面对没有空格而不能放球的人为输. ...
- P2822 组合数问题 HMR大佬讲解
今天HMR大佬给我们讲解了这一道难题. 基本思路是: 可以将问题转化为:求出杨辉三角,用二维数组f[i][j]来表示在杨辉三角中以第i行第j列的点为右下角,第0行第0列处的点为左上角的矩阵中所有元素是 ...
- shell之获取终端信息
#!/bin/bash #tput和stty是两款终端处理工具 #获取列数和行数 tput cols tput lines #打印当前终端名 tput longname #移动光标 移动光标到100 ...
- Linux-服务器创建swap交换分区
服务器 swap 交换分区制作 作用:‘提升‘ 内存的容量,防止OOM(Out Of Memory) 查看当前的交换分区 # cat /proc/swaps # free -m # swapon -s ...
- jmeter笔记(3)--响应结果中文乱码的解决方式
1.举例 新建HTTP请求访问百度首页,响应结果如下: 2.原因 Jmeter安装目录/bin/jmeter.properties中sampleresult.default.encoding默认为IS ...