src/server/util/util.c

changeset 81
d25825f37967
parent 77
f1cff81e425a
child 91
fac51f87def0
--- a/src/server/util/util.c	Wed Jun 26 17:14:45 2013 +0200
+++ b/src/server/util/util.c	Fri Jun 28 14:52:35 2013 +0200
@@ -255,6 +255,87 @@
 // TODO: asprintf
 
 
+
+/* -------------------------- util_uri_unescape --------------------------- */
+
+NSAPI_PUBLIC void util_uri_unescape(char *s)
+{
+    char *t, *u;
+
+    for(t = s, u = s; *t; ++t, ++u) {
+        if((*t == '%') && t[1] && t[2]) {
+            *u = ((t[1] >= 'A' ? ((t[1] & 0xdf) - 'A')+10 : (t[1] - '0'))*16) +
+                  (t[2] >= 'A' ? ((t[2] & 0xdf) - 'A')+10 : (t[2] - '0'));
+            t += 2;
+        }
+        else
+            if(u != t)
+                *u = *t;
+    }
+    *u = *t;
+}
+
+/*
+ * Same as util_uri_unescape, but returns success/failure
+ */
+NSAPI_PUBLIC int util_uri_unescape_strict(char *s)
+{
+    char *t, *u, t1, t2;
+    int rv = 1;
+
+    for(t = s, u = s; *t; ++t, ++u) {
+        if (*t == '%') {
+            t1 = t[1] & 0xdf; /* [a-f] -> [A-F] */
+            if ((t1 < 'A' || t1 > 'F') && (t[1] < '0' || t[1] > '9'))
+                rv = 0;
+
+            t2 = t[2] & 0xdf; /* [a-f] -> [A-F] */
+            if ((t2 < 'A' || t2 > 'F') && (t[2] < '0' || t[2] > '9'))
+                rv = 0;
+
+            *u = ((t[1] >= 'A' ? ((t[1] & 0xdf) - 'A')+10 : (t[1] - '0'))*16) +
+                  (t[2] >= 'A' ? ((t[2] & 0xdf) - 'A')+10 : (t[2] - '0'));
+            t += 2;
+        }
+        else if (u != t)
+            *u = *t;
+    }
+    *u = *t;
+
+    return rv;
+}
+
+
+NSAPI_PUBLIC int
+util_uri_unescape_plus (const char *src, char *trg, int len)
+{
+    const char *t = src;
+    char *u = trg == NULL ? (char *)src : trg;
+    int	rlen = 0;
+
+    if (len == -1)
+        len = strlen (src);
+
+    for( ; len && *t; ++t, ++u, len--, rlen++)
+    {
+        if((*t == '%') && t[1] && t[2])
+        {
+            *u = ((t[1] >= 'A' ? ((t[1] & 0xdf) - 'A') + 10 : (t[1] - '0')) * 16) +
+                  (t[2] >= 'A' ? ((t[2] & 0xdf) - 'A') + 10 : (t[2] - '0'));
+            t  += 2;
+            len-= 2;
+        }
+        else
+            if (*t == '+')
+                *u = ' ';
+            else
+                *u = *t;
+    }
+    *u = 0;
+    return rlen;
+}
+
+
 NSAPI_PUBLIC int INTutil_getboolean(const char *v, int def) {
     if(v[0] == 'T' || v[0] == 't') {
         return 1;
@@ -379,32 +460,7 @@
     return 500;
 }
 
-NSAPI_PUBLIC int util_uri_unescape_strict(char *s)
-{
-    char *t, *u, t1, t2;
-    int rv = 1;
 
-    for(t = s, u = s; *t; ++t, ++u) {
-        if (*t == '%') {
-            t1 = t[1] & 0xdf; /* [a-f] -> [A-F] */
-            if ((t1 < 'A' || t1 > 'F') && (t[1] < '0' || t[1] > '9'))
-                rv = 0;
-
-            t2 = t[2] & 0xdf; /* [a-f] -> [A-F] */
-            if ((t2 < 'A' || t2 > 'F') && (t[2] < '0' || t[2] > '9'))
-                rv = 0;
-
-            *u = ((t[1] >= 'A' ? ((t[1] & 0xdf) - 'A')+10 : (t[1] - '0'))*16) +
-                  (t[2] >= 'A' ? ((t[2] & 0xdf) - 'A')+10 : (t[2] - '0'));
-            t += 2;
-        }
-        else if (u != t)
-            *u = *t;
-    }
-    *u = *t;
-
-    return rv;
-}
 
 NSAPI_PUBLIC
 sstr_t util_path_append(pool_handle_t *pool, char *path, char *ch) {
@@ -453,3 +509,62 @@
     }
     return path;
 }
+
+
+// new - code in parts from params.cpp
+NSAPI_PUBLIC pblock* util_parse_param(pool_handle_t *pool, char *query) {
+    pblock *pb = pblock_create_pool(pool, 32);
+    if(!pb) {
+        return NULL;
+    }
+    if(!query || !(*query)) {
+        return pb;
+    }
+    
+    int loopFlag = 1;
+    int nl = 0;	// size of the name substring
+    int vl = 0;	// size of the value substring
+    int state = 0;
+    const char *np = query;
+    const char *vp = NULL;
+    
+    while (loopFlag) {
+        char delim = *query++;
+        switch (delim) {
+            case '&':
+            case '\0': {
+                if(!delim) {
+                    loopFlag = 0;
+                }
+                
+                state = 0;
+                
+                if(nl > 0) {
+                    util_uri_unescape_plus(np, NULL, nl);
+                    util_uri_unescape_plus(vp, NULL, vl);
+                    pblock_nvlinsert(np, nl, vp, vl, pb);
+                }
+                
+                nl = 0;
+                vl = 0;
+                vp = NULL;
+                np = query;
+                break;
+            }
+            case '=': {
+                state = 1;
+                vp = query;
+                break;
+            }
+            default: {
+                if(state) {
+                    vl++;
+                } else {
+                    nl++;
+                }
+            }
+        } /* switch */
+    } /* while */
+
+    return pb;
+}

mercurial