json decode support unicode

vote_node
YuQing 2022-05-29 21:13:00 +08:00
parent 275279a264
commit 64e9499de6
2 changed files with 71 additions and 27 deletions

View File

@ -88,6 +88,10 @@ static int json_escape_string(fc_json_context_t *context,
*dest++ = '\\'; *dest++ = '\\';
*dest++ = 'n'; *dest++ = 'n';
break; break;
case '\b':
*dest++ = '\\';
*dest++ = 'b';
break;
case '\f': case '\f':
*dest++ = '\\'; *dest++ = '\\';
*dest++ = 'f'; *dest++ = 'f';
@ -96,9 +100,13 @@ static int json_escape_string(fc_json_context_t *context,
*dest++ = '\\'; *dest++ = '\\';
*dest++ = '\"'; *dest++ = '\"';
break; break;
case '\'': case '\0':
*dest++ = '\\'; *dest++ = '\\';
*dest++ = '\''; *dest++ = 'u';
*dest++ = '0';
*dest++ = '0';
*dest++ = '0';
*dest++ = '0';
break; break;
default: default:
*dest++ = *src; *dest++ = *src;
@ -112,8 +120,11 @@ static int json_escape_string(fc_json_context_t *context,
static int next_json_element(fc_json_context_t *context) static int next_json_element(fc_json_context_t *context)
{ {
char *dest; char *dest;
const char *start;
char buff[128]; char buff[128];
char quote_ch; char quote_ch;
int unicode;
int i;
dest = context->element.str; dest = context->element.str;
quote_ch = *context->p; quote_ch = *context->p;
@ -127,6 +138,39 @@ static int next_json_element(fc_json_context_t *context)
&context->error_info, context->error_size); &context->error_info, context->error_size);
return EINVAL; return EINVAL;
} }
if (*context->p == 'u') { //unicode
start = ++context->p; //skip charator 'u'
i = 0;
while (i < 4 && context->p < context->end &&
IS_HEX_CHAR(*context->p))
{
buff[i++] = *context->p;
++context->p;
}
if (i != 4) {
set_parse_error(context->str, start,
EXPECT_STR_LEN, "expect 4 hex characters "
"after \\u", &context->error_info,
context->error_size);
return EINVAL;
}
buff[i] = '\0';
unicode = strtol(buff, NULL, 16);
if (unicode < 0x80) {
*dest++ = unicode;
} else if (unicode < 0x800) {
*dest++ = 0xC0 | ((unicode >> 6) & 0x1F);
*dest++ = 0x80 | (unicode & 0x3F);
} else {
*dest++ = 0xE0 | ((unicode >> 12) & 0x0F);
*dest++ = 0x80 | ((unicode >> 6) & 0x3F);
*dest++ = 0x80 | (unicode & 0x3F);
}
continue;
}
switch (*context->p) { switch (*context->p) {
case '\\': case '\\':
*dest++ = '\\'; *dest++ = '\\';
@ -146,12 +190,12 @@ static int next_json_element(fc_json_context_t *context)
case 'f': case 'f':
*dest++ = '\f'; *dest++ = '\f';
break; break;
case 'b':
*dest++ = '\b';
break;
case '"': case '"':
*dest++ = '\"'; *dest++ = '\"';
break; break;
case '\'':
*dest++ = '\'';
break;
default: default:
sprintf(buff, "invalid escaped character: %c(0x%x)", sprintf(buff, "invalid escaped character: %c(0x%x)",
*context->p, (unsigned char)*context->p); *context->p, (unsigned char)*context->p);
@ -264,18 +308,18 @@ static inline void json_quote_string(fc_json_context_t
*buff = p; *buff = p;
} }
const BufferInfo *fc_encode_json_array(fc_json_context_t const BufferInfo *fc_encode_json_array(fc_json_context_t *context,
*context, const fc_json_array_t *array) const string_t *elements, const int count)
{ {
string_t *el; const string_t *el;
string_t *end; const string_t *end;
char *p; char *p;
int expect_size; int expect_size;
expect_size = 3; expect_size = 3;
end = array->elements + array->count; end = elements + count;
for (el=array->elements; el<end; el++) { for (el=elements; el<end; el++) {
expect_size += 2 * el->len + 3; expect_size += 6 * el->len + 3;
} }
if (context->output.alloc_size < expect_size) { if (context->output.alloc_size < expect_size) {
@ -290,8 +334,8 @@ const BufferInfo *fc_encode_json_array(fc_json_context_t
p = context->output.buff; p = context->output.buff;
*p++ = '['; *p++ = '[';
for (el=array->elements; el<end; el++) { for (el=elements; el<end; el++) {
if (el > array->elements) { if (el > elements) {
*p++ = ','; *p++ = ',';
} }
@ -304,18 +348,18 @@ const BufferInfo *fc_encode_json_array(fc_json_context_t
return &context->output; return &context->output;
} }
const BufferInfo *fc_encode_json_map(fc_json_context_t const BufferInfo *fc_encode_json_map(fc_json_context_t *context,
*context, const fc_json_map_t *map) const key_value_pair_t *elements, const int count)
{ {
key_value_pair_t *pair; const key_value_pair_t *pair;
key_value_pair_t *end; const key_value_pair_t *end;
char *p; char *p;
int expect_size; int expect_size;
expect_size = 3; expect_size = 3;
end = map->elements + map->count; end = elements + count;
for (pair=map->elements; pair<end; pair++) { for (pair=elements; pair<end; pair++) {
expect_size += 2 * (pair->key.len + pair->value.len + 2) + 1; expect_size += 6 * (pair->key.len + pair->value.len) + 5;
} }
if (context->output.alloc_size < expect_size) { if (context->output.alloc_size < expect_size) {
@ -330,8 +374,8 @@ const BufferInfo *fc_encode_json_map(fc_json_context_t
p = context->output.buff; p = context->output.buff;
*p++ = '{'; *p++ = '{';
for (pair=map->elements; pair<end; pair++) { for (pair=elements; pair<end; pair++) {
if (pair > map->elements) { if (pair > elements) {
*p++ = ','; *p++ = ',';
} }

View File

@ -161,11 +161,11 @@ extern "C" {
int fc_detect_json_type(const string_t *input); int fc_detect_json_type(const string_t *input);
const BufferInfo *fc_encode_json_array(fc_json_context_t const BufferInfo *fc_encode_json_array(fc_json_context_t *context,
*context, const fc_json_array_t *array); const string_t *elements, const int count);
const BufferInfo *fc_encode_json_map(fc_json_context_t const BufferInfo *fc_encode_json_map(fc_json_context_t *context,
*context, const fc_json_map_t *map); const key_value_pair_t *elements, const int count);
const fc_json_array_t *fc_decode_json_array(fc_json_context_t const fc_json_array_t *fc_decode_json_array(fc_json_context_t
*context, const string_t *input); *context, const string_t *input);