1 Star 0 Fork 43

yaobyron / libjson

forked from 风尘叹 / libjson 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
libjson.c 13.33 KB
一键复制 编辑 原始数据 按行查看 历史
风尘叹 提交于 2015-05-08 17:18 . Change: 初始化代码
#include "libjson.h"
enum {
STS_START = 0,
STS_END,
STS_OBJECT_START,
STS_OBJECT_COLON,
STS_OBJECT_COMMA,
STS_ARRAY_START,
STS_ARRAY_COMMA,
STS_STRING_START,
STS_STRING_ESCAPE,
STS_STRING_HEX1,
STS_STRING_HEX2,
STS_STRING_HEX3,
STS_STRING_HEX4,
STS_NUMBER_START,
STS_NUMBER_POSITIVE,
STS_NUMBER_A,
STS_NUMBER_B,
STS_NUMBER_DECIMAL,
STS_NUMBER_EXPONENT,
STS_NUMBER_EXPONENT_A,
STS_NUMBER_EXPONENT_DIGIT,
STS_NUMBER_EXPONENT_DIGIT_A
};
int json_parse_true( json_task *task );
int json_parse_false( json_task *task );
int json_parse_null( json_task *task );
int json_parse_number( json_task *task );
int json_parse_string( json_task *task );
int json_parse_value( json_task *task, json_str_t *parent );
int json_parse_array( json_task *task, json_str_t *parent );
int json_parse_object( json_task *task, json_str_t *parent );
int json_parse_true( json_task *task ) {
if( task->count + 3 < task->len &&
*(task->str + task->count) == 'r' &&
*(task->str + task->count + 1) == 'u' &&
*(task->str + task->count + 2) == 'e' ) {
task->count += 3;
return 0;
}
task->err_msg = "expect 'true'";
return -1;
}
int json_parse_false( json_task *task ) {
if( task->count + 4 < task->len &&
*(task->str + task->count) == 'a' &&
*(task->str + task->count + 1) == 'l' &&
*(task->str + task->count + 2) == 's' &&
*(task->str + task->count + 3) == 'e' ) {
task->count += 4;
return 0;
}
task->err_msg = "expect 'false'";
return -1;
}
int json_parse_null( json_task *task ) {
if( task->count + 3 < task->len &&
*(task->str + task->count) == 'u' &&
*(task->str + task->count + 1) == 'l' &&
*(task->str + task->count + 2) == 'l' ) {
task->count += 3;
return 0;
}
task->err_msg = "expect 'null'";
return -1;
}
int json_parse_number( json_task *task ) {
char ch;
task->status = STS_NUMBER_START;
while( ch = *(task->str + task->count) ) {
task->count ++;
switch( task->status ) {
case STS_NUMBER_START:
if( ch == '-' ) {
task->status = STS_NUMBER_POSITIVE;
} else {
task->count --;
task->status = STS_NUMBER_POSITIVE;
}
break;
case STS_NUMBER_POSITIVE:
if( ch == '0' ) {
task->status = STS_NUMBER_A;
} else if ( ch >= '1' && ch <= '9' ) {
task->status = STS_NUMBER_B;
} else {
task->err_msg = "expect '0-9'";
return -1;
}
break;
case STS_NUMBER_B:
if ( ch >= '0' && ch <= '9' ) {
// do nothing
} else {
task->count --;
task->status = STS_NUMBER_A;
}
break;
case STS_NUMBER_A:
if( ch == '.' ) {
task->status = STS_NUMBER_DECIMAL;
} else {
task->count --;
task->status = STS_NUMBER_EXPONENT;
}
break;
case STS_NUMBER_DECIMAL:
if ( ch >= '0' && ch <= '9' ) {
// do nothing
} else {
task->count --;
task->status = STS_NUMBER_EXPONENT;
}
break;
case STS_NUMBER_EXPONENT:
if( ch == 'e' || ch == 'E' ) {
task->status = STS_NUMBER_EXPONENT_A;
} else {
task->count --;
return 0;
}
break;
case STS_NUMBER_EXPONENT_A:
if( ch == '+' || ch == '-' ) {
task->status = STS_NUMBER_EXPONENT_DIGIT;
} else {
task->count --;
task->status = STS_NUMBER_EXPONENT_DIGIT;
}
break;
case STS_NUMBER_EXPONENT_DIGIT:
if ( ch >= '0' && ch <= '9' ) {
task->status = STS_NUMBER_EXPONENT_DIGIT_A;
} else {
task->err_msg = "expect '0-9'";
return -1;
}
break;
case STS_NUMBER_EXPONENT_DIGIT_A:
if ( ch >= '0' && ch <= '9' ) {
task->status = STS_NUMBER_EXPONENT_DIGIT_A;
} else {
task->count --;
return 0;
}
break;
default:
task->err_msg = "unknown status";
return -1;
}
}
task->err_msg = "unexpect EOF";
return -1;
}
int json_parse_string( json_task *task ) {
char ch;
task->status = STS_STRING_START;
while( ch = *(task->str + task->count) ) {
task->count ++;
switch( task->status ) {
case STS_STRING_START:
if( ch == '"' ) {
return 0;
} else if( ch == '\\' ) {
task->status = STS_STRING_ESCAPE;
} else {
// do nothing
}
break;
case STS_STRING_ESCAPE:
if( ch == '"' || ch == '\\' || ch == '/' || ch == 'b' ||
ch == 'f' || ch == 'n' || ch == 'r' || ch == 't' ) {
task->status = STS_STRING_START;
} else if( ch == 'u' ) {
task->status = STS_STRING_HEX1;
} else {
task->err_msg = "illegal escape";
return -1;
}
break;
case STS_STRING_HEX1:
case STS_STRING_HEX2:
case STS_STRING_HEX3:
case STS_STRING_HEX4:
if( ( ch >= '0' && ch <= '9' ) ||
( ch >= 'a' && ch <= 'f' ) ||
( ch >= 'A' && ch <= 'F' ) ) {
if( task->status == STS_STRING_HEX4 ) {
task->status = STS_STRING_START;
} else {
task->status ++;
}
} else {
task->err_msg = "expect '0-9', 'a-f', 'A-F'";
return -1;
}
break;
default:
task->err_msg = "unknown status";
return -1;
}
}
task->err_msg = "unexpect EOF";
return -1;
}
int json_parse_value( json_task *task, json_str_t *parent ) {
char ch;
while( ch = *(task->str + task->count) ) {
task->count ++;
if( ch == ' ' || ch == '\n' || ch == '\t' ) {
continue;
}
if( ch == '"' ) {
return json_parse_string( task );
} else if( ch == '-' || ( ch >= '0' && ch <= '9' ) ) {
task->count --;
return json_parse_number( task );
} else if( ch == '{' ) {
return json_parse_object( task, parent );
} else if( ch == '[' ) {
return json_parse_array( task, parent );
} else if( ch == 't' ) {
return json_parse_true( task );
} else if( ch == 'f' ) {
return json_parse_false( task );
} else if( ch == 'n' ) {
return json_parse_null( task );
} else {
task->err_msg = "illegal value";
return -1;
}
}
task->err_msg = "unexpect EOF";
return -1;
}
int json_parse_array( json_task *task, json_str_t *parent ) {
char ch;
task->status = STS_ARRAY_START;
json_str_t path;
path.parent = parent;
path.str = NULL;
path.len = 0;
while( ch = *(task->str + task->count) ) {
task->count ++;
if( ch == ' ' || ch == '\n' || ch == '\t' ) {
continue;
}
switch( task->status ) {
case STS_ARRAY_START:
if( ch == ']' ) {
return 0;
} else {
task->count --;
if( json_parse_value( task, &path ) != 0 ) {
return -1;
}
path.len ++;
task->status = STS_ARRAY_COMMA;
}
break;
case STS_ARRAY_COMMA:
if( ch == ',' ) {
task->status = STS_ARRAY_START;
} else if( ch == ']' ) {
return 0;
} else {
task->err_msg = "expect ',' or ']'";
return -1;
}
break;
default:
task->err_msg = "unknown status";
return -1;
}
}
task->err_msg = "unexpect EOF";
return -1;
}
int json_parse_object( json_task *task, json_str_t *parent ) {
char ch;
json_str_t path, value;
path.parent = parent;
path.str = NULL;
path.len = 0;
task->status = STS_OBJECT_START;
while( ch = *(task->str + task->count) ) {
task->count ++;
if( ch == ' ' || ch == '\n' || ch == '\t' ) {
continue;
}
switch( task->status ) {
case STS_OBJECT_START:
if( ch == '"' ) {
path.str = task->str + task->count;
if( json_parse_string( task ) != 0 ) {
return -1;
}
path.len = task->str + task->count - path.str - 1;
task->status = STS_OBJECT_COLON;
} else if( ch == '}' ) {
// 空对象 {},忽略
return 0;
} else {
task->err_msg = "expect '\"' or '}'";
return -1;
}
break;
case STS_OBJECT_COLON:
if( ch == ':' ) {
value.str = task->str + task->count;
if( json_parse_value( task, &path ) != 0 ) {
return -1;
}
value.len = task->str + task->count - value.str;
task->status = STS_OBJECT_COMMA;
} else {
task->err_msg = "expect ':'";
return -1;
}
break;
case STS_OBJECT_COMMA:
if( ( ch == ',' || ch == '}' ) ) {
int i = 0;
if( value.str[i] == ' ' || value.str[i] == '\r' || value.str[i] == '\t' ) i++;
if( value.str[i] != '[' && value.str[i] != '{' ) {
if( task->callback ) task->callback( &path, &value );
}
}
if( ch == ',' ) {
task->status = STS_OBJECT_START;
} else if( ch == '}' ) {
return 0;
} else {
task->err_msg = "expect ',' or '}'";
return -1;
}
break;
default:
task->err_msg = "unknown status";
return -1;
}
}
task->err_msg = "unexpect EOF";
return -1;
}
void json_err_psotion( json_task *task, int *line, int *row ) {
int p = 0;
char ch;
(*line) = 1;
(*row) = 0;
while( ch = *(task->str + p) ) {
p ++;
if( ch == '\n' ) {
(*line) ++;
(*row) = 0;
} else {
(*row) ++;
}
if( p == task->count ) break;
}
}
int json_parser( json_task *task ) {
char ch;
json_str_t path;
path.parent = NULL;
path.str = "root";
path.len = 4;
task->err_msg = "OK";
task->count = 0;
task->status = STS_START;
if( task->str == NULL || task->len <= 0 ) {
task->err_msg = "the input string is not specified";
return -1;
}
while( ch = *(task->str + task->count) ) {
task->count ++;
if( ch == ' ' || ch == '\n' || ch == '\t' ) {
continue;
}
switch( task->status ) {
case STS_START:
if( ch == '{' ) {
if( json_parse_object( task, &path ) != 0 ) {
return -1;
}
task->status = STS_END;
} else if( ch == '[' ) {
if( json_parse_array( task, &path ) != 0 ) {
return -1;
}
task->status = STS_END;
} else {
task->err_msg = "expect '{' or '['";
return -1;
}
break;
case STS_END:
if( task->count == task->len ) {
return 0;
} else {
task->err_msg = "expect EOF";
return -1;
}
break;
default:
task->err_msg = "unknown status";
return -1;
}
}
if( task->status == STS_END ) {
return 0;
} else {
return -1;
}
}
1
https://gitee.com/byronyao/libjson.git
git@gitee.com:byronyao/libjson.git
byronyao
libjson
libjson
master

搜索帮助