Welcome! Log In Create A New Profile

Advanced

[njs] Introduced generic string builder API.

Dmitry Volyntsev
December 11, 2019 08:00AM
details: https://hg.nginx.org/njs/rev/5ba9145d9b0c
branches:
changeset: 1282:5ba9145d9b0c
user: Dmitry Volyntsev <xeioex@nginx.com>
date: Wed Dec 11 15:30:26 2019 +0300
description:
Introduced generic string builder API.

diffstat:

auto/sources | 1 +
src/njs_chb.c | 242 ++++++++++++++++++++++++
src/njs_chb.h | 114 +++++++++++
src/njs_json.c | 464 +++++++++++++---------------------------------
src/njs_main.h | 1 +
src/njs_vm.c | 68 +-----
src/test/njs_unit_test.c | 146 ++++++++++++++
7 files changed, 649 insertions(+), 387 deletions(-)

diffs (truncated from 1548 to 1000 lines):

diff -r 3bef40125db2 -r 5ba9145d9b0c auto/sources
--- a/auto/sources Wed Nov 27 14:02:04 2019 +0000
+++ b/auto/sources Wed Dec 11 15:30:26 2019 +0300
@@ -20,6 +20,7 @@ NJS_LIB_SRCS=" \
src/njs_malloc.c \
src/njs_mp.c \
src/njs_sprintf.c \
+ src/njs_chb.c \
src/njs_value.c \
src/njs_vm.c \
src/njs_vmcode.c \
diff -r 3bef40125db2 -r 5ba9145d9b0c src/njs_chb.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/njs_chb.c Wed Dec 11 15:30:26 2019 +0300
@@ -0,0 +1,242 @@
+
+/*
+ * Copyright (C) Dmitry Volyntsev
+ * Copyright (C) NGINX, Inc.
+ */
+
+
+#include <njs_main.h>
+
+
+#define NJS_CHB_MIN_SIZE 256
+
+
+void
+njs_chb_append0(njs_chb_t *chain, const char *msg, size_t len)
+{
+ u_char *p;
+
+ if (len != 0 && !chain->error) {
+ p = njs_chb_reserve(chain, len);
+ if (njs_slow_path(p == NULL)) {
+ return;
+ }
+
+ memcpy(p, msg, len);
+
+ njs_chb_written(chain, len);
+ }
+}
+
+
+u_char *
+njs_chb_reserve(njs_chb_t *chain, size_t size)
+{
+ njs_chb_node_t *n;
+
+ if (njs_slow_path(size == 0)) {
+ return NULL;
+ }
+
+ n = chain->last;
+
+ if (njs_fast_path(n != NULL && njs_chb_node_room(n) >= size)) {
+ return n->pos;
+ }
+
+ if (size < NJS_CHB_MIN_SIZE) {
+ size = NJS_CHB_MIN_SIZE;
+ }
+
+ n = njs_mp_alloc(chain->pool, sizeof(njs_chb_node_t) + size);
+ if (njs_slow_path(n == NULL)) {
+ chain->error = 1;
+ return NULL;
+ }
+
+ n->next = NULL;
+ n->start = (u_char *) n + sizeof(njs_chb_node_t);
+ n->pos = n->start;
+ n->end = n->pos + size;
+
+ if (chain->last != NULL) {
+ chain->last->next = n;
+
+ } else {
+ chain->nodes = n;
+ }
+
+ chain->last = n;
+
+ return n->start;
+}
+
+
+void
+njs_chb_vsprintf(njs_chb_t *chain, size_t size, const char *fmt, va_list args)
+{
+ u_char *start, *end;
+
+ start = njs_chb_reserve(chain, size);
+ if (njs_slow_path(start == NULL)) {
+ return;
+ }
+
+ end = njs_vsprintf(start, start + size, fmt, args);
+
+ njs_chb_written(chain, end - start);
+}
+
+
+void
+njs_chb_sprintf(njs_chb_t *chain, size_t size, const char* fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+
+ njs_chb_vsprintf(chain, size, fmt, args);
+
+ va_end(args);
+}
+
+
+/*
+ * Drains size bytes from the beginning of the chain.
+ */
+void
+njs_chb_drain(njs_chb_t *chain, size_t drain)
+{
+ njs_chb_node_t *n;
+
+ n = chain->nodes;
+
+ while (n != NULL) {
+ if (njs_chb_node_size(n) > drain) {
+ n->start += drain;
+ return;
+ }
+
+ drain -= njs_chb_node_size(n);
+ chain->nodes = n->next;
+
+ njs_mp_free(chain->pool, n);
+ n = chain->nodes;
+ }
+
+ chain->last = NULL;
+}
+
+
+/*
+ * Drops size bytes from the end of the chain.
+ */
+void
+njs_chb_drop(njs_chb_t *chain, size_t drop)
+{
+ size_t size;
+ njs_chb_node_t *n, *next;
+
+ n = chain->last;
+
+ if (njs_fast_path(n != NULL && (njs_chb_node_size(n) > drop))) {
+ n->pos -= drop;
+ return;
+ }
+
+ n = chain->nodes;
+ size = njs_chb_size(chain);
+
+ if (drop >= size) {
+ njs_chb_destroy(chain);
+ njs_chb_init(chain, chain->pool);
+ return;
+ }
+
+ while (n != NULL) {
+ size -= njs_chb_node_size(n);
+
+ if (size <= drop) {
+ chain->last = n;
+ chain->last->pos -= drop - size;
+
+ n = chain->last->next;
+ chain->last->next = NULL;
+
+ break;
+ }
+
+ n = n->next;
+ }
+
+ while (n != NULL) {
+ next = n->next;
+ njs_mp_free(chain->pool, n);
+ n = next;
+ }
+}
+
+
+njs_int_t
+njs_chb_join(njs_chb_t *chain, njs_str_t *str)
+{
+ u_char *start;
+ size_t size;
+ njs_chb_node_t *n;
+
+ if (chain->error) {
+ return NJS_DECLINED;
+ }
+
+ n = chain->nodes;
+
+ if (n == NULL) {
+ str->length = 0;
+ str->start = NULL;
+ return NJS_OK;
+ }
+
+ size = njs_chb_size(chain);
+
+ start = njs_mp_alloc(chain->pool, size);
+ if (njs_slow_path(start == NULL)) {
+ return NJS_ERROR;
+ }
+
+ n = chain->nodes;
+ str->length = size;
+ str->start = start;
+
+ njs_chb_join_to(chain, start);
+
+ return NJS_OK;
+}
+
+
+void
+njs_chb_join_to(njs_chb_t *chain, u_char *dst)
+{
+ njs_chb_node_t *n;
+
+ n = chain->nodes;
+
+ while (n != NULL) {
+ dst = njs_cpymem(dst, n->start, njs_chb_node_size(n));
+ n = n->next;
+ }
+}
+
+
+void
+njs_chb_destroy(njs_chb_t *chain)
+{
+ njs_chb_node_t *n, *next;
+
+ n = chain->nodes;
+
+ while (n != NULL) {
+ next = n->next;
+ njs_mp_free(chain->pool, n);
+ n = next;
+ }
+}
diff -r 3bef40125db2 -r 5ba9145d9b0c src/njs_chb.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/njs_chb.h Wed Dec 11 15:30:26 2019 +0300
@@ -0,0 +1,114 @@
+
+/*
+ * Copyright (C) Dmitry Volyntsev
+ * Copyright (C) NGINX, Inc.
+ */
+
+#ifndef _NJS_CHB_H_INCLUDED_
+#define _NJS_CHB_H_INCLUDED_
+
+
+typedef struct njs_chb_node_s njs_chb_node_t;
+
+struct njs_chb_node_s {
+ njs_chb_node_t *next;
+ u_char *start;
+ u_char *pos;
+ u_char *end;
+};
+
+typedef struct {
+ njs_bool_t error;
+ njs_mp_t *pool;
+ njs_chb_node_t *nodes;
+ njs_chb_node_t *last;
+} njs_chb_t;
+
+
+void njs_chb_append0(njs_chb_t *chain, const char *msg, size_t len);
+void njs_chb_vsprintf(njs_chb_t *chain, size_t size, const char *fmt,
+ va_list args);
+void njs_chb_sprintf(njs_chb_t *chain, size_t size, const char* fmt, ...);
+u_char *njs_chb_reserve(njs_chb_t *chain, size_t size);
+void njs_chb_drain(njs_chb_t *chain, size_t drop);
+void njs_chb_drop(njs_chb_t *chain, size_t drop);
+njs_int_t njs_chb_join(njs_chb_t *chain, njs_str_t *str);
+void njs_chb_join_to(njs_chb_t *chain, u_char *dst);
+void njs_chb_destroy(njs_chb_t *chain);
+
+
+#define njs_chb_append(chain, msg, len) \
+ njs_chb_append0(chain, (const char *) msg, len)
+
+#define njs_chb_append_literal(chain, literal) \
+ njs_chb_append0(chain, literal, njs_length(literal))
+
+#define njs_chb_append_str(chain, str) \
+ njs_chb_append0(chain, (const char *) (str)->start, (str)->length)
+
+
+#define njs_chb_node_size(n) (size_t) ((n)->pos - (n)->start)
+#define njs_chb_node_room(n) (size_t) ((n)->end - (n)->pos)
+
+
+njs_inline void
+njs_chb_init(njs_chb_t *chain, njs_mp_t *pool)
+{
+ chain->error = 0;
+ chain->pool = pool;
+ chain->nodes = NULL;
+ chain->last = NULL;
+}
+
+
+njs_inline size_t
+njs_chb_size(njs_chb_t *chain)
+{
+ size_t size;
+ njs_chb_node_t *n;
+
+ n = chain->nodes;
+
+ size = 0;
+
+ while (n != NULL) {
+ size += njs_chb_node_size(n);
+ n = n->next;
+ }
+
+ return size;
+}
+
+
+njs_inline ssize_t
+njs_chb_utf8_length(njs_chb_t *chain)
+{
+ ssize_t len, length;
+ njs_chb_node_t *n;
+
+ n = chain->nodes;
+
+ length = 0;
+
+ while (n != NULL) {
+ len = njs_utf8_length(n->start, njs_chb_node_size(n));
+ if (njs_slow_path(len < 0)) {
+ return len;
+ }
+
+ length += len;
+ n = n->next;
+ }
+
+ return length;
+}
+
+
+njs_inline void
+njs_chb_written(njs_chb_t *chain, size_t bytes)
+{
+ chain->last->pos += bytes;
+}
+
+
+#endif /* _NJS_JSON_H_INCLUDED_ */
diff -r 3bef40125db2 -r 5ba9145d9b0c src/njs_json.c
--- a/src/njs_json.c Wed Nov 27 14:02:04 2019 +0000
+++ b/src/njs_json.c Wed Dec 11 15:30:26 2019 +0300
@@ -44,23 +44,10 @@ typedef struct {
} njs_json_parse_t;


-typedef struct njs_chb_node_s njs_chb_node_t;
-
-struct njs_chb_node_s {
- njs_chb_node_t *next;
- u_char *start;
- u_char *pos;
- u_char *end;
-};
-
-
typedef struct {
njs_value_t retval;

njs_vm_t *vm;
- njs_mp_t *pool;
- njs_chb_node_t *nodes;
- njs_chb_node_t *last;

njs_uint_t depth;
njs_json_state_t states[NJS_JSON_MAX_DEPTH];
@@ -104,33 +91,15 @@ static njs_int_t njs_json_stringify_repl
static njs_int_t njs_json_stringify_array(njs_vm_t *vm,
njs_json_stringify_t *stringify);

-static njs_int_t njs_json_append_value(njs_json_stringify_t *stringify,
- const njs_value_t *value);
-static njs_int_t njs_json_append_string(njs_json_stringify_t *stringify,
- const njs_value_t *value, char quote);
-static njs_int_t njs_json_append_number(njs_json_stringify_t *stringify,
- const njs_value_t *value);
+static void njs_json_append_value(njs_chb_t *chain, const njs_value_t *value);
+static void njs_json_append_string(njs_chb_t *chain, const njs_value_t *value,
+ char quote);
+static void njs_json_append_number(njs_chb_t *chain, const njs_value_t *value);

static njs_object_t *njs_json_wrap_value(njs_vm_t *vm, njs_value_t *wrapper,
const njs_value_t *value);


-#define NJS_JSON_BUF_MIN_SIZE 128
-
-#define njs_json_buf_written(stringify, bytes) \
- (stringify)->last->pos += (bytes);
-
-#define njs_json_buf_node_size(n) (size_t) ((n)->pos - (n)->start)
-#define njs_json_buf_node_room(n) (size_t) ((n)->end - (n)->pos)
-
-static njs_int_t njs_json_buf_append(njs_json_stringify_t *stringify,
- const char *msg, size_t len);
-static u_char *njs_json_buf_reserve(njs_json_stringify_t *stringify,
- size_t size);
-static njs_int_t njs_json_buf_pullup(njs_json_stringify_t *stringify,
- njs_str_t *str);
-
-
static const njs_object_prop_t njs_json_object_properties[];


@@ -224,10 +193,7 @@ njs_json_stringify(njs_vm_t *vm, njs_val
stringify = &json_stringify;

stringify->vm = vm;
- stringify->pool = vm->mem_pool;
stringify->depth = 0;
- stringify->nodes = NULL;
- stringify->last = NULL;
stringify->keys_type = NJS_ENUM_STRING;

replacer = njs_arg(args, nargs, 2);
@@ -1129,43 +1095,24 @@ njs_json_pop_stringify_state(njs_json_st
|| ((value)->type >= NJS_REGEXP))


-#define njs_json_stringify_append(str, len) \
- ret = njs_json_buf_append(stringify, (char *) str, len); \
- if (ret != NJS_OK) { \
- goto memory_error; \
- }
-
-
#define njs_json_stringify_indent(times) \
if (stringify->space.length != 0) { \
- njs_json_stringify_append("\n", 1); \
+ njs_chb_append(&chain,"\n", 1); \
for (i = 0; i < (njs_int_t) (times) - 1; i++) { \
- njs_json_stringify_append(stringify->space.start, \
- stringify->space.length); \
+ njs_chb_append_str(&chain, &stringify->space); \
} \
}

-#define njs_json_stringify_append_value(value) \
- ret = njs_json_append_value(stringify, value); \
- if (njs_slow_path(ret != NJS_OK)) { \
- if (ret == NJS_DECLINED) { \
- return NJS_ERROR; \
- } \
- \
- goto memory_error; \
- }
-
-
static njs_int_t
njs_json_stringify_iterator(njs_vm_t *vm, njs_json_stringify_t *stringify,
njs_value_t *object)
{
- u_char *start;
+ u_char *p;
size_t size;
+ njs_chb_t chain;
ssize_t length;
njs_int_t i;
njs_int_t ret;
- njs_str_t str;
njs_value_t *key, *value, wrapper;
njs_object_t *obj;
njs_json_state_t *state;
@@ -1180,17 +1127,19 @@ njs_json_stringify_iterator(njs_vm_t *vm
goto memory_error;
}

+ njs_chb_init(&chain, vm->mem_pool);
+
for ( ;; ) {
switch (state->type) {
case NJS_JSON_OBJECT:
if (state->index == 0) {
- njs_json_stringify_append("{", 1);
+ njs_chb_append_literal(&chain,"{");
njs_json_stringify_indent(stringify->depth);
}

if (state->index >= state->keys->length) {
njs_json_stringify_indent(stringify->depth - 1);
- njs_json_stringify_append("}", 1);
+ njs_chb_append_literal(&chain,"}");

state = njs_json_pop_stringify_state(stringify);
if (state == NULL) {
@@ -1226,15 +1175,15 @@ njs_json_stringify_iterator(njs_vm_t *vm
}

if (state->written) {
- njs_json_stringify_append(",", 1);
+ njs_chb_append_literal(&chain,",");
njs_json_stringify_indent(stringify->depth);
}

state->written = 1;
- njs_json_append_string(stringify, key, '\"');
- njs_json_stringify_append(":", 1);
+ njs_json_append_string(&chain, key, '\"');
+ njs_chb_append_literal(&chain,":");
if (stringify->space.length != 0) {
- njs_json_stringify_append(" ", 1);
+ njs_chb_append_literal(&chain," ");
}

if (njs_json_is_object(value)) {
@@ -1246,19 +1195,19 @@ njs_json_stringify_iterator(njs_vm_t *vm
break;
}

- njs_json_stringify_append_value(value);
+ njs_json_append_value(&chain, value);

break;

case NJS_JSON_ARRAY:
if (state->index == 0) {
- njs_json_stringify_append("[", 1);
+ njs_chb_append_literal(&chain,"[");
njs_json_stringify_indent(stringify->depth);
}

if (state->index >= njs_array_len(&state->value)) {
njs_json_stringify_indent(stringify->depth - 1);
- njs_json_stringify_append("]", 1);
+ njs_chb_append_literal(&chain,"]");

state = njs_json_pop_stringify_state(stringify);
if (state == NULL) {
@@ -1269,7 +1218,7 @@ njs_json_stringify_iterator(njs_vm_t *vm
}

if (state->written) {
- njs_json_stringify_append(",", 1);
+ njs_chb_append_literal(&chain,",");
njs_json_stringify_indent(stringify->depth);
}

@@ -1296,7 +1245,7 @@ njs_json_stringify_iterator(njs_vm_t *vm
}

state->written = 1;
- njs_json_stringify_append_value(value);
+ njs_json_append_value(&chain, value);

break;
}
@@ -1304,43 +1253,40 @@ njs_json_stringify_iterator(njs_vm_t *vm

done:

- ret = njs_json_buf_pullup(stringify, &str);
- if (njs_slow_path(ret != NJS_OK)) {
- goto memory_error;
- }
-
/*
* The value to stringify is wrapped as '{"": value}'.
- * An empty object means empty result.
+ * Stripping the wrapper's data.
*/
- if (str.length <= njs_length("{\n\n}")) {
+
+ njs_chb_drain(&chain, njs_length("{\"\":"));
+ njs_chb_drop(&chain, njs_length("}"));
+
+ if (stringify->space.length != 0) {
+ njs_chb_drain(&chain, njs_length("\n "));
+ njs_chb_drop(&chain, njs_length("\n"));
+ }
+
+ size = njs_chb_size(&chain);
+ if (njs_slow_path(size == 0)) {
njs_set_undefined(&vm->retval);
goto release;
}

- /* Stripping the wrapper's data. */
-
- start = str.start + njs_length("{\"\":");
- size = str.length - njs_length("{\"\":}");
-
- if (stringify->space.length != 0) {
- start += njs_length("\n ");
- size -= njs_length("\n \n");
- }
-
- length = njs_utf8_length(start, size);
+ length = njs_chb_utf8_length(&chain);
if (njs_slow_path(length < 0)) {
length = 0;
}

- ret = njs_string_new(vm, &vm->retval, start, size, length);
- if (njs_slow_path(ret != NJS_OK)) {
+ p = njs_string_alloc(vm, &vm->retval, size, length);
+ if (njs_slow_path(p == NULL)) {
goto memory_error;
}

+ njs_chb_join_to(&chain, p);
+
release:

- njs_mp_free(vm->mem_pool, str.start);
+ njs_chb_destroy(&chain);

return NJS_OK;

@@ -1521,8 +1467,8 @@ njs_json_stringify_array(njs_vm_t *vm, n
}


-static njs_int_t
-njs_json_append_value(njs_json_stringify_t *stringify, const njs_value_t *value)
+static void
+njs_json_append_value(njs_chb_t *chain, const njs_value_t *value)
{
switch (value->type) {
case NJS_OBJECT_STRING:
@@ -1530,14 +1476,16 @@ njs_json_append_value(njs_json_stringify
/* Fall through. */

case NJS_STRING:
- return njs_json_append_string(stringify, value, '\"');
+ njs_json_append_string(chain, value, '\"');
+ break;

case NJS_OBJECT_NUMBER:
value = njs_object_value(value);
/* Fall through. */

case NJS_NUMBER:
- return njs_json_append_number(stringify, value);
+ njs_json_append_number(chain, value);
+ break;

case NJS_OBJECT_BOOLEAN:
value = njs_object_value(value);
@@ -1545,26 +1493,27 @@ njs_json_append_value(njs_json_stringify

case NJS_BOOLEAN:
if (njs_is_true(value)) {
- return njs_json_buf_append(stringify, "true", 4);
+ njs_chb_append_literal(chain, "true");

} else {
- return njs_json_buf_append(stringify, "false", 5);
+ njs_chb_append_literal(chain, "false");
}

+ break;
+
case NJS_UNDEFINED:
case NJS_NULL:
case NJS_SYMBOL:
case NJS_INVALID:
case NJS_FUNCTION:
default:
- return njs_json_buf_append(stringify, "null", 4);
+ njs_chb_append_literal(chain, "null");
}
}


-static njs_int_t
-njs_json_append_string(njs_json_stringify_t *stringify,
- const njs_value_t *value, char quote)
+static void
+njs_json_append_string(njs_chb_t *chain, const njs_value_t *value, char quote)
{
u_char c, *dst, *dst_end;
size_t length;
@@ -1580,12 +1529,12 @@ njs_json_append_string(njs_json_stringif
end = p + str.size;
length = str.length;

- dst = njs_json_buf_reserve(stringify, 64);
+ dst = njs_chb_reserve(chain, length + 2);
if (njs_slow_path(dst == NULL)) {
- return NJS_ERROR;
+ return;
}

- dst_end = dst + 64;
+ dst_end = dst + length + 2;

*dst++ = quote;

@@ -1651,26 +1600,25 @@ njs_json_append_string(njs_json_stringif
}

if (dst_end - dst <= 6) {
- njs_json_buf_written(stringify, dst - stringify->last->pos);
-
- dst = njs_json_buf_reserve(stringify, 64);
+ njs_chb_written(chain, dst - chain->last->pos);
+
+ dst = njs_chb_reserve(chain, 64);
if (njs_slow_path(dst == NULL)) {
- return NJS_ERROR;
+ return;
}

dst_end = dst + 64;
}
}

- njs_json_buf_written(stringify, dst - stringify->last->pos);
-
- return njs_json_buf_append(stringify, &quote, 1);
+ njs_chb_written(chain, dst - chain->last->pos);
+
+ njs_chb_append(chain, &quote, 1);
}


-static njs_int_t
-njs_json_append_number(njs_json_stringify_t *stringify,
- const njs_value_t *value)
+static void
+njs_json_append_number(njs_chb_t *chain, const njs_value_t *value)
{
u_char *p;
size_t size;
@@ -1679,20 +1627,18 @@ njs_json_append_number(njs_json_stringif
num = njs_number(value);

if (isnan(num) || isinf(num)) {
- return njs_json_buf_append(stringify, "null", 4);
+ njs_chb_append_literal(chain, "null");

} else {
- p = njs_json_buf_reserve(stringify, 64);
+ p = njs_chb_reserve(chain, 64);
if (njs_slow_path(p == NULL)) {
- return NJS_ERROR;
+ return;
}

size = njs_dtoa(num, (char *) p);

- njs_json_buf_written(stringify, size);
+ njs_chb_written(chain, size);
}
-
- return NJS_OK;
}


@@ -1737,117 +1683,6 @@ njs_json_wrap_value(njs_vm_t *vm, njs_va
}


-static njs_int_t
-njs_json_buf_append(njs_json_stringify_t *stringify, const char *msg,
- size_t len)
-{
- u_char *p;
-
- if (len != 0) {
- p = njs_json_buf_reserve(stringify, len);
- if (njs_slow_path(p == NULL)) {
- return NJS_ERROR;
- }
-
- memcpy(p, msg, len);
-
- njs_json_buf_written(stringify, len);
- }
-
- return NJS_OK;
-}
-
-
-static u_char *
-njs_json_buf_reserve(njs_json_stringify_t *stringify, size_t size)
-{
- njs_chb_node_t *n;
-
- if (njs_slow_path(size == 0)) {
- return NULL;
- }
-
- n = stringify->last;
-
- if (njs_fast_path(n != NULL && njs_json_buf_node_room(n) >= size)) {
- return n->pos;
- }
-
- if (size < NJS_JSON_BUF_MIN_SIZE) {
- size = NJS_JSON_BUF_MIN_SIZE;
- }
-
- n = njs_mp_alloc(stringify->pool, sizeof(njs_chb_node_t) + size);
- if (njs_slow_path(n == NULL)) {
- return NULL;
- }
-
- n->next = NULL;
- n->start = (u_char *) n + sizeof(njs_chb_node_t);
- n->pos = n->start;
- n->end = n->pos + size;
-
- if (stringify->last != NULL) {
- stringify->last->next = n;
-
- } else {
- stringify->nodes = n;
- }
-
- stringify->last = n;
-
- return n->start;
-}
-
-
-static njs_int_t
-njs_json_buf_pullup(njs_json_stringify_t *stringify, njs_str_t *str)
-{
- u_char *start;
- size_t size;
- njs_chb_node_t *n;
-
- n = stringify->nodes;
-
- if (n == NULL) {
- str->length = 0;
- str->start = NULL;
- return NJS_OK;
- }
-
- if (n->next == NULL) {
- str->length = njs_json_buf_node_size(n);
- str->start = n->start;
- return NJS_OK;
- }
-
- size = 0;
-
- while (n != NULL) {
- size += njs_json_buf_node_size(n);
- n = n->next;
- }
-
- start = njs_mp_alloc(stringify->pool, size);
- if (njs_slow_path(start == NULL)) {
- return NJS_ERROR;
- }
-
- n = stringify->nodes;
- str->length = size;
- str->start = start;
-
- while (n != NULL) {
- size = njs_json_buf_node_size(n);
- memcpy(start, n->start, size);
- start += size;
- n = n->next;
- }
-
- return NJS_OK;
-}
-
-
static const njs_object_prop_t njs_json_object_properties[] =
{
{
@@ -1881,22 +1716,13 @@ const njs_object_init_t njs_json_object
};


-#define njs_dump(str) \
- ret = njs_json_buf_append(stringify, str, njs_length(str)); \
- if (njs_slow_path(ret != NJS_OK)) { \
- goto memory_error; \
- }
-
-
static njs_int_t
-njs_dump_value(njs_json_stringify_t *stringify, const njs_value_t *value,
- njs_uint_t console)
+njs_dump_value(njs_json_stringify_t *stringify, njs_chb_t *chain,
+ const njs_value_t *value, njs_uint_t console)
{
- u_char *p;
+ njs_str_t str;
njs_int_t ret;
- njs_str_t str;
njs_value_t str_val;
- u_char buf[32];

njs_int_t (*to_string)(njs_vm_t *, njs_value_t *, const njs_value_t *);

@@ -1904,26 +1730,20 @@ njs_dump_value(njs_json_stringify_t *str
case NJS_OBJECT_STRING:
value = njs_object_value(value);

- njs_string_get(value, &str);
-
- njs_dump("[String: ");
-
- ret = njs_json_append_string(stringify, value, '\'');
- if (njs_slow_path(ret != NJS_OK)) {
- goto memory_error;
- }
-
- njs_dump("]");
+ njs_chb_append_literal(chain, "[String: ");
+ njs_json_append_string(chain, value, '\'');
+ njs_chb_append_literal(chain, "]");
break;

case NJS_STRING:
njs_string_get(value, &str);

if (!console || stringify->depth != 0) {
- return njs_json_append_string(stringify, value, '\'');
+ njs_json_append_string(chain, value, '\'');
+ return NJS_OK;
}

- return njs_json_buf_append(stringify, (char *) str.start, str.length);
+ njs_chb_append_str(chain, &str);

break;

@@ -1936,15 +1756,7 @@ njs_dump_value(njs_json_stringify_t *str
}

njs_string_get(&str_val, &str);
-
- njs_dump("[Symbol: ");
-
- ret = njs_json_buf_append(stringify, (char *) str.start, str.length);
- if (njs_slow_path(ret != NJS_OK)) {
- goto memory_error;
- }
-
- njs_dump("]");
+ njs_chb_sprintf(chain, 16 + str.length, "[Symbol: %V]", &str);

break;

@@ -1955,11 +1767,7 @@ njs_dump_value(njs_json_stringify_t *str
}

njs_string_get(&str_val, &str);
-
- ret = njs_json_buf_append(stringify, (char *) str.start, str.length);
- if (njs_slow_path(ret != NJS_OK)) {
- goto memory_error;
- }
+ njs_chb_append_str(chain, &str);

break;

@@ -1970,7 +1778,7 @@ njs_dump_value(njs_json_stringify_t *str
&& signbit(njs_number(value))))
{

- njs_dump("[Number: -0]");
+ njs_chb_append_literal(chain, "[Number: -0]");
break;
}
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[njs] Introduced generic string builder API.

Dmitry Volyntsev 261 December 11, 2019 08:00AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 295
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready