almost json on the non-dmap version

This commit is contained in:
Ron Pedde 2006-03-28 23:36:23 +00:00
parent a102c38763
commit 8d8178b46e
2 changed files with 97 additions and 43 deletions

View File

@ -32,6 +32,7 @@ typedef struct tag_xmlstack {
typedef struct tag_xmlstruct { typedef struct tag_xmlstruct {
WS_CONNINFO *pwsc; WS_CONNINFO *pwsc;
int stack_level; int stack_level;
int suppress_lead;
int flags; int flags;
XMLSTACK stack; XMLSTACK stack;
} XMLSTRUCT; } 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 pxml xml struct obtained from xml_init
* @param term next xlm section to start * @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; XMLSTACK *pstack;
int is_array=0;
int parent_is_array=0;
int suppress_nl=0;
char *parent_term;
pstack = (XMLSTACK *)malloc(sizeof(XMLSTACK)); pstack = (XMLSTACK *)malloc(sizeof(XMLSTACK));
pstack->next=pxml->stack.next; pstack->next=pxml->stack.next;
pstack->tag=strdup(term); pstack->tag=strdup(term);
pxml->stack.next=pstack; pxml->stack.next=pstack;
if(pxml->flags & XML_FLAG_READABLE) if((strlen(term) > 5)&&(strcasecmp(&term[strlen(term)-5],"array") == 0)) {
ws_writefd(pxml->pwsc,"\n%*s",pxml->stack_level,""); 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) { 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 { } else {
ws_writefd(pxml->pwsc,"<%s>",term); ws_writefd(pxml->pwsc,"<%s>",term);
} }
if((container) && (pxml->flags & XML_FLAG_READABLE)&&(!suppress_nl))
ws_writefd(pxml->pwsc,"\n");
pxml->stack_level++; pxml->stack_level++;
} }
@ -109,9 +141,14 @@ void xml_push(XMLSTRUCT *pxml, char *term) {
* *
* @param pxml xml struct we are working with * @param pxml xml struct we are working with
*/ */
void xml_pop(XMLSTRUCT *pxml) { void xml_pop(XMLSTRUCT *pxml, int container) {
XMLSTACK *pstack; XMLSTACK *pstack;
int is_array=0;
int parent_is_array=0;
char *term;
char *parent_term;
int suppress_nl = 0;
pstack=pxml->stack.next; pstack=pxml->stack.next;
if(!pstack) { if(!pstack) {
DPRINTF(E_LOG,L_XML,"xml_pop: tried to pop an empty stack\n"); 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--; pxml->stack_level--;
if(pxml->flags & XML_FLAG_READABLE) term = pstack->tag;
ws_writefd(pxml->pwsc,"\n%*s",pxml->stack_level,""); 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) { 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 { } else {
ws_writefd(pxml->pwsc,"</%s>",pstack->tag); ws_writefd(pxml->pwsc,"</%s>",pstack->tag);
} }
if(pxml->flags & XML_FLAG_READABLE) if((pxml->flags & XML_FLAG_READABLE)&&(!suppress_nl))
ws_writefd(pxml->pwsc,"%*s",pxml->stack_level,""); ws_writefd(pxml->pwsc,"\n");
free(pstack->tag); free(pstack->tag);
free(pstack); free(pstack);
@ -145,32 +203,28 @@ void xml_output(XMLSTRUCT *pxml, char *section, char *fmt, ...) {
va_list ap; va_list ap;
char buf[256]; char buf[256];
char *output; char *output;
int oldflags;
va_start(ap, fmt); va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap); vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap); va_end(ap);
if(section) { if(section) {
xml_push(pxml,section); xml_push(pxml,section,FALSE);
} }
output = xml_entity_encode(buf); output = xml_entity_encode(buf);
if(pxml->flags & XML_FLAG_JSON) { if(pxml->flags & XML_FLAG_JSON) {
ws_writefd(pxml->pwsc,"\"%s\" ",output); ws_writefd(pxml->pwsc,"\"%s\"",output);
} else { } else {
ws_writefd(pxml->pwsc,"%s",output); ws_writefd(pxml->pwsc,"%s",output);
} }
free(output); free(output);
oldflags = pxml->flags;
pxml->flags = pxml->flags & ~XML_FLAG_READABLE;
if(section) { 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); pxml=xml_init(pwsc,1,flag);
xml_push(pxml,"status"); xml_push(pxml,"status",TRUE);
xml_push(pxml,"service_status"); xml_push(pxml,"service_array",TRUE);
xml_push(pxml,"service"); xml_push(pxml,"service",TRUE);
xml_output(pxml,"name","Rendezvous"); xml_output(pxml,"name","Rendezvous");
#ifndef WITHOUT_MDNS #ifndef WITHOUT_MDNS
@ -254,38 +308,38 @@ void xml_get_stats(WS_CONNINFO *pwsc) {
ws_writefd(pwsc,"<td>No Support</td><td>&nbsp;</td></tr>\n"); ws_writefd(pwsc,"<td>No Support</td><td>&nbsp;</td></tr>\n");
#endif #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,"name","DAAP Server");
xml_output(pxml,"status",config.stop ? "Stopping" : "Running"); 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,"name","File Scanner");
xml_output(pxml,"status",config.reload ? "Running" : "Idle"); 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); pci = ws_thread_enum_first(config.server,&wste);
while(pci) { while(pci) {
pss = ws_get_local_storage(pci); pss = ws_get_local_storage(pci);
if(pss) { if(pss) {
xml_push(pxml,"thread"); xml_push(pxml,"thread",TRUE);
xml_output(pxml,"id","%d",pss->thread); xml_output(pxml,"id","%d",pss->thread);
xml_output(pxml,"sourceip","%s",pss->host); xml_output(pxml,"sourceip","%s",pss->host);
xml_output(pxml,"action","%s",pss->what); xml_output(pxml,"action","%s",pss->what);
xml_pop(pxml); /* thread */ xml_pop(pxml,TRUE); /* thread */
} }
pci=ws_thread_enum_next(config.server,&wste); 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); 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, sprintf((char*)&buf[strlen(buf)],"%d second%s ", r_secs,
r_secs == 1 ? "" : "s"); r_secs == 1 ? "" : "s");
xml_push(pxml,"stat"); xml_push(pxml,"stat",TRUE);
xml_output(pxml,"name","Uptime"); xml_output(pxml,"name","Uptime");
xml_output(pxml,"value","%s",buf); 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"); xml_output(pxml,"name","Songs");
db_get_song_count(NULL,&count); db_get_song_count(NULL,&count);
xml_output(pxml,"value","%d",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,"name","Songs Served");
xml_output(pxml,"value","%d",config.stats.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,TRUE); /* statistics */
xml_pop(pxml); /* status */ xml_pop(pxml,TRUE); /* status */
xml_deinit(pxml); xml_deinit(pxml);
return; return;

View File

@ -15,10 +15,10 @@
struct tag_xmlstruct; struct tag_xmlstruct;
extern void xml_handle(WS_CONNINFO *pwsc); 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); int flags);
extern void xml_push(struct tag_xmlstruct *pxml, char *term); extern void xml_push(struct tag_xmlstruct *pxml, char *term, int container);
extern void xml_pop(struct tag_xmlstruct *pxml); 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_output(struct tag_xmlstruct *pxml, char *section, char *fmt, ...);
extern void xml_deinit(struct tag_xmlstruct *pxml); extern void xml_deinit(struct tag_xmlstruct *pxml);