blobmsg: allow data/length iterator/accessor functions to work on non-blobmsg elements
authorFelix Fietkau <nbd@openwrt.org>
Wed, 12 Mar 2014 19:08:27 +0000 (20:08 +0100)
committerFelix Fietkau <nbd@openwrt.org>
Wed, 12 Mar 2014 19:18:12 +0000 (20:18 +0100)
This primarily helps with simplifying the ubus APIs.
blobmsg header presence is indicated by the BLOB_ATTR_EXTENDED bit in
the id_len field.

This changes the format ABI, but not the API.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
blob.c
blob.h
blobmsg.c
blobmsg.h

diff --git a/blob.c b/blob.c
index faa3bb8061eb2d5f630a6a4f7c44d03d138a14ae..2da7cac7e492819d00e122bcbf3334d0ebb3973e 100644 (file)
--- a/blob.c
+++ b/blob.c
@@ -115,10 +115,9 @@ blob_fill_pad(struct blob_attr *attr)
 void
 blob_set_raw_len(struct blob_attr *attr, unsigned int len)
 {
-       int id = blob_id(attr);
        len &= BLOB_ATTR_LEN_MASK;
-       len |= (id << BLOB_ATTR_ID_SHIFT) & BLOB_ATTR_ID_MASK;
-       attr->id_len = cpu_to_be32(len);
+       attr->id_len &= ~cpu_to_be32(BLOB_ATTR_LEN_MASK);
+       attr->id_len |= cpu_to_be32(len);
 }
 
 struct blob_attr *
diff --git a/blob.h b/blob.h
index fa430a859605394f5677bfd19a0ac1a372e9ff43..37a572b0974940d1739590ea08a32d4d3c1d7e0e 100644 (file)
--- a/blob.h
+++ b/blob.h
@@ -42,10 +42,11 @@ enum {
        BLOB_ATTR_LAST
 };
 
-#define BLOB_ATTR_ID_MASK  0xff000000
+#define BLOB_ATTR_ID_MASK  0x7f000000
 #define BLOB_ATTR_ID_SHIFT 24
 #define BLOB_ATTR_LEN_MASK 0x00ffffff
 #define BLOB_ATTR_ALIGN    4
+#define BLOB_ATTR_EXTENDED 0x80000000
 
 struct blob_attr {
        uint32_t id_len;
@@ -85,6 +86,12 @@ blob_id(const struct blob_attr *attr)
        return id;
 }
 
+static inline bool
+blob_is_extended(const struct blob_attr *attr)
+{
+       return !!(attr->id_len & cpu_to_be32(BLOB_ATTR_EXTENDED));
+}
+
 /*
  * blob_len: returns the length of the attribute's payload
  */
index 307662051d9ae66b84f6f2304feb38e2465c3e9a..47ee9e7f15433464d8908f3017af03c79c586cdb 100644 (file)
--- a/blobmsg.c
+++ b/blobmsg.c
@@ -181,6 +181,7 @@ blobmsg_new(struct blob_buf *buf, int type, const char *name, int payload_len, v
        if (!attr)
                return NULL;
 
+       attr->id_len |= be32_to_cpu(BLOB_ATTR_EXTENDED);
        hdr = blob_data(attr);
        hdr->namelen = cpu_to_be16(namelen);
        strcpy((char *) hdr->name, (const char *)name);
index 4619643e27d6c97b19878d3cfcaee65fef4e68fa..e9e0e6e08ed4c0a03eee3a54accdf5f83fd7c052 100644 (file)
--- a/blobmsg.h
+++ b/blobmsg.h
@@ -65,7 +65,12 @@ static inline int blobmsg_type(const struct blob_attr *attr)
 static inline void *blobmsg_data(const struct blob_attr *attr)
 {
        struct blobmsg_hdr *hdr = (struct blobmsg_hdr *) blob_data(attr);
-       return (char *) hdr + blobmsg_hdrlen(be16_to_cpu(hdr->namelen));
+       char *data = blob_data(attr);
+
+       if (blob_is_extended(attr))
+               data += blobmsg_hdrlen(be16_to_cpu(hdr->namelen));
+
+       return data;
 }
 
 static inline int blobmsg_data_len(const struct blob_attr *attr)