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_to_blob(struct blob_buf
*b
, struct uci_section
*s
,
85 const struct uci_blob_param_list
*p
)
87 const struct blobmsg_policy
*attr
= NULL
;
88 struct uci_element
*e
;
93 uci_foreach_element(&s
->options
, e
) {
94 for (i
= 0; i
< p
->n_params
; i
++) {
96 if (!strcmp(attr
->name
, e
->name
))
100 if (i
== p
->n_params
)
103 o
= uci_to_option(e
);
105 if (attr
->type
== BLOBMSG_TYPE_ARRAY
) {
109 array
= blobmsg_open_array(b
, attr
->name
);
110 uci_array_to_blob(b
, o
, p
->info
[i
].type
);
111 blobmsg_close_array(b
, array
);
116 if (o
->type
== UCI_TYPE_LIST
)
119 ret
+= uci_attr_to_blob(b
, o
->v
.string
, attr
->name
, attr
->type
);
126 uci_to_blob(struct blob_buf
*b
, struct uci_section
*s
,
127 const struct uci_blob_param_list
*p
)
132 ret
+= __uci_to_blob(b
, s
, p
);
133 for (i
= 0; i
< p
->n_next
; i
++)
134 ret
+= uci_to_blob(b
, s
, p
->next
[i
]);
140 uci_blob_diff(struct blob_attr
**tb1
, struct blob_attr
**tb2
,
141 const struct uci_blob_param_list
*config
, unsigned long *diff
)
146 for (i
= 0; i
< config
->n_params
; i
++) {
147 if (!tb1
[i
] && !tb2
[i
])
150 if (!!tb1
[i
] != !!tb2
[i
])
153 if (blob_len(tb1
[i
]) != blob_len(tb2
[i
]))
156 if (memcmp(tb1
[i
], tb2
[i
], blob_raw_len(tb1
[i
])) != 0)
164 bitfield_set(diff
, i
);
174 __uci_blob_check_equal(struct blob_attr
*c1
, struct blob_attr
*c2
,
175 const struct uci_blob_param_list
*config
)
177 struct blob_attr
**tb1
, **tb2
;
185 tb1
= alloca(config
->n_params
* sizeof(struct blob_attr
*));
186 blobmsg_parse(config
->params
, config
->n_params
, tb1
,
187 blob_data(c1
), blob_len(c1
));
189 tb2
= alloca(config
->n_params
* sizeof(struct blob_attr
*));
190 blobmsg_parse(config
->params
, config
->n_params
, tb2
,
191 blob_data(c2
), blob_len(c2
));
193 return !uci_blob_diff(tb1
, tb2
, config
, NULL
);
197 uci_blob_check_equal(struct blob_attr
*c1
, struct blob_attr
*c2
,
198 const struct uci_blob_param_list
*config
)
202 if (!__uci_blob_check_equal(c1
, c2
, config
))
205 for (i
= 0; i
< config
->n_next
; i
++) {
206 if (!__uci_blob_check_equal(c1
, c2
, config
->next
[i
]))