hotplug: add parser for new hotplug event rulesets (work in progress, not integrated...
[project/procd.git] / utils.c
1 #include <libubox/avl.h>
2 #include <libubox/avl-cmp.h>
3 #include "utils.h"
4
5 void
6 __blobmsg_list_init(struct blobmsg_list *list, int offset, int len, blobmsg_list_cmp cmp)
7 {
8         avl_init(&list->avl, avl_strcmp, false, NULL);
9         list->node_offset = offset;
10         list->node_len = len;
11         list->cmp = cmp;
12 }
13
14 int
15 blobmsg_list_fill(struct blobmsg_list *list, void *data, int len, bool array)
16 {
17         struct avl_tree *tree = &list->avl;
18         struct blobmsg_list_node *node;
19         struct blob_attr *cur;
20         void *ptr;
21         int count = 0;
22         int rem = len;
23
24         __blob_for_each_attr(cur, data, rem) {
25                 if (!blobmsg_check_attr(cur, !array))
26                         continue;
27
28                 ptr = calloc(1, list->node_len);
29                 if (!ptr)
30                         return -1;
31
32                 node = (void *) ((char *)ptr + list->node_offset);
33                 if (array)
34                         node->avl.key = blobmsg_data(cur);
35                 else
36                         node->avl.key = blobmsg_name(cur);
37                 node->data = cur;
38                 if (avl_insert(tree, &node->avl)) {
39                         free(ptr);
40                         continue;
41                 }
42
43                 count++;
44         }
45
46         return count;
47 }
48
49 void
50 blobmsg_list_move(struct blobmsg_list *list, struct blobmsg_list *src)
51 {
52         struct blobmsg_list_node *node, *tmp;
53         void *ptr;
54
55         avl_remove_all_elements(&src->avl, node, avl, tmp) {
56                 if (avl_insert(&list->avl, &node->avl)) {
57                         ptr = ((char *) node - list->node_offset);
58                         free(ptr);
59                 }
60         }
61 }
62
63 void
64 blobmsg_list_free(struct blobmsg_list *list)
65 {
66         struct blobmsg_list_node *node, *tmp;
67         void *ptr;
68
69         avl_remove_all_elements(&list->avl, node, avl, tmp) {
70                 ptr = ((char *) node - list->node_offset);
71                 free(ptr);
72         }
73 }
74
75 bool
76 blobmsg_list_equal(struct blobmsg_list *l1, struct blobmsg_list *l2)
77 {
78         struct blobmsg_list_node *n1, *n2;
79         int count = l1->avl.count;
80
81         if (count != l2->avl.count)
82                 return false;
83
84         n1 = avl_first_element(&l1->avl, n1, avl);
85         n2 = avl_first_element(&l2->avl, n2, avl);
86
87         while (count-- > 0) {
88                 int len;
89
90                 len = blob_len(n1->data);
91                 if (len != blob_len(n2->data))
92                         return false;
93
94                 if (memcmp(n1->data, n2->data, len) != 0)
95                         return false;
96
97                 if (l1->cmp && !l1->cmp(n1, n2))
98                         return false;
99
100                 if (!count)
101                         break;
102
103                 n1 = avl_next_element(n1, avl);
104                 n2 = avl_next_element(n2, avl);
105         }
106
107         return true;
108 }