diff options
Diffstat (limited to '')
-rw-r--r-- | src/nxt_conf.h | 4 | ||||
-rw-r--r-- | src/nxt_conf_json.c | 366 | ||||
-rw-r--r-- | src/nxt_controller.c | 5 |
3 files changed, 213 insertions, 162 deletions
diff --git a/src/nxt_conf.h b/src/nxt_conf.h index f06fbf3b..91002741 100644 --- a/src/nxt_conf.h +++ b/src/nxt_conf.h @@ -36,7 +36,9 @@ nxt_conf_json_value_t *nxt_conf_json_parse(nxt_mp_t *mp, u_char *start, #define nxt_conf_json_str_parse(mp, str) \ nxt_conf_json_parse(mp, (str)->start, (str)->start + (str)->length) -uintptr_t nxt_conf_json_print_value(u_char *p, nxt_conf_json_value_t *value, +size_t nxt_conf_json_value_length(nxt_conf_json_value_t *value, + nxt_conf_json_pretty_t *pretty); +u_char *nxt_conf_json_value_print(u_char *p, nxt_conf_json_value_t *value, nxt_conf_json_pretty_t *pretty); diff --git a/src/nxt_conf_json.c b/src/nxt_conf_json.c index 9ec3ea7d..8117b679 100644 --- a/src/nxt_conf_json.c +++ b/src/nxt_conf_json.c @@ -104,16 +104,23 @@ static nxt_int_t nxt_conf_json_copy_value(nxt_mp_t *mp, nxt_conf_json_op_t *op, static nxt_int_t nxt_conf_json_copy_object(nxt_mp_t *mp, nxt_conf_json_op_t *op, nxt_conf_json_value_t *dst, nxt_conf_json_value_t *src); -static uintptr_t nxt_conf_json_print_integer(u_char *p, +static size_t nxt_conf_json_integer_length(nxt_conf_json_value_t *value); +static u_char *nxt_conf_json_integer_print(u_char *p, nxt_conf_json_value_t *value); -static uintptr_t nxt_conf_json_print_string(u_char *p, +static size_t nxt_conf_json_string_length(nxt_conf_json_value_t *value); +static u_char *nxt_conf_json_string_print(u_char *p, nxt_conf_json_value_t *value); -static uintptr_t nxt_conf_json_print_array(u_char *p, +static size_t nxt_conf_json_array_length(nxt_conf_json_value_t *value, + nxt_conf_json_pretty_t *pretty); +static u_char *nxt_conf_json_array_print(u_char *p, nxt_conf_json_value_t *value, nxt_conf_json_pretty_t *pretty); -static uintptr_t nxt_conf_json_print_object(u_char *p, +static size_t nxt_conf_json_object_length(nxt_conf_json_value_t *value, + nxt_conf_json_pretty_t *pretty); +static u_char *nxt_conf_json_object_print(u_char *p, nxt_conf_json_value_t *value, nxt_conf_json_pretty_t *pretty); -static uintptr_t nxt_conf_json_escape(u_char *dst, u_char *src, size_t size); +static size_t nxt_conf_json_escape_length(u_char *p, size_t size); +static u_char *nxt_conf_json_escape(u_char *dst, u_char *src, size_t size); #define nxt_conf_json_newline(p) \ @@ -132,6 +139,19 @@ nxt_conf_json_indentation(u_char *p, uint32_t level) } +nxt_inline void +nxt_conf_json_value_get_string(nxt_conf_json_value_t *value, nxt_str_t *str) +{ + if (value->type == NXT_CONF_JSON_SHORT_STRING) { + str->length = value->u.str[0]; + str->start = &value->u.str[1]; + + } else { + *str = *value->u.string; + } +} + + typedef struct { u_char *start; u_char *end; @@ -801,18 +821,9 @@ static nxt_int_t nxt_conf_json_object_hash_add(nxt_mp_t *mp, nxt_lvlhsh_t *lvlhsh, nxt_conf_json_obj_member_t *member) { - nxt_lvlhsh_query_t lhq; - nxt_conf_json_value_t *name; + nxt_lvlhsh_query_t lhq; - name = &member->name; - - if (name->type == NXT_CONF_JSON_SHORT_STRING) { - lhq.key.length = name->u.str[0]; - lhq.key.start = &name->u.str[1]; - - } else { - lhq.key = *name->u.string; - } + nxt_conf_json_value_get_string(&member->name, &lhq.key); lhq.key_hash = nxt_djb_hash(lhq.key.start, lhq.key.length); lhq.replace = 0; @@ -827,18 +838,12 @@ nxt_conf_json_object_hash_add(nxt_mp_t *mp, nxt_lvlhsh_t *lvlhsh, static nxt_int_t nxt_conf_json_object_hash_test(nxt_lvlhsh_query_t *lhq, void *data) { - nxt_str_t str; - nxt_conf_json_value_t *name; + nxt_str_t str; + nxt_conf_json_obj_member_t *member; - name = &((nxt_conf_json_obj_member_t *) data)->name; + member = data; - if (name->type == NXT_CONF_JSON_SHORT_STRING) { - str.length = name->u.str[0]; - str.start = &name->u.str[1]; - - } else { - str = *name->u.string; - } + nxt_conf_json_value_get_string(&member->name, &str); if (nxt_strstr_eq(&lhq->key, &str)) { return NXT_OK; @@ -1149,7 +1154,7 @@ nxt_conf_json_parse_string(nxt_mp_t *mp, nxt_conf_json_value_t *value, || utf < 0xdc00 || utf > 0xdfff)) { - /* invalid surrogate pair */ + /* Invalid surrogate pair. */ return NULL; } @@ -1312,112 +1317,135 @@ nxt_conf_json_parse_number(nxt_mp_t *mp, nxt_conf_json_value_t *value, } -uintptr_t -nxt_conf_json_print_value(u_char *p, nxt_conf_json_value_t *value, +size_t +nxt_conf_json_value_length(nxt_conf_json_value_t *value, nxt_conf_json_pretty_t *pretty) { switch (value->type) { case NXT_CONF_JSON_NULL: + return sizeof("null") - 1; - if (p == NULL) { - return sizeof("null") - 1; - } + case NXT_CONF_JSON_BOOLEAN: + return value->u.boolean ? sizeof("true") - 1 : sizeof("false") - 1; - return (uintptr_t) nxt_cpymem(p, "null", 4); + case NXT_CONF_JSON_INTEGER: + return nxt_conf_json_integer_length(value); - case NXT_CONF_JSON_BOOLEAN: + case NXT_CONF_JSON_NUMBER: + /* TODO */ + return 0; - if (p == NULL) { - return value->u.boolean ? sizeof("true") - 1 : sizeof("false") - 1; - } + case NXT_CONF_JSON_SHORT_STRING: + case NXT_CONF_JSON_STRING: + return nxt_conf_json_string_length(value); - if (value->u.boolean) { - return (uintptr_t) nxt_cpymem(p, "true", 4); - } + case NXT_CONF_JSON_ARRAY: + return nxt_conf_json_array_length(value, pretty); + + case NXT_CONF_JSON_OBJECT: + return nxt_conf_json_object_length(value, pretty); + } + + nxt_unreachable(); + + return 0; +} + + +u_char * +nxt_conf_json_value_print(u_char *p, nxt_conf_json_value_t *value, + nxt_conf_json_pretty_t *pretty) +{ + switch (value->type) { + + case NXT_CONF_JSON_NULL: + return nxt_cpymem(p, "null", 4); - return (uintptr_t) nxt_cpymem(p, "false", 5); + case NXT_CONF_JSON_BOOLEAN: + return value->u.boolean ? nxt_cpymem(p, "true", 4) + : nxt_cpymem(p, "false", 5); case NXT_CONF_JSON_INTEGER: - return nxt_conf_json_print_integer(p, value); + return nxt_conf_json_integer_print(p, value); case NXT_CONF_JSON_NUMBER: /* TODO */ - return (p == NULL) ? 0 : (uintptr_t) p; + return p; case NXT_CONF_JSON_SHORT_STRING: case NXT_CONF_JSON_STRING: - return nxt_conf_json_print_string(p, value); + return nxt_conf_json_string_print(p, value); case NXT_CONF_JSON_ARRAY: - return nxt_conf_json_print_array(p, value, pretty); + return nxt_conf_json_array_print(p, value, pretty); case NXT_CONF_JSON_OBJECT: - return nxt_conf_json_print_object(p, value, pretty); + return nxt_conf_json_object_print(p, value, pretty); } nxt_unreachable(); - return (p == NULL) ? 0 : (uintptr_t) p; + return p; } -static uintptr_t -nxt_conf_json_print_integer(u_char *p, nxt_conf_json_value_t *value) +static size_t +nxt_conf_json_integer_length(nxt_conf_json_value_t *value) { int64_t num; - num = value->u.integer; + num = llabs(value->u.integer); - if (p == NULL) { - num = llabs(num); + if (num <= 9999) { + return sizeof("-9999") - 1; + } - if (num <= 9999) { - return sizeof("-9999") - 1; - } + if (num <= 99999999999) { + return sizeof("-99999999999") - 1; + } - if (num <= 99999999999) { - return sizeof("-99999999999") - 1; - } + return NXT_INT64_T_LEN; +} - return NXT_INT64_T_LEN; - } - return (uintptr_t) nxt_sprintf(p, p + NXT_INT64_T_LEN, "%L", num); +static u_char * +nxt_conf_json_integer_print(u_char *p, nxt_conf_json_value_t *value) +{ + return nxt_sprintf(p, p + NXT_INT64_T_LEN, "%L", value->u.integer); } -static uintptr_t -nxt_conf_json_print_string(u_char *p, nxt_conf_json_value_t *value) +static size_t +nxt_conf_json_string_length(nxt_conf_json_value_t *value) { - size_t len; - u_char *s; + nxt_str_t str; - if (value->type == NXT_CONF_JSON_SHORT_STRING) { - len = value->u.str[0]; - s = &value->u.str[1]; + nxt_conf_json_value_get_string(value, &str); - } else { - len = value->u.string->length; - s = value->u.string->start; - } + return 2 + nxt_conf_json_escape_length(str.start, str.length); +} - if (p == NULL) { - return 2 + len + nxt_conf_json_escape(NULL, s, len); - } + +static u_char * +nxt_conf_json_string_print(u_char *p, nxt_conf_json_value_t *value) +{ + nxt_str_t str; + + nxt_conf_json_value_get_string(value, &str); *p++ = '"'; - p = (u_char *) nxt_conf_json_escape(p, s, len); + p = nxt_conf_json_escape(p, str.start, str.length); *p++ = '"'; - return (uintptr_t) p; + return p; } -static uintptr_t -nxt_conf_json_print_array(u_char *p, nxt_conf_json_value_t *value, +static size_t +nxt_conf_json_array_length(nxt_conf_json_value_t *value, nxt_conf_json_pretty_t *pretty) { size_t len; @@ -1426,38 +1454,47 @@ nxt_conf_json_print_array(u_char *p, nxt_conf_json_value_t *value, array = value->u.array; - if (p == NULL) { - /* [] */ - len = 2; + /* [] */ + len = 2; - if (pretty != NULL) { - pretty->level++; - } + if (pretty != NULL) { + pretty->level++; + } - value = array->elements; + value = array->elements; - for (n = 0; n < array->count; n++) { - len += nxt_conf_json_print_value(NULL, &value[n], pretty); + for (n = 0; n < array->count; n++) { + len += nxt_conf_json_value_length(&value[n], pretty); - if (pretty != NULL) { - /* indentation and new line */ - len += pretty->level + 2; - } + if (pretty != NULL) { + /* Indentation and new line. */ + len += pretty->level + 2; } + } - if (pretty != NULL) { - pretty->level--; + if (pretty != NULL) { + pretty->level--; - if (n != 0) { - /* indentation and new line */ - len += pretty->level + 2; - } + if (n != 0) { + /* Indentation and new line. */ + len += pretty->level + 2; } - - /* reserve space for "n" commas */ - return len + n; } + /* Reserve space for "n" commas. */ + return len + n; +} + + +static u_char * +nxt_conf_json_array_print(u_char *p, nxt_conf_json_value_t *value, + nxt_conf_json_pretty_t *pretty) +{ + nxt_uint_t n; + nxt_conf_json_array_t *array; + + array = value->u.array; + *p++ = '['; if (array->count != 0) { @@ -1470,7 +1507,7 @@ nxt_conf_json_print_array(u_char *p, nxt_conf_json_value_t *value, p = nxt_conf_json_indentation(p, pretty->level); } - p = (u_char *) nxt_conf_json_print_value(p, &value[0], pretty); + p = nxt_conf_json_value_print(p, &value[0], pretty); for (n = 1; n < array->count; n++) { *p++ = ','; @@ -1482,7 +1519,7 @@ nxt_conf_json_print_array(u_char *p, nxt_conf_json_value_t *value, pretty->more_space = 0; } - p = (u_char *) nxt_conf_json_print_value(p, &value[n], pretty); + p = nxt_conf_json_value_print(p, &value[n], pretty); } if (pretty != NULL) { @@ -1497,12 +1534,12 @@ nxt_conf_json_print_array(u_char *p, nxt_conf_json_value_t *value, *p++ = ']'; - return (uintptr_t) p; + return p; } -static uintptr_t -nxt_conf_json_print_object(u_char *p, nxt_conf_json_value_t *value, +static size_t +nxt_conf_json_object_length(nxt_conf_json_value_t *value, nxt_conf_json_pretty_t *pretty) { size_t len; @@ -1512,39 +1549,48 @@ nxt_conf_json_print_object(u_char *p, nxt_conf_json_value_t *value, object = value->u.object; - if (p == NULL) { - /* {} */ - len = 2; + /* {} */ + len = 2; + + if (pretty != NULL) { + pretty->level++; + } + + member = object->members; + + for (n = 0; n < object->count; n++) { + len += nxt_conf_json_string_length(&member[n].name) + 1 + + nxt_conf_json_value_length(&member[n].value, pretty) + 1; if (pretty != NULL) { - pretty->level++; + /* + * Indentation, space after ":", new line, and possible + * additional empty line between non-empty objects. + */ + len += pretty->level + 1 + 2 + 2; } + } - member = object->members; + if (pretty != NULL) { + pretty->level--; - for (n = 0; n < object->count; n++) { - len += nxt_conf_json_print_string(NULL, &member[n].name) + 1 - + nxt_conf_json_print_value(NULL, &member[n].value, pretty) - + 1; + /* Indentation and new line. */ + len += pretty->level + 2; + } - if (pretty != NULL) { - /* - * indentation, space after ":", new line, and possible - * additional empty line between non-empty objects - */ - len += pretty->level + 1 + 2 + 2; - } - } + return len; +} - if (pretty != NULL) { - pretty->level--; - /* indentation and new line */ - len += pretty->level + 2; - } +static u_char * +nxt_conf_json_object_print(u_char *p, nxt_conf_json_value_t *value, + nxt_conf_json_pretty_t *pretty) +{ + nxt_uint_t n; + nxt_conf_json_object_t *object; + nxt_conf_json_obj_member_t *member; - return len; - } + object = value->u.object; *p++ = '{'; @@ -1564,7 +1610,7 @@ nxt_conf_json_print_object(u_char *p, nxt_conf_json_value_t *value, p = nxt_conf_json_indentation(p, pretty->level); } - p = (u_char *) nxt_conf_json_print_string(p, &member[n].name); + p = nxt_conf_json_string_print(p, &member[n].name); *p++ = ':'; @@ -1572,8 +1618,7 @@ nxt_conf_json_print_object(u_char *p, nxt_conf_json_value_t *value, *p++ = ' '; } - p = (u_char *) nxt_conf_json_print_value(p, &member[n].value, - pretty); + p = nxt_conf_json_value_print(p, &member[n].value, pretty); n++; @@ -1605,47 +1650,52 @@ nxt_conf_json_print_object(u_char *p, nxt_conf_json_value_t *value, *p++ = '}'; - return (uintptr_t) p; + return p; } -static uintptr_t -nxt_conf_json_escape(u_char *dst, u_char *src, size_t size) +static size_t +nxt_conf_json_escape_length(u_char *p, size_t size) { u_char ch; size_t len; - if (dst == NULL) { - len = 0; + len = size; - while (size) { - ch = *src++; + while (size) { + ch = *p++; - if (ch == '\\' || ch == '"') { - len++; + if (ch == '\\' || ch == '"') { + len++; - } else if (ch <= 0x1f) { + } else if (ch <= 0x1f) { - switch (ch) { - case '\n': - case '\r': - case '\t': - case '\b': - case '\f': - len++; - break; + switch (ch) { + case '\n': + case '\r': + case '\t': + case '\b': + case '\f': + len++; + break; - default: - len += sizeof("\\u001F") - 2; - } + default: + len += sizeof("\\u001F") - 2; } - - size--; } - return len; + size--; } + return len; +} + + +static u_char * +nxt_conf_json_escape(u_char *dst, u_char *src, size_t size) +{ + u_char ch; + while (size) { ch = *src++; @@ -1694,5 +1744,5 @@ nxt_conf_json_escape(u_char *dst, u_char *src, size_t size) size--; } - return (uintptr_t) dst; + return dst; } diff --git a/src/nxt_controller.c b/src/nxt_controller.c index f20fd685..33bb3e93 100644 --- a/src/nxt_controller.c +++ b/src/nxt_controller.c @@ -786,7 +786,7 @@ nxt_controller_response_body(nxt_controller_response_t *resp, nxt_mp_t *pool) nxt_memzero(&pretty, sizeof(nxt_conf_json_pretty_t)); - size = nxt_conf_json_print_value(NULL, value, &pretty) + 2; + size = nxt_conf_json_value_length(value, &pretty) + 2; b = nxt_buf_mem_alloc(pool, size, 0); if (nxt_slow_path(b == NULL)) { @@ -795,8 +795,7 @@ nxt_controller_response_body(nxt_controller_response_t *resp, nxt_mp_t *pool) nxt_memzero(&pretty, sizeof(nxt_conf_json_pretty_t)); - b->mem.free = (u_char *) nxt_conf_json_print_value(b->mem.free, value, - &pretty); + b->mem.free = nxt_conf_json_value_print(b->mem.free, value, &pretty); *b->mem.free++ = '\r'; *b->mem.free++ = '\n'; |