summaryrefslogtreecommitdiffstats
path: root/src/tree_data.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/tree_data.h222
1 files changed, 165 insertions, 57 deletions
diff --git a/src/tree_data.h b/src/tree_data.h
index ff98f60..4d87fba 100644
--- a/src/tree_data.h
+++ b/src/tree_data.h
@@ -822,7 +822,7 @@ struct lyd_node_inner {
}; /**< common part corresponding to ::lyd_node */
struct lyd_node *child; /**< pointer to the first child node. */
- struct hash_table *children_ht; /**< hash table with all the direct children (except keys for a list, lists without keys) */
+ struct ly_ht *children_ht; /**< hash table with all the direct children (except keys for a list, lists without keys) */
#define LYD_HT_MIN_ITEMS 4 /**< minimal number of children to create ::lyd_node_inner.children_ht hash table. */
};
@@ -1004,15 +1004,7 @@ struct lyd_node_opaq {
* @return Pointer to the parent node of the @p node.
* @return NULL in case of the top-level node or if the @p node is NULL itself.
*/
-static inline struct lyd_node *
-lyd_parent(const struct lyd_node *node)
-{
- if (!node || !node->parent) {
- return NULL;
- }
-
- return &node->parent->node;
-}
+LIBYANG_API_DECL struct lyd_node *lyd_parent(const struct lyd_node *node);
/**
* @brief Get the child pointer of a generic data node.
@@ -1024,29 +1016,7 @@ lyd_parent(const struct lyd_node *node)
* @param[in] node Node to use.
* @return Pointer to the first child node (if any) of the @p node.
*/
-static inline struct lyd_node *
-lyd_child(const struct lyd_node *node)
-{
- if (!node) {
- return NULL;
- }
-
- if (!node->schema) {
- /* opaq node */
- return ((const struct lyd_node_opaq *)node)->child;
- }
-
- switch (node->schema->nodetype) {
- case LYS_CONTAINER:
- case LYS_LIST:
- case LYS_RPC:
- case LYS_ACTION:
- case LYS_NOTIF:
- return ((const struct lyd_node_inner *)node)->child;
- default:
- return NULL;
- }
-}
+LIBYANG_API_DECL struct lyd_node *lyd_child(const struct lyd_node *node);
/**
* @brief Get the child pointer of a generic data node but skip its keys in case it is ::LYS_LIST.
@@ -1072,6 +1042,14 @@ LIBYANG_API_DECL struct lyd_node *lyd_child_no_keys(const struct lyd_node *node)
LIBYANG_API_DECL const struct lys_module *lyd_owner_module(const struct lyd_node *node);
/**
+ * @brief Get the module of a node. Useful mainly for opaque nodes.
+ *
+ * @param[in] node Node to examine.
+ * @return Module of the node.
+ */
+LIBYANG_API_DECL const struct lys_module *lyd_node_module(const struct lyd_node *node);
+
+/**
* @brief Check whether a node value equals to its default one.
*
* @param[in] node Term node to test.
@@ -1133,23 +1111,7 @@ LIBYANG_API_DECL const char *lyd_value_get_canonical(const struct ly_ctx *ctx, c
* @param[in] node Data node to use.
* @return Canonical value.
*/
-static inline const char *
-lyd_get_value(const struct lyd_node *node)
-{
- if (!node) {
- return NULL;
- }
-
- if (!node->schema) {
- return ((const struct lyd_node_opaq *)node)->value;
- } else if (node->schema->nodetype & LYD_NODE_TERM) {
- const struct lyd_value *value = &((const struct lyd_node_term *)node)->value;
-
- return value->_canonical ? value->_canonical : lyd_value_get_canonical(LYD_CTX(node), value);
- }
-
- return NULL;
-}
+LIBYANG_API_DECL const char *lyd_get_value(const struct lyd_node *node);
/**
* @brief Get anydata string value.
@@ -1172,6 +1134,14 @@ LIBYANG_API_DECL LY_ERR lyd_any_copy_value(struct lyd_node *trg, const union lyd
LYD_ANYDATA_VALUETYPE value_type);
/**
+ * @brief Get schema node of a data node. Useful especially for opaque nodes.
+ *
+ * @param[in] node Data node to use.
+ * @return Schema node represented by data @p node, NULL if there is none.
+ */
+LIBYANG_API_DECL const struct lysc_node *lyd_node_schema(const struct lyd_node *node);
+
+/**
* @brief Create a new inner node in the data tree.
*
* To create list, use ::lyd_new_list() or ::lyd_new_list2().
@@ -1287,6 +1257,57 @@ LIBYANG_API_DECL LY_ERR lyd_new_list2(struct lyd_node *parent, const struct lys_
const char *keys, ly_bool output, struct lyd_node **node);
/**
+ * @brief Create a new list node in the data tree.
+ *
+ * @param[in] parent Parent node for the node being created. NULL in case of creating a top level element.
+ * @param[in] module Module of the node being created. If NULL, @p parent module will be used.
+ * @param[in] name Schema node name of the new data node. The node must be #LYS_LIST.
+ * @param[in] format Format of key values.
+ * @param[in] key_values Ordered key string values of the new list instance, all must be set.
+ * @param[in] value_lengths Array of lengths of each @p key_values, may be NULL if @p key_values are 0-terminated strings.
+ * @param[in] output Flag in case the @p parent is RPC/Action. If value is 0, the input's data nodes of the RPC/Action are
+ * taken into consideration. Otherwise, the output's data node is going to be created.
+ * @param[out] node Optional created node.
+ * @return LY_ERR value.
+ */
+LIBYANG_API_DECL LY_ERR lyd_new_list3(struct lyd_node *parent, const struct lys_module *module, const char *name,
+ const char **key_values, uint32_t *value_lengths, ly_bool output, struct lyd_node **node);
+
+/**
+ * @brief Create a new list node in the data tree.
+ *
+ * @param[in] parent Parent node for the node being created. NULL in case of creating a top level element.
+ * @param[in] module Module of the node being created. If NULL, @p parent module will be used.
+ * @param[in] name Schema node name of the new data node. The node must be #LYS_LIST.
+ * @param[in] format Format of key values.
+ * @param[in] key_values Ordered key binary (LYB) values of the new list instance, all must be set.
+ * @param[in] value_lengths Array of lengths of each @p key_values.
+ * @param[in] output Flag in case the @p parent is RPC/Action. If value is 0, the input's data nodes of the RPC/Action are
+ * taken into consideration. Otherwise, the output's data node is going to be created.
+ * @param[out] node Optional created node.
+ * @return LY_ERR value.
+ */
+LIBYANG_API_DECL LY_ERR lyd_new_list3_bin(struct lyd_node *parent, const struct lys_module *module, const char *name,
+ const void **key_values, uint32_t *value_lengths, ly_bool output, struct lyd_node **node);
+
+/**
+ * @brief Create a new list node in the data tree.
+ *
+ * @param[in] parent Parent node for the node being created. NULL in case of creating a top level element.
+ * @param[in] module Module of the node being created. If NULL, @p parent module will be used.
+ * @param[in] name Schema node name of the new data node. The node must be #LYS_LIST.
+ * @param[in] format Format of key values.
+ * @param[in] key_values Ordered key canonical values of the new list instance, all must be set.
+ * @param[in] value_lengths Array of lengths of each @p key_values, may be NULL if @p key_values are 0-terminated strings.
+ * @param[in] output Flag in case the @p parent is RPC/Action. If value is 0, the input's data nodes of the RPC/Action are
+ * taken into consideration. Otherwise, the output's data node is going to be created.
+ * @param[out] node Optional created node.
+ * @return LY_ERR value.
+ */
+LIBYANG_API_DECL LY_ERR lyd_new_list3_canon(struct lyd_node *parent, const struct lys_module *module, const char *name,
+ const char **key_values, uint32_t *value_lengths, ly_bool output, struct lyd_node **node);
+
+/**
* @brief Create a new term node in the data tree.
*
* To create a top-level term node defined in an extension instance, use ::lyd_new_ext_term().
@@ -1506,6 +1527,7 @@ LIBYANG_API_DECL LY_ERR lyd_new_attr2(struct lyd_node *parent, const char *modul
#define LYD_NEW_PATH_CANON_VALUE 0x10 /**< Interpret the provided leaf/leaf-list @p value as being in the canonical
(or JSON if no defined) ::LY_VALUE_CANON format. If it is not, it may lead
to unexpected behavior. */
+#define LYD_NEW_PATH_WITH_OPAQ 0x20 /**< Consider opaque nodes normally when searching for existing nodes. */
/** @} pathoptions */
@@ -1519,7 +1541,8 @@ LIBYANG_API_DECL LY_ERR lyd_new_attr2(struct lyd_node *parent, const char *modul
* Also, if a leaf-list is being created and both a predicate is defined in @p path
* and @p value is set, the predicate is preferred.
*
- * For key-less lists and non-configuration leaf-lists, positional predicates should be used (indices starting from 1).
+ * For key-less lists, positional predicates must be used (indices starting from 1). For non-configuration leaf-lists
+ * either positional predicate can be used or leaf-list predicate, when an instance is always created at the end.
* If no predicate is used for these nodes, they are always created.
*
* @param[in] parent Data parent to add to/modify, can be NULL. Note that in case a first top-level sibling is used,
@@ -1531,7 +1554,11 @@ LIBYANG_API_DECL LY_ERR lyd_new_attr2(struct lyd_node *parent, const char *modul
* For other node types, it should be NULL.
* @param[in] options Bitmask of options, see @ref pathoptions.
* @param[out] node Optional first created node.
- * @return LY_ERR value.
+ * @return LY_SUCCESS on success.
+ * @return LY_EEXIST if the final node to create exists (unless ::LYD_NEW_PATH_UPDATE is used).
+ * @return LY_EINVAL on invalid arguments including invalid @p path.
+ * @return LY_EVALID on invalid @p value.
+ * @return LY_ERR on other errors.
*/
LIBYANG_API_DECL LY_ERR lyd_new_path(struct lyd_node *parent, const struct ly_ctx *ctx, const char *path, const char *value,
uint32_t options, struct lyd_node **node);
@@ -1554,7 +1581,11 @@ LIBYANG_API_DECL LY_ERR lyd_new_path(struct lyd_node *parent, const struct ly_ct
* @param[in] options Bitmask of options, see @ref pathoptions.
* @param[out] new_parent Optional first parent node created. If only one node was created, equals to @p new_node.
* @param[out] new_node Optional last node created.
- * @return LY_ERR value.
+ * @return LY_SUCCESS on success.
+ * @return LY_EEXIST if the final node to create exists (unless ::LYD_NEW_PATH_UPDATE is used).
+ * @return LY_EINVAL on invalid arguments including invalid @p path.
+ * @return LY_EVALID on invalid @p value.
+ * @return LY_ERR on other errors.
*/
LIBYANG_API_DECL LY_ERR lyd_new_path2(struct lyd_node *parent, const struct ly_ctx *ctx, const char *path, const void *value,
size_t value_len, LYD_ANYDATA_VALUETYPE value_type, uint32_t options, struct lyd_node **new_parent,
@@ -1576,7 +1607,11 @@ LIBYANG_API_DECL LY_ERR lyd_new_path2(struct lyd_node *parent, const struct ly_c
* @param[in] value Value of the new leaf/leaf-list. For other node types, it should be NULL.
* @param[in] options Bitmask of options, see @ref pathoptions.
* @param[out] node Optional first created node.
- * @return LY_ERR value.
+ * @return LY_SUCCESS on success.
+ * @return LY_EEXIST if the final node to create exists (unless ::LYD_NEW_PATH_UPDATE is used).
+ * @return LY_EINVAL on invalid arguments including invalid @p path.
+ * @return LY_EVALID on invalid @p value.
+ * @return LY_ERR on other errors.
*/
LIBYANG_API_DECL LY_ERR lyd_new_ext_path(struct lyd_node *parent, const struct lysc_ext_instance *ext, const char *path,
const void *value, uint32_t options, struct lyd_node **node);
@@ -1662,7 +1697,7 @@ LIBYANG_API_DECL LY_ERR lyd_change_term(struct lyd_node *term, const char *val_s
* is always cleared.
*
* @param[in] term Term node to change.
- * @param[in] value New value to set in binary format, see @ref howtoDataLYB.
+ * @param[in] value New value to set in binary format (usually a pointer), see @ref howtoDataLYB.
* @param[in] value_len Length of @p value.
* @return LY_SUCCESS if value was changed,
* @return LY_EEXIST if value was the same and only the default flag was cleared,
@@ -1927,6 +1962,8 @@ LIBYANG_API_DECL LY_ERR lyd_compare_meta(const struct lyd_meta *meta1, const str
#define LYD_DUP_WITH_FLAGS 0x08 /**< Also copy any data node flags. That will cause the duplicated data to preserve
its validation/default node state. */
#define LYD_DUP_NO_EXT 0x10 /**< Do not duplicate nodes with the ::LYD_EXT flag (nested extension instance data). */
+#define LYD_DUP_WITH_PRIV 0x20 /**< Also copy data node private pointer. Only the pointer is copied, it still points
+ to the same data. */
/** @} dupoptions */
@@ -2131,7 +2168,7 @@ LIBYANG_API_DECL LY_ERR lyd_merge_module(struct lyd_node **target, const struct
* @param[in] first First data tree.
* @param[in] second Second data tree.
* @param[in] options Bitmask of options flags, see @ref diffoptions.
- * @param[out] diff Generated diff.
+ * @param[out] diff Generated diff, NULL if there are no differences.
* @return LY_SUCCESS on success,
* @return LY_ERR on error.
*/
@@ -2146,7 +2183,7 @@ LIBYANG_API_DECL LY_ERR lyd_diff_tree(const struct lyd_node *first, const struct
* @param[in] first First data tree.
* @param[in] second Second data tree.
* @param[in] options Bitmask of options flags, see @ref diffoptions.
- * @param[out] diff Generated diff.
+ * @param[out] diff Generated diff, NULL if there are no differences.
* @return LY_SUCCESS on success,
* @return LY_ERR on error.
*/
@@ -2302,6 +2339,10 @@ typedef enum {
/**
* @brief Generate path of the given node in the requested format.
*
+ * The path is constructed based on the parent node(s) of this node. When run on a node which is disconnected
+ * from its parent(s), this function might yield unexpected results such as `/example:b` instead of the expected
+ * `/example:a/b`.
+ *
* @param[in] node Data path of this node will be generated.
* @param[in] pathtype Format of the path to generate.
* @param[in,out] buffer Prepared buffer of the @p buflen length to store the generated path.
@@ -2419,6 +2460,8 @@ LIBYANG_API_DECL void lyxp_vars_free(struct lyxp_var *vars);
* `leaf-list[.=...]`, these instances are found using hashes with constant (*O(1)*) complexity
* (unless they are defined in top-level). Other predicates can still follow the aforementioned ones.
*
+ * Opaque nodes are part of the evaluation.
+ *
* @param[in] ctx_node XPath context node.
* @param[in] xpath [XPath](@ref howtoXPath) to select in JSON format. It must evaluate into a node set.
* @param[out] set Set of found data nodes. In case the result is a number, a string, or a boolean,
@@ -2527,11 +2570,61 @@ LIBYANG_API_DECL LY_ERR lyd_eval_xpath3(const struct lyd_node *ctx_node, const s
const char *xpath, LY_VALUE_FORMAT format, void *prefix_data, const struct lyxp_var *vars, ly_bool *result);
/**
+ * @brief XPath result type.
+ */
+typedef enum {
+ LY_XPATH_NODE_SET, /**< XPath node set */
+ LY_XPATH_STRING, /**< XPath string */
+ LY_XPATH_NUMBER, /**< XPath number */
+ LY_XPATH_BOOLEAN /**< XPath boolean */
+} LY_XPATH_TYPE;
+
+/**
+ * @brief Evaluate an XPath on data and return the result or convert it first to an expected result type.
+ *
+ * Either all return type parameters @p node_set, @p string, @p number, and @p boolean with @p ret_type
+ * are provided or exactly one of @p node_set, @p string, @p number, and @p boolean is provided with @p ret_type
+ * being obvious and hence optional.
+ *
+ * @param[in] ctx_node XPath context node, NULL for the root node.
+ * @param[in] tree Data tree to evaluate on.
+ * @param[in] cur_mod Current module of @p xpath, needed for some kinds of @p format.
+ * @param[in] xpath [XPath](@ref howtoXPath) to select.
+ * @param[in] format Format of any prefixes in @p xpath.
+ * @param[in] prefix_data Format-specific prefix data.
+ * @param[in] vars Optional [sized array](@ref sizedarrays) of XPath variables.
+ * @param[out] ret_type XPath type of the result selecting which of @p node_set, @p string, @p number, and @p boolean to use.
+ * @param[out] node_set XPath node set result.
+ * @param[out] string XPath string result.
+ * @param[out] number XPath number result.
+ * @param[out] boolean XPath boolean result.
+ * @return LY_SUCCESS on success.
+ * @return LY_ERR value on error.
+ */
+LIBYANG_API_DECL LY_ERR lyd_eval_xpath4(const struct lyd_node *ctx_node, const struct lyd_node *tree,
+ const struct lys_module *cur_mod, const char *xpath, LY_VALUE_FORMAT format, void *prefix_data,
+ const struct lyxp_var *vars, LY_XPATH_TYPE *ret_type, struct ly_set **node_set, char **string,
+ long double *number, ly_bool *boolean);
+
+/**
+ * @brief Evaluate an XPath on data and free all the nodes except the subtrees selected by the expression.
+ *
+ * @param[in,out] tree Data tree to evaluate on and trim.
+ * @param[in] xpath [XPath](@ref howtoXPath) to select in JSON format.
+ * @param[in] vars Optional [sized array](@ref sizedarrays) of XPath variables.
+ * @return LY_SUCCESS on success.
+ * @return LY_ERR value on error.
+ */
+LIBYANG_API_DEF LY_ERR lyd_trim_xpath(struct lyd_node **tree, const char *xpath, const struct lyxp_var *vars);
+
+/**
* @brief Search in given data for a node uniquely identified by a path.
*
* Always works in constant (*O(1)*) complexity. To be exact, it is *O(n)* where *n* is the depth
* of the path used.
*
+ * Opaque nodes are NEVER found/traversed.
+ *
* @param[in] ctx_node Path context node.
* @param[in] path [Path](@ref howtoXPath) to find.
* @param[in] output Whether to search in RPC/action output nodes or in input nodes.
@@ -2557,6 +2650,21 @@ LIBYANG_API_DECL LY_ERR lyd_find_path(const struct lyd_node *ctx_node, const cha
LIBYANG_API_DECL LY_ERR lyd_find_target(const struct ly_path *path, const struct lyd_node *tree, struct lyd_node **match);
/**
+ * @brief Get current timezone (including DST setting) UTC (GMT) time offset in seconds.
+ *
+ * @return Timezone shift in seconds.
+ */
+LIBYANG_API_DECL int ly_time_tz_offset(void);
+
+/**
+ * @brief Get UTC (GMT) timezone offset in seconds at a specific timestamp (including DST setting).
+ *
+ * @param[in] time Timestamp to get the offset at.
+ * @return Timezone shift in seconds.
+ */
+LIBYANG_API_DECL int ly_time_tz_offset_at(time_t time);
+
+/**
* @brief Convert date-and-time from string to UNIX timestamp and fractions of a second.
*
* @param[in] value Valid string date-and-time value.