2 * blobmsg - library for generating/parsing structured blob messages
4 * Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License version 2.1
8 * as published by the Free Software Foundation
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
17 #include "blobmsg_json.h"
19 static bool blobmsg_add_object(struct blob_buf
*b
, json_object
*obj
)
21 json_object_object_foreach(obj
, key
, val
) {
22 if (!blobmsg_add_json_element(b
, key
, val
))
28 static bool blobmsg_add_array(struct blob_buf
*b
, struct array_list
*a
)
32 for (i
= 0, len
= array_list_length(a
); i
< len
; i
++) {
33 if (!blobmsg_add_json_element(b
, NULL
, array_list_get_idx(a
, i
)))
40 bool blobmsg_add_json_element(struct blob_buf
*b
, const char *name
, json_object
*obj
)
48 switch (json_object_get_type(obj
)) {
49 case json_type_object
:
50 c
= blobmsg_open_table(b
, name
);
51 ret
= blobmsg_add_object(b
, obj
);
52 blobmsg_close_table(b
, c
);
55 c
= blobmsg_open_array(b
, name
);
56 ret
= blobmsg_add_array(b
, json_object_get_array(obj
));
57 blobmsg_close_array(b
, c
);
59 case json_type_string
:
60 blobmsg_add_string(b
, name
, json_object_get_string(obj
));
62 case json_type_boolean
:
63 blobmsg_add_u8(b
, name
, json_object_get_boolean(obj
));
66 blobmsg_add_u32(b
, name
, json_object_get_int(obj
));
74 bool blobmsg_add_json_from_string(struct blob_buf
*b
, const char *str
)
79 obj
= json_tokener_parse(str
);
83 if (json_object_get_type(obj
) != json_type_object
)
86 ret
= blobmsg_add_object(b
, obj
);
99 blobmsg_json_format_t custom_format
;
103 static bool blobmsg_puts(struct strbuf
*s
, const char *c
, int len
)
108 if (s
->pos
+ len
>= s
->len
) {
110 s
->buf
= realloc(s
->buf
, s
->len
);
114 memcpy(s
->buf
+ s
->pos
, c
, len
);
119 static void blobmsg_format_string(struct strbuf
*s
, const char *str
)
121 const char *p
, *last
= str
, *end
= str
+ strlen(str
);
122 char buf
[8] = "\\u00";
124 blobmsg_puts(s
, "\"", 1);
125 for (p
= str
; *p
; p
++) {
157 blobmsg_puts(s
, last
, p
- last
);
162 sprintf(buf
+ 4, "%02x", (unsigned char) *p
);
167 blobmsg_puts(s
, buf
, len
);
170 blobmsg_puts(s
, last
, end
- last
);
171 blobmsg_puts(s
, "\"", 1);
174 static void blobmsg_format_json_list(struct strbuf
*s
, struct blob_attr
*attr
, int len
, bool array
);
176 static void blobmsg_format_element(struct strbuf
*s
, struct blob_attr
*attr
, bool array
, bool head
)
178 const char *data_str
;
183 if (!blobmsg_check_attr(attr
, false))
186 if (!array
&& blobmsg_name(attr
)[0]) {
187 blobmsg_format_string(s
, blobmsg_name(attr
));
188 blobmsg_puts(s
, ":", 1);
191 data
= blob_data(attr
);
192 len
= blob_len(attr
);
194 data
= blobmsg_data(attr
);
195 len
= blobmsg_data_len(attr
);
197 if (s
->custom_format
) {
198 data_str
= s
->custom_format(s
->priv
, attr
);
205 switch(blob_id(attr
)) {
206 case BLOBMSG_TYPE_INT8
:
207 sprintf(buf
, "%d", *(uint8_t *)data
);
209 case BLOBMSG_TYPE_INT16
:
210 sprintf(buf
, "%d", *(uint16_t *)data
);
212 case BLOBMSG_TYPE_INT32
:
213 sprintf(buf
, "%d", *(uint32_t *)data
);
215 case BLOBMSG_TYPE_INT64
:
216 sprintf(buf
, "%lld", (long long int) *(uint64_t *)data
);
218 case BLOBMSG_TYPE_STRING
:
219 blobmsg_format_string(s
, data
);
221 case BLOBMSG_TYPE_ARRAY
:
222 blobmsg_format_json_list(s
, data
, len
, true);
224 case BLOBMSG_TYPE_TABLE
:
225 blobmsg_format_json_list(s
, data
, len
, false);
230 blobmsg_puts(s
, data_str
, strlen(data_str
));
233 static void blobmsg_format_json_list(struct strbuf
*s
, struct blob_attr
*attr
, int len
, bool array
)
235 struct blob_attr
*pos
;
239 blobmsg_puts(s
, (array
? "[ " : "{ "), 2);
240 __blob_for_each_attr(pos
, attr
, rem
) {
242 blobmsg_puts(s
, ", ", 2);
244 blobmsg_format_element(s
, pos
, array
, false);
247 blobmsg_puts(s
, (array
? " ]" : " }"), 2);
250 char *blobmsg_format_json_with_cb(struct blob_attr
*attr
, bool list
, blobmsg_json_format_t cb
, void *priv
)
254 s
.len
= blob_len(attr
);
255 s
.buf
= malloc(s
.len
);
257 s
.custom_format
= cb
;
261 blobmsg_format_json_list(&s
, blob_data(attr
), blob_len(attr
), false);
263 blobmsg_format_element(&s
, attr
, false, false);
268 s
.buf
= realloc(s
.buf
, s
.pos
+ 1);