return cnt;
}
+/** Free/zero out value (or children) of a given VP
+ *
+ * @param[in] vp to clear value from.
+ */
+void fr_pair_value_clear(VALUE_PAIR *vp)
+{
+ switch (vp->da->type) {
+ default:
+ fr_value_box_clear_value(&vp->data);
+ return;
+
+ case FR_TYPE_STRUCTURAL:
+ /*
+ * Depth first freeing of children
+ *
+ * This ensures orderly freeing, regardless
+ * of talloc hierarchy.
+ */
+ switch (vp->children.type) {
+ case FR_PAIR_LIST_SINGLE:
+ {
+ fr_cursor_t cursor;
+ VALUE_PAIR *vpc;
+
+ for (vpc = fr_cursor_init(&cursor, &vp->children.slist);
+ vpc;
+ vpc = fr_cursor_next(&cursor)) {
+ fr_pair_value_clear(vpc);
+ talloc_free(vpc);
+ }
+ }
+ break;
+
+ case FR_PAIR_LIST_DOUBLE:
+ {
+ VALUE_PAIR *vpc = NULL;
+
+ while ((vpc = fr_dlist_next(&vp->children.dlist, vpc))) {
+ fr_pair_value_clear(vpc);
+ talloc_free(vpc);
+ }
+ }
+ break;
+ }
+ return;
+ }
+}
+
/** Copy the value from one pair to another
*
* @param[out] out where to copy the value to.
typedef struct {
union {
VALUE_PAIR *slist; //!< The head of the list.
- fr_dlist_head_t *dlist; //!< Doubly linked list head.
+ fr_dlist_head_t dlist; //!< Doubly linked list head.
};
fr_pair_list_type_t type; //!< What type of list this is.
} fr_pair_list_t;
VALUE_PAIR *from, fr_dict_attr_t const *parent_da);
/* Value manipulation */
+void fr_pair_value_clear(VALUE_PAIR *vp);
int fr_pair_value_copy(VALUE_PAIR *out, VALUE_PAIR *in);
int fr_pair_value_from_str(VALUE_PAIR *vp, char const *value, ssize_t len, char quote, bool tainted);
[FR_TYPE_MAX] = 0 //!< Ensure array covers all types.
};
-/** Clear/free any existing value and metadata
- *
- * @note Do not use on uninitialised memory.
- *
- * @param[in] data to clear.
- */
-inline void fr_value_box_clear(fr_value_box_t *data)
-{
- switch (data->type) {
- case FR_TYPE_OCTETS:
- case FR_TYPE_STRING:
- talloc_free(data->datum.ptr);
- break;
-
- case FR_TYPE_STRUCTURAL:
- fr_assert_fail(NULL);
- return;
-
- case FR_TYPE_INVALID:
- return;
-
- default:
- break;
- }
-
- fr_value_box_init(data, FR_TYPE_INVALID, NULL, false);
-}
-
-/** Clear/free any existing value
- *
- * @note Do not use on uninitialised memory.
- *
- * @param[in] data to clear.
- */
-inline void fr_value_box_clear_value(fr_value_box_t *data)
-{
- switch (data->type) {
- case FR_TYPE_OCTETS:
- case FR_TYPE_STRING:
- talloc_free(data->datum.ptr);
- break;
-
- case FR_TYPE_STRUCTURAL:
- fr_assert_fail(NULL);
- return;
-
- case FR_TYPE_INVALID:
- return;
-
- default:
- break;
- }
-
- memset(&data->datum, 0, sizeof(data->datum));
-}
-
/** Copy flags and type data from one value box to another
*
* @param[in] dst to copy flags to
return 0;
}
+/** Clear/free any existing value
+ *
+ * @note Do not use on uninitialised memory.
+ *
+ * @param[in] data to clear.
+ */
+inline void fr_value_box_clear_value(fr_value_box_t *data)
+{
+ switch (data->type) {
+ case FR_TYPE_OCTETS:
+ case FR_TYPE_STRING:
+ talloc_free(data->datum.ptr);
+ break;
+
+ case FR_TYPE_STRUCTURAL:
+ /*
+ * Depth first freeing of children
+ *
+ * This ensures orderly freeing, regardless
+ * of talloc hierarchy.
+ */
+ switch (data->datum.children.type) {
+ case FR_VALUE_BOX_LIST_SINGLE:
+ {
+ fr_cursor_t cursor;
+ fr_value_box_t *vb;
+
+ for (vb = fr_cursor_init(&cursor, &data->datum.children.slist);
+ vb;
+ vb = fr_cursor_next(&cursor)) {
+ fr_value_box_clear_value(vb);
+ talloc_free(vb);
+ }
+ }
+ break;
+
+ case FR_VALUE_BOX_LIST_DOUBLE:
+ {
+ fr_value_box_t *vb = NULL;
+
+ while ((vb = fr_dlist_next(&data->datum.children.dlist, vb))) {
+ fr_value_box_clear_value(vb);
+ talloc_free(vb);
+ }
+ }
+ break;
+ }
+ return;
+
+ case FR_TYPE_INVALID:
+ return;
+
+ default:
+ break;
+ }
+
+ memset(&data->datum, 0, sizeof(data->datum));
+}
+
+/** Clear/free any existing value and metadata
+ *
+ * @note Do not use on uninitialised memory.
+ *
+ * @param[in] data to clear.
+ */
+inline void fr_value_box_clear(fr_value_box_t *data)
+{
+ fr_value_box_clear_value(data);
+ fr_value_box_init(data, FR_TYPE_INVALID, NULL, false);
+}
+
/** Copy value data verbatim duplicating any buffers
*
* @note Will free any exiting buffers associated with the dst #fr_value_box_t.
typedef struct {
union {
fr_value_box_t *slist; //!< The head of the list.
- fr_dlist_head_t *dlist; //!< Doubly linked list head.
+ fr_dlist_head_t dlist; //!< Doubly linked list head.
};
fr_value_box_list_type_t type; //!< What type of list this is.
} fr_value_box_list_t;
)(_var, _box)
/** @} */
-/*
- * Allocation - init/alloc use static functions (above)
- */
-void fr_value_box_clear(fr_value_box_t *data);
-
-void fr_value_box_clear_value(fr_value_box_t *data);
/*
* Comparison
*
* @{
*/
+void fr_value_box_clear_value(fr_value_box_t *data);
+
+void fr_value_box_clear(fr_value_box_t *data);
+
int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t *src);
void fr_value_box_copy_shallow(TALLOC_CTX *ctx, fr_value_box_t *dst,