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); }