diff --git a/src/xml-rpc.c b/src/xml-rpc.c index 533b4ec0..31474cb8 100644 --- a/src/xml-rpc.c +++ b/src/xml-rpc.c @@ -32,6 +32,7 @@ typedef struct tag_xmlstack { typedef struct tag_xmlstruct { WS_CONNINFO *pwsc; int stack_level; + int suppress_lead; int flags; XMLSTACK stack; } XMLSTRUCT; @@ -84,23 +85,54 @@ XMLSTRUCT *xml_init(WS_CONNINFO *pwsc, int emit_header, int flags) { * @param pxml xml struct obtained from xml_init * @param term next xlm section to start */ -void xml_push(XMLSTRUCT *pxml, char *term) { +void xml_push(XMLSTRUCT *pxml, char *term, int container) { XMLSTACK *pstack; + int is_array=0; + int parent_is_array=0; + int suppress_nl=0; + char *parent_term; pstack = (XMLSTACK *)malloc(sizeof(XMLSTACK)); pstack->next=pxml->stack.next; pstack->tag=strdup(term); pxml->stack.next=pstack; - if(pxml->flags & XML_FLAG_READABLE) - ws_writefd(pxml->pwsc,"\n%*s",pxml->stack_level,""); + if((strlen(term) > 5)&&(strcasecmp(&term[strlen(term)-5],"array") == 0)) { + is_array=1; + } + + if(pstack->next) { + parent_term = pstack->next->tag; + if((strlen(parent_term) > 5) && + (strcasecmp(&parent_term[strlen(parent_term)-5],"array") == 0)) { + parent_is_array=1; + } + } + + if((pxml->flags & XML_FLAG_READABLE) && (!pxml->suppress_lead)) + ws_writefd(pxml->pwsc,"%*s",pxml->stack_level,""); if(pxml->flags & XML_FLAG_JSON) { - ws_writefd(pxml->pwsc,"{ \"%s\": ",term); + if(pxml->suppress_lead) { + ws_writefd(pxml->pwsc,", "); + } + if(!parent_is_array) { + ws_writefd(pxml->pwsc,"\"%s\": ",term); + } else { + suppress_nl=1; + } + if(is_array) { + ws_writefd(pxml->pwsc,"["); + } else if(container) { + ws_writefd(pxml->pwsc,"{"); + } } else { ws_writefd(pxml->pwsc,"<%s>",term); } + if((container) && (pxml->flags & XML_FLAG_READABLE)&&(!suppress_nl)) + ws_writefd(pxml->pwsc,"\n"); + pxml->stack_level++; } @@ -109,9 +141,14 @@ void xml_push(XMLSTRUCT *pxml, char *term) { * * @param pxml xml struct we are working with */ -void xml_pop(XMLSTRUCT *pxml) { +void xml_pop(XMLSTRUCT *pxml, int container) { XMLSTACK *pstack; + int is_array=0; + int parent_is_array=0; + char *term; + char *parent_term; + int suppress_nl = 0; pstack=pxml->stack.next; if(!pstack) { DPRINTF(E_LOG,L_XML,"xml_pop: tried to pop an empty stack\n"); @@ -122,17 +159,38 @@ void xml_pop(XMLSTRUCT *pxml) { pxml->stack_level--; - if(pxml->flags & XML_FLAG_READABLE) - ws_writefd(pxml->pwsc,"\n%*s",pxml->stack_level,""); + term = pstack->tag; + if((strlen(term) > 5)&&(strcasecmp(&term[strlen(term)-5],"array") == 0)) { + is_array=1; + } + + if(pxml->stack.next) { + parent_term = pxml->stack.next->tag; + if((strlen(parent_term) > 5) && + (strcasecmp(&parent_term[strlen(parent_term)-5],"array") == 0)) { + parent_is_array=1; + } + } + + if((container) && (pxml->flags & XML_FLAG_READABLE)) + ws_writefd(pxml->pwsc,"%*s",pxml->stack_level,""); if(pxml->flags & XML_FLAG_JSON) { - ws_writefd(pxml->pwsc,"}",pstack->tag); + pxml->suppress_lead=0; + if(is_array) { + ws_writefd(pxml->pwsc,"]"); + } else if(container) { + ws_writefd(pxml->pwsc,"}"); + } else { + suppress_nl = 1; + pxml->suppress_lead=1; + } } else { ws_writefd(pxml->pwsc,"%s>",pstack->tag); } - if(pxml->flags & XML_FLAG_READABLE) - ws_writefd(pxml->pwsc,"%*s",pxml->stack_level,""); + if((pxml->flags & XML_FLAG_READABLE)&&(!suppress_nl)) + ws_writefd(pxml->pwsc,"\n"); free(pstack->tag); free(pstack); @@ -145,32 +203,28 @@ void xml_output(XMLSTRUCT *pxml, char *section, char *fmt, ...) { va_list ap; char buf[256]; char *output; - int oldflags; va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); if(section) { - xml_push(pxml,section); + xml_push(pxml,section,FALSE); } output = xml_entity_encode(buf); if(pxml->flags & XML_FLAG_JSON) { - ws_writefd(pxml->pwsc,"\"%s\" ",output); - + ws_writefd(pxml->pwsc,"\"%s\"",output); + } else { ws_writefd(pxml->pwsc,"%s",output); } free(output); - oldflags = pxml->flags; - pxml->flags = pxml->flags & ~XML_FLAG_READABLE; if(section) { - xml_pop(pxml); + xml_pop(pxml,FALSE); } - pxml->flags = oldflags; } /** @@ -239,9 +293,9 @@ void xml_get_stats(WS_CONNINFO *pwsc) { pxml=xml_init(pwsc,1,flag); - xml_push(pxml,"status"); - xml_push(pxml,"service_status"); - xml_push(pxml,"service"); + xml_push(pxml,"status",TRUE); + xml_push(pxml,"service_array",TRUE); + xml_push(pxml,"service",TRUE); xml_output(pxml,"name","Rendezvous"); #ifndef WITHOUT_MDNS @@ -254,38 +308,38 @@ void xml_get_stats(WS_CONNINFO *pwsc) { ws_writefd(pwsc,"