98c8d8a13a1ec627fe55c2510163d49c56088aed
2 * blob.c - uci <-> blobmsg conversion layer
3 * Copyright (C) 2012-2013 Felix Fietkau <nbd@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 Lesser General Public License for more details.
18 #include <libubox/blobmsg.h>
23 uci_attr_to_blob(struct blob_buf
*b
, const char *str
,
24 const char *name
, enum blobmsg_type type
)
30 case BLOBMSG_TYPE_STRING
:
31 blobmsg_add_string(b
, name
, str
);
33 case BLOBMSG_TYPE_BOOL
:
34 if (!strcmp(str
, "true") || !strcmp(str
, "1"))
36 else if (!strcmp(str
, "false") || !strcmp(str
, "0"))
41 blobmsg_add_u8(b
, name
, intval
);
43 case BLOBMSG_TYPE_INT32
:
44 intval
= strtol(str
, &err
, 0);
48 blobmsg_add_u32(b
, name
, intval
);
57 uci_array_to_blob(struct blob_buf
*b
, struct uci_option
*o
,
58 enum blobmsg_type type
)
60 struct uci_element
*e
;
61 char *str
, *next
, *word
;
63 if (o
->type
== UCI_TYPE_LIST
) {
64 uci_foreach_element(&o
->v
.list
, e
) {
65 uci_attr_to_blob(b
, e
->name
, NULL
, type
);
70 str
= strdup(o
->v
.string
);
73 while ((word
= strsep(&next
, " \t")) != NULL
) {
77 uci_attr_to_blob(b
, word
, NULL
, type
);
84 __uci_element_to_blob(struct blob_buf
*b
, struct uci_element
*e
,
85 const struct uci_blob_param_list
*p
)
87 const struct blobmsg_policy
*attr
= NULL
;
88 struct uci_option
*o
= uci_to_option(e
);
89 unsigned int types
= 0;
93 for (i
= 0; i
< p
->n_params
; i
++) {
96 if (strcmp(attr
->name
, e
->name
) != 0)
99 if (attr
->type
> BLOBMSG_TYPE_LAST
)
102 if (types
& (1 << attr
->type
))
105 types
|= 1 << attr
->type
;
107 if (attr
->type
== BLOBMSG_TYPE_ARRAY
) {
111 array
= blobmsg_open_array(b
, attr
->name
);
112 uci_array_to_blob(b
, o
, p
->info
[i
].type
);
113 blobmsg_close_array(b
, array
);
118 if (o
->type
== UCI_TYPE_LIST
)
121 ret
+= uci_attr_to_blob(b
, o
->v
.string
, attr
->name
, attr
->type
);
127 __uci_to_blob(struct blob_buf
*b
, struct uci_section
*s
,
128 const struct uci_blob_param_list
*p
)
130 struct uci_element
*e
;
133 uci_foreach_element(&s
->options
, e
)
134 ret
+= __uci_element_to_blob(b
, e
, p
);
140 uci_to_blob(struct blob_buf
*b
, struct uci_section
*s
,
141 const struct uci_blob_param_list
*p
)
146 ret
+= __uci_to_blob(b
, s
, p
);
147 for (i
= 0; i
< p
->n_next
; i
++)
148 ret
+= uci_to_blob(b
, s
, p
->next
[i
]);
154 uci_blob_diff(struct blob_attr
**tb1
, struct blob_attr
**tb2
,
155 const struct uci_blob_param_list
*config
, unsigned long *diff
)
160 for (i
= 0; i
< config
->n_params
; i
++) {
161 if (!tb1
[i
] && !tb2
[i
])
164 if (!!tb1
[i
] != !!tb2
[i
])
167 if (blob_len(tb1
[i
]) != blob_len(tb2
[i
]))
170 if (memcmp(tb1
[i
], tb2
[i
], blob_raw_len(tb1
[i
])) != 0)
178 bitfield_set(diff
, i
);
188 __uci_blob_check_equal(struct blob_attr
*c1
, struct blob_attr
*c2
,
189 const struct uci_blob_param_list
*config
)
191 struct blob_attr
**tb1
, **tb2
;
199 tb1
= alloca(config
->n_params
* sizeof(struct blob_attr
*));
200 blobmsg_parse(config
->params
, config
->n_params
, tb1
,
201 blob_data(c1
), blob_len(c1
));
203 tb2
= alloca(config
->n_params
* sizeof(struct blob_attr
*));
204 blobmsg_parse(config
->params
, config
->n_params
, tb2
,
205 blob_data(c2
), blob_len(c2
));
207 return !uci_blob_diff(tb1
, tb2
, config
, NULL
);
211 uci_blob_check_equal(struct blob_attr
*c1
, struct blob_attr
*c2
,
212 const struct uci_blob_param_list
*config
)
216 if (!__uci_blob_check_equal(c1
, c2
, config
))
219 for (i
= 0; i
< config
->n_next
; i
++) {
220 if (!__uci_blob_check_equal(c1
, c2
, config
->next
[i
]))