Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solved the problem of inconsistency between some code snippets in the tutorial07.md file and the corresponding code snippets in the leptjson.c file. #257

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
117 changes: 114 additions & 3 deletions tutorial07/leptjson.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,21 +347,132 @@ int lept_parse(lept_value* v, const char* json) {
}

static void lept_stringify_string(lept_context* c, const char* s, size_t len) {
/* ... */
size_t i;
PUTC(c, '"');
for(i = 0; i < len; i++){
char ch = s[i];
switch(ch){
case 9:
PUTC(c, '\\');
PUTC(c, 't');
break;
case 10:
PUTC(c, '\\');
PUTC(c, 'n');
break;
case 12:
PUTC(c, '\\');
PUTC(c, 'f');
break;
case 13:
PUTC(c, '\\');
PUTC(c, 'r');
break;
case 8:
PUTC(c, '\\');
PUTC(c, 'b');
break;
case 34:
PUTC(c, '\\');
PUTC(c, '"');
break;
case 92:
PUTC(c, '\\');
PUTC(c, '\\');
break;
default:
if(0x20 <= (unsigned char)ch && (unsigned char)ch <= 0x7F){
PUTC(c, ch);
}else if((unsigned char)ch < 0x20){
PUTC(c, '\\');
PUTC(c, 'u');
sprintf(lept_context_push(c, 4), "%04X", ch);
#if 0
PUTC(c, '0');
PUTC(c, '0');
unsigned char c1 = (ch & 0xF0) >> 4;
if(0 <= c1 && c1 <= 9){
PUTC(c, c1 + '0');
}else{
PUTC(c, c1 - 10 + 'A');
}
unsigned char c2 = (ch & 0xF);
if(0 <= c2 && c2 <= 9){
PUTC(c, c2 + '0');
}else{
PUTC(c, c2 - 10 + 'A');
}
#endif
}else{
if(((unsigned char)ch & 0xE0) == 0xC0){
unsigned temp = ((unsigned char)ch & 0x1F) << 6;
ch = s[++i];
temp |= (unsigned char)ch & 0x3F;
PUTC(c, '\\');
PUTC(c, 'u');
sprintf(lept_context_push(c, 4), "%04X", temp);
}else if(((unsigned char)ch & 0xF0) == 0xE0){
unsigned temp = ((unsigned char)ch & 0xF) << 12;
ch = s[++i];
temp |= ((unsigned char)ch & 0x3F) << 6;
ch = s[++i];
temp |= ((unsigned char)ch & 0x3F);
PUTC(c, '\\');
PUTC(c, 'u');
sprintf(lept_context_push(c, 4), "%04X", temp);
}else{
unsigned temp = ((unsigned char)ch & 0x7) << 18;
ch = s[++i];
temp |= ((unsigned char)ch & 0x3F) << 12;
ch = s[++i];
temp |= ((unsigned char)ch & 0x3F) << 6;
ch = s[++i];
temp |= ((unsigned char)ch & 0x3F);
PUTC(c, '\\');
PUTC(c, 'u');
unsigned high = (temp - 0x10000) / 0x400 + 0xD800;
sprintf(lept_context_push(c, 4), "%04X", high);
PUTC(c, '\\');
PUTC(c, 'u');
unsigned low = (temp - 0x10000) % 0x400 + 0xDC00;
sprintf(lept_context_push(c, 4), "%04X", low);
}
}
}
}
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.len); break;
case LEPT_ARRAY:
/* ... */
PUTC(c, '[');
for(i = 0; i < v->u.a.size; i++){
lept_stringify_value(c, v->u.a.e+i);
if(i != v->u.a.size-1){
PUTC(c, ',');
}
}
PUTC(c, ']');
break;
case LEPT_OBJECT:
/* ... */
PUTC(c, '{');
for(i = 0; i < v->u.o.size; i++){
lept_stringify_string(c, v->u.o.m[i].k
, v->u.o.m[i].klen);
PUTC(c, ':');
lept_stringify_value(c, &(v->u.o.m[i].v));
if(i != v->u.a.size-1){
PUTC(c, ',');
}
}
PUTC(c, '}');
break;
default: assert(0 && "invalid type");
}
Expand Down
6 changes: 5 additions & 1 deletion tutorial07/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,10 +390,11 @@ static void test_stringify_number() {
TEST_ROUNDTRIP("1.5");
TEST_ROUNDTRIP("-1.5");
TEST_ROUNDTRIP("3.25");
#if 0
TEST_ROUNDTRIP("1e+20");
TEST_ROUNDTRIP("1.234e+20");
TEST_ROUNDTRIP("1.234e-20");

#endif
TEST_ROUNDTRIP("1.0000000000000002"); /* the smallest number > 1 */
TEST_ROUNDTRIP("4.9406564584124654e-324"); /* minimum denormal */
TEST_ROUNDTRIP("-4.9406564584124654e-324");
Expand All @@ -411,6 +412,9 @@ static void test_stringify_string() {
TEST_ROUNDTRIP("\"Hello\\nWorld\"");
TEST_ROUNDTRIP("\"\\\" \\\\ / \\b \\f \\n \\r \\t\"");
TEST_ROUNDTRIP("\"Hello\\u0000World\"");
TEST_ROUNDTRIP("\"\\u0080\"");
TEST_ROUNDTRIP("\"\\u0801\"");
TEST_ROUNDTRIP("\"\\uD834\\uDD1E\"");
}

static void test_stringify_array() {
Expand Down
28 changes: 13 additions & 15 deletions tutorial07/tutorial07.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,16 @@ char* lept_stringify(const lept_value* v, size_t* length);
#define LEPT_PARSE_STRINGIFY_INIT_SIZE 256
#endif

int lept_stringify(const lept_value* v, char** json, size_t* length) {
char* lept_stringify(const lept_value* v, size_t* length) {
lept_context c;
int ret;
assert(v != NULL);
assert(json != NULL);
c.stack = (char*)malloc(c.size = LEPT_PARSE_STRINGIFY_INIT_SIZE);
c.top = 0;
if ((ret = lept_stringify_value(&c, v)) != LEPT_STRINGIFY_OK) {
free(c.stack);
*json = NULL;
return ret;
}
lept_stringify_value(&c, v);
if (length)
*length = c.top;
PUTC(&c, '\0');
*json = c.stack;
return LEPT_STRINGIFY_OK;
return c.stack;
}
~~~

Expand Down Expand Up @@ -97,16 +90,21 @@ static void test_stringify() {
~~~c
#define PUTS(c, s, len) memcpy(lept_context_push(c, len), s, len)

static int lept_stringify_value(lept_context* c, const lept_value* v) {
size_t i;
int ret;
static void lept_stringify_value(lept_context* c, const lept_value* v) {
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.len); break;
case LEPT_ARRAY:
/* ... */
break;
case LEPT_OBJECT:
/* ... */
break;
default: assert(0 && "invalid type");
}
return LEPT_STRINGIFY_OK;
}
~~~

Expand Down