notfastjson项目介绍

项目地址 https://github.com/kafmws/notfastjson

notfastjson

© 2019 kafm (wdxdesperado@qq.com)

简介

简单 不是很快的 JSON解析库 C语言实现

构建

原项目Win平台下使用VS编写,使用<crtdbg.h>_CRTDBG_MAP_ALLOC宏检测内存泄漏
使用宏

#define EXPECT_EQ_BASE(equality, expect, actual, format) \
    do {\
        test_count++;\
        if (equality)\
            test_pass++;\
        else {\
            fprintf(stderr, "%s:%d: expect: " format " actual: " format "\n", __FILE__, __LINE__, expect, actual);\
            main_ret = 1;\
        }\
    } while(0)

构建简单单元测试

JSON类型

类型 enum 表示
null JSON_NULL
bool JSON_TRUE / JSON_FALSE
number JSON_NUMBER
string JSON_STRING
array JSON_ARRAY
object JSON_OBJECT

数据结构

typedef struct nfjson_value nfjson_value;

typedef struct { char *s; size_t len; } nfjson_string;

struct nfjson_value {
    union {
        nfjson_string s;
        struct { nfjson_value *e; size_t len; }a;/* type == JSON_ARRAY */
        hash_table *hto;/* type == JSON_OBJECT */
        double n;/* type == JSON_NUMBER */
    }u;
    nfjson_type type;
};

typedef struct {
    const char *json;/*the parsing position in the json*/
    char *stack;/*parsing buffer*/
    size_t size;/*size of stack*/
    size_t top;/*pointer of stack*/
}nfjson_context;
类型 意义/实现方式
nfjson_context JSON字符串解析信息
nfjson_value 解析出的JSON值
nfjson_string UTF-8字符串值
hash_table 通用hash表,
内置使用以nfjson_string为key类型,
nfjson_value为value类型使用
nfjson_context 中 stack 任意类型动态堆栈,
用作string,array类型解析缓冲区

文件目录

|-- access.c .h				//getter & setter
|-- hash_table.c .h			//hash_table
|-- memory.c .h				//manage memory
|-- nfjson.h				//define data structure, error code & json type
|-- parse.c .h				//recursive-descent json parser
|-- pch.c .h				//VS required
|-- test.c .h				//unit testing

其它

  • 内存管理 mallocreallocfreenfjson_string_free及递归nfjson_free
  • 缓冲堆栈 realloc扩容,任意类型,悬浮指针问题
  • 哈希支持 任意类型,按需配置

示例

nfjson_value val;

nfjson_parse(&val, 
				" { "
				"\"n\" : null , "
				"\"f\" : false , "
				"\"t\" : true , "
				"\"i\" : 123 , "
				"\"s\" : \"abc\", "
				"\"a\" : [ 1, 2, 3 ],"
				"\"o\" : { \"1\" : 1, \"2\" : 2, \"3\" : 3 }"
				"}"
);
nfjson_get_type(&val) == JSON_OBJECT;
nfjson_get_object_size(&val) == 7;
nfjson_string []s = 
			{ {"n", 1},{"f", 1},{"t", 1},{"i", 1},{"s", 1},{"a", 1},{"o", 1}, };

//access { "n" : null }
nfjson_value *v = nfjson_get_object_value(&s[0]);
nfjson_get_type(&v) == JSON_NULL;
//access { "i" : 123 }
v = nfjson_get_object_value(&s[3]);
nfjson_get_number(&v) == 123;
//access 1 in { "a" : [1, 2, 3] }
v = nfjson_get_object_value(&s[5]);
nfjson_get_type(&val) == JSON_ARRAY;
nfjson_get_array_size(&val) == 3;
v = nfjson_get_array_element(&v, 1);
nfjson_get_type(&val) == JSON_NUMBER;
nfjson_get_number(&v) == 1;

更多示例见 test.c


notfastjson

© 2019 kafm (wdxdesperado@qq.com)

Introduction

a simple and not fast json parsing library writed in C

  • standard ANSI C,cross-platform / compiler
  • recursive decent parser
  • UTF-8 char support
  • number in range of doublein C only
  • based on json-tutorial @ Milo Yip

Build

write in Windows with Visual Studio,using <crtdbg.h>& macro _CRTDBG_MAP_ALLOCto detect memory leaks
using following marco

static int test_count = 0;
static int test_pass = 0;
#define EXPECT_EQ_BASE(equality, expect, actual, format) \
    do {\
        test_count++;\
        if (equality)\
            test_pass++;\
        else {\
            fprintf(stderr, "%s:%d: expect: " format " actual: " format "\n", __FILE__, __LINE__, expect, actual);\
            main_ret = 1;\
        }\
    } while(0)

build simple unit testing.

JSON type

type enum
null JSON_NULL
bool JSON_TRUE / JSON_FALSE
number JSON_NUMBER
string JSON_STRING
array JSON_ARRAY
object JSON_OBJECT

Data Structure

typedef struct nfjson_value nfjson_value;

typedef struct { char *s; size_t len; } nfjson_string;

struct nfjson_value {
    union {
        nfjson_string s;
        struct { nfjson_value *e; size_t len; }a;/* type == JSON_ARRAY */
        hash_table *hto;/* type == JSON_OBJECT */
        double n;/* type == JSON_NUMBER */
    }u;
    nfjson_type type;
};

typedef struct {
    const char *json;/*the parsing position in the json*/
    char *stack;/*parsing buffer*/
    size_t size;/*size of stack*/
    size_t top;/*pointer of stack*/
}nfjson_context;
type define meaning/implement
nfjson_context JSON string context in parsing
nfjson_value json value
nfjson_string UTF-8 string
hash_table a hash table,
using nfjson_string as key
and nfjson_value as value
stack in nfjson_context dynamic stack for any type,
as a buffer for json string type
and json array type in parsing

file index

|-- access.c .h				//getter & setter
|-- hash_table.c .h			//hash_table
|-- memory.c .h				//manage memory
|-- nfjson.h				//define data structure, error code & json type
|-- parse.c .h				//recursive-descent json parser
|-- pch.c .h				//VS required
|-- test.c .h				//unit testing

Other

  • memory managment mallocreallocfreenfjson_string_free& recursive nfjson_free
  • buffer stack reallocdynamic expansion,support any type,suspensive pointer problem
  • hash table support support any type,on-demand configure

examples

nfjson_value val;

nfjson_parse(&val, 
				" { "
				"\"n\" : null , "
				"\"f\" : false , "
				"\"t\" : true , "
				"\"i\" : 123 , "
				"\"s\" : \"abc\", "
				"\"a\" : [ 1, 2, 3 ],"
				"\"o\" : { \"1\" : 1, \"2\" : 2, \"3\" : 3 }"
				"}"
);
nfjson_get_type(&val) == JSON_OBJECT;
nfjson_get_object_size(&val) == 7;
nfjson_string []s = 
			{ {"n", 1},{"f", 1},{"t", 1},{"i", 1},{"s", 1},{"a", 1},{"o", 1}, };

//access { "n" : null }
nfjson_value *v = nfjson_get_object_value(&s[0]);
nfjson_get_type(&v) == JSON_NULL;
//access { "i" : 123 }
v = nfjson_get_object_value(&s[3]);
nfjson_get_number(&v) == 123;
//access 1 in { "a" : [1, 2, 3] }
v = nfjson_get_object_value(&s[5]);
nfjson_get_type(&val) == JSON_ARRAY;
nfjson_get_array_size(&val) == 3;
v = nfjson_get_array_element(&v, 1);
nfjson_get_type(&val) == JSON_NUMBER;
nfjson_get_number(&v) == 1;

for more examples, see test.c

posted @ 2019-11-17 12:01  kafm  阅读(74)  评论(0编辑  收藏  举报