From 8d8178b46e7a172acfa2aa822639125b90c0266a Mon Sep 17 00:00:00 2001 From: Ron Pedde Date: Tue, 28 Mar 2006 23:36:23 +0000 Subject: [PATCH] almost json on the non-dmap version --- src/xml-rpc.c | 134 +++++++++++++++++++++++++++++++++++--------------- src/xml-rpc.h | 6 +-- 2 files changed, 97 insertions(+), 43 deletions(-) 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,"",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,"No Support \n"); #endif - xml_pop(pxml); /* service */ + xml_pop(pxml,TRUE); /* service */ - xml_push(pxml,"service"); + xml_push(pxml,"service",TRUE); xml_output(pxml,"name","DAAP Server"); xml_output(pxml,"status",config.stop ? "Stopping" : "Running"); - xml_pop(pxml); /* service */ + xml_pop(pxml,TRUE); /* service */ - xml_push(pxml,"service"); + xml_push(pxml,"service",TRUE); xml_output(pxml,"name","File Scanner"); xml_output(pxml,"status",config.reload ? "Running" : "Idle"); - xml_pop(pxml); /* service */ + xml_pop(pxml,TRUE); /* service */ - xml_pop(pxml); /* service_status */ + xml_pop(pxml,TRUE); /* service_status */ - xml_push(pxml,"thread_status"); + xml_push(pxml,"thread_array",TRUE); pci = ws_thread_enum_first(config.server,&wste); while(pci) { pss = ws_get_local_storage(pci); if(pss) { - xml_push(pxml,"thread"); + xml_push(pxml,"thread",TRUE); xml_output(pxml,"id","%d",pss->thread); xml_output(pxml,"sourceip","%s",pss->host); xml_output(pxml,"action","%s",pss->what); - xml_pop(pxml); /* thread */ + xml_pop(pxml,TRUE); /* thread */ } pci=ws_thread_enum_next(config.server,&wste); } - xml_pop(pxml); /* thread_status */ + xml_pop(pxml,TRUE); /* thread_status */ - xml_push(pxml,"statistics"); + xml_push(pxml,"stat_array",TRUE); r_secs=(int)(time(NULL)-config.stats.start_time); @@ -314,24 +368,24 @@ void xml_get_stats(WS_CONNINFO *pwsc) { sprintf((char*)&buf[strlen(buf)],"%d second%s ", r_secs, r_secs == 1 ? "" : "s"); - xml_push(pxml,"stat"); + xml_push(pxml,"stat",TRUE); xml_output(pxml,"name","Uptime"); xml_output(pxml,"value","%s",buf); - xml_pop(pxml); /* stat */ + xml_pop(pxml,TRUE); /* stat */ - xml_push(pxml,"stat"); + xml_push(pxml,"stat",TRUE); xml_output(pxml,"name","Songs"); db_get_song_count(NULL,&count); xml_output(pxml,"value","%d",count); - xml_pop(pxml); /* stat */ + xml_pop(pxml,TRUE); /* stat */ - xml_push(pxml,"stat"); + xml_push(pxml,"stat",TRUE); xml_output(pxml,"name","Songs Served"); xml_output(pxml,"value","%d",config.stats.songs_served); - xml_pop(pxml); /* stat */ + xml_pop(pxml,TRUE); /* stat */ - xml_pop(pxml); /* statistics */ - xml_pop(pxml); /* status */ + xml_pop(pxml,TRUE); /* statistics */ + xml_pop(pxml,TRUE); /* status */ xml_deinit(pxml); return; diff --git a/src/xml-rpc.h b/src/xml-rpc.h index 62ccd9df..3706a578 100644 --- a/src/xml-rpc.h +++ b/src/xml-rpc.h @@ -15,10 +15,10 @@ struct tag_xmlstruct; extern void xml_handle(WS_CONNINFO *pwsc); -extern struct tag_xmlstruct *xml_init(WS_CONNINFO *pwsc, int emit_header, +extern struct tag_xmlstruct *xml_init(WS_CONNINFO *pwsc, int emit_header, int flags); -extern void xml_push(struct tag_xmlstruct *pxml, char *term); -extern void xml_pop(struct tag_xmlstruct *pxml); +extern void xml_push(struct tag_xmlstruct *pxml, char *term, int container); +extern void xml_pop(struct tag_xmlstruct *pxml, int container); extern void xml_output(struct tag_xmlstruct *pxml, char *section, char *fmt, ...); extern void xml_deinit(struct tag_xmlstruct *pxml);