Configuration printing functions splitted in two parts.

Requested by Igor.
This commit is contained in:
Valentin Bartenev
2017-06-23 23:28:37 +03:00
parent 72429410f7
commit 9399a04121
3 changed files with 243 additions and 192 deletions

View File

@@ -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) \ #define nxt_conf_json_str_parse(mp, str) \
nxt_conf_json_parse(mp, (str)->start, (str)->start + (str)->length) 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); nxt_conf_json_pretty_t *pretty);

View File

@@ -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, 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); 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); 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); 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); 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); 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) \ #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 { typedef struct {
u_char *start; u_char *start;
u_char *end; u_char *end;
@@ -802,17 +822,8 @@ nxt_conf_json_object_hash_add(nxt_mp_t *mp, nxt_lvlhsh_t *lvlhsh,
nxt_conf_json_obj_member_t *member) nxt_conf_json_obj_member_t *member)
{ {
nxt_lvlhsh_query_t lhq; nxt_lvlhsh_query_t lhq;
nxt_conf_json_value_t *name;
name = &member->name; nxt_conf_json_value_get_string(&member->name, &lhq.key);
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;
}
lhq.key_hash = nxt_djb_hash(lhq.key.start, lhq.key.length); lhq.key_hash = nxt_djb_hash(lhq.key.start, lhq.key.length);
lhq.replace = 0; lhq.replace = 0;
@@ -828,17 +839,11 @@ static nxt_int_t
nxt_conf_json_object_hash_test(nxt_lvlhsh_query_t *lhq, void *data) nxt_conf_json_object_hash_test(nxt_lvlhsh_query_t *lhq, void *data)
{ {
nxt_str_t str; nxt_str_t str;
nxt_conf_json_value_t *name; 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) { nxt_conf_json_value_get_string(&member->name, &str);
str.length = name->u.str[0];
str.start = &name->u.str[1];
} else {
str = *name->u.string;
}
if (nxt_strstr_eq(&lhq->key, &str)) { if (nxt_strstr_eq(&lhq->key, &str)) {
return NXT_OK; 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 < 0xdc00
|| utf > 0xdfff)) || utf > 0xdfff))
{ {
/* invalid surrogate pair */ /* Invalid surrogate pair. */
return NULL; return NULL;
} }
@@ -1312,65 +1317,85 @@ nxt_conf_json_parse_number(nxt_mp_t *mp, nxt_conf_json_value_t *value,
} }
uintptr_t size_t
nxt_conf_json_print_value(u_char *p, nxt_conf_json_value_t *value, nxt_conf_json_value_length(nxt_conf_json_value_t *value,
nxt_conf_json_pretty_t *pretty) nxt_conf_json_pretty_t *pretty)
{ {
switch (value->type) { switch (value->type) {
case NXT_CONF_JSON_NULL: case NXT_CONF_JSON_NULL:
if (p == NULL) {
return sizeof("null") - 1; return sizeof("null") - 1;
}
return (uintptr_t) nxt_cpymem(p, "null", 4);
case NXT_CONF_JSON_BOOLEAN: case NXT_CONF_JSON_BOOLEAN:
if (p == NULL) {
return value->u.boolean ? sizeof("true") - 1 : sizeof("false") - 1; return value->u.boolean ? sizeof("true") - 1 : sizeof("false") - 1;
}
if (value->u.boolean) {
return (uintptr_t) nxt_cpymem(p, "true", 4);
}
return (uintptr_t) nxt_cpymem(p, "false", 5);
case NXT_CONF_JSON_INTEGER: case NXT_CONF_JSON_INTEGER:
return nxt_conf_json_print_integer(p, value); return nxt_conf_json_integer_length(value);
case NXT_CONF_JSON_NUMBER: case NXT_CONF_JSON_NUMBER:
/* TODO */ /* TODO */
return (p == NULL) ? 0 : (uintptr_t) p; return 0;
case NXT_CONF_JSON_SHORT_STRING: case NXT_CONF_JSON_SHORT_STRING:
case NXT_CONF_JSON_STRING: case NXT_CONF_JSON_STRING:
return nxt_conf_json_print_string(p, value); return nxt_conf_json_string_length(value);
case NXT_CONF_JSON_ARRAY: case NXT_CONF_JSON_ARRAY:
return nxt_conf_json_print_array(p, value, pretty); return nxt_conf_json_array_length(value, pretty);
case NXT_CONF_JSON_OBJECT: case NXT_CONF_JSON_OBJECT:
return nxt_conf_json_print_object(p, value, pretty); return nxt_conf_json_object_length(value, pretty);
} }
nxt_unreachable(); nxt_unreachable();
return (p == NULL) ? 0 : (uintptr_t) p; return 0;
} }
static uintptr_t u_char *
nxt_conf_json_print_integer(u_char *p, nxt_conf_json_value_t *value) 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);
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_integer_print(p, value);
case NXT_CONF_JSON_NUMBER:
/* TODO */
return p;
case NXT_CONF_JSON_SHORT_STRING:
case NXT_CONF_JSON_STRING:
return nxt_conf_json_string_print(p, value);
case NXT_CONF_JSON_ARRAY:
return nxt_conf_json_array_print(p, value, pretty);
case NXT_CONF_JSON_OBJECT:
return nxt_conf_json_object_print(p, value, pretty);
}
nxt_unreachable();
return p;
}
static size_t
nxt_conf_json_integer_length(nxt_conf_json_value_t *value)
{ {
int64_t num; int64_t num;
num = value->u.integer; num = llabs(value->u.integer);
if (p == NULL) {
num = llabs(num);
if (num <= 9999) { if (num <= 9999) {
return sizeof("-9999") - 1; return sizeof("-9999") - 1;
@@ -1381,43 +1406,46 @@ nxt_conf_json_print_integer(u_char *p, nxt_conf_json_value_t *value)
} }
return NXT_INT64_T_LEN; return NXT_INT64_T_LEN;
}
return (uintptr_t) nxt_sprintf(p, p + NXT_INT64_T_LEN, "%L", num);
} }
static uintptr_t static u_char *
nxt_conf_json_print_string(u_char *p, nxt_conf_json_value_t *value) nxt_conf_json_integer_print(u_char *p, nxt_conf_json_value_t *value)
{ {
size_t len; return nxt_sprintf(p, p + NXT_INT64_T_LEN, "%L", value->u.integer);
u_char *s;
if (value->type == NXT_CONF_JSON_SHORT_STRING) {
len = value->u.str[0];
s = &value->u.str[1];
} else {
len = value->u.string->length;
s = value->u.string->start;
}
if (p == NULL) {
return 2 + len + nxt_conf_json_escape(NULL, s, len);
}
*p++ = '"';
p = (u_char *) nxt_conf_json_escape(p, s, len);
*p++ = '"';
return (uintptr_t) p;
} }
static uintptr_t static size_t
nxt_conf_json_print_array(u_char *p, nxt_conf_json_value_t *value, nxt_conf_json_string_length(nxt_conf_json_value_t *value)
{
nxt_str_t str;
nxt_conf_json_value_get_string(value, &str);
return 2 + nxt_conf_json_escape_length(str.start, str.length);
}
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 = nxt_conf_json_escape(p, str.start, str.length);
*p++ = '"';
return p;
}
static size_t
nxt_conf_json_array_length(nxt_conf_json_value_t *value,
nxt_conf_json_pretty_t *pretty) nxt_conf_json_pretty_t *pretty)
{ {
size_t len; size_t len;
@@ -1426,7 +1454,6 @@ nxt_conf_json_print_array(u_char *p, nxt_conf_json_value_t *value,
array = value->u.array; array = value->u.array;
if (p == NULL) {
/* [] */ /* [] */
len = 2; len = 2;
@@ -1437,10 +1464,10 @@ nxt_conf_json_print_array(u_char *p, nxt_conf_json_value_t *value,
value = array->elements; value = array->elements;
for (n = 0; n < array->count; n++) { for (n = 0; n < array->count; n++) {
len += nxt_conf_json_print_value(NULL, &value[n], pretty); len += nxt_conf_json_value_length(&value[n], pretty);
if (pretty != NULL) { if (pretty != NULL) {
/* indentation and new line */ /* Indentation and new line. */
len += pretty->level + 2; len += pretty->level + 2;
} }
} }
@@ -1449,14 +1476,24 @@ nxt_conf_json_print_array(u_char *p, nxt_conf_json_value_t *value,
pretty->level--; pretty->level--;
if (n != 0) { if (n != 0) {
/* indentation and new line */ /* Indentation and new line. */
len += pretty->level + 2; len += pretty->level + 2;
} }
} }
/* reserve space for "n" commas */ /* Reserve space for "n" commas. */
return len + n; 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++ = '['; *p++ = '[';
@@ -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 = 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++) { for (n = 1; n < array->count; n++) {
*p++ = ','; *p++ = ',';
@@ -1482,7 +1519,7 @@ nxt_conf_json_print_array(u_char *p, nxt_conf_json_value_t *value,
pretty->more_space = 0; 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) { if (pretty != NULL) {
@@ -1497,12 +1534,12 @@ nxt_conf_json_print_array(u_char *p, nxt_conf_json_value_t *value,
*p++ = ']'; *p++ = ']';
return (uintptr_t) p; return p;
} }
static uintptr_t static size_t
nxt_conf_json_print_object(u_char *p, nxt_conf_json_value_t *value, nxt_conf_json_object_length(nxt_conf_json_value_t *value,
nxt_conf_json_pretty_t *pretty) nxt_conf_json_pretty_t *pretty)
{ {
size_t len; size_t len;
@@ -1512,7 +1549,6 @@ nxt_conf_json_print_object(u_char *p, nxt_conf_json_value_t *value,
object = value->u.object; object = value->u.object;
if (p == NULL) {
/* {} */ /* {} */
len = 2; len = 2;
@@ -1523,14 +1559,13 @@ nxt_conf_json_print_object(u_char *p, nxt_conf_json_value_t *value,
member = object->members; member = object->members;
for (n = 0; n < object->count; n++) { for (n = 0; n < object->count; n++) {
len += nxt_conf_json_print_string(NULL, &member[n].name) + 1 len += nxt_conf_json_string_length(&member[n].name) + 1
+ nxt_conf_json_print_value(NULL, &member[n].value, pretty) + nxt_conf_json_value_length(&member[n].value, pretty) + 1;
+ 1;
if (pretty != NULL) { if (pretty != NULL) {
/* /*
* indentation, space after ":", new line, and possible * Indentation, space after ":", new line, and possible
* additional empty line between non-empty objects * additional empty line between non-empty objects.
*/ */
len += pretty->level + 1 + 2 + 2; len += pretty->level + 1 + 2 + 2;
} }
@@ -1539,12 +1574,23 @@ nxt_conf_json_print_object(u_char *p, nxt_conf_json_value_t *value,
if (pretty != NULL) { if (pretty != NULL) {
pretty->level--; pretty->level--;
/* indentation and new line */ /* Indentation and new line. */
len += pretty->level + 2; len += pretty->level + 2;
} }
return len; return len;
} }
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;
object = value->u.object;
*p++ = '{'; *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 = 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++ = ':'; *p++ = ':';
@@ -1572,8 +1618,7 @@ nxt_conf_json_print_object(u_char *p, nxt_conf_json_value_t *value,
*p++ = ' '; *p++ = ' ';
} }
p = (u_char *) nxt_conf_json_print_value(p, &member[n].value, p = nxt_conf_json_value_print(p, &member[n].value, pretty);
pretty);
n++; n++;
@@ -1605,21 +1650,20 @@ nxt_conf_json_print_object(u_char *p, nxt_conf_json_value_t *value,
*p++ = '}'; *p++ = '}';
return (uintptr_t) p; return p;
} }
static uintptr_t static size_t
nxt_conf_json_escape(u_char *dst, u_char *src, size_t size) nxt_conf_json_escape_length(u_char *p, size_t size)
{ {
u_char ch; u_char ch;
size_t len; size_t len;
if (dst == NULL) { len = size;
len = 0;
while (size) { while (size) {
ch = *src++; ch = *p++;
if (ch == '\\' || ch == '"') { if (ch == '\\' || ch == '"') {
len++; len++;
@@ -1644,7 +1688,13 @@ nxt_conf_json_escape(u_char *dst, u_char *src, size_t size)
} }
return len; return len;
} }
static u_char *
nxt_conf_json_escape(u_char *dst, u_char *src, size_t size)
{
u_char ch;
while (size) { while (size) {
ch = *src++; ch = *src++;
@@ -1694,5 +1744,5 @@ nxt_conf_json_escape(u_char *dst, u_char *src, size_t size)
size--; size--;
} }
return (uintptr_t) dst; return dst;
} }

View File

@@ -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)); 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); b = nxt_buf_mem_alloc(pool, size, 0);
if (nxt_slow_path(b == NULL)) { 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)); nxt_memzero(&pretty, sizeof(nxt_conf_json_pretty_t));
b->mem.free = (u_char *) nxt_conf_json_print_value(b->mem.free, value, b->mem.free = nxt_conf_json_value_print(b->mem.free, value, &pretty);
&pretty);
*b->mem.free++ = '\r'; *b->mem.free++ = '\r';
*b->mem.free++ = '\n'; *b->mem.free++ = '\n';