From 947f282098e980e1533d974438d96c3659413d94 Mon Sep 17 00:00:00 2001 From: Krisztian Litkey Date: Wed, 26 Sep 2012 16:18:39 +0300 Subject: [PATCH] common: added mrp_msg_set, mrp_msg_iterate, mrp_msg_find for arrays. --- src/common/msg.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/common/msg.h | 17 +++++++- 2 files changed, 141 insertions(+), 7 deletions(-) diff --git a/src/common/msg.c b/src/common/msg.c index deb13a6..8b521f1 100644 --- a/src/common/msg.c +++ b/src/common/msg.c @@ -367,6 +367,95 @@ int mrp_msg_prepend(mrp_msg_t *msg, uint16_t tag, ...) } +int mrp_msg_set(mrp_msg_t *msg, uint16_t tag, ...) +{ + mrp_msg_field_t *of, *nf; + va_list ap; + + of = mrp_msg_find(msg, tag); + + if (of != NULL) { + va_start(ap, tag); + nf = create_field(tag, &ap); + va_end(ap); + + if (nf != NULL) { + mrp_list_append(&of->hook, &nf->hook); + destroy_field(of); + + return TRUE; + } + } + + return FALSE; +} + + +int mrp_msg_iterate(mrp_msg_t *msg, void **it, uint16_t *tagp, uint16_t *typep, + mrp_msg_value_t *valp, size_t *sizep) +{ + mrp_list_hook_t *p = *(mrp_list_hook_t **)it; + mrp_msg_field_t *f; + + if (p == NULL) + p = msg->fields.next; + + if (p == &msg->fields) + return FALSE; + + f = mrp_list_entry(p, typeof(*f), hook); + + *tagp = f->tag; + *typep = f->type; + + switch (f->type) { +#define HANDLE_TYPE(type, member) \ + case MRP_MSG_FIELD_##type: \ + valp->member = f->member; \ + if (sizep != NULL) \ + *sizep = sizeof(typeof(f->member)); \ + break + + HANDLE_TYPE(BOOL , bln); + HANDLE_TYPE(UINT8 , u8); + HANDLE_TYPE(SINT8 , s8); + HANDLE_TYPE(UINT16, u16); + HANDLE_TYPE(SINT16, s16); + HANDLE_TYPE(UINT32, u32); + HANDLE_TYPE(SINT32, s32); + HANDLE_TYPE(UINT64, u64); + HANDLE_TYPE(SINT64, s64); + HANDLE_TYPE(DOUBLE, dbl); + + case MRP_MSG_FIELD_STRING: + valp->str = f->str; + if (sizep != NULL) + *sizep = strlen(f->str); + break; + + case MRP_MSG_FIELD_BLOB: + valp->blb = f->blb; + if (sizep != NULL) + *sizep = (size_t)f->size[0]; + break; + + default: + if (f->type & MRP_MSG_FIELD_ARRAY) { + valp->aany = f->aany; + if (sizep != NULL) + *sizep = f->size[0]; + } + else + return FALSE; +#undef HANDLE_TYPE + } + + *it = p->next; + + return TRUE; +} + + mrp_msg_field_t *mrp_msg_find(mrp_msg_t *msg, uint16_t tag) { mrp_msg_field_t *f; @@ -385,13 +474,23 @@ mrp_msg_field_t *mrp_msg_find(mrp_msg_t *msg, uint16_t tag) int mrp_msg_get(mrp_msg_t *msg, ...) { #define HANDLE_TYPE(_type, _member) \ - case MRP_MSG_FIELD_##_type: \ - valp = va_arg(ap, typeof(valp)); \ - valp->_member = f->_member; \ - break + case MRP_MSG_FIELD_##_type: \ + valp = va_arg(ap, typeof(valp)); \ + valp->_member = f->_member; \ + break + +#define HANDLE_ARRAY(_type, _member) \ + case MRP_MSG_FIELD_##_type: \ + cntp = va_arg(ap, typeof(cntp)); \ + valp = va_arg(ap, typeof(valp)); \ + *cntp = f->size[0]; \ + valp->_member = f->_member; \ + break + mrp_msg_field_t *f; mrp_msg_value_t *valp; + uint32_t *cntp; mrp_list_hook_t *start, *p; uint16_t tag, type; int found; @@ -443,9 +542,27 @@ int mrp_msg_get(mrp_msg_t *msg, ...) HANDLE_TYPE(UINT64, u64); HANDLE_TYPE(SINT64, s64); HANDLE_TYPE(DOUBLE, dbl); - /* XXX TODO: add handling for array types */ default: - goto out; + if (type & MRP_MSG_FIELD_ARRAY) { + switch (type & ~MRP_MSG_FIELD_ARRAY) { + HANDLE_ARRAY(STRING, astr); + HANDLE_ARRAY(BOOL , abln); + HANDLE_ARRAY(UINT8 , au8 ); + HANDLE_ARRAY(SINT8 , as8 ); + HANDLE_ARRAY(UINT16, au16); + HANDLE_ARRAY(SINT16, as16); + HANDLE_ARRAY(UINT32, au32); + HANDLE_ARRAY(SINT32, as32); + HANDLE_ARRAY(UINT64, au64); + HANDLE_ARRAY(SINT64, as64); + HANDLE_ARRAY(DOUBLE, adbl); + default: + goto out; + + } + } + else + goto out; } start = p->next; @@ -463,6 +580,8 @@ int mrp_msg_get(mrp_msg_t *msg, ...) return found; #undef HANDLE_TYPE +#undef HANDLE_ARRAY + } diff --git a/src/common/msg.h b/src/common/msg.h index d4fe420..078610c 100644 --- a/src/common/msg.h +++ b/src/common/msg.h @@ -71,6 +71,7 @@ typedef enum { #define MRP_MSG_END ((char *)MRP_MSG_FIELD_INVALID) /* NULL */ #define MRP_MSG_FIELD_ARRAY_OF(t) (MRP_MSG_FIELD_ARRAY | MRP_MSG_FIELD_##t) +#define MRP_MSG_FIELD_IS_ARRAY(t) ((t) & MRP_MSG_FIELD_ARRAY) #define MRP_MSG_TAG_STRING(tag, arg) (tag), MRP_MSG_FIELD_STRING, (arg) #define MRP_MSG_TAG_BOOL(tag, arg) (tag), MRP_MSG_FIELD_BOOL , (arg) @@ -86,7 +87,7 @@ typedef enum { #define MRP_MSG_TAG_BLOB(tag, arg) (tag), MRP_MSG_FIELD_BLOB , (arg) #define MRP_MSG_TAG_ARRAY(tag, type, cnt, arr) \ - ((tag), MRP_MSG_FIELD_ARRAY | MRP_MSG_FIELD_##type, (cnt), (arr)) + (tag), MRP_MSG_FIELD_ARRAY | MRP_MSG_FIELD_##type, (cnt), (arr) #define MRP_MSG_TAG_STRING_ARRAY(tag, cnt, arr) \ MRP_MSG_TAG_ARRAY((tag), STRING, (cnt), (arr)) #define MRP_MSG_TAG_BOOL_ARRAY(tag, cnt, arr) \ @@ -200,6 +201,20 @@ int mrp_msg_append(mrp_msg_t *msg, uint16_t tag, ...); /** Prepend a field to a message. */ int mrp_msg_prepend(mrp_msg_t *msg, uint16_t tag, ...); +/** Set a field in a message to the given value. */ +int mrp_msg_set(mrp_msg_t *msg, uint16_t tag, ...); + +/** Iterate through the fields of a message. You must not any of the + fields while iterating. */ +int mrp_msg_iterate(mrp_msg_t *msg, void **it, uint16_t *tagp, + uint16_t *typep, mrp_msg_value_t *valp, size_t *sizep); + +/** Iterate through the matching fields of a message. You should not delete + * any of the fields while iterating through the message. */ +int mrp_msg_iterate_matching(mrp_msg_t *msg, void **it, uint16_t *tagp, + uint16_t *typep, mrp_msg_value_t *valp, + size_t *sizep); + /** Find a field in a message. */ mrp_msg_field_t *mrp_msg_find(mrp_msg_t *msg, uint16_t tag); -- 2.7.4