json decode support unicode
parent
275279a264
commit
64e9499de6
|
|
@ -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++ = ',';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue