[sr-dev] git:master: xmlrpc: added support for nested structs in RPC reply via XMLRPC

Jason Penton jason.penton at gmail.com
Tue May 15 13:47:22 CEST 2012


Module: sip-router
Branch: master
Commit: fb3f37a0ba46bcb39a79a05465f512197a30da6b
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=fb3f37a0ba46bcb39a79a05465f512197a30da6b

Author: Jason Penton <jason.penton at smilecoms.com>
Committer: Jason Penton <jason.penton at 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++;




More information about the sr-dev mailing list