data tree NEW lyd_new, lyd_new_leaf_str, lyd_new_leaf_val implementation
lyd_new_anyxml not implemented yet.
diff --git a/src/tree_data.c b/src/tree_data.c
index c75c223..3fa856f 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -29,6 +29,7 @@
#include "common.h"
#include "context.h"
+#include "tree_data.h"
#include "parser.h"
#include "resolve.h"
#include "xml.h"
@@ -55,6 +56,310 @@
return NULL;
}
+API struct lyd_node *
+lyd_new(struct lyd_node *parent, struct lys_module *module, const char *name)
+{
+ struct lyd_node *ret;
+ struct lys_node *snode = NULL, *siblings;
+
+ if ((!parent && !module) || !name) {
+ ly_errno = LY_EINVAL;
+ return NULL;
+ }
+
+ if (!parent) {
+ siblings = module->data;
+ } else {
+ siblings = parent->child->schema;
+ }
+
+ if (resolve_sibling(module, siblings, NULL, 0, name, strlen(name), LYS_CONTAINER | LYS_INPUT | LYS_OUTPUT
+ | LYS_NOTIF | LYS_RPC, &snode) || !snode) {
+ return NULL;
+ }
+
+ ret = calloc(1, sizeof *ret);
+ ret->schema = snode;
+ ret->prev = ret;
+ if (parent) {
+ if (lyd_insert(parent, ret, 0)) {
+ free(ret);
+ return NULL;
+ }
+ }
+
+ return ret;
+}
+
+API struct lyd_node *
+lyd_new_leaf_val(struct lyd_node *parent, struct lys_module *module, const char *name, LY_DATA_TYPE type,
+ lyd_val *value)
+{
+ struct lyd_node_leaf_list *ret;
+ struct lys_node *snode = NULL, *siblings;
+ struct lys_type *stype;
+ struct lys_module *src_mod, *dst_mod;
+ char *val_str = NULL, str_num[22];
+ const char *prefix;
+ int i, str_len = 0, prev_len;
+ uint64_t exp;
+
+ if ((!parent && !module) || !name || ((type != LY_TYPE_EMPTY) && !value)) {
+ ly_errno = LY_EINVAL;
+ return NULL;
+ }
+
+ if (!parent) {
+ siblings = module->data;
+ } else {
+ siblings = parent->child->schema;
+ }
+
+ if (resolve_sibling(module, siblings, NULL, 0, name, strlen(name), LYS_LEAFLIST | LYS_LEAF, &snode)
+ || !snode) {
+ return NULL;
+ }
+
+ switch (type) {
+ case LY_TYPE_BINARY:
+ val_str = (char *)lydict_insert(snode->module->ctx, value->binary, 0);
+ break;
+
+ case LY_TYPE_BITS:
+ /* find the type definition */
+ for (stype = &((struct lys_node_leaf *)snode)->type; stype->der->module; stype = &stype->der->type) {
+ if (stype->base != LY_TYPE_BITS) {
+ LOGINT;
+ return NULL;
+ }
+ }
+
+ /* concatenate set bits */
+ for (i = 0; i < stype->info.bits.count; ++i) {
+ if (!value->bit[i]) {
+ continue;
+ }
+
+ prev_len = str_len;
+ str_len += strlen(value->bit[i]->name) + 1;
+ val_str = realloc((char *)val_str, str_len * sizeof(char));
+
+ if (prev_len) {
+ val_str[prev_len] = ' ';
+ ++prev_len;
+ }
+ strcpy(val_str + prev_len, value->bit[i]->name);
+ }
+
+ val_str = (char *)lydict_insert_zc(snode->module->ctx, val_str);
+ break;
+
+ case LY_TYPE_BOOL:
+ if (value->bool) {
+ val_str = (char *)lydict_insert(snode->module->ctx, "true", 4);
+ } else {
+ val_str = (char *)lydict_insert(snode->module->ctx, "false", 5);
+ }
+ break;
+
+ case LY_TYPE_DEC64:
+ /* find the type definition */
+ for (stype = &((struct lys_node_leaf *)snode)->type; stype->der->module; stype = &stype->der->type) {
+ if (stype->base != LY_TYPE_DEC64) {
+ LOGINT;
+ return NULL;
+ }
+ }
+
+ for (i = 0, exp = 1; i < stype->info.dec64.dig; ++i, exp *= 10);
+ sprintf(str_num, "%01.1Lf", ((long double)value->dec64) / exp);
+ val_str = (char *)lydict_insert(snode->module->ctx, str_num, 0);
+ break;
+
+ case LY_TYPE_EMPTY:
+ break;
+
+ case LY_TYPE_ENUM:
+ val_str = (char *)lydict_insert(snode->module->ctx, value->enm->name, 0);
+ break;
+
+ case LY_TYPE_IDENT:
+ /* TODO move to function if used somewhere else (module -> import prefix) */
+ src_mod = value->ident->module;
+ if (src_mod->type) {
+ src_mod = ((struct lys_submodule *)src_mod)->belongsto;
+ }
+ dst_mod = snode->module;
+ if (dst_mod->type) {
+ dst_mod = ((struct lys_submodule *)dst_mod)->belongsto;
+ }
+ if (src_mod != dst_mod) {
+ for (i = 0; i < src_mod->imp_size; ++i) {
+ if (src_mod->imp[i].module == dst_mod) {
+ prefix = src_mod->imp[i].prefix;
+ break;
+ }
+ }
+ if (!prefix) {
+ LOGINT;
+ return NULL;
+ }
+ } else {
+ prefix = NULL;
+ }
+
+ if (!prefix) {
+ val_str = (char *)lydict_insert(snode->module->ctx, value->ident->name, 0);
+ } else {
+ val_str = malloc((strlen(prefix) + 1 + strlen(value->ident->name) + 1) * sizeof(char));
+ sprintf(val_str, "%s:%s", prefix, value->ident->name);
+ val_str = (char *)lydict_insert_zc(snode->module->ctx, val_str);
+ }
+ break;
+
+ case LY_TYPE_INST:
+ /* TODO */
+ break;
+
+ case LY_TYPE_LEAFREF:
+ val_str = (char *)lydict_insert(snode->module->ctx, ((struct lyd_node_leaf_list *)value->leafref)->value_str, 0);
+ break;
+
+ case LY_TYPE_STRING:
+ val_str = (char *)lydict_insert(snode->module->ctx, value->string, 0);
+ break;
+
+ case LY_TYPE_INT8:
+ sprintf(str_num, "%hhd", value->int8);
+ val_str = (char *)lydict_insert(snode->module->ctx, str_num, 0);
+ break;
+
+ case LY_TYPE_INT16:
+ sprintf(str_num, "%hd", value->int16);
+ val_str = (char *)lydict_insert(snode->module->ctx, str_num, 0);
+ break;
+
+ case LY_TYPE_INT32:
+ sprintf(str_num, "%d", value->int32);
+ val_str = (char *)lydict_insert(snode->module->ctx, str_num, 0);
+ break;
+
+ case LY_TYPE_INT64:
+ sprintf(str_num, "%ld", value->int64);
+ val_str = (char *)lydict_insert(snode->module->ctx, str_num, 0);
+ break;
+
+ case LY_TYPE_UINT8:
+ sprintf(str_num, "%hhu", value->uint8);
+ val_str = (char *)lydict_insert(snode->module->ctx, str_num, 0);
+ break;
+
+ case LY_TYPE_UINT16:
+ sprintf(str_num, "%hu", value->uint16);
+ val_str = (char *)lydict_insert(snode->module->ctx, str_num, 0);
+ break;
+
+ case LY_TYPE_UINT32:
+ sprintf(str_num, "%u", value->uint32);
+ val_str = (char *)lydict_insert(snode->module->ctx, str_num, 0);
+ break;
+
+ case LY_TYPE_UINT64:
+ sprintf(str_num, "%lu", value->uint64);
+ val_str = (char *)lydict_insert(snode->module->ctx, str_num, 0);
+ break;
+
+ default:
+ LOGINT;
+ return NULL;
+ }
+
+ ret = calloc(1, sizeof *ret);
+ ret->schema = snode;
+ ret->prev = (struct lyd_node *)ret;
+ if (parent) {
+ if (lyd_insert(parent, (struct lyd_node *)ret, 0)) {
+ free(ret);
+ lydict_remove(snode->module->ctx, val_str);
+ return NULL;
+ }
+ }
+ ret->value = *value;
+ ret->value_str = val_str;
+ ret->value_type = type;
+
+ return (struct lyd_node *)ret;
+}
+
+API struct lyd_node *
+lyd_new_leaf_str(struct lyd_node *parent, struct lys_module *module, const char *name, LY_DATA_TYPE type,
+ const char *val_str)
+{
+ struct lyd_node_leaf_list *ret;
+ struct lys_node *snode = NULL, *siblings;
+ struct lys_type *stype, *utype;
+ int found;
+
+ if ((!parent && !module) || !name) {
+ ly_errno = LY_EINVAL;
+ return NULL;
+ }
+
+ if (!parent) {
+ siblings = module->data;
+ } else {
+ siblings = parent->child->schema;
+ }
+
+ if (resolve_sibling(module, siblings, NULL, 0, name, strlen(name), LYS_LEAFLIST | LYS_LEAF, &snode)
+ || !snode) {
+ return NULL;
+ }
+
+ ret = calloc(1, sizeof *ret);
+ ret->schema = snode;
+ ret->prev = (struct lyd_node *)ret;
+ if (parent) {
+ if (lyd_insert(parent, (struct lyd_node *)ret, 0)) {
+ free(ret);
+ return NULL;
+ }
+ }
+ ret->value_str = val_str;
+ ret->value_type = type;
+
+ /* get the correct type struct */
+ stype = &((struct lys_node_leaf *)snode)->type;
+ if (stype->base == LY_TYPE_UNION) {
+ found = 0;
+ utype = stype;
+ stype = lyp_get_next_union_type(utype, NULL, &found);
+ while (stype && (stype->base != type)) {
+ found = 0;
+ stype = lyp_get_next_union_type(utype, stype, &found);
+ }
+ if (!stype) {
+ free(ret);
+ return NULL;
+ }
+ }
+
+ if (lyp_parse_value(ret, stype, 1, NULL, 0)) {
+ free(ret);
+ return NULL;
+ }
+
+ return (struct lyd_node *)ret;
+
+}
+
+API struct lyd_node *
+lyd_new_anyxml(struct lyd_node *parent, struct lys_module *module, const char *name, const char *val_xml)
+{
+ /* TODO */
+ return NULL;
+}
+
API int
lyd_insert(struct lyd_node *parent, struct lyd_node *node, int options)
{