data parser CHANGE unify API with schema parser and use input handler
diff --git a/src/tree_data.c b/src/tree_data.c
index eceaebf..b558038 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -34,6 +34,8 @@
#include "dict.h"
#include "hash_table.h"
#include "log.h"
+#include "parser_data.h"
+#include "parser_internal.h"
#include "path.h"
#include "plugins_exts.h"
#include "plugins_exts_metadata.h"
@@ -280,98 +282,14 @@
return meta->value.realtype->plugin->print(&meta->value, LYD_JSON, json_print_get_prefix, NULL, dynamic);
}
-API struct lyd_node *
-lyd_parse_mem(struct ly_ctx *ctx, const char *data, LYD_FORMAT format, int options)
+static LYD_FORMAT
+lyd_parse_get_format(struct ly_in *in, LYD_FORMAT format)
{
- struct lyd_node *result = NULL;
-#if 0
- const char *yang_data_name = NULL;
-#endif
- LY_CHECK_ARG_RET(ctx, ctx, NULL);
-
- if ((options & LYD_OPT_PARSE_ONLY) && (options & LYD_VALOPT_MASK)) {
- LOGERR(ctx, LY_EINVAL, "Passing validation flags with LYD_OPT_PARSE_ONLY is not allowed.");
- return NULL;
- }
-
-#if 0
- if (options & LYD_OPT_RPCREPLY) {
- /* first item in trees is mandatory - the RPC/action request */
- LY_CHECK_ARG_RET(ctx, trees, LY_ARRAY_SIZE(trees) >= 1, NULL);
- if (!trees[0] || trees[0]->parent || !(trees[0]->schema->nodetype & (LYS_ACTION | LYS_LIST | LYS_CONTAINER))) {
- LOGERR(ctx, LY_EINVAL, "Data parser invalid argument trees - the first item in the array must be the RPC/action request when parsing %s.",
- lyd_parse_options_type2str(options));
- return NULL;
- }
- }
-
- if (options & LYD_OPT_DATA_TEMPLATE) {
- yang_data_name = va_arg(ap, const char *);
- }
-#endif
-
- if (!format) {
- /* TODO try to detect format from the content */
- }
-
- switch (format) {
- case LYD_XML:
- lyd_parse_xml_data(ctx, data, options, &result);
- break;
-#if 0
- case LYD_JSON:
- lyd_parse_json(ctx, data, options, trees, &result);
- break;
-#endif
- case LYD_LYB:
- lyd_parse_lyb_data(ctx, data, options, &result, NULL);
- break;
- case LYD_SCHEMA:
- LOGINT(ctx);
- break;
- }
-
- return result;
-}
-
-API struct lyd_node *
-lyd_parse_fd(struct ly_ctx *ctx, int fd, LYD_FORMAT format, int options)
-{
- struct lyd_node *result;
- size_t length;
- char *addr;
-
- LY_CHECK_ARG_RET(ctx, ctx, NULL);
- if (fd < 0) {
- LOGARG(ctx, fd);
- return NULL;
- }
-
- LY_CHECK_RET(ly_mmap(ctx, fd, &length, (void **)&addr), NULL);
- result = lyd_parse_mem(ctx, addr ? addr : "", format, options);
- if (addr) {
- ly_munmap(addr, length);
- }
-
- return result;
-}
-
-API struct lyd_node *
-lyd_parse_path(struct ly_ctx *ctx, const char *path, LYD_FORMAT format, int options)
-{
- int fd;
- struct lyd_node *result;
- size_t len;
-
- LY_CHECK_ARG_RET(ctx, ctx, path, NULL);
-
- fd = open(path, O_RDONLY);
- LY_CHECK_ERR_RET(fd == -1, LOGERR(ctx, LY_ESYS, "Opening file \"%s\" failed (%s).", path, strerror(errno)), NULL);
-
- if (!format) {
+ if (!format && in->type == LY_IN_FILEPATH) {
/* unknown format - try to detect it from filename's suffix */
- len = strlen(path);
+ const char *path = in->method.fpath.filepath;
+ size_t len = strlen(path);
/* ignore trailing whitespaces */
for (; len > 0 && isspace(path[len - 1]); len--);
@@ -381,16 +299,157 @@
#if 0
} else if (len >= 6 && !strncmp(&path[len - 5], ".json", 5)) {
format = LYD_JSON;
+#endif
} else if (len >= 5 && !strncmp(&path[len - 4], ".lyb", 4)) {
format = LYD_LYB;
-#endif
- } /* else still unknown, try later to detect it from the content */
+ } /* else still unknown */
}
- result = lyd_parse_fd(ctx, fd, format, options);
- close(fd);
+ return format;
+}
- return result;
+API LY_ERR
+lyd_parse_data(const struct ly_ctx *ctx, struct ly_in *in, LYD_FORMAT format, int parse_options, int validate_options, struct lyd_node **tree)
+{
+ LY_CHECK_ARG_RET(ctx, ctx, in, tree, LY_EINVAL);
+ LY_CHECK_ARG_RET(ctx, !(parse_options & ~LYD_PARSE_OPTS_MASK), LY_EINVAL);
+ LY_CHECK_ARG_RET(ctx, !(validate_options & ~LYD_VALIDATE_OPTS_MASK), LY_EINVAL);
+
+ format = lyd_parse_get_format(in, format);
+ LY_CHECK_ARG_RET(ctx, format, LY_EINVAL);
+
+ LY_CHECK_ARG_RET(ctx, format, LY_EINVAL);
+
+ switch (format) {
+ case LYD_XML:
+ return lyd_parse_xml_data(ctx, in->current, parse_options, validate_options, tree);
+#if 0
+ case LYD_JSON:
+ return lyd_parse_json_data(ctx, in->current, parse_options, validate_options, tree);
+#endif
+ case LYD_LYB:
+ return lyd_parse_lyb_data(ctx, in->current, parse_options, validate_options, tree, NULL);
+ case LYD_SCHEMA:
+ LOGINT_RET(ctx);
+ }
+
+ /* TODO move here the top-level validation from parser_xml.c's lyd_parse_xml_data() and make
+ * it common for all the lyd_parse_*_data() functions */
+
+ LOGINT_RET(ctx);
+}
+
+API LY_ERR
+lyd_parse_data_mem(const struct ly_ctx *ctx, const char *data, LYD_FORMAT format, int parse_options, int validate_options, struct lyd_node **tree)
+{
+ LY_ERR ret;
+ struct ly_in *in;
+
+ LY_CHECK_RET(ly_in_new_memory(data, &in));
+ ret = lyd_parse_data(ctx, in, format, parse_options, validate_options, tree);
+
+ ly_in_free(in, 0);
+ return ret;
+}
+
+API LY_ERR
+lyd_parse_data_fd(const struct ly_ctx *ctx, int fd, LYD_FORMAT format, int parse_options, int validate_options, struct lyd_node **tree)
+{
+ LY_ERR ret;
+ struct ly_in *in;
+
+ LY_CHECK_RET(ly_in_new_fd(fd, &in));
+ ret = lyd_parse_data(ctx, in, format, parse_options, validate_options, tree);
+
+ ly_in_free(in, 0);
+ return ret;
+}
+
+API LY_ERR
+lyd_parse_data_path(const struct ly_ctx *ctx, const char *path, LYD_FORMAT format, int parse_options, int validate_options, struct lyd_node **tree)
+{
+ LY_ERR ret;
+ struct ly_in *in;
+
+ LY_CHECK_RET(ly_in_new_filepath(path, 0, &in));
+ ret = lyd_parse_data(ctx, in, format, parse_options, validate_options, tree);
+
+ ly_in_free(in, 0);
+ return ret;
+}
+
+
+API LY_ERR
+lyd_parse_rpc(const struct ly_ctx *ctx, struct ly_in *in, LYD_FORMAT format, struct lyd_node **tree, struct lyd_node **op)
+{
+ LY_CHECK_ARG_RET(ctx, ctx, in, tree, LY_EINVAL);
+
+ format = lyd_parse_get_format(in, format);
+ LY_CHECK_ARG_RET(ctx, format, LY_EINVAL);
+
+ switch (format) {
+ case LYD_XML:
+ return lyd_parse_xml_rpc(ctx, in->current, tree, op);
+#if 0
+ case LYD_JSON:
+ return lyd_parse_json_rpc(ctx, in->current, tree, op);
+#endif
+ case LYD_LYB:
+ return lyd_parse_lyb_rpc(ctx, in->current, tree, op, NULL);
+ case LYD_SCHEMA:
+ LOGINT_RET(ctx);
+ }
+
+ LOGINT_RET(ctx);
+}
+
+API LY_ERR
+lyd_parse_reply(const struct lyd_node *request, struct ly_in *in, LYD_FORMAT format, struct lyd_node **tree, struct lyd_node **op)
+{
+ LY_CHECK_ARG_RET(NULL, request, LY_EINVAL);
+ LY_CHECK_ARG_RET(LYD_NODE_CTX(request), in, tree, LY_EINVAL);
+
+ format = lyd_parse_get_format(in, format);
+ LY_CHECK_ARG_RET(LYD_NODE_CTX(request), format, LY_EINVAL);
+
+ switch (format) {
+ case LYD_XML:
+ return lyd_parse_xml_reply(request, in->current, tree, op);
+#if 0
+ case LYD_JSON:
+ return lyd_parse_json_reply(request, in->current, tree, op);
+#endif
+ case LYD_LYB:
+ return lyd_parse_lyb_reply(request, in->current, tree, op, NULL);
+ case LYD_SCHEMA:
+ LOGINT_RET(LYD_NODE_CTX(request));
+ }
+
+ LOGINT_RET(LYD_NODE_CTX(request));
+}
+
+API LY_ERR
+lyd_parse_notif(const struct ly_ctx *ctx, struct ly_in *in, LYD_FORMAT format, struct lyd_node **tree, struct lyd_node **ntf)
+{
+ LY_CHECK_ARG_RET(ctx, ctx, in, tree, LY_EINVAL);
+
+ format = lyd_parse_get_format(in, format);
+ LY_CHECK_ARG_RET(ctx, format, LY_EINVAL);
+
+ switch (format) {
+ case LYD_XML:
+ return lyd_parse_xml_notif(ctx, in->current, tree, ntf);
+#if 0
+ case LYD_JSON:
+ return lyd_parse_json_notif(ctx, in->current, tree, ntf);
+#endif
+ case LYD_LYB:
+ return lyd_parse_lyb_notif(ctx, in->current, tree, ntf, NULL);
+ case LYD_SCHEMA:
+ LOGINT_RET(ctx);
+ }
+
+ LOGINT_RET(ctx);
}
LY_ERR