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 bool blobmsg_check_attr(const struct blob_attr
*attr
, bool name
)
20 const struct blobmsg_hdr
*hdr
;
22 if (blob_len(attr
) < sizeof(struct blobmsg_hdr
))
25 hdr
= (void *) attr
->data
;
26 if (!hdr
->namelen
&& name
)
29 if (hdr
->namelen
> blob_len(attr
))
32 if (hdr
->name
[hdr
->namelen
] != 0)
38 int blobmsg_parse(const struct blobmsg_policy
*policy
, int policy_len
,
39 struct blob_attr
**tb
, void *data
, int len
)
41 struct blobmsg_hdr
*hdr
;
42 struct blob_attr
*attr
;
46 memset(tb
, 0, policy_len
* sizeof(*tb
));
47 pslen
= alloca(policy_len
);
48 for (i
= 0; i
< policy_len
; i
++) {
52 pslen
[i
] = strlen(policy
[i
].name
);
55 __blob_for_each_attr(attr
, data
, len
) {
56 hdr
= blob_data(attr
);
57 for (i
= 0; i
< policy_len
; i
++) {
61 if (policy
[i
].type
!= BLOBMSG_TYPE_UNSPEC
&&
62 blob_id(attr
) != policy
[i
].type
)
65 if (hdr
->namelen
!= pslen
[i
])
68 if (!blobmsg_check_attr(attr
, true))
74 if (strcmp(policy
[i
].name
, (char *) hdr
->name
) != 0)
85 static struct blob_attr
*
86 blobmsg_new(struct blob_buf
*buf
, int type
, const char *name
, int payload_len
, void **data
)
88 struct blob_attr
*attr
;
89 struct blobmsg_hdr
*hdr
;
92 if (blob_id(buf
->head
) == BLOBMSG_TYPE_ARRAY
&& !name
) {
93 attr
= blob_new(buf
, type
, payload_len
);
94 *data
= blob_data(attr
);
98 if (blob_id(buf
->head
) != BLOBMSG_TYPE_TABLE
|| !name
)
101 namelen
= strlen(name
);
102 attrlen
= blobmsg_hdrlen(namelen
) + payload_len
;
103 attr
= blob_new(buf
, type
, attrlen
);
107 hdr
= blob_data(attr
);
108 hdr
->namelen
= namelen
;
109 strcpy((char *) hdr
->name
, (const char *)name
);
110 *data
= blobmsg_data(attr
);
116 attr_to_offset(struct blob_buf
*buf
, struct blob_attr
*attr
)
118 return (char *)attr
- (char *) buf
->buf
;
123 blobmsg_open_nested(struct blob_buf
*buf
, const char *name
, bool array
)
125 struct blob_attr
*head
= buf
->head
;
126 int type
= array
? BLOBMSG_TYPE_ARRAY
: BLOBMSG_TYPE_TABLE
;
127 unsigned long offset
= attr_to_offset(buf
, buf
->head
);
130 if (blob_id(head
) == BLOBMSG_TYPE_ARRAY
&& !name
)
131 return blob_nest_start(buf
, type
);
133 if (blob_id(head
) == BLOBMSG_TYPE_TABLE
&& name
) {
134 head
= blobmsg_new(buf
, type
, name
, 0, &data
);
135 blob_set_raw_len(buf
->head
, blob_pad_len(buf
->head
) - blobmsg_hdrlen(strlen(name
)));
137 return (void *)offset
;
144 blobmsg_add_field(struct blob_buf
*buf
, int type
, const char *name
,
145 const void *data
, int len
)
147 struct blob_attr
*attr
;
150 if (type
== BLOBMSG_TYPE_ARRAY
||
151 type
== BLOBMSG_TYPE_TABLE
)
154 attr
= blobmsg_new(buf
, type
, name
, len
, &data_dest
);
159 memcpy(data_dest
, data
, len
);