From ffca8e36c3713f72970bb82f3cd653691d0fe932 Mon Sep 17 00:00:00 2001 From: SaNeOr <534369503@qq.com> Date: Fri, 27 Oct 2017 09:04:38 +0800 Subject: [PATCH 01/14] Create tutorial --- tutorial | 1 + 1 file changed, 1 insertion(+) create mode 100644 tutorial diff --git a/tutorial b/tutorial new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/tutorial @@ -0,0 +1 @@ + From 5ee787531f41372f5b3560c14e2fb314a87ab240 Mon Sep 17 00:00:00 2001 From: SaNeOr <534369503@qq.com> Date: Fri, 27 Oct 2017 09:08:05 +0800 Subject: [PATCH 02/14] Delete tutorial --- tutorial | 1 - 1 file changed, 1 deletion(-) delete mode 100644 tutorial diff --git a/tutorial b/tutorial deleted file mode 100644 index 8b137891..00000000 --- a/tutorial +++ /dev/null @@ -1 +0,0 @@ - From be8f2e1bbbd89e3cfd353ffd9287504ce96f17c3 Mon Sep 17 00:00:00 2001 From: SaNeOr <534369503@qq.com> Date: Fri, 27 Oct 2017 09:09:30 +0800 Subject: [PATCH 03/14] Create leptjson.h --- my_json_tutorial01/leptjson.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 my_json_tutorial01/leptjson.h diff --git a/my_json_tutorial01/leptjson.h b/my_json_tutorial01/leptjson.h new file mode 100644 index 00000000..684ae631 --- /dev/null +++ b/my_json_tutorial01/leptjson.h @@ -0,0 +1,27 @@ +#ifndef LEPTJSON_H__ +#define LEPTJSON_H__ + + +enum class lept_type { LNULL, FALSE, TRUE, NUMBER, STRING, ARRAY, OBJECT }; //JSON_ALL_TYPES + + +struct lept_value +{ + lept_type type; +}; + +enum +{ + LEPT_PARSE_OK = 0, + LEPT_PARSE_EXECPT_VALUE, //若一个 JSON 只含有空白 + LEPT_PARSE_INVALID_VALUE, //既不是空白 也不是含有其它字符 + LEPT_PARSE_ROOT_NOT_SINGULAR // 若一个值之后,在空白之后还有其他字符 +}; + + +int lept_parse(lept_value &v, const char *json); // equlity a json if ok +lept_type lept_get_type(const lept_value& v); //parse lept_value is what lept_type + + + +#endif // !LEPTJSON_H__ From c26e55e409ee0b9d52acb28f54b6a6d29473d024 Mon Sep 17 00:00:00 2001 From: SaNeOr <534369503@qq.com> Date: Fri, 27 Oct 2017 09:10:03 +0800 Subject: [PATCH 04/14] Create leptjson.cpp --- my_json_tutorial01/leptjson.cpp | 110 ++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 my_json_tutorial01/leptjson.cpp diff --git a/my_json_tutorial01/leptjson.cpp b/my_json_tutorial01/leptjson.cpp new file mode 100644 index 00000000..20c74435 --- /dev/null +++ b/my_json_tutorial01/leptjson.cpp @@ -0,0 +1,110 @@ +#include + + +#include"leptjson.h" + + +#define EXPECT(c, ch) do { assert(*c.json == (ch)); c.json++; } while(0) //如果第一个字母不是'n' 说明是参数问题....直接令程序崩溃 + +struct lept_context +{ + const char* json; //底层 指针 +}; + +static void lept_parse_whitespace(lept_context &c) +{ + const char*p = c.json; + while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') + p++; + c.json = p; +} + + + +static int lept_parse_null(lept_context&c, lept_value &v) +{ + EXPECT(c, 'n'); + if (c.json[0] != 'u' || c.json[1] != 'l' || c.json[2] != 'l') + return LEPT_PARSE_INVALID_VALUE; + c.json += 3; //已经结束了对"null"的parse + + /* + lept_parse_whitespace(c); //JSON-text = ws value ws 这里处理value后面的ws + if (c.json[0]) + return LEPT_PARSE_ROOT_NOT_SINGULAR; + */ + + v.type = lept_type::LNULL; + return LEPT_PARSE_OK; + +} + +static int lept_parse_true(lept_context &c, lept_value &v) +{ + EXPECT(c, 't'); + if (c.json[0] != 'r' || c.json[1] != 'u' || c.json[2] != 'e') + return LEPT_PARSE_INVALID_VALUE; + c.json += 3; + /*lept_parse_whitespace(c); + if (c.json[0]) + return LEPT_PARSE_INVALID_VALUE;*/ + + v.type = lept_type::TRUE; + return LEPT_PARSE_OK; +} + +static int lept_parse_false(lept_context &c, lept_value &v) +{ + EXPECT(c, 'f'); + 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; + + /*lept_parse_whitespace(c); + if (c.json[0]) + return LEPT_PARSE_ROOT_NOT_SINGULAR;*/ + v.type = lept_type::FALSE; + + return LEPT_PARSE_OK; +} + +static int lept_parse_value(lept_context &c, lept_value& v) +{ + switch (*(&c)->json) // *(&c)->json 取的是jason第一个字符的内容 + { + 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_EXECPT_VALUE; + default:return LEPT_PARSE_INVALID_VALUE; + } + +} + +////////////////////////////////////////////////////////////// +int lept_parse(lept_value &v, const char *json) +{ + lept_context c; + + int ret; + + assert(&v != NULL); + c.json = json; + //v.type = lept_type::LNULL; + lept_parse_whitespace(c); + if (ret = lept_parse_value(c, v) == LEPT_PARSE_OK) + { + lept_parse_whitespace(c); + if (c.json[0] != '\0') + ret = LEPT_PARSE_ROOT_NOT_SINGULAR; + } + return ret; + +} + +lept_type lept_get_type(const lept_value& v) { + assert(&v != NULL); + return v.type; +} From 2ddea25f89ff61eccee9e51887fd4f3ae734ab51 Mon Sep 17 00:00:00 2001 From: SaNeOr <534369503@qq.com> Date: Fri, 27 Oct 2017 09:10:23 +0800 Subject: [PATCH 05/14] Create test.cpp --- my_json_tutorial01/test.cpp | 64 +++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 my_json_tutorial01/test.cpp diff --git a/my_json_tutorial01/test.cpp b/my_json_tutorial01/test.cpp new file mode 100644 index 00000000..269140d4 --- /dev/null +++ b/my_json_tutorial01/test.cpp @@ -0,0 +1,64 @@ +#include +#include +#include +#include"leptjson.h" + + +static int main_ret = 0; +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) + + +#define EXPECT_EQ_INT(expect, actual) EXPECT_EQ_BASE((expect) == (actual), expect, actual, "%d") + +static void test_parse_null() +{ + lept_value v; + //v.type = lept_type::TRUE; + EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(v, " null "));//EQ lept_parse if success + EXPECT_EQ_INT(lept_type::LNULL, lept_get_type(v)); //EQ the v.type if == LNULL +} + +static void test_parse_true() +{ + lept_value v; + + EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(v, " true ")); + EXPECT_EQ_INT(lept_type::TRUE, lept_get_type(v)); + + +} + +static void test_parse_false() +{ + lept_value v; + EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(v, " false ")); + EXPECT_EQ_INT(lept_type::FALSE, lept_get_type(v)); + +} + + +static void test_parse() +{ + test_parse_null(); + test_parse_true(); + test_parse_false(); +} + +int main() +{ + test_parse(); + printf("%d/%d (%3.2f%%) passed\n", test_pass, test_count, test_pass * 100.0 / test_count); + return main_ret; + +} From 9d0210f7ed2c118c081e35ed17aef0c5b176dea5 Mon Sep 17 00:00:00 2001 From: SaNeOr <534369503@qq.com> Date: Tue, 31 Oct 2017 22:35:51 +0800 Subject: [PATCH 06/14] Update leptjson.h From 1138bca493ff760b67a2f119743f5c72b05cc522 Mon Sep 17 00:00:00 2001 From: SaNeOr <534369503@qq.com> Date: Tue, 31 Oct 2017 22:36:17 +0800 Subject: [PATCH 07/14] Update test.cpp --- my_json_tutorial01/test.cpp | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/my_json_tutorial01/test.cpp b/my_json_tutorial01/test.cpp index 269140d4..80bff7e5 100644 --- a/my_json_tutorial01/test.cpp +++ b/my_json_tutorial01/test.cpp @@ -4,7 +4,7 @@ #include"leptjson.h" -static int main_ret = 0; +static int main_ret = 0; static int test_count = 0; static int test_pass = 0; #define EXPECT_EQ_BASE(equality,expect, actual, format)\ @@ -21,6 +21,16 @@ static int test_pass = 0; #define EXPECT_EQ_INT(expect, actual) EXPECT_EQ_BASE((expect) == (actual), expect, actual, "%d") +#define TEST_ERROR(error, json)\ + do {\ + lept_value v; \ + EXPECT_EQ_INT(error, lept_parse(v, json)); \ + EXPECT_EQ_INT(lept_type::LNULL, lept_get_type(v)); \ + }while(0) + + + + static void test_parse_null() { lept_value v; @@ -47,12 +57,34 @@ static void test_parse_false() } +static void test_parse_except_value() +{ + TEST_ERROR(LEPT_PARSE_EXECPT_VALUE, ""); +} + + +static void test_parse_invalid_value() +{ + TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "tr"); +} + +static void test_parse_root_not_singular() +{ + TEST_ERROR(LEPT_PARSE_ROOT_NOT_SINGULAR, "true s"); +} + + + static void test_parse() { test_parse_null(); test_parse_true(); test_parse_false(); + + test_parse_except_value(); + test_parse_invalid_value(); + test_parse_root_not_singular(); } int main() From f8c1606073199bfc55467eac3466a7f67a9b2d48 Mon Sep 17 00:00:00 2001 From: SaNeOr <534369503@qq.com> Date: Mon, 18 Dec 2017 23:00:13 +0800 Subject: [PATCH 08/14] Update leptjson.cpp --- my_json_tutorial01/leptjson.cpp | 131 ++++++++++---------------------- 1 file changed, 39 insertions(+), 92 deletions(-) diff --git a/my_json_tutorial01/leptjson.cpp b/my_json_tutorial01/leptjson.cpp index 20c74435..9c96abf5 100644 --- a/my_json_tutorial01/leptjson.cpp +++ b/my_json_tutorial01/leptjson.cpp @@ -1,110 +1,57 @@ -#include - +#ifndef LEPTJSON_H__ +#define LEPTJSON_H__ -#include"leptjson.h" +enum class lept_type { LNULL, FALSE, TRUE, NUMBER, STRING, ARRAY, OBJECT }; //JSON_ALL_TYPES -#define EXPECT(c, ch) do { assert(*c.json == (ch)); c.json++; } while(0) //如果第一个字母不是'n' 说明是参数问题....直接令程序崩溃 -struct lept_context +struct lept_value { - const char* json; //底层 指针 + union { + struct { char *s; size_t len; }; + double n;//json number + }; + lept_type type; + }; -static void lept_parse_whitespace(lept_context &c) + +enum { - const char*p = c.json; - while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') - p++; - c.json = p; -} + LEPT_PARSE_OK = 0, //parse ok + LEPT_PARSE_EXECPT_VALUE, //若一个 JSON 只含有空白 + LEPT_PARSE_INVALID_VALUE, //既不是空白 也不是含有其它字符 + LEPT_PARSE_ROOT_NOT_SINGULAR, // 若一个值之后,在空白之后还有其他字符 + LEPT_PARSE_NUMBER_TOO_BIG, //数字太大了 + LEPT_PARSE_MISS_QUOTATION_MARK, //引号问题 +}; +// is json right? +int lept_parse(lept_value &v, const char *json); -static int lept_parse_null(lept_context&c, lept_value &v) -{ - EXPECT(c, 'n'); - if (c.json[0] != 'u' || c.json[1] != 'l' || c.json[2] != 'l') - return LEPT_PARSE_INVALID_VALUE; - c.json += 3; //已经结束了对"null"的parse - - /* - lept_parse_whitespace(c); //JSON-text = ws value ws 这里处理value后面的ws - if (c.json[0]) - return LEPT_PARSE_ROOT_NOT_SINGULAR; - */ - - v.type = lept_type::LNULL; - return LEPT_PARSE_OK; - -} - -static int lept_parse_true(lept_context &c, lept_value &v) -{ - EXPECT(c, 't'); - if (c.json[0] != 'r' || c.json[1] != 'u' || c.json[2] != 'e') - return LEPT_PARSE_INVALID_VALUE; - c.json += 3; - /*lept_parse_whitespace(c); - if (c.json[0]) - return LEPT_PARSE_INVALID_VALUE;*/ - - v.type = lept_type::TRUE; - return LEPT_PARSE_OK; -} - -static int lept_parse_false(lept_context &c, lept_value &v) -{ - EXPECT(c, 'f'); - 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; +//parse lept_value is what lept_type +lept_type lept_get_type(const lept_value &v); - /*lept_parse_whitespace(c); - if (c.json[0]) - return LEPT_PARSE_ROOT_NOT_SINGULAR;*/ - v.type = lept_type::FALSE; +double lept_get_number(const lept_value &v); - return LEPT_PARSE_OK; -} +//获得lept.string +char *lept_get_string(const lept_value &v); -static int lept_parse_value(lept_context &c, lept_value& v) -{ - switch (*(&c)->json) // *(&c)->json 取的是jason第一个字符的内容 - { - case'n':return lept_parse_null(c, v); - case't':return lept_parse_true(c, v); - case'f':return lept_parse_false(c, v); +//获得lept.string_length +int lept_get_string_length(const lept_value &v); - case'\0':return LEPT_PARSE_EXECPT_VALUE; - default:return LEPT_PARSE_INVALID_VALUE; - } -} -////////////////////////////////////////////////////////////// -int lept_parse(lept_value &v, const char *json) -{ - lept_context c; - - int ret; - - assert(&v != NULL); - c.json = json; - //v.type = lept_type::LNULL; - lept_parse_whitespace(c); - if (ret = lept_parse_value(c, v) == LEPT_PARSE_OK) - { - lept_parse_whitespace(c); - if (c.json[0] != '\0') - ret = LEPT_PARSE_ROOT_NOT_SINGULAR; - } - return ret; - -} - -lept_type lept_get_type(const lept_value& v) { - assert(&v != NULL); - return v.type; -} +#include +#include + +void lept_set_string(lept_value &v, const char* s, size_t len); + +void lept_free(lept_value &v); + +#define lept_init(v) do{ v.type = lept_type::LNULL; }while(0) + + +#endif // !LEPTJSON_H__ From 72baede86febbc2992c87dd154780db504a8b23f Mon Sep 17 00:00:00 2001 From: SaNeOr <534369503@qq.com> Date: Mon, 18 Dec 2017 23:00:49 +0800 Subject: [PATCH 09/14] Update test.cpp --- my_json_tutorial01/test.cpp | 85 +++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/my_json_tutorial01/test.cpp b/my_json_tutorial01/test.cpp index 80bff7e5..e656831c 100644 --- a/my_json_tutorial01/test.cpp +++ b/my_json_tutorial01/test.cpp @@ -1,6 +1,9 @@ #include #include #include + + + #include"leptjson.h" @@ -21,6 +24,7 @@ static int test_pass = 0; #define EXPECT_EQ_INT(expect, actual) EXPECT_EQ_BASE((expect) == (actual), expect, actual, "%d") + #define TEST_ERROR(error, json)\ do {\ lept_value v; \ @@ -29,6 +33,13 @@ static int test_pass = 0; }while(0) +#define TEST_NUMBER(expect, json)\ + do{\ + lept_value v;\ + EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(v,json));\ + EXPECT_EQ_INT(lept_type::NUMBER, lept_get_type(v));\ + EXPECT_EQ_INT(expect, lept_get_number(v));\ + }while(0) static void test_parse_null() @@ -66,14 +77,68 @@ static void test_parse_except_value() static void test_parse_invalid_value() { TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "tr"); + + /*invalid number*/ + + /* invalid number */ + TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "+0"); + TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "+1"); + TEST_ERROR(LEPT_PARSE_INVALID_VALUE, ".123"); /* at least one digit before '.' */ + TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "1."); /* at least one digit after '.' */ + +#if 1 + TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "INF"); + TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "inf"); + TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "NAN"); + TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "nan"); +#endif + + TEST_ERROR(LEPT_PARSE_NUMBER_TOO_BIG, "1e309"); } static void test_parse_root_not_singular() { TEST_ERROR(LEPT_PARSE_ROOT_NOT_SINGULAR, "true s"); +#if 0 + /* invalid number */ + TEST_ERROR(LEPT_PARSE_ROOT_NOT_SINGULAR, "0123"); /* after zero should be '.' or nothing */ + TEST_ERROR(LEPT_PARSE_ROOT_NOT_SINGULAR, "0x0"); + TEST_ERROR(LEPT_PARSE_ROOT_NOT_SINGULAR, "0x123"); +#endif + +} +static void test_parse_number_too_big() { +#if 0 + TEST_ERROR(LEPT_PARSE_NUMBER_TOO_BIG, "1e309"); + TEST_ERROR(LEPT_PARSE_NUMBER_TOO_BIG, "-1e309"); +#endif } +static void test_parse_number() { + TEST_NUMBER(0.0, "0"); + TEST_NUMBER(0.0, "-0"); + TEST_NUMBER(0.0, "-0.0"); + TEST_NUMBER(1.0, "1"); + TEST_NUMBER(-1.0, "-1"); + TEST_NUMBER(1.5, "1.5"); + TEST_NUMBER(-1.5, "-1.5"); + TEST_NUMBER(3.1416, "3.1416"); + TEST_NUMBER(1E10, "1E10"); + TEST_NUMBER(1e10, "1e10"); + TEST_NUMBER(1E+10, "1E+10"); + TEST_NUMBER(1E-10, "1E-10"); + TEST_NUMBER(-1E10, "-1E10"); + TEST_NUMBER(-1e10, "-1e10"); + TEST_NUMBER(-1E+10, "-1E+10"); + TEST_NUMBER(-1E-10, "-1E-10"); + TEST_NUMBER(1.234E+10, "1.234E+10"); + TEST_NUMBER(1.234E-10, "1.234E-10"); + TEST_NUMBER(0.0, "1e-10000"); /* must underflow */ + + + +} static void test_parse() @@ -85,8 +150,28 @@ static void test_parse() test_parse_except_value(); test_parse_invalid_value(); test_parse_root_not_singular(); + + test_parse_number(); } + + +#define EXPECT_EQ_STRING(expect,actual, alength)\ + EXPECT_EQ_BASE(sizeof(expect)-1 == alength && memcmp(expect, actual, alength)== 0, expect,actual, "%s" ) + +static void test_access_string() +{ + lept_value v; + lept_init(v); + lept_set_string(v, "", 0); + EXPECT_EQ_STRING("", lept_get_string(v), lept_get_string_length(v)); + + lept_set_string(v, "P&S", 3); + EXPECT_EQ_STRING("P&G", lept_get_string(v), lept_get_string_length(v)); + lept_free(v); +} + + int main() { test_parse(); From 4fed7e83b70df1589fe1c9a199389ec7d87b10f9 Mon Sep 17 00:00:00 2001 From: SaNeOr <534369503@qq.com> Date: Mon, 18 Dec 2017 23:01:08 +0800 Subject: [PATCH 10/14] Update leptjson.h --- my_json_tutorial01/leptjson.h | 38 +++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/my_json_tutorial01/leptjson.h b/my_json_tutorial01/leptjson.h index 684ae631..9c96abf5 100644 --- a/my_json_tutorial01/leptjson.h +++ b/my_json_tutorial01/leptjson.h @@ -7,21 +7,51 @@ enum class lept_type { LNULL, FALSE, TRUE, NUMBER, STRING, ARRAY, OBJECT }; //JS struct lept_value { + union { + struct { char *s; size_t len; }; + double n;//json number + }; lept_type type; + }; + enum { - LEPT_PARSE_OK = 0, + LEPT_PARSE_OK = 0, //parse ok LEPT_PARSE_EXECPT_VALUE, //若一个 JSON 只含有空白 LEPT_PARSE_INVALID_VALUE, //既不是空白 也不是含有其它字符 - LEPT_PARSE_ROOT_NOT_SINGULAR // 若一个值之后,在空白之后还有其他字符 + LEPT_PARSE_ROOT_NOT_SINGULAR, // 若一个值之后,在空白之后还有其他字符 + LEPT_PARSE_NUMBER_TOO_BIG, //数字太大了 + LEPT_PARSE_MISS_QUOTATION_MARK, //引号问题 }; +// is json right? +int lept_parse(lept_value &v, const char *json); + + +//parse lept_value is what lept_type +lept_type lept_get_type(const lept_value &v); + +double lept_get_number(const lept_value &v); + +//获得lept.string +char *lept_get_string(const lept_value &v); + +//获得lept.string_length +int lept_get_string_length(const lept_value &v); + + + + +#include +#include + +void lept_set_string(lept_value &v, const char* s, size_t len); -int lept_parse(lept_value &v, const char *json); // equlity a json if ok -lept_type lept_get_type(const lept_value& v); //parse lept_value is what lept_type +void lept_free(lept_value &v); +#define lept_init(v) do{ v.type = lept_type::LNULL; }while(0) #endif // !LEPTJSON_H__ From 546e521bfd7c9e2626e68b6dda6fbfdb2bd2015c Mon Sep 17 00:00:00 2001 From: SaNeOr <534369503@qq.com> Date: Sat, 7 Apr 2018 09:46:40 +0800 Subject: [PATCH 11/14] Update leptjson.cpp --- my_json_tutorial01/leptjson.cpp | 76 +++++++++++---------------------- 1 file changed, 24 insertions(+), 52 deletions(-) diff --git a/my_json_tutorial01/leptjson.cpp b/my_json_tutorial01/leptjson.cpp index 9c96abf5..3dc51b9f 100644 --- a/my_json_tutorial01/leptjson.cpp +++ b/my_json_tutorial01/leptjson.cpp @@ -1,57 +1,29 @@ -#ifndef LEPTJSON_H__ -#define LEPTJSON_H__ - - -enum class lept_type { LNULL, FALSE, TRUE, NUMBER, STRING, ARRAY, OBJECT }; //JSON_ALL_TYPES - - -struct lept_value -{ - union { - struct { char *s; size_t len; }; - double n;//json number - }; - lept_type type; - +#ifndef leptjson_h__ +#define leptjson_h__ + +//namespace lept_json { + enum class lept_type{ + LNULL, + FALSE,TRUE, + NUMBER, + STRING, + ARRAY, + OBJECT + }; +//using namespace lept_json; +enum{ + LEPT_PARSE_OK, + LEPT_PARSE_EXPECT_VALUE, + LEPT_PARSE_INVALID_VALUE, + LEPT_PARSE_ROOT_NOT_SINGULAR }; - -enum -{ - LEPT_PARSE_OK = 0, //parse ok - LEPT_PARSE_EXECPT_VALUE, //若一个 JSON 只含有空白 - LEPT_PARSE_INVALID_VALUE, //既不是空白 也不是含有其它字符 - LEPT_PARSE_ROOT_NOT_SINGULAR, // 若一个值之后,在空白之后还有其他字符 - LEPT_PARSE_NUMBER_TOO_BIG, //数字太大了 - LEPT_PARSE_MISS_QUOTATION_MARK, //引号问题 +struct lept_value{ + lept_type type; + }; -// is json right? -int lept_parse(lept_value &v, const char *json); - - -//parse lept_value is what lept_type -lept_type lept_get_type(const lept_value &v); - -double lept_get_number(const lept_value &v); - -//获得lept.string -char *lept_get_string(const lept_value &v); - -//获得lept.string_length -int lept_get_string_length(const lept_value &v); - - - - -#include -#include - -void lept_set_string(lept_value &v, const char* s, size_t len); - -void lept_free(lept_value &v); - -#define lept_init(v) do{ v.type = lept_type::LNULL; }while(0) - +int lept_parse(lept_value &v, const char* json); +lept_type lept_get_type(const lept_value& v); -#endif // !LEPTJSON_H__ +#endif /* leptjson_h__ */ From 48a49eede2041fcbe5e1873ef10015c24106bd61 Mon Sep 17 00:00:00 2001 From: SaNeOr <534369503@qq.com> Date: Sat, 7 Apr 2018 09:46:58 +0800 Subject: [PATCH 12/14] Update leptjson.cpp --- my_json_tutorial01/leptjson.cpp | 90 +++++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 26 deletions(-) diff --git a/my_json_tutorial01/leptjson.cpp b/my_json_tutorial01/leptjson.cpp index 3dc51b9f..43fd88c1 100644 --- a/my_json_tutorial01/leptjson.cpp +++ b/my_json_tutorial01/leptjson.cpp @@ -1,29 +1,67 @@ -#ifndef leptjson_h__ -#define leptjson_h__ - -//namespace lept_json { - enum class lept_type{ - LNULL, - FALSE,TRUE, - NUMBER, - STRING, - ARRAY, - OBJECT - }; -//using namespace lept_json; -enum{ - LEPT_PARSE_OK, - LEPT_PARSE_EXPECT_VALUE, - LEPT_PARSE_INVALID_VALUE, - LEPT_PARSE_ROOT_NOT_SINGULAR +#include +#include"leptjson.h" +#include +struct lept_context{ + const char*json; }; +#define EXPECT(c,ch) do{assert(*c.json == (ch));c.json++;}while(0) +static void lept_parse_whitespace(lept_context& c){ + const char *p = c.json; + while(*p ==' ' || *p == '\t' || *p == '\n' || *p == '\r') + p++; + c.json = p; +} -struct lept_value{ - lept_type type; +static int lept_parse_null(lept_context &c, lept_value& v){ + EXPECT(c, 'n'); + if(c.json[0] != 'u' || c.json[1] != 'l' || c.json[2] != 'l') + return LEPT_PARSE_INVALID_VALUE; + c.json += 3; + v.type = lept_type::LNULL; + return LEPT_PARSE_OK; -}; - -int lept_parse(lept_value &v, const char* json); -lept_type lept_get_type(const lept_value& v); - -#endif /* leptjson_h__ */ +} +static int lept_parse_true(lept_context &c, lept_value &v){ + EXPECT(c,'t'); + if(c.json[0] != 'r' || c.json[1]!= 'u' || c.json[2] != 'e') + return LEPT_PARSE_INVALID_VALUE; + c.json+=3; + v.type = lept_type::TRUE; + return LEPT_PARSE_OK; +} +static int lept_parse_false(lept_context&c, lept_value &v){ + EXPECT(c,'f'); + 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_type::FALSE; + return LEPT_PARSE_OK; +} +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; + default: return LEPT_PARSE_INVALID_VALUE; + } +} +int lept_parse(lept_value &v, const char* json){ + lept_context c; + + assert( &v !=NULL); + int ret; + c.json = json; + v.type = lept_type::LNULL; + lept_parse_whitespace(c); + if((ret = lept_parse_value(c, v)) == LEPT_PARSE_OK){ + lept_parse_whitespace(c); + if(*c.json != '\0') + ret = LEPT_PARSE_ROOT_NOT_SINGULAR; + } + return ret; +} +lept_type lept_get_type(const lept_value& v){ + assert(& v!= NULL); + return v.type; +} From 0b318f9c483445ebf8883ad8f8a357f4c5c391e1 Mon Sep 17 00:00:00 2001 From: SaNeOr <534369503@qq.com> Date: Sat, 7 Apr 2018 09:47:38 +0800 Subject: [PATCH 13/14] Update leptjson.h --- my_json_tutorial01/leptjson.h | 76 +++++++++++------------------------ 1 file changed, 24 insertions(+), 52 deletions(-) diff --git a/my_json_tutorial01/leptjson.h b/my_json_tutorial01/leptjson.h index 9c96abf5..3dc51b9f 100644 --- a/my_json_tutorial01/leptjson.h +++ b/my_json_tutorial01/leptjson.h @@ -1,57 +1,29 @@ -#ifndef LEPTJSON_H__ -#define LEPTJSON_H__ - - -enum class lept_type { LNULL, FALSE, TRUE, NUMBER, STRING, ARRAY, OBJECT }; //JSON_ALL_TYPES - - -struct lept_value -{ - union { - struct { char *s; size_t len; }; - double n;//json number - }; - lept_type type; - +#ifndef leptjson_h__ +#define leptjson_h__ + +//namespace lept_json { + enum class lept_type{ + LNULL, + FALSE,TRUE, + NUMBER, + STRING, + ARRAY, + OBJECT + }; +//using namespace lept_json; +enum{ + LEPT_PARSE_OK, + LEPT_PARSE_EXPECT_VALUE, + LEPT_PARSE_INVALID_VALUE, + LEPT_PARSE_ROOT_NOT_SINGULAR }; - -enum -{ - LEPT_PARSE_OK = 0, //parse ok - LEPT_PARSE_EXECPT_VALUE, //若一个 JSON 只含有空白 - LEPT_PARSE_INVALID_VALUE, //既不是空白 也不是含有其它字符 - LEPT_PARSE_ROOT_NOT_SINGULAR, // 若一个值之后,在空白之后还有其他字符 - LEPT_PARSE_NUMBER_TOO_BIG, //数字太大了 - LEPT_PARSE_MISS_QUOTATION_MARK, //引号问题 +struct lept_value{ + lept_type type; + }; -// is json right? -int lept_parse(lept_value &v, const char *json); - - -//parse lept_value is what lept_type -lept_type lept_get_type(const lept_value &v); - -double lept_get_number(const lept_value &v); - -//获得lept.string -char *lept_get_string(const lept_value &v); - -//获得lept.string_length -int lept_get_string_length(const lept_value &v); - - - - -#include -#include - -void lept_set_string(lept_value &v, const char* s, size_t len); - -void lept_free(lept_value &v); - -#define lept_init(v) do{ v.type = lept_type::LNULL; }while(0) - +int lept_parse(lept_value &v, const char* json); +lept_type lept_get_type(const lept_value& v); -#endif // !LEPTJSON_H__ +#endif /* leptjson_h__ */ From f8443e61e240405cee70c1b0c3284be374079b77 Mon Sep 17 00:00:00 2001 From: SaNeOr <534369503@qq.com> Date: Sat, 7 Apr 2018 09:47:53 +0800 Subject: [PATCH 14/14] Update test.cpp --- my_json_tutorial01/test.cpp | 228 +++++++++++------------------------- 1 file changed, 68 insertions(+), 160 deletions(-) diff --git a/my_json_tutorial01/test.cpp b/my_json_tutorial01/test.cpp index e656831c..a2c54265 100644 --- a/my_json_tutorial01/test.cpp +++ b/my_json_tutorial01/test.cpp @@ -1,181 +1,89 @@ -#include #include -#include +#include +#include +#include "leptjson.h" - - -#include"leptjson.h" - - -static int main_ret = 0; +static int main_ret = 0; 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) - - -#define EXPECT_EQ_INT(expect, actual) EXPECT_EQ_BASE((expect) == (actual), expect, actual, "%d") - - -#define TEST_ERROR(error, json)\ - do {\ - lept_value v; \ - EXPECT_EQ_INT(error, lept_parse(v, json)); \ - EXPECT_EQ_INT(lept_type::LNULL, lept_get_type(v)); \ - }while(0) - - -#define TEST_NUMBER(expect, json)\ - do{\ - lept_value v;\ - EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(v,json));\ - EXPECT_EQ_INT(lept_type::NUMBER, lept_get_type(v));\ - EXPECT_EQ_INT(expect, lept_get_number(v));\ - }while(0) - - -static void test_parse_null() -{ - lept_value v; - //v.type = lept_type::TRUE; - EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(v, " null "));//EQ lept_parse if success - EXPECT_EQ_INT(lept_type::LNULL, lept_get_type(v)); //EQ the v.type if == LNULL +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) + +#define EXPECT_EQ_INT(expect, actual) EXPECT_EQ_BASE((expect) == (actual), expect, actual, "%d"); + +static void test_parse_null(){ + lept_value v; + v.type = lept_type::FALSE; + EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(v,"null")); + EXPECT_EQ_INT(lept_type::LNULL, lept_get_type(v)); } -static void test_parse_true() -{ - lept_value v; - - EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(v, " true ")); - EXPECT_EQ_INT(lept_type::TRUE, lept_get_type(v)); - - +static void test_parse_true(){ + lept_value v; + v.type = lept_type::LNULL; + EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(v,"true")); + EXPECT_EQ_INT(lept_type::TRUE, lept_get_type(v)); } -static void test_parse_false() -{ - lept_value v; - EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(v, " false ")); - EXPECT_EQ_INT(lept_type::FALSE, lept_get_type(v)); - -} - -static void test_parse_except_value() -{ - TEST_ERROR(LEPT_PARSE_EXECPT_VALUE, ""); +static void test_parse_false(){ + lept_value v; + v.type = lept_type::LNULL; + EXPECT_EQ_INT(LEPT_PARSE_OK, lept_parse(v,"false")); + EXPECT_EQ_INT(lept_type::FALSE, lept_get_type(v)); } +static void test_parse_expect_value(){ + lept_value v; + v.type = lept_type::FALSE; + EXPECT_EQ_INT(LEPT_PARSE_EXPECT_VALUE, lept_parse(v,"")); + EXPECT_EQ_INT(lept_type::LNULL, lept_get_type(v)); -static void test_parse_invalid_value() -{ - TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "tr"); - - /*invalid number*/ + v.type = lept_type::FALSE; + EXPECT_EQ_INT(LEPT_PARSE_EXPECT_VALUE, lept_parse(v, " ")); + EXPECT_EQ_INT(lept_type::LNULL, lept_get_type(v)); - /* invalid number */ - TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "+0"); - TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "+1"); - TEST_ERROR(LEPT_PARSE_INVALID_VALUE, ".123"); /* at least one digit before '.' */ - TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "1."); /* at least one digit after '.' */ - -#if 1 - TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "INF"); - TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "inf"); - TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "NAN"); - TEST_ERROR(LEPT_PARSE_INVALID_VALUE, "nan"); -#endif - - TEST_ERROR(LEPT_PARSE_NUMBER_TOO_BIG, "1e309"); } -static void test_parse_root_not_singular() -{ - TEST_ERROR(LEPT_PARSE_ROOT_NOT_SINGULAR, "true s"); -#if 0 - /* invalid number */ - TEST_ERROR(LEPT_PARSE_ROOT_NOT_SINGULAR, "0123"); /* after zero should be '.' or nothing */ - TEST_ERROR(LEPT_PARSE_ROOT_NOT_SINGULAR, "0x0"); - TEST_ERROR(LEPT_PARSE_ROOT_NOT_SINGULAR, "0x123"); -#endif - +static void test_parse_invalid_value(){ + lept_value v; + v.type = lept_type::FALSE; + EXPECT_EQ_INT(LEPT_PARSE_INVALID_VALUE, lept_parse(v, "nul")); + EXPECT_EQ_INT(lept_type::LNULL, lept_get_type(v)); + + v.type =lept_type::FALSE; + EXPECT_EQ_INT(LEPT_PARSE_INVALID_VALUE, lept_parse(v, "?")); + EXPECT_EQ_INT(lept_type::LNULL, lept_get_type(v)); } -static void test_parse_number_too_big() { -#if 0 - TEST_ERROR(LEPT_PARSE_NUMBER_TOO_BIG, "1e309"); - TEST_ERROR(LEPT_PARSE_NUMBER_TOO_BIG, "-1e309"); -#endif +static void test_parse_root_not_singular(){ + lept_value v; + v.type =lept_type::FALSE; + EXPECT_EQ_INT(LEPT_PARSE_ROOT_NOT_SINGULAR, lept_parse(v," null x")); + EXPECT_EQ_INT(lept_type::LNULL, lept_get_type(v)); + } -static void test_parse_number() { - TEST_NUMBER(0.0, "0"); - TEST_NUMBER(0.0, "-0"); - TEST_NUMBER(0.0, "-0.0"); - TEST_NUMBER(1.0, "1"); - TEST_NUMBER(-1.0, "-1"); - TEST_NUMBER(1.5, "1.5"); - TEST_NUMBER(-1.5, "-1.5"); - TEST_NUMBER(3.1416, "3.1416"); - TEST_NUMBER(1E10, "1E10"); - TEST_NUMBER(1e10, "1e10"); - TEST_NUMBER(1E+10, "1E+10"); - TEST_NUMBER(1E-10, "1E-10"); - TEST_NUMBER(-1E10, "-1E10"); - TEST_NUMBER(-1e10, "-1e10"); - TEST_NUMBER(-1E+10, "-1E+10"); - TEST_NUMBER(-1E-10, "-1E-10"); - TEST_NUMBER(1.234E+10, "1.234E+10"); - TEST_NUMBER(1.234E-10, "1.234E-10"); - TEST_NUMBER(0.0, "1e-10000"); /* must underflow */ - - - -} - - -static void test_parse() -{ - test_parse_null(); - test_parse_true(); - test_parse_false(); - - test_parse_except_value(); - test_parse_invalid_value(); - test_parse_root_not_singular(); - test_parse_number(); +static void test_parse(){ + test_parse_null(); + test_parse_true(); + test_parse_false(); + test_parse_expect_value(); + test_parse_invalid_value(); + test_parse_root_not_singular(); } +int main(){ - - -#define EXPECT_EQ_STRING(expect,actual, alength)\ - EXPECT_EQ_BASE(sizeof(expect)-1 == alength && memcmp(expect, actual, alength)== 0, expect,actual, "%s" ) - -static void test_access_string() -{ - lept_value v; - lept_init(v); - lept_set_string(v, "", 0); - EXPECT_EQ_STRING("", lept_get_string(v), lept_get_string_length(v)); - - lept_set_string(v, "P&S", 3); - EXPECT_EQ_STRING("P&G", lept_get_string(v), lept_get_string_length(v)); - lept_free(v); -} - - -int main() -{ - test_parse(); - printf("%d/%d (%3.2f%%) passed\n", test_pass, test_count, test_pass * 100.0 / test_count); - return main_ret; - + test_parse(); + printf("%d/%d (%3.2f%%) passed\n",test_pass, test_count,test_pass*100.0 / test_count); + return main_ret; }