JSON.h
#ifndef __JSON__H__
#define __JSON__H__
#include <stdio.h>
typedef enum //表示7种数据类型
{
LEPT_NULL, //null
LEPT_FALSE, //false
LEPT_TRUE, //true
LEPT_NUMBER,//数字
LEPT_STRING,//字符串
LEPT_ARRAY, //数组
LEPT_OBJECT //对象
}lept_type;
enum //
{
LEPT_PARSE_OK = 0, //表示没有错误
LEPT_PARSE_EXPECT_VALUE,//表示一个json只含有空白
LEPT_PARSE_INVALID_VALUE,//一个值之后,在空白之后还有其他字符
LEPT_PARSE_ROOT_NOT_SINGULAR,//不属于那7种类型
//double数字越界错误码
LEPT_PARSE_NUMBER_TOO_BIG, //数字过大
//字符串中丢失双引号错误码
LEPT_PARSE_MISS_QUOTATION_MARK, //丢失双引号
//转义符号后边出现了非转义字符的错误码
LEPT_PARSE_INVALID_STRING_ESCAPE,//转义错误
//出现了0x20一下的字符的错误码
LEPT_PARSE_INVALID_STRING_CHAR,//字符错误
//0xXXXX字符转义中的错误码
LEPT_PARSE_INVALID_UNICODE_HEX,// \u 后不是 4 位十六进位数
LEPT_PARSE_INVALID_UNICODE_SURROGATE, //只有高代理项而欠缺低代理项,或是低代理项不在合法码点范围
//解析数组出现错误
LEPT_PARSE_MISS_COMMA_OR_SQUARE_BRACKET,//丢失逗号或者右中括号
//解析对象出现错误
LEPT_PARSE_MISS_KEY, //丢失key
LEPT_PARSE_MISS_COLON, //丢失冒号
LEPT_PARSE_MISS_COMMA_OR_CURLY_BRACKET //丢失逗号或者右大括号
};
typedef struct lept_value lept_value;
typedef struct lept_member lept_member;
struct lept_value //节点的数据结构
{
union
{
struct{ lept_member* m; size_t size; }o; //对象数组
struct{ lept_value* e; size_t size; }a; //数组
struct{ char* s; int length; }s;//字符串
double n;
}u;
lept_type _type;
}e;
struct lept_member
{
char* kstr;
size_t klen;
lept_value value;
};
int lept_parse(lept_value* v/*根节点指针*/, const char* json);//解析json字符串
char* lept_stringify(const lept_value* v, size_t* length);
lept_type lept_get_type(const lept_value* v);//获取v节点的数据类型
void lept_init(lept_value* v); //初始化类型
void lept_free(lept_value* v); //释放string空间
#define lept_set_null(v) lept_free(v)
int lept_get_boolean(const lept_value* v); //获取bool值
void lept_set_boolean(lept_value* v, int b);//设置bool值
double lept_get_number(const lept_value* v);//获取数字大小
void lept_set_number(lept_value* v, double n); //设置数字大小
const char* lept_get_string(const lept_value* v);//获取字符串
size_t lept_get_string_length(const lept_value* v);//获取字符串长度
void lept_set_string(lept_value* v, const char* s, size_t len);//设置字符串
size_t lept_get_array_size(const lept_value* v);
lept_value* lept_get_array_element(const lept_value* v, size_t index);
size_t lept_get_object_size(const lept_value* v);
const char* lept_get_object_key(const lept_value* v, size_t index);
size_t lept_get_object_key_length(const lept_value* v, size_t index);
lept_value* lept_get_object_value(const lept_value* v, size_t index);
#endif //__JSON__H__
JSON.c
#define _CRT_SECURE_NO_WARNINGS 1
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <math.h>
#include <string.h>
#include "JSON.h"
#define ISDIGIT(ch) ((ch) >= '0' && (ch) <= '9')
#define ISDIGIT1TO9(ch) ((ch) >= '1' && (ch) <= '9')
#define PUTC(c, ch) do { *(char*)lept_context_push(c, sizeof(char)) = (ch); } while(0)
#define PUTS(c, s, len) memcpy(lept_context_push(c, len), s, len)
typedef struct //解析器
{
const char* json; //指向未解析字符串的开始位置
//维护一个栈
char* stack;
size_t size; //栈的空间大小
size_t top; //栈顶
}lept_context;
static void* lept_context_push(lept_context* c, size_t size)
{
void* ret;
assert(size > 0);
if (c->top + size >= c->size) //栈放不下了
{
if (c->size == 0) //表示栈为空
{
c->size = 256;
}
while (c->top + size >= c->size)
{
c->size += c->size >> 1;//将大小扩大为当前的1.5倍;
}
c->stack = (char*)realloc(c->stack,c->size);
}
ret = c->stack + c->top;
c->top += size;
return ret; //返回栈顶的指针
}
static void* lept_context_pop(lept_context* c, size_t size)
{
assert(c->top >= size);
return c->stack + (c->top -= size); //返回栈顶的指针
}
static void lept_parse_whitespace(lept_context* c)//忽略空白字符
{
const char* cur = c->json;
while (*cur == ' ' || *cur == '\n' || *cur == '\t' || *cur == 'r')
++cur;
c->json = cur;
}
static int lept_parse_null(lept_context* c, lept_value* v) //判断是否为null
{
assert(*c->json == 'n');
c->json++;
if (c->json[0] != 'u' || c->json[1] != 'l' || c->json[2] != 'l')
return LEPT_PARSE_INVALID_VALUE;//表示不符合特定数据类型
c->json += 3;
v->_type = LEPT_NULL;
return LEPT_PARSE_OK;
}
static int lept_parse_true(lept_context* c, lept_value* v) //判断是否为true
{
assert(*c->json == 't');
c->json++;
if (c->json[0] != 'r' || c->json[1] != 'u' || c->json[2] != 'e')
return LEPT_PARSE_INVALID_VALUE;
c->json += 3;
v->_type = LEPT_TRUE;
return LEPT_PARSE_OK;
}
static int lept_parse_false(lept_context* c, lept_value* v) //判断是否为false
{
assert(*c->json == 'f');
c->json++;
if (c->json[0] != 'a' || c->json[1] != 'l' || c->json[2] != 's' || c->json[3] != 'e')
return LEPT_PARSE_INVALID_VALUE;
c->json += 4;
v->_type = LEPT_FALSE;
return LEPT_PARSE_OK;
}
static int lept_parse_number(lept_context* c, lept_value* v) //判断是否为数字
{
const char* p = c->json;
if (*p == '-')//整数部分
++p;
if (*p == '0')
++p;
else
{
if (!ISDIGIT1TO9(*p))
return LEPT_PARSE_INVALID_VALUE;
for (p++; ISDIGIT(*p); p++);
}
if (*p == '.') //小数部分
{
++p;
if (!ISDIGIT(*p)) //有可能小数点后边没有数字
return LEPT_PARSE_INVALID_VALUE;
for (p++; ISDIGIT(*p); p++);
}
if (*p == 'e' || *p == 'E') //指数部分
{
++p;
if (*p == '+' || *p == '-')
++p;
if (!ISDIGIT(*p)) //有可能没有指数
return LEPT_PARSE_INVALID_VALUE;
for (p++; ISDIGIT(*p); p++);//跳过数字(指数部分第一个为0是合法的)
}
errno = 0;
v->u.n = strtod(c->json, NULL);
if (errno == ERANGE && (v->u.n == HUGE_VAL || v->u.n == -HUGE_VAL)) //处理越界
return LEPT_PARSE_NUMBER_TOO_BIG;
v->_type = LEPT_NUMBER;
c->json = p;
return LEPT_PARSE_OK;
}
static const char* lept_parse_hex4(const char* p, unsigned* u) //判断\u后是不是4位十六进位数
{
int i;
*u = 0;
for (i = 0; i < 4; i++) {
char ch = *p++;
*u <<= 4;
if (ch >= '0' && ch <= '9') *u |= ch - '0';
else if (ch >= 'A' && ch <= 'F') *u |= ch - ('A' - 10);
else if (ch >= 'a' && ch <= 'f') *u |= ch - ('a' - 10);
else return NULL;
}
return p;
}
static void lept_encode_utf8(lept_context* c, unsigned u) //UTF-8编码 U+0000 ~ U+10FFFF
{
if (u <= 0x7f)
{
PUTC(c, u & 0xFF);
}
else if (u <= 0x7FF)
{
PUTC(c, 0xC0 | (u >> 6) & 0xFF);
PUTC(c, 0x80 | (u) & 0x3F);
}
else if (u <= 0xFFFF)
{
PUTC(c, 0xE0 | (u >> 12) & 0xFF);
PUTC(c, 0x80 | (u >> 6) & 0x3F);
PUTC(c, 0x80 | (u) & 0x3F);
}
else
{
assert(u <= 0x10FFFF);
PUTC(c, 0xF0 | ((u >> 18) & 0xFF));
PUTC(c, 0x80 | ((u >> 12) & 0x3F));
PUTC(c, 0x80 | ((u >> 6) & 0x3F));
PUTC(c, 0x80 | (u & 0x3F));
}
}
#define STRING_ERROR(error) do{ c->top = head; return error; }while(0)
static int lept_parse_string_raw(lept_context* c, char** str, size_t* len)
{
assert(*c->json == '\"');
c->json++;
unsigned u;
unsigned u2;
size_t head = c->top;
const char* p = c->json;
while (1)
{
char ch = *p++;
switch (ch)
{
case '\"': //表示当前字符串到结尾
*len = c->top - head;
*str = (char*)lept_context_pop(c, *len); //pop只是修改了top的值,原本存储的数据并不会丢失
c->json = p;
return LEPT_PARSE_OK;
case '\\': //表示下一个字符是转义字符
switch (*p++)
{
case '\"': PUTC(c, '\"'); break;
case '\\': PUTC(c, '\\'); break;
case '/': PUTC(c, '/'); break;
case 'b': PUTC(c, '\b'); break;
case 'f': PUTC(c, '\f'); break;
case 'n': PUTC(c, '\n'); break;
case 'r': PUTC(c, '\r'); break;
case 't': PUTC(c, '\t'); break;
case 'u':
if (!(p = lept_parse_hex4(p, &u)))
STRING_ERROR(LEPT_PARSE_INVALID_UNICODE_HEX);
if (u >= 0xD800 && u <= 0xDBFF)//代理对(高代理项)
{
if (*p++ != '\\')
STRING_ERROR(LEPT_PARSE_INVALID_UNICODE_SURROGATE);
if (*p++ != 'u')
STRING_ERROR(LEPT_PARSE_INVALID_UNICODE_SURROGATE);
if (!(p = lept_parse_hex4(p, &u2)))
STRING_ERROR(LEPT_PARSE_INVALID_UNICODE_HEX);
if (u2<0xDC00 || u2> 0xDFFF)
STRING_ERROR(LEPT_PARSE_INVALID_UNICODE_SURROGATE);
u = (((u - 0xD800) << 10) | (u2 - 0xDC00)) + 0x10000;
}
lept_encode_utf8(c, u);
break;
default:
STRING_ERROR(LEPT_PARSE_INVALID_STRING_ESCAPE);
}break;
case '\0':
STRING_ERROR(LEPT_PARSE_MISS_QUOTATION_MARK);
default: //表示为普通字符
if ((unsigned char)ch < 0x20) {
STRING_ERROR(LEPT_PARSE_INVALID_STRING_CHAR);
}
PUTC(c, ch);
}
}
}
static int lept_parse_string(lept_context* c, lept_value* v) //判断是否为字符串
{
int ret;
char* s;
size_t len;
if ((ret = lept_parse_string_raw(c, &s, &len)) == LEPT_PARSE_OK)
lept_set_string(v, s, len);
return ret;
}
static int lept_parse_value(lept_context* c, lept_value* v);//声明
static int lept_parse_array(lept_context* c, lept_value* v)
{
assert(*c->json == '[');
c->json++;
int i;
size_t size = 0; //数组元素个数
int ret;
lept_parse_whitespace(c);//处理空白
if (*c->json == ']') //[]数组为空
{
c->json++;
v->_type = LEPT_ARRAY;
v->u.a.size = 0;
v->u.a.e = NULL;
return LEPT_PARSE_OK;
}
while (1)
{
lept_value e;
lept_init(&e);
if ((ret = lept_parse_value(c, &e)) != LEPT_PARSE_OK)
break;
memcpy(lept_context_push(c,sizeof(lept_value)),&e,sizeof(lept_value)); //e为一个有效的对象,将其压栈
++size;
lept_parse_whitespace(c);//处理空白
if (*c->json == ',')
{
c->json++;
lept_parse_whitespace(c);
}
else if (*c->json == ']')
{
c->json++;
v->_type = LEPT_ARRAY;
v->u.a.size = size;
size *= sizeof(lept_value);
memcpy(v->u.a.e = (lept_value*)malloc(size),lept_context_pop(c,size),size);//出栈
return LEPT_PARSE_OK;
}
else
{
ret = LEPT_PARSE_MISS_COMMA_OR_SQUARE_BRACKET;
break;
}
}
for (i = 0; (size_t)i < size; i++)
lept_free((lept_value*)lept_context_pop(c, sizeof(lept_value)));
return ret;
}
static int lept_parse_object(lept_context* c, lept_value* v)
{
assert(*c->json == '{');
c->json++;
int ret;
int i;
lept_member m;
size_t size;
lept_parse_whitespace(c);
if (*c->json == '}') //有可能存在空对象
{
c->json++;
v->_type = LEPT_OBJECT;
v->u.o.size = 0;
v->u.o.m = NULL;
return LEPT_PARSE_OK;
}
m.kstr = NULL;
size = 0;
while (1)
{
//先处理key
char* str;
lept_init(&m.value);
if (*c->json != '"') //丢失key
{
ret = LEPT_PARSE_MISS_KEY;
break;
}
if ((ret = lept_parse_string_raw(c, &str, &m.klen)) != LEPT_PARSE_OK) //获取key值
break;
memcpy(m.kstr = (char*)malloc(m.klen + 1), str, m.klen); //给key申请空间
m.kstr[m.klen] = '\0';
lept_parse_whitespace(c);
if (*c->json != ':') //判断有无冒号
{
ret = LEPT_PARSE_MISS_COLON;
break;
}
c->json++;
lept_parse_whitespace(c);
//处理value
if ((ret = lept_parse_value(c, &m.value)) != LEPT_PARSE_OK) //获取value值
break;
memcpy(lept_context_push(c,sizeof(lept_member)),&m,sizeof(lept_member)); //需要压栈
++size;
m.kstr = NULL; //已经压如栈中,因此可以置空
lept_parse_whitespace(c);
if (*c->json == ',')
{
c->json++;
lept_parse_whitespace(c);
}
else if (*c->json == '}')
{
size_t s = sizeof(lept_member)*size;
memcpy(v->u.o.m = (lept_member*)malloc(s),lept_context_pop(c,s),s);//出栈并分配空间
v->_type = LEPT_OBJECT;
v->u.o.size = size;
c->json++;
return LEPT_PARSE_OK;
}
else
{
ret = LEPT_PARSE_MISS_COMMA_OR_CURLY_BRACKET;
break;
}
}
//解析出现错误就会到这
//释放之前的内存
free(m.kstr);
for (i = 0; (size_t)i < size; ++i)
{
lept_member* m = (lept_member*)lept_context_pop(c, sizeof(lept_member));
free(m->kstr);
lept_free(&m->value);
}
v->_type = LEPT_NULL;
return ret;
}
static int lept_parse_value(lept_context* c, lept_value* v)
{
switch (*c->json)
{
case 'n':return lept_parse_null(c, v);
case 't':return lept_parse_true(c, v);
case 'f':return lept_parse_false(c, v);
case '\0':return LEPT_PARSE_EXPECT_VALUE;
case '"':return lept_parse_string(c, v);
case '[':return lept_parse_array(c, v);
case '{':return lept_parse_object(c, v);
default:return lept_parse_number(c, v);
}
}
int lept_parse(lept_value* v/*根节点指针*/, const char* json)//解析json字符串
{
assert(v);
lept_context c;
int ret;
//初始化c的成员
c.json = json;
c.stack = NULL;
c.top = c.size = 0;
//初始化类型
lept_init(v);
//处理空白
lept_parse_whitespace(&c);
if ((ret = lept_parse_value(&c, v)) == LEPT_PARSE_OK)//处理value
{
lept_parse_whitespace(&c);//处理空白
if (*c.json != '\0')
{
v->_type = LEPT_NULL;
ret = LEPT_PARSE_ROOT_NOT_SINGULAR;
}
}
assert(c.top == 0);//保证栈中数据已经处理完
free(c.stack);
return ret;
}
static void lept_stringify_string(lept_context* c, const char* s, size_t len)
{
assert(c && s);
size_t i = 0;
PUTC(c, '"');
for (i; i < len; ++i)
{
unsigned char ch = (unsigned char)s[i];
switch (ch) {
case '\"': PUTS(c, "\\\"", 2); break;
case '\\': PUTS(c, "\\\\", 2); break;
case '\b': PUTS(c, "\\b", 2); break;
case '\f': PUTS(c, "\\f", 2); break;
case '\n': PUTS(c, "\\n", 2); break;
case '\r': PUTS(c, "\\r", 2); break;
case '\t': PUTS(c, "\\t", 2); break;
default:
if (ch < 0x20) {
char buffer[7];
sprintf(buffer, "\\u%04X", ch);
PUTS(c, buffer, 6);
}
else
PUTC(c, s[i]);
}
}
PUTC(c, '"');
}
static void lept_stringify_value(lept_context* c, const lept_value* v)
{
size_t i;
switch (v->_type) {
case LEPT_NULL: PUTS(c, "null", 4); break;
case LEPT_FALSE: PUTS(c, "false", 5); break;
case LEPT_TRUE: PUTS(c, "true", 4); break;
case LEPT_NUMBER: c->top -= 32 - sprintf(lept_context_push(c, 32), "%.17g", v->u.n); break;
case LEPT_STRING: lept_stringify_string(c, v->u.s.s, v->u.s.length); break;
case LEPT_ARRAY:
PUTC(c, '[');
for (i = 0; i < v->u.a.size; ++i)
{
if (i>0)
PUTC(c, ',');
lept_stringify_value(c, &v->u.a.e[i]);
}
PUTC(c, ']');
break;
case LEPT_OBJECT:
PUTC(c, '{');
for (i = 0; i < v->u.o.size; ++i)
{
if (i>0)
PUTC(c, ',');
lept_stringify_string(c, v->u.o.m[i].kstr, v->u.o.m[i].klen); //先写key
PUTC(c, ':'); //写:
lept_stringify_value(c, &v->u.o.m[i].value);//写value
}
PUTC(c, '}');
break;
default: assert(0 && "invalid type");
}
}
char* lept_stringify(const lept_value* v, size_t* length)
{
assert(v);
lept_context c;
c.stack = (char*)malloc(256);
c.size = 256;
c.top = 0;
lept_stringify_value(&c, v);
if (length)
*length = c.top;
PUTC(&c, '\0');
return c.stack;
}
void lept_init(lept_value* v) //初始化类型
{
assert(v);
v->_type = LEPT_NULL;
}
void lept_free(lept_value* v) //空间的释放
{
size_t i;
assert(v != NULL);
switch (v->_type)
{
case LEPT_STRING:
free(v->u.s.s);
break;
case LEPT_ARRAY:
for (i = 0; i < v->u.a.size; i++)
lept_free(&v->u.a.e[i]);
free(v->u.a.e);
break;
case LEPT_OBJECT:
for (i = 0; i < v->u.o.size; i++)
{
free(v->u.o.m[i].kstr);
lept_free(&v->u.o.m[i].value);
}
free(v->u.o.m);
break;
default: break;
}
v->_type = LEPT_NULL;
}
lept_type lept_get_type(const lept_value* v)//获取v节点的数据类型
{
assert(v);
return v->_type;
}
int lept_get_boolean(const lept_value* v)
{
assert(v && (v->_type == LEPT_TRUE || v->_type == LEPT_FALSE));
return v->_type == LEPT_TRUE;
}
void lept_set_boolean(lept_value* v, int b)
{
lept_free(v);
v->_type = b ? LEPT_TRUE : LEPT_FALSE;
}
double lept_get_number(const lept_value* v)//获取数字
{
assert(v && v->_type == LEPT_NUMBER);
return v->u.n;
}
void lept_set_number(lept_value* v, double n)
{
lept_free(v);
v->u.n = n;
v->_type = LEPT_NUMBER;
}
const char* lept_get_string(const lept_value* v)
{
assert(v && v->_type == LEPT_STRING);
return v->u.s.s;
}
void lept_set_string(lept_value* v, const char* s, size_t len)
{
assert(v && (s!=NULL || len == 0));//可以是空字符串
lept_free(v);
v->u.s.s = (char*)malloc(len+1);
memcpy(v->u.s.s, s ,len);
v->u.s.s[len] = '\0';
v->u.s.length = len;
v->_type = LEPT_STRING;
}
size_t lept_get_string_length(const lept_value* v)
{
assert(v && v->_type == LEPT_STRING);
return v->u.s.length;
}
size_t lept_get_array_size(const lept_value* v)
{
assert(v && v->_type == LEPT_ARRAY);
return v->u.a.size;
}
lept_value* lept_get_array_element(const lept_value* v, size_t index)
{
assert(v && v->_type == LEPT_ARRAY);
assert(index < v->u.a.size);
return &v->u.a.e[index];
}
size_t lept_get_object_size(const lept_value* v)
{
assert(v && v->_type == LEPT_OBJECT);
return v->u.o.size;
}
const char* lept_get_object_key(const lept_value* v, size_t index)
{
assert(v && v->_type == LEPT_OBJECT);
assert(index < v->u.o.size);
return v->u.o.m[index].kstr;
}
size_t lept_get_object_key_length(const lept_value* v, size_t index)
{
assert(v && v->_type == LEPT_OBJECT);
assert(index < v->u.o.size);
return v->u.o.m[index].klen;
}
lept_value* lept_get_object_value(const lept_value* v, size_t index)
{
assert(v && v->_type == LEPT_OBJECT);
assert(index < v->u.o.size);
return &v->u.o.m[index].value;
}
test.c
#include "JSON.h"
int main()
{
//char b[] = " \"programmers\": [ \"firstName\": \"Elliotte\", \"lastName\" : \"Harold\", \"email\" : \"elharo@macfaq.com\"] ";
char a[] = " {"
"\"n\" : null , "
"\"f\" : false , "
"\"t\" : true , "
"\"i\" : 123 , "
"\"s\" : \"abc\", "
"\"a\" : [ 1, 2, 3 ],"
"\"o\" : { \"1\" : 1, \"2\" : 2, \"3\" : 3 }"
" } ";
lept_value v[] = { 0 };
int size = 0;
lept_parse(v, a); //先将字符串转成结构体存储于v中
size = sizeof(v) / sizeof(v[0]);
printf("%s", lept_stringify(v, &size));//将v结构体转成字符串
return 0;
}