16bf3131fb3d1d16304d67b33a68ecc662046cd1
kent
  Fri Mar 14 11:24:30 2014 -0700
Renaming dyJson* to jsonWrite* and eliminating isMiddle parameter.
diff --git src/lib/jsonWrite.c src/lib/jsonWrite.c
index 4f2d810..5883cc0 100644
--- src/lib/jsonWrite.c
+++ src/lib/jsonWrite.c
@@ -1,101 +1,154 @@
 /* jsonWrite - Helper routines for writing out JSON. 
  *
  * Apologies for the awkward 'isMiddle' parameter.  This is
  * from JSON not allowing a terminal comma for a comma separated
  * list.   A larger, more usable library might find a way to
  * take care of this for you. */
 
 #include "common.h"
 #include "hash.h"
 #include "dystring.h"
 #include "sqlNum.h"
 #include "jsonParse.h"
 #include "jsonWrite.h"
 
-void dyJsonTag(struct dyString *dy, char *var)
+struct jsonWrite *jsonWriteNew()
+/* Return new empty jsonWrite struct. */
+{
+struct jsonWrite *jw;
+AllocVar(jw);
+jw->dy = dyStringNew(0);
+return jw;
+}
+
+void jsonWriteFree(struct jsonWrite **pJw)
+/* Free up a jsonWrite object. */
+{
+struct jsonWrite *jw = *pJw;
+if (jw != NULL)
+    {
+    dyStringFree(&jw->dy);
+    freez(pJw);
+    }
+}
+
+static void jsonWritePushObjStack(struct jsonWrite *jw, bool val)
+/* Push val on stack */
+{
+int stackIx = jw->stackIx + 1;
+if (stackIx >= ArraySize(jw->objStack))
+    errAbort("Stack overflow in jsonWritePush");
+jw->objStack[stackIx] = val;
+jw->stackIx = stackIx;
+}
+
+static void jsonWritePopObjStack(struct jsonWrite *jw)
+/* pop object stack and just discard val. */
+{
+int stackIx = jw->stackIx - 1;
+if (stackIx < 0)
+    errAbort("Stack underflow in jsonWritePopObjStack");
+jw->stackIx = stackIx;
+}
+
+void jsonWriteTag(struct jsonWrite *jw, char *var)
 /* Print out quoted tag followed by colon */
 {
-dyStringPrintf(dy, "\"%s\": ", var);
+struct dyString *dy = jw->dy;
+if (jw->objStack[jw->stackIx] != 0)
+    dyStringAppend(dy, ",\n");
+else
+    jw->objStack[jw->stackIx] = 1;
+dyStringPrintf(jw->dy, "\"%s\": ", var);
 }
 
-void dyJsonEndLine(struct dyString *dy, boolean isMiddle)
+#ifdef OLD
+void jsonWriteEndLine(struct jsonWrite *jw)
 /* Write comma if in middle, and then newline regardless. */
 {
+struct dyString *dy = jw->dy;
 if (isMiddle)
    dyStringAppendC(dy, ',');
 dyStringAppendC(dy, '\n');
 }
+#endif /* OLD */
 
-void dyJsonString(struct dyString *dy, char *var, char *string, boolean isMiddle)
+void jsonWriteString(struct jsonWrite *jw, char *var, char *string)
 /* Print out "var": "val" */
 {
-dyJsonTag(dy, var);
+struct dyString *dy = jw->dy;
+jsonWriteTag(jw, var);
 dyStringPrintf(dy, "\"%s\"", string);
-dyJsonEndLine(dy, isMiddle);
 }
 
-void dyJsonDateFromUnix(struct dyString *dy, char *var, long long unixTimeVal, boolean isMiddle)
+void jsonWriteDateFromUnix(struct jsonWrite *jw, char *var, long long unixTimeVal)
 /* Add "var": YYYY-MM-DDT-HH:MM:SSZ given a Unix time stamp */
 {
+struct dyString *dy = jw->dy;
 time_t timeStamp = unixTimeVal;
 struct tm tm;
 gmtime_r(&timeStamp, &tm);
-dyJsonTag(dy, var);
+jsonWriteTag(jw, var);
 dyStringPrintf(dy, "\"%d:%02d:%02dT%02d:%02d:%02dZ\"",
     1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
-dyJsonEndLine(dy, isMiddle);
 }
 
-void dyJsonNumber(struct dyString *dy, char *var, long long val, boolean isMiddle)
+void jsonWriteNumber(struct jsonWrite *jw, char *var, long long val)
 /* print out "var": val as number */
 {
-dyJsonTag(dy, var);
+struct dyString *dy = jw->dy;
+jsonWriteTag(jw, var);
 dyStringPrintf(dy, "%lld", val);
-dyJsonEndLine(dy, isMiddle);
 }
 
-void dyJsonLink(struct dyString *dy, char *var, char *objRoot, char *name, boolean isMiddle)
+void jsonWriteLink(struct jsonWrite *jw, char *var, char *objRoot, char *name)
 /* Print out the jsony type link to another object.  objRoot will start and end with a '/'
  * and may have additional slashes in this usage. */
 {
-dyJsonTag(dy, var);
+struct dyString *dy = jw->dy;
+jsonWriteTag(jw, var);
 dyStringPrintf(dy, "\"%s%s\"", objRoot, name);
-dyJsonEndLine(dy, isMiddle);
 }
 
-void dyJsonLinkNum(struct dyString *dy, char *var, char *objRoot, long long id, boolean isMiddle)
+void jsonWriteLinkNum(struct jsonWrite *jw, char *var, char *objRoot, long long id)
 /* Print out the jsony type link to another object with a numerical id.  objRoot will start 
  * and end with a '/' and may have additional slashes in this usage. */
 {
-dyJsonTag(dy, var);
+struct dyString *dy = jw->dy;
+jsonWriteTag(jw, var);
 dyStringPrintf(dy, "\"%s%lld\"", objRoot, id);
-dyJsonEndLine(dy, isMiddle);
 }
 
-void dyJsonListStart(struct dyString *dy, char *var)
+void jsonWriteListStart(struct jsonWrite *jw, char *var)
 /* Start an array in JSON */
 {
-dyJsonTag(dy, var);
+struct dyString *dy = jw->dy;
+jsonWriteTag(jw, var);
 dyStringAppend(dy, "[\n");
+jsonWritePushObjStack(jw, FALSE);
 }
 
-void dyJsonListEnd(struct dyString *dy, boolean isMiddle)
+void jsonWriteListEnd(struct jsonWrite *jw)
 /* End an array in JSON */
 {
-dyStringAppendC(dy, ']');
-dyJsonEndLine(dy, isMiddle);
+struct dyString *dy = jw->dy;
+dyStringAppend(dy, "]\n");
+jsonWritePopObjStack(jw);
 }
 
-void dyJsonObjectStart(struct dyString *dy)
+void jsonWriteObjectStart(struct jsonWrite *jw)
 /* Print start of object */
 {
+struct dyString *dy = jw->dy;
 dyStringAppend(dy, "{\n");
+jsonWritePushObjStack(jw, FALSE);
 }
 
-void dyJsonObjectEnd(struct dyString *dy, boolean isMiddle)
+void jsonWriteObjectEnd(struct jsonWrite *jw)
 /* End object in JSON */
 {
-dyStringAppendC(dy, '}');
-dyJsonEndLine(dy, isMiddle);
+struct dyString *dy = jw->dy;
+dyStringAppend(dy, "}\n");
+jsonWritePopObjStack(jw);
 }