Module: sip-router Branch: master Commit: fb3f37a0ba46bcb39a79a05465f512197a30da6b URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=fb3f37a0...
Author: Jason Penton jason.penton@smilecoms.com Committer: Jason Penton jason.penton@smilecoms.com Date: Tue May 15 13:46:35 2012 +0200
xmlrpc: added support for nested structs in RPC reply via XMLRPC
---
modules/xmlrpc/xmlrpc.c | 47 +++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 39 insertions(+), 8 deletions(-)
diff --git a/modules/xmlrpc/xmlrpc.c b/modules/xmlrpc/xmlrpc.c index 566e6b9..4f8fa4d 100644 --- a/modules/xmlrpc/xmlrpc.c +++ b/modules/xmlrpc/xmlrpc.c @@ -22,7 +22,6 @@ * with this program; if not, write to the Free Software Foundation, Inc., 59 * Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - /*This define breaks on Solaris OS */ #ifndef __OS_solaris #define _XOPEN_SOURCE 4 /* strptime */ @@ -263,7 +262,6 @@ static str member_suffix = STR_STATIC_INIT("</member>"); static str name_prefix = STR_STATIC_INIT("<name>"); static str name_suffix = STR_STATIC_INIT("</name>");
- /** Garbage collection data structure. * * This is the data structure used by the garbage collector in this module. @@ -359,6 +357,8 @@ struct rpc_struct { xmlDocPtr doc; /**< XML-RPC document */ int offset; /**< Offset in the reply where the structure should be printed */ + struct rpc_struct* nnext; /**< nested structure support - a recursive list of nested structrures */ + struct rpc_struct* parent; /**< access to parent structure - used for flattening structure before reply */ struct rpc_struct* next; };
@@ -558,7 +558,6 @@ static int add_xmlrpc_reply(struct xmlrpc_reply* reply, str* text) return 0; }
- /** Adds arbitrary text to the XML-RPC reply being constructed, the text will * be inserted at a specified offset within the XML-RPC reply. * @@ -600,7 +599,7 @@ static int add_xmlrpc_reply_offset(struct xmlrpc_reply* reply, unsigned int offs }
-/** Returns the current lenght of the XML-RPC reply body. +/** Returns the current length of the XML-RPC reply body. * * @param reply The XML-RPC reply being constructed * @return Number of bytes of the XML-RPC reply body. @@ -809,6 +808,20 @@ static int send_reply(sip_msg_t* msg, str* body) return 0; }
+static int flatten_nests(struct rpc_struct* st, struct xmlrpc_reply* reply) { + if (!st) + return 1; + + if (!st->nnext) { + if (add_xmlrpc_reply(&st->struct_out, &struct_suffix) < 0) return -1; + if (add_xmlrpc_reply_offset(&st->parent->struct_out, st->offset, &st->struct_out.body) < 0) return -1; + } else { + flatten_nests(st->nnext, reply); + if (add_xmlrpc_reply(&st->struct_out, &struct_suffix) < 0) return -1; + if (add_xmlrpc_reply_offset(&st->parent->struct_out, st->offset, &st->struct_out.body) < 0) return -1; + } + return 1; +}
static int print_structures(struct xmlrpc_reply* reply, struct rpc_struct* st) @@ -816,8 +829,8 @@ static int print_structures(struct xmlrpc_reply* reply, while(st) { /* Close the structure first */ if (add_xmlrpc_reply(&st->struct_out, &struct_suffix) < 0) return -1; - if (add_xmlrpc_reply_offset(reply, st->offset, - &st->struct_out.body) < 0) return -1; + if (flatten_nests(st->nnext, &st->struct_out) < 0) return -1; + if (add_xmlrpc_reply_offset(reply, st->offset, &st->struct_out.body) < 0) return -1; st = st->next; } return 0; @@ -1032,7 +1045,7 @@ static int print_value(struct xmlrpc_reply* res,
default: set_fault(err_reply, 500, "Bug In SER (Invalid formatting character)"); - ERR("Invalid formatting character\n"); + ERR("Invalid formatting character [%c]\n", fmt); goto err; }
@@ -1677,6 +1690,8 @@ static int rpc_struct_add(struct rpc_struct* s, char* fmt, ...) va_list ap; str member_name; struct xmlrpc_reply* reply; + void* void_ptr; + struct rpc_struct* p, *tmp;
reply = &s->struct_out;
@@ -1690,7 +1705,23 @@ static int rpc_struct_add(struct rpc_struct* s, char* fmt, ...) if (add_xmlrpc_reply_esc(reply, &member_name) < 0) goto err; if (add_xmlrpc_reply(reply, &name_suffix) < 0) goto err; if (add_xmlrpc_reply(reply, &value_prefix) < 0) goto err; - if (print_value(reply, reply, *fmt, &ap) < 0) goto err; + if (*fmt == '{') { + void_ptr = va_arg(ap, void**); + p = new_rpcstruct(0, 0, s->reply); + if (!p) + goto err; + *(struct rpc_struct**) void_ptr = p; + p->offset = get_reply_len(reply); + p->parent = s; + if (!s->nnext) { + s->nnext = p; + } else { + for (tmp = s; tmp->nnext; tmp=tmp->nnext); + tmp->nnext = p; + } + } else { + if (print_value(reply, reply, *fmt, &ap) < 0) goto err; + } if (add_xmlrpc_reply(reply, &value_suffix) < 0) goto err; if (add_xmlrpc_reply(reply, &member_suffix) < 0) goto err; fmt++;