data tree CHANGE remove lprev and lnext pointers in list and leaflist instances
save memory in cost of some additional time when going through the data tree.
diff --git a/src/printer_json.c b/src/printer_json.c
index f597bbb..6e2b4c1 100644
--- a/src/printer_json.c
+++ b/src/printer_json.c
@@ -34,7 +34,7 @@
#define INDENT ""
#define LEVEL (level*2)
-void json_print_node(FILE *f, int level, struct lyd_node *node);
+void json_print_nodes(FILE *f, int level, struct lyd_node *root);
/* 0 - same, 1 - different */
static int
@@ -122,9 +122,6 @@
fprintf(f, "\"(!error!)\"");
}
- if (!onlyvalue) {
- fprintf(f, "%s\n", lyd_is_last(node) ? "" : ",");
- }
return;
}
@@ -132,7 +129,6 @@
json_print_container(FILE *f, int level, struct lyd_node *node)
{
const char *schema;
- struct lyd_node *child;
if (!node->parent || nscmp(node, node->parent)) {
/* print "namespace" */
@@ -146,37 +142,15 @@
} else {
fprintf(f, "%*s\"%s\": {\n", LEVEL, INDENT, node->schema->name);
}
- LY_TREE_FOR(node->child, child) {
- json_print_node(f, level + 1, child);
- }
- fprintf(f, "%*s}%s\n", LEVEL, INDENT, lyd_is_last(node) ? "" : ",");
-}
-
-static void
-json_print_list_internal(FILE *f, int level, struct lyd_node_list *list)
-{
- struct lyd_node *child;
-
- fprintf(f, "%*s{\n", LEVEL, INDENT);
-
- LY_TREE_FOR(list->child, child) {
- json_print_node(f, level + 1, child);
- }
-
- fprintf(f, "%*s}%s\n", LEVEL, INDENT, (list->lnext ? "," : ""));
+ json_print_nodes(f, level + 1, node->child);
+ fprintf(f, "%*s}", LEVEL, INDENT);
}
static void
json_print_leaf_list(FILE *f, int level, struct lyd_node *node, int is_list)
{
const char *schema;
- struct lyd_node_list *list = (struct lyd_node_list *)node;
- struct lyd_node_leaflist *llist = (struct lyd_node_leaflist *)node;
-
- if ((is_list && list->lprev) || (!is_list && llist->lprev)) {
- /* this list is already printed */
- return;
- }
+ struct lyd_node *list = node;
if (!node->parent || nscmp(node, node->parent)) {
/* print "namespace" */
@@ -194,70 +168,107 @@
if (!is_list) {
++level;
}
- while ((is_list && list) || (!is_list && llist)) {
+
+ while (list) {
if (is_list) {
- json_print_list_internal(f, level + 1, list);
- list = list->lnext;
+ /* list print */
+ ++level;
+ fprintf(f, "%*s{\n", LEVEL, INDENT);
+ json_print_nodes(f, level + 1, list->child);
+ fprintf(f, "%*s}", LEVEL, INDENT);
+ --level;
} else {
+ /* leaf-list print */
fprintf(f, "%*s", LEVEL, INDENT);
- json_print_leaf(f, level, (struct lyd_node *)llist, 1);
- fprintf(f, "%s\n", (llist->lnext ? "," : ""));
- llist = llist->lnext;
+ json_print_leaf(f, level, list, 1);
+ }
+ for (list = list->next; list && list->schema != node->schema; list = list->next);
+ if (list) {
+ fprintf(f, ",\n");
}
}
+
if (!is_list) {
--level;
}
- fprintf(f, "%*s]%s\n", LEVEL, INDENT, lyd_is_last(node) ? "" : ",");
+ fprintf(f, "\n%*s]", LEVEL, INDENT);
}
static void
json_print_anyxml(FILE *f, int level, struct lyd_node *node)
{
- struct lyd_node_anyxml *axml = (struct lyd_node_anyxml *)node;
-
- fprintf(f, "%*s\"%s\": [null]%s\n", LEVEL, INDENT, axml->value->name, lyd_is_last(node) ? "" : ",");
+ fprintf(f, "%*s\"%s\": [null]", LEVEL, INDENT, node->schema->name);
}
void
-json_print_node(FILE *f, int level, struct lyd_node *node)
+json_print_nodes(FILE *f, int level, struct lyd_node *root)
{
- switch (node->schema->nodetype) {
- case LYS_CONTAINER:
- json_print_container(f, level, node);
- break;
- case LYS_LEAF:
- json_print_leaf(f, level, node, 0);
- break;
- case LYS_LEAFLIST:
- json_print_leaf_list(f, level, node, 0);
- break;
- case LYS_LIST:
- json_print_leaf_list(f, level, node, 1);
- break;
- case LYS_ANYXML:
- json_print_anyxml(f, level, node);
- break;
- default:
- LOGINT;
- break;
+ struct lyd_node *node, *iter;
+
+ LY_TREE_FOR(root, node) {
+ switch (node->schema->nodetype) {
+ case LYS_CONTAINER:
+ if (node->prev->next) {
+ /* print the previous comma */
+ fprintf(f, ",\n");
+ }
+ json_print_container(f, level, node);
+ break;
+ case LYS_LEAF:
+ if (node->prev->next) {
+ /* print the previous comma */
+ fprintf(f, ",\n");
+ }
+ json_print_leaf(f, level, node, 0);
+ break;
+ case LYS_LEAFLIST:
+ case LYS_LIST:
+ /* is it already printed? */
+ for (iter = node; iter->prev->next; iter = iter->prev) {
+ if (iter == node) {
+ continue;
+ }
+ if (iter->schema == node->schema) {
+ /* the list has alread some previous instance and therefore it is already printed */
+ break;
+ }
+ }
+ if (!iter->prev->next) {
+ if (node->prev->next) {
+ /* print the previous comma */
+ fprintf(f, ",\n");
+ }
+
+ /* print the list/leaflist */
+ json_print_leaf_list(f, level, node, node->schema->nodetype == LYS_LIST ? 1 : 0);
+ }
+ break;
+ case LYS_ANYXML:
+ if (node->prev->next) {
+ /* print the previous comma */
+ fprintf(f, ",\n");
+ }
+ json_print_anyxml(f, level, node);
+ break;
+ default:
+ LOGINT;
+ break;
+ }
}
+ fprintf(f, "\n");
}
API int
json_print_data(FILE *f, struct lyd_node *root)
{
int level = 0;
- struct lyd_node *node;
/* start */
fprintf(f, "{\n");
/* content */
- LY_TREE_FOR(root, node) {
- json_print_node(f, level + 1, node);
- }
+ json_print_nodes(f, level + 1, root);
/* end */
fprintf(f, "}\n");