_pair_list_dcursor_insert, _pair_list_dcursor_remove, list, is_const);
}
-
/** Initialise a cursor that will return only attributes matching the specified #fr_dict_attr_t
*
* @param[in] cursor to initialise.
_pair_list_dcursor_insert, _pair_list_dcursor_remove, list, is_const);
}
+/** Iterate over pairs
+ *
+ * @param[in] list to iterate over.
+ * @param[in] current The fr_value_box_t cursor->current. Will be advanced and checked to
+ * see if it matches the specified fr_dict_attr_t.
+ * @param[in] uctx The fr_dict_attr_t to search for.
+ * @return
+ * - Next matching fr_pair_t.
+ * - NULL if not more matching fr_pair_ts could be found.
+ */
+static void *_fr_pair_iter_next_value(fr_dlist_head_t *list, void *current, UNUSED void *uctx)
+{
+ fr_pair_t *vp;
+
+ if (!current) {
+ vp = NULL;
+ } else {
+ vp = (fr_pair_t *) ((uint8_t *) current - offsetof(fr_pair_t, data));
+ PAIR_VERIFY(vp);
+ }
+
+ while ((vp = fr_dlist_next(list, vp))) {
+ PAIR_VERIFY(vp);
+ if (!fr_type_is_leaf(vp->da->type)) break;
+
+ continue;
+ }
+
+ return vp;
+}
+
+/** Initialises a special dcursor over a #fr_pair_list_t, but which returns #fr_value_box_t
+ *
+ * Filters can be applied later with fr_dcursor_filter_set.
+ *
+ * @note This is the only way to use a dcursor in non-const mode with fr_pair_list_t.
+ *
+ * @param[out] cursor to initialise.
+ * @param[in] list to iterate over.
+ * @param[in] is_const whether the fr_pair_list_t is const.
+ * @return
+ * - NULL if src does not point to any items.
+ * - The first pair in the list.
+ */
+fr_value_box_t *_fr_pair_dcursor_value_init(fr_dcursor_t *cursor, fr_pair_list_t const *list,
+ bool is_const)
+{
+ return _fr_dcursor_init(cursor, fr_pair_order_list_dlist_head(&list->order),
+ _fr_pair_iter_next_value, NULL, NULL, NULL, NULL, NULL, is_const);
+}
+
/** Add a VP to the start of the list.
*
* Links an additional VP 'add' at the beginning a list.
fr_pair_list_t const *list, fr_dict_attr_t const *da,
bool is_const) CC_HINT(nonnull);
+/** Initialises a special dcursor which returns only the values of a pair.
+ *
+ * @note - the list cannot be modified, and structural attributes are not returned.
+ *
+ * @param[out] cursor to initialise.
+ * @param[in] list to iterate over.
+ * @return
+ * - NULL if src does not point to any items.
+ * - The first pair in the list.
+ */
+#define fr_pair_dcursor_value_init(_cursor, _list) \
+ _fr_pair_dcursor_value_init(_cursor, \
+ _list, \
+ IS_CONST(fr_pair_list_t *, _list))
+fr_value_box_t *_fr_pair_dcursor_value_init(fr_dcursor_t *cursor, fr_pair_list_t const *list,
+ bool is_const) CC_HINT(nonnull);
+
+
/** Compare two attributes using and operator.
*
* @return
TEST_CHECK(needle && needle->da == fr_dict_attr_test_tlv_string);
}
+static void test_fr_pair_dcursor_value_init(void)
+{
+ int i = 0;
+ fr_value_box_t *box;
+ fr_dcursor_t cursor;
+ fr_pair_t *vp;
+ fr_pair_list_t local_pairs;
+
+ fr_pair_list_init(&local_pairs);
+
+ MEM(vp = fr_pair_afrom_da(autofree, fr_dict_attr_test_string));
+ fr_pair_value_strdup(vp, "hello", false);
+ fr_pair_append(&local_pairs, vp);
+
+ MEM(vp = fr_pair_afrom_da(autofree, fr_dict_attr_test_uint32));
+ vp->vp_uint32 = 6809;
+ fr_pair_append(&local_pairs, vp);
+
+ MEM(vp = fr_pair_afrom_da(autofree, fr_dict_attr_test_uint8));
+ vp->vp_uint8 = 12;
+ fr_pair_append(&local_pairs, vp);
+
+ TEST_CASE("Searching for fr_dict_attr_test_tlv_string as ascend of fr_dict_attr_test_tlv using fr_pair_dcursor_by_ancestor_init()");
+ for (box = fr_pair_dcursor_value_init(&cursor, &local_pairs);
+ box;
+ box = fr_dcursor_next(&cursor), i++) {
+ switch (i) {
+ case 0:
+ TEST_CASE("First box is a string with value 'hello'");
+ TEST_CHECK(box->type == FR_TYPE_STRING);
+ TEST_CHECK(strcmp(box->vb_strvalue, "hello") == 0);
+ break;
+
+ case 1:
+ TEST_CASE("First box is a uint32 with value 6809");
+ TEST_CHECK(box->type == FR_TYPE_UINT32);
+ TEST_CHECK(box->vb_uint32 == 6809);
+ break;
+
+ case 2:
+ TEST_CASE("First box is a uint8 r with value 12");
+ TEST_CHECK(box->type == FR_TYPE_UINT8);
+ TEST_CHECK(box->vb_uint8 == 12);
+ break;
+
+ default:
+ TEST_CASE("Too many pairs");
+ TEST_CHECK(i < 3);
+ break;
+ }
+ }
+
+ fr_pair_list_free(&local_pairs);
+}
+
static void test_fr_pair_find_by_da_idx(void)
{
fr_pair_t *vp;
/* Searching and list modification */
{ "fr_dcursor_iter_by_da_init", test_fr_pair_dcursor_by_da_init },
{ "fr_pair_dcursor_by_ancestor_init", test_fr_pair_dcursor_by_ancestor_init },
+ { "fr_pair_dcursor_value_init", test_fr_pair_dcursor_value_init },
{ "fr_pair_to_unknown", test_fr_pair_to_unknown },
{ "fr_pair_find_by_da_idx", test_fr_pair_find_by_da_idx },
{ "fr_pair_find_by_child_num_idx", test_fr_pair_find_by_child_num_idx },