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.
18 static const int blob_type
[__BLOBMSG_TYPE_LAST
] = {
19 [BLOBMSG_TYPE_INT8
] = BLOB_ATTR_INT8
,
20 [BLOBMSG_TYPE_INT16
] = BLOB_ATTR_INT16
,
21 [BLOBMSG_TYPE_INT32
] = BLOB_ATTR_INT32
,
22 [BLOBMSG_TYPE_INT64
] = BLOB_ATTR_INT64
,
23 [BLOBMSG_TYPE_STRING
] = BLOB_ATTR_STRING
,
26 bool blobmsg_check_attr(const struct blob_attr
*attr
, bool name
)
28 const struct blobmsg_hdr
*hdr
;
32 if (blob_len(attr
) < sizeof(struct blobmsg_hdr
))
35 hdr
= (void *) attr
->data
;
36 if (!hdr
->namelen
&& name
)
39 if (hdr
->namelen
> blob_len(attr
) - sizeof(struct blobmsg_hdr
))
42 if (hdr
->name
[hdr
->namelen
] != 0)
46 len
= blobmsg_data_len(attr
);
47 data
= blobmsg_data(attr
);
49 if (!id
|| id
> BLOBMSG_TYPE_LAST
)
55 return blob_check_type(data
, len
, blob_type
[id
]);
58 int blobmsg_parse(const struct blobmsg_policy
*policy
, int policy_len
,
59 struct blob_attr
**tb
, void *data
, int len
)
61 struct blobmsg_hdr
*hdr
;
62 struct blob_attr
*attr
;
66 memset(tb
, 0, policy_len
* sizeof(*tb
));
67 pslen
= alloca(policy_len
);
68 for (i
= 0; i
< policy_len
; i
++) {
72 pslen
[i
] = strlen(policy
[i
].name
);
75 __blob_for_each_attr(attr
, data
, len
) {
76 hdr
= blob_data(attr
);
77 for (i
= 0; i
< policy_len
; i
++) {
81 if (policy
[i
].type
!= BLOBMSG_TYPE_UNSPEC
&&
82 blob_id(attr
) != policy
[i
].type
)
85 if (hdr
->namelen
!= pslen
[i
])
88 if (!blobmsg_check_attr(attr
, true))
94 if (strcmp(policy
[i
].name
, (char *) hdr
->name
) != 0)
105 static struct blob_attr
*
106 blobmsg_new(struct blob_buf
*buf
, int type
, const char *name
, int payload_len
, void **data
)
108 struct blob_attr
*attr
;
109 struct blobmsg_hdr
*hdr
;
110 int attrlen
, namelen
;
115 namelen
= strlen(name
);
116 attrlen
= blobmsg_hdrlen(namelen
) + payload_len
;
117 attr
= blob_new(buf
, type
, attrlen
);
121 hdr
= blob_data(attr
);
122 hdr
->namelen
= namelen
;
123 strcpy((char *) hdr
->name
, (const char *)name
);
124 *data
= blobmsg_data(attr
);
130 attr_to_offset(struct blob_buf
*buf
, struct blob_attr
*attr
)
132 return (char *)attr
- (char *) buf
->buf
;
137 blobmsg_open_nested(struct blob_buf
*buf
, const char *name
, bool array
)
139 struct blob_attr
*head
= buf
->head
;
140 int type
= array
? BLOBMSG_TYPE_ARRAY
: BLOBMSG_TYPE_TABLE
;
141 unsigned long offset
= attr_to_offset(buf
, buf
->head
);
147 head
= blobmsg_new(buf
, type
, name
, 0, &data
);
148 blob_set_raw_len(buf
->head
, blob_pad_len(buf
->head
) - blobmsg_hdrlen(strlen(name
)));
150 return (void *)offset
;
154 blobmsg_alloc_string_buffer(struct blob_buf
*buf
, const char *name
, int maxlen
)
156 struct blob_attr
*attr
;
159 attr
= blobmsg_new(buf
, BLOBMSG_TYPE_STRING
, name
, maxlen
, &data_dest
);
163 data_dest
= blobmsg_data(attr
);
164 blob_set_raw_len(buf
->head
, blob_pad_len(buf
->head
) - blob_pad_len(attr
));
165 blob_set_raw_len(attr
, blob_raw_len(attr
) - maxlen
);
171 blobmsg_add_string_buffer(struct blob_buf
*buf
)
173 struct blob_attr
*attr
;
176 attr
= blob_next(buf
->head
);
177 len
= strlen(blobmsg_data(attr
)) + 1;
179 attrlen
= blob_raw_len(attr
) + len
;
180 blob_set_raw_len(attr
, attrlen
);
181 blob_set_raw_len(buf
->head
, blob_raw_len(buf
->head
) + blob_pad_len(attr
));
185 blobmsg_add_field(struct blob_buf
*buf
, int type
, const char *name
,
186 const void *data
, int len
)
188 struct blob_attr
*attr
;
191 attr
= blobmsg_new(buf
, type
, name
, len
, &data_dest
);
196 memcpy(data_dest
, data
, len
);