src/hg/instinct/lib/json.c 1.6
1.6 2010/02/10 21:38:11 jsanborn
cleaned up
Index: src/hg/instinct/lib/json.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/instinct/lib/json.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -b -B -U 1000000 -r1.5 -r1.6
--- src/hg/instinct/lib/json.c 10 Feb 2010 21:35:35 -0000 1.5
+++ src/hg/instinct/lib/json.c 10 Feb 2010 21:38:11 -0000 1.6
@@ -1,339 +1,331 @@
/********************************************************************************/
/* Copyright 2007-2009 -- The Regents of the University of California */
/********************************************************************************/
/* json.c - a set of routines for organizing and outputting JSON-formatted objects, to
* communicate with JavaScript client
*/
#include "common.h"
#include "linefile.h"
#include "hash.h"
#include "json.h"
static char const rcsid[] = "$Id$";
void jsonWarning(char *format, va_list args)
{
-//printf("({ 'warning' : \"");
printf("{ 'warning' : \"");
/* newline characters screws up JSON parser, so remove any that may be in format str*/
format = replaceChars(format, "\n", " ");
vfprintf(stdout, format, args);
-//printf("\"})");
printf("\"}");
exit(-1);
}
void jsonWarnAbort(char *line, ...)
{
va_list args;
va_start(args, line);
jsonWarning(line, args);
va_end(args);
exit(-1);
}
void jsonEarlyWarningHandler(char *format, va_list args)
{ /* send error to client via JSON-formatted object, to avoid parsing error */
-//printf("({ 'err' : \"");
printf("{ 'err' : \"");
/* newline characters screws up JSON parser, so remove any that may be in format str*/
format = replaceChars(format, "\n", " ");
vfprintf(stdout, format, args);
-//printf("\"})");
printf("\"}");
exit(-1);
}
/* Default function, gets overwritten by each data type's particular append function */
void appendNothing(struct jsonObject *jo, struct dyString *dy)
{
return;
}
/* Allocate new JSON object */
struct jsonObject *newJsonObject(char *name, void *data)
{
struct jsonObject *jo = AllocA(struct jsonObject);
jo->name = NULL;
if (name)
jo->name = cloneString(name);
jo->data = data;
jo->appendVal = appendNothing;
return jo;
}
/* Append integer -- 'name' : 1212 */
void appendJsonInt(struct jsonObject *jo, struct dyString *dy)
{
if (!jo)
return;
struct slInt *sl = jo->data;
dyStringPrintf(dy, "'%s' : %d", jo->name, sl->val);
}
/* Add single integer */
void jsonAddInt(struct json *js, char *name, int val)
{
struct slInt *sl = AllocA(struct slInt);
sl->val = val;
struct jsonObject *jo = newJsonObject(name, (void *)sl);
jo->appendVal = appendJsonInt;
slAddHead(&js->objects, jo);
}
/* Append slInt list -- 'name' : [132, 14, ...] */
void appendJsonSlInt(struct jsonObject *jo, struct dyString *dy)
{
if (!jo)
return;
if (jo->name)
dyStringPrintf(dy, "'%s' : ", jo->name);
dyStringPrintf(dy, "[");
struct slInt *sl, *slList = jo->data;
for (sl = slList; sl; sl = sl->next)
{
dyStringPrintf(dy, "%d", sl->val);
if (sl->next)
dyStringPrintf(dy, ",");
}
dyStringPrintf(dy, "]");
}
/* Add slDouble list -- does NOT allocate new space, must keep input list in memory */
void jsonAddSlInt(struct json *js, char *name, struct slInt *slList)
{
struct jsonObject *jo = newJsonObject(name, (void *)slList);
jo->appendVal = appendJsonSlInt;
slAddHead(&js->objects, jo);
}
/* Append double -- 'name' : 1212.8 */
void appendJsonDouble(struct jsonObject *jo, struct dyString *dy)
{
if (!jo)
return;
struct slDouble *sl = jo->data;
dyStringPrintf(dy, "'%s' : %f", jo->name, sl->val);
}
/* Add single double */
void jsonAddDouble(struct json *js, char *name, double val)
{
struct slDouble *sl = AllocA(struct slDouble);
sl->val = val;
struct jsonObject *jo = newJsonObject(name, (void *)sl);
jo->appendVal = appendJsonDouble;
slAddHead(&js->objects, jo);
}
/* Append slDouble list -- 'name' : [132.0, 14.0, ...] */
void appendJsonSlDouble(struct jsonObject *jo, struct dyString *dy)
{
if (!jo)
return;
if (jo->name)
dyStringPrintf(dy, "'%s' : ", jo->name);
dyStringPrintf(dy, "[");
struct slDouble *sl, *slList = jo->data;
for (sl = slList; sl; sl = sl->next)
{
dyStringPrintf(dy, "%f", sl->val);
if (sl->next)
dyStringPrintf(dy, ",");
}
dyStringPrintf(dy, "]");
}
/* Add slDouble list -- does NOT allocate new space, must keep input list in memory */
void jsonAddSlDouble(struct json *js, char *name, struct slDouble *slList)
{
struct jsonObject *jo = newJsonObject(name, (void *)slList);
jo->appendVal = appendJsonSlDouble;
slAddHead(&js->objects, jo);
}
/* Append string -- 'name' : 'str' */
void appendJsonString(struct jsonObject *jo, struct dyString *dy)
{
if (!jo)
return;
char *str = jo->data;
if (str)
dyStringPrintf(dy, "'%s' : \"%s\"", jo->name, str);
else
dyStringPrintf(dy, "'%s' : \"\"", jo->name);
}
/* Add string -- makes local copy */
void jsonAddString(struct json *js, char *name, char *str)
{
char *data = cloneString(str);
struct jsonObject *jo = newJsonObject(name, (void *)data);
jo->appendVal = appendJsonString;
slAddHead(&js->objects, jo);
}
/* Append slName list -- 'name' : ['str1', 'str2', ...] */
void appendJsonSlName(struct jsonObject *jo, struct dyString *dy)
{
if (!jo)
return;
if (jo->name)
dyStringPrintf(dy, "'%s' : ", jo->name);
dyStringPrintf(dy, "[");
struct slName *sl, *slList = jo->data;
for (sl = slList; sl; sl = sl->next)
{
dyStringPrintf(dy, "\"%s\"", sl->name);
if (sl->next)
dyStringPrintf(dy, ",");
}
dyStringPrintf(dy, "]");
}
/* Add slName list -- does NOT allocate new space, must keep input list in memory */
void jsonAddSlName(struct json *js, char *name, struct slName *slList)
{
struct jsonObject *jo = newJsonObject(name, (void *)slList);
jo->appendVal = appendJsonSlName;
slAddHead(&js->objects, jo);
}
/* Append objects in container (whatever they may be) to growing string */
void appendObjects(struct jsonObject *joList, struct dyString *dy)
{
-//if (!joList)
-// return;
dyStringPrintf(dy, "{");
struct jsonObject *jo;
for (jo = joList; jo; jo = jo->next)
{
jo->appendVal(jo, dy);
if (jo->next)
dyStringPrintf(dy, ", ");
}
dyStringPrintf(dy, "}");
}
/* Append container -- 'name' : {'str1' : 1112.3, 'str2' : 'blah', ...} */
void appendContainer(struct jsonObject *jo, struct dyString *dy)
{
if (!jo)
return;
struct json *js = jo->data;
if (!js)
return;
dyStringPrintf(dy, "'%s' : ", jo->name);
slReverse(&js->objects);
appendObjects(js->objects, dy);
}
/* Add container to root container, return pointer to container so that objects
* may be put into it */
struct json *jsonAddContainer(struct json *js, char *name)
{ /* Container of objects, { ... } */
struct json *new = newJson();
struct jsonObject *jo = newJsonObject(name, (void *)new);
jo->appendVal = appendContainer;
slAddHead(&js->objects, jo);
return new;
}
/* Append list of containers -- 'name' : [{ ... }, { ... }, ...] */
void appendContainerList(struct jsonObject *jo, struct dyString *dy)
{
if (!jo)
return;
struct json *js, *jsList = jo->data;
if (!jsList)
return;
dyStringPrintf(dy, "'%s' : [", jo->name);
for (js = jsList; js; js = js->next)
{
slReverse(&js->objects);
appendObjects(js->objects, dy);
if (js->next)
dyStringPrintf(dy, ",");
}
dyStringPrintf(dy, "]");
}
/* Add list of containers */
struct json *jsonAddContainerList(struct json *js, char *name)
{
struct json *new = newJson();
struct jsonObject *jo = newJsonObject(name, (void *)new);
jo->appendVal = appendContainerList;
slAddHead(&js->objects, jo);
return new;
}
/* Add container end of container list, to retain original pointer */
struct json *jsonAddContainerToList(struct json **jsList)
{
struct json *new = newJson();
slAddTail(jsList, new);
return new;
}
/* Print root container, ({ ... }) */
char *printJson(struct json *js)
{
if (!js)
return NULL;
slReverse(&js->objects);
struct dyString *dy = newDyString(100);
-//dyStringPrintf(dy, "(");
appendObjects(js->objects, dy);
-//dyStringPrintf(dy, ")");
return dy->string;
}
struct json *newJson()
{ /* Root container of objects ({ ... }) */
struct json *js = AllocA(struct json);
js->objects = NULL;
js->print = printJson;
return js;
}