2 * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
3 * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License version 2.1
7 * as published by the Free Software Foundation
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <libubox/avl.h>
16 #include <libubox/avl-cmp.h>
20 __blobmsg_list_init(struct blobmsg_list
*list
, int offset
, int len
, blobmsg_list_cmp cmp
)
22 avl_init(&list
->avl
, avl_strcmp
, false, NULL
);
23 list
->node_offset
= offset
;
29 blobmsg_list_fill(struct blobmsg_list
*list
, void *data
, int len
, bool array
)
31 struct avl_tree
*tree
= &list
->avl
;
32 struct blobmsg_list_node
*node
;
33 struct blob_attr
*cur
;
38 __blob_for_each_attr(cur
, data
, rem
) {
39 if (!blobmsg_check_attr(cur
, !array
))
42 ptr
= calloc(1, list
->node_len
);
46 node
= (void *) ((char *)ptr
+ list
->node_offset
);
48 node
->avl
.key
= blobmsg_data(cur
);
50 node
->avl
.key
= blobmsg_name(cur
);
52 if (avl_insert(tree
, &node
->avl
)) {
64 blobmsg_list_move(struct blobmsg_list
*list
, struct blobmsg_list
*src
)
66 struct blobmsg_list_node
*node
, *tmp
;
69 avl_remove_all_elements(&src
->avl
, node
, avl
, tmp
) {
70 if (avl_insert(&list
->avl
, &node
->avl
)) {
71 ptr
= ((char *) node
- list
->node_offset
);
78 blobmsg_list_free(struct blobmsg_list
*list
)
80 struct blobmsg_list_node
*node
, *tmp
;
83 avl_remove_all_elements(&list
->avl
, node
, avl
, tmp
) {
84 ptr
= ((char *) node
- list
->node_offset
);
90 blobmsg_list_equal(struct blobmsg_list
*l1
, struct blobmsg_list
*l2
)
92 struct blobmsg_list_node
*n1
, *n2
;
93 int count
= l1
->avl
.count
;
95 if (count
!= l2
->avl
.count
)
98 n1
= avl_first_element(&l1
->avl
, n1
, avl
);
99 n2
= avl_first_element(&l2
->avl
, n2
, avl
);
101 while (count
-- > 0) {
104 len
= blob_len(n1
->data
);
105 if (len
!= blob_len(n2
->data
))
108 if (memcmp(n1
->data
, n2
->data
, len
) != 0)
111 if (l1
->cmp
&& !l1
->cmp(n1
, n2
))
117 n1
= avl_next_element(n1
, avl
);
118 n2
= avl_next_element(n2
, avl
);