b2f0702d9548acaf85fd929834bf5bce52af4d99
kent
  Mon Feb 9 15:20:53 2015 -0800
Adding cgiEncodeHash and cgiParseNext functions.

diff --git src/lib/cheapcgi.c src/lib/cheapcgi.c
index af0730f..3cff88e 100644
--- src/lib/cheapcgi.c
+++ src/lib/cheapcgi.c
@@ -624,30 +624,64 @@
 }
 
 void cgiDictionaryFreeList(struct cgiDictionary **pList)
 /* Free up a whole list of cgiDictionaries */
 {
 struct cgiDictionary *el, *next;
 
 for (el = *pList; el != NULL; el = next)
     {
     next = el->next;
     cgiDictionaryFree(&el);
     }
 *pList = NULL;
 }
 
+boolean cgiParseNext(char **pInput, char **retVar, char **retVal)
+/* Parse out next var/val in a var=val&var=val... cgi formatted string 
+ * This will insert zeroes and other things into string. 
+ * Usage:
+ *     char *pt = cgiStringStart;
+ *     char *var, *val
+ *     while (cgiParseNext(&pt, &var, &val))
+ *          printf("%s\t%s\n", var, val); */
+{
+char *var = *pInput;
+if (var == NULL || var[0] == 0)
+    return FALSE;
+char *val = strchr(var, '=');
+if (val == NULL)
+    errAbort("Mangled CGI input string %s", var);
+*val++ = 0;
+char *end = strchr(val, '&');
+if (end == NULL)
+    end = strchr(val, ';');  // For DAS
+if (end == NULL)
+    {
+    end = val + strlen(val);
+    *pInput = NULL;
+    }
+else
+    {
+    *pInput = end+1;
+    *end = 0;
+    }
+*retVar = var;
+*retVal = val;
+cgiDecode(val,val,end-val);
+return TRUE;
+}
 
 void cgiParseInputAbort(char *input, struct hash **retHash,
         struct cgiVar **retList)
 /* Parse cgi-style input into a hash table and list.  This will alter
  * the input data.  The hash table will contain references back
  * into input, so please don't free input until you're done with
  * the hash. Prints message aborts if there's an error.
  * To clean up - slFreeList, hashFree, and only then free input. */
 {
 char *namePt, *dataPt, *nextNamePt;
 struct hash *hash = *retHash;
 struct cgiVar *list = *retList, *el;
 
 if (!hash)
   hash = newHash(6);
@@ -2292,15 +2326,37 @@
 }
 
 void cgiParsedVarsFree(struct cgiParsedVars **pTags)
 /* Free up memory associated with cgiParsedVars */
 {
 struct cgiParsedVars *tags = *pTags;
 if (tags != NULL)
     {
     slFreeList(&tags->list);
     hashFree(&tags->hash);
     freeMem(tags->stringBuf);
     freez(pTags);
     }
 }
 
+void cgiEncodeHash(struct hash *hash, struct dyString *dy)
+/* Put a cgi-encoding of a string valued hash into dy.  Tags are always
+ * alphabetical to make it easier to compare if two hashes are same. */
+{
+struct hashEl *el, *elList = hashElListHash(hash);
+slSort(&elList, hashElCmp);
+boolean firstTime = TRUE;
+char *s = NULL;
+for (el = elList; el != NULL; el = el->next)
+    {
+    if (firstTime)
+	firstTime = FALSE;
+    else
+	dyStringAppendC(dy, '&');
+    dyStringAppend(dy, el->name);
+    dyStringAppendC(dy, '=');
+    s = cgiEncode(el->val);
+    dyStringAppend(dy, s);
+    freez(&s);
+    }
+hashElFreeList(&elList);
+}