* shallow copying buffers.
*/
while (vp != NULL) {
- value = fr_value_box_alloc(ctx, vp->data.type, vp->da, vp->data.tainted);
- fr_value_box_copy(value, value, &vp->data);
+ if (fr_type_is_structural(vp->da->type)) {
+ value = fr_value_box_alloc(ctx, FR_TYPE_GROUP, NULL, false);
+ if (!value) goto oom;
+
+ if (fr_pair_list_copy_to_box(value, &vp->vp_group) < 0) {
+ talloc_free(value);
+ goto oom;
+ }
+
+ } else {
+ value = fr_value_box_alloc(ctx, vp->data.type, vp->da, vp->data.tainted);
+ if (!value) goto oom;
+ fr_value_box_copy(value, value, &vp->data);
+ }
+
fr_dlist_insert_tail(&list, value);
vp = fr_dcursor_next(&cursor);
}
return cnt;
}
+
+/** Copy the contents of a pair list to a set of value-boxes
+ *
+ * This function should be removed when the xlats use dcursors
+ * of copying all of the boxes.
+ *
+ * @param[in] dst where boxes will be created
+ * @param[in] from whence to copy #fr_pair_t (s).
+ * @return
+ * - >0 the number of boxes copied.
+ * - 0 if no boxes copied.
+ * - -1 on error.
+ */
+int fr_pair_list_copy_to_box(fr_value_box_t *dst, fr_pair_list_t *from)
+{
+ int cnt = 0;
+ fr_value_box_t *value, *first_added = NULL;
+ fr_pair_t *vp;
+
+ fr_assert(dst->type == FR_TYPE_GROUP);
+
+ for (vp = fr_pair_list_head(from);
+ vp;
+ vp = fr_pair_list_next(from, vp), cnt++) {
+ PAIR_VERIFY_WITH_LIST(from, vp);
+
+ if (fr_type_is_structural(vp->da->type)) {
+ value = fr_value_box_alloc(dst, FR_TYPE_GROUP, NULL, false);
+ if (!value) goto fail;
+
+ if (fr_pair_list_copy_to_box(value, &vp->vp_group) < 0) {
+ talloc_free(value);
+ goto fail;
+ }
+
+ } else {
+ value = fr_value_box_alloc(dst, vp->data.type, vp->da, vp->data.tainted);
+ if (!value) {
+ fail:
+ fr_dlist_talloc_free_to_tail(&dst->vb_group, first_added);
+ return -1;
+ }
+ fr_value_box_copy(value, value, &vp->data);
+ }
+
+ if (!first_added) first_added = value;
+ fr_dlist_insert_tail(&dst->vb_group, value);
+ }
+
+ return cnt;
+}
+
/** Duplicate pairs in a list matching the specified da
*
* Copy all pairs from 'from' matching the specified da.
void fr_pair_list_steal(TALLOC_CTX *ctx, fr_pair_list_t *list);
+int fr_pair_list_copy_to_box(fr_value_box_t *dst, fr_pair_list_t *from);
+
int fr_pair_list_copy_by_da(TALLOC_CTX *ctx, fr_pair_list_t *to,
fr_pair_list_t const *from, fr_dict_attr_t const *da, unsigned int count);