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 int blobmsg_parse(const struct blobmsg_policy
*policy
, int policy_len
,
19 struct blob_attr
**tb
, void *data
, int len
)
21 struct blobmsg_hdr
*hdr
;
22 struct blob_attr
*attr
;
26 memset(tb
, 0, policy_len
* sizeof(*tb
));
27 pslen
= alloca(policy_len
);
28 for (i
= 0; i
< policy_len
; i
++) {
32 pslen
[i
] = strlen(policy
[i
].name
);
35 __blob_for_each_attr(attr
, data
, len
) {
36 hdr
= blob_data(attr
);
37 for (i
= 0; i
< policy_len
; i
++) {
41 if (policy
[i
].type
!= BLOBMSG_TYPE_UNSPEC
&&
42 blob_id(attr
) != policy
[i
].type
)
45 if (hdr
->namelen
!= pslen
[i
])
51 if (sizeof(*attr
) + blobmsg_hdrlen(hdr
->namelen
) > blob_pad_len(attr
))
54 if (hdr
->name
[hdr
->namelen
] != 0)
60 if (strcmp(policy
[i
].name
, (char *) hdr
->name
) != 0)
71 static struct blob_attr
*
72 blobmsg_new(struct blob_buf
*buf
, int type
, const char *name
, int payload_len
, void **data
)
74 struct blob_attr
*attr
;
75 struct blobmsg_hdr
*hdr
;
78 if (blob_id(buf
->head
) == BLOBMSG_TYPE_ARRAY
&& !name
) {
79 attr
= blob_new(buf
, type
, payload_len
);
80 *data
= blob_data(attr
);
84 if (blob_id(buf
->head
) != BLOBMSG_TYPE_TABLE
|| !name
)
87 namelen
= strlen(name
);
88 attrlen
= blobmsg_hdrlen(namelen
) + payload_len
;
89 attr
= blob_new(buf
, type
, attrlen
);
93 hdr
= blob_data(attr
);
94 hdr
->namelen
= namelen
;
95 strcpy((char *) hdr
->name
, (const char *)name
);
96 *data
= blobmsg_data(attr
);
102 attr_to_offset(struct blob_buf
*buf
, struct blob_attr
*attr
)
104 return (char *)attr
- (char *) buf
->buf
;
109 blobmsg_open_nested(struct blob_buf
*buf
, const char *name
, bool array
)
111 struct blob_attr
*head
= buf
->head
;
112 int type
= array
? BLOBMSG_TYPE_ARRAY
: BLOBMSG_TYPE_TABLE
;
113 unsigned long offset
= attr_to_offset(buf
, buf
->head
);
116 if (blob_id(head
) == BLOBMSG_TYPE_ARRAY
&& !name
)
117 return blob_nest_start(buf
, type
);
119 if (blob_id(head
) == BLOBMSG_TYPE_TABLE
&& name
) {
120 head
= blobmsg_new(buf
, type
, name
, 0, &data
);
121 blob_set_raw_len(buf
->head
, blob_pad_len(buf
->head
) - blobmsg_hdrlen(strlen(name
)));
123 return (void *)offset
;
130 blobmsg_add_field(struct blob_buf
*buf
, int type
, const char *name
,
131 const void *data
, int len
)
133 struct blob_attr
*attr
;
136 if (type
== BLOBMSG_TYPE_ARRAY
||
137 type
== BLOBMSG_TYPE_TABLE
)
140 attr
= blobmsg_new(buf
, type
, name
, len
, &data_dest
);
145 memcpy(data_dest
, data
, len
);