00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <stdarg.h>
00029
00030 #include <libxml/uri.h>
00031 #include "qparams.h"
00032 #include <string.h>
00033
00034 struct qparam_set *
00035 new_qparam_set (int init_alloc, ...)
00036 {
00037 va_list args;
00038 struct qparam_set *ps;
00039 const char *pname, *pvalue;
00040
00041 if (init_alloc <= 0) init_alloc = 1;
00042
00043
00044 ps = (struct qparam_set *)calloc( 1, sizeof(*(ps)));
00045 if( !ps ) {
00046 return NULL;
00047 }
00048
00049 ps->n = 0;
00050 ps->alloc = init_alloc;
00051
00052 ps->p = (struct qparam *) calloc( ps->alloc, sizeof(*(ps->p)));
00053
00054 if (!ps->p) {
00055 free(ps);
00056 return NULL;
00057 }
00058
00059 va_start (args, init_alloc);
00060 while ((pname = va_arg (args, char *)) != NULL) {
00061 pvalue = va_arg (args, char *);
00062
00063 if (append_qparam (ps, pname, pvalue) == -1) {
00064 free_qparam_set (ps);
00065 ps = NULL;
00066 break;
00067 }
00068 }
00069 va_end (args);
00070
00071 return ps;
00072 }
00073
00074 int
00075 append_qparams (struct qparam_set *ps, ...)
00076 {
00077 va_list args;
00078 const char *pname, *pvalue;
00079 int ret = 0;
00080
00081 va_start (args, ps);
00082 while ((pname = va_arg (args, char *)) != NULL) {
00083 pvalue = va_arg (args, char *);
00084
00085 if (append_qparam (ps, pname, pvalue) == -1) {
00086 ret = -1;
00087 break;
00088 }
00089 }
00090 va_end (args);
00091
00092 return ret;
00093 }
00094
00095
00096
00097
00098 static int
00099 grow_qparam_set (struct qparam_set *ps)
00100 {
00101 if (ps->n >= ps->alloc) {
00102
00103 void *tmp = realloc( ps->p, ps->alloc * 2);
00104 if( !tmp ) {
00105 return -1;
00106 }
00107 ps->p = (struct qparam *)tmp;
00108 ps->alloc *= 2;
00109 }
00110
00111 return 0;
00112 }
00113
00114 int
00115 append_qparam (struct qparam_set *ps,
00116 const char *name, const char *value)
00117 {
00118 char *pname, *pvalue;
00119
00120 pname = strdup (name);
00121 if (!pname) {
00122 return -1;
00123 }
00124
00125 pvalue = strdup (value);
00126 if (!pvalue) {
00127 free(pname);
00128 return -1;
00129 }
00130
00131 if (grow_qparam_set (ps) == -1) {
00132 free(pname);
00133 free(pvalue);
00134 return -1;
00135 }
00136
00137 ps->p[ps->n].name = pname;
00138 ps->p[ps->n].value = pvalue;
00139 ps->p[ps->n].ignore = 0;
00140 ps->n++;
00141
00142 return 0;
00143 }
00144
00145 void
00146 free_qparam_set (struct qparam_set *ps)
00147 {
00148 int i;
00149
00150 for (i = 0; i < ps->n; ++i) {
00151 free(ps->p[i].name);
00152 free(ps->p[i].value);
00153 }
00154 free(ps->p);
00155 ps->p = NULL;
00156 free(ps);
00157 }
00158
00159 struct qparam_set *
00160 qparam_query_parse (const char *query)
00161 {
00162 struct qparam_set *ps;
00163 const char *end, *eq;
00164
00165 ps = new_qparam_set (0, NULL);
00166 if (!ps) {
00167 return NULL;
00168 }
00169
00170 if (!query || query[0] == '\0') return ps;
00171
00172 while (*query) {
00173 char *name = NULL, *value = NULL;
00174
00175
00176 end = strchr (query, '&');
00177 if (!end)
00178 end = strchr (query, ';');
00179 if (!end)
00180 end = query + strlen (query);
00181
00182
00183 eq = strchr (query, '=');
00184 if (eq && eq >= end) eq = NULL;
00185
00186
00187 if (end == query)
00188 goto next;
00189
00190
00191
00192
00193 else if (!eq) {
00194 name = xmlURIUnescapeString (query, end - query, NULL);
00195 if (!name) goto out_of_memory;
00196 }
00197
00198
00199
00200 else if (eq+1 == end) {
00201 name = xmlURIUnescapeString (query, eq - query, NULL);
00202 if (!name) goto out_of_memory;
00203 }
00204
00205
00206
00207 else if (query == eq)
00208 goto next;
00209
00210
00211 else {
00212 name = xmlURIUnescapeString (query, eq - query, NULL);
00213 if (!name)
00214 goto out_of_memory;
00215 value = xmlURIUnescapeString (eq+1, end - (eq+1), NULL);
00216 if (!value) {
00217 free(name);
00218 goto out_of_memory;
00219 }
00220 }
00221
00222
00223 if (append_qparam (ps, name, value ? value : "") == -1) {
00224 free(name);
00225 free(value);
00226 goto out_of_memory;
00227 }
00228 free(name);
00229 free(value);
00230
00231 next:
00232 query = end;
00233 if (*query) query ++;
00234 }
00235
00236 return ps;
00237
00238 out_of_memory:
00239 free_qparam_set (ps);
00240 return NULL;
00241 }