Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals

vars.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005, 2006 by KoanLogic s.r.l. <http://www.koanlogic.com>
00003  * All rights reserved.
00004  *
00005  * This file is part of KLone, and as such it is subject to the license stated
00006  * in the LICENSE file which you have received as part of this distribution.
00007  *
00008  * $Id: vars.c,v 1.23 2006/06/20 08:08:16 tat Exp $
00009  */
00010 
00011 #include "klone_conf.h"
00012 #include <sys/types.h>
00013 #include <stdlib.h>
00014 #include <u/libu.h>
00015 #include <klone/vars.h>
00016 #include <klone/varprv.h>
00017 #include <klone/utils.h>
00018 
00019 TAILQ_HEAD(var_list_s, var_s);
00020 
00021 struct vars_s
00022 {
00023     struct var_list_s list;     /* list of variables (var_t) */
00024     size_t count;               /* # of vars in the list     */
00025 };
00026 
00044 u_string_t *vars_get_value_s(vars_t *vs, const char *name)
00045 {
00046     var_t *v = NULL;
00047 
00048     dbg_err_if (vs == NULL);
00049     dbg_err_if (name == NULL);
00050 
00051     dbg_err_if((v = vars_get(vs, name)) == NULL);
00052 
00053     return var_get_value_s(v);
00054 err:
00055     return NULL;
00056 }
00057 
00058 int vars_create(vars_t **pvs)
00059 {
00060     vars_t *vs = NULL;
00061 
00062     dbg_err_if (pvs == NULL);
00063 
00064     vs = u_zalloc(sizeof(vars_t));
00065     dbg_err_if(vs == NULL);
00066 
00067     TAILQ_INIT(&vs->list);
00068 
00069     *pvs = vs;
00070 
00071     return 0;
00072 err:
00073     if(vs)
00074         vars_free(vs);
00075     return ~0;
00076 }
00077 
00078 int vars_free(vars_t *vs)
00079 {
00080     var_t *v;
00081 
00082     if(vs)
00083     {
00084         /* free all variables */
00085         while((v = TAILQ_FIRST(&vs->list)) != NULL)
00086         {
00087             vars_del(vs, v);
00088             var_free(v);
00089         }
00090         U_FREE(vs);
00091     }
00092 
00093     return 0;
00094 }
00095 
00096 int vars_add(vars_t *vs, var_t *v)
00097 {
00098     TAILQ_INSERT_TAIL(&vs->list, v, np);
00099     vs->count++;
00100 
00101     return 0;
00102 }
00103 
00104 int vars_del(vars_t *vs, var_t *v)
00105 {
00106     dbg_return_if (vs == NULL, ~0);
00107     dbg_return_if (v == NULL, ~0);
00108    
00109     TAILQ_REMOVE(&vs->list, v, np);
00110     vs->count--;
00111 
00112     return 0;
00113 }
00114 
00125 var_t *vars_getn(vars_t *vs, size_t i)
00126 {
00127     var_t *v;
00128 
00129     dbg_goto_if (vs == NULL, notfound);
00130     dbg_goto_if (i >= vs->count, notfound); /* out of bounds */
00131 
00132     TAILQ_FOREACH(v, &vs->list, np)
00133     {
00134         if(i-- == 0)
00135             return v;
00136     }
00137 
00138 notfound:
00139     return NULL;
00140 }
00141 
00151 size_t vars_count(vars_t *vs)
00152 {
00153     dbg_return_if (vs == NULL, 0);
00154 
00155     return vs->count;
00156 }
00157 
00168 size_t vars_countn(vars_t *vs, const char *name)
00169 {
00170     var_t *v;
00171     size_t c = 0;
00172 
00173     dbg_return_if (vs == NULL || name == NULL, 0);
00174 
00175     TAILQ_FOREACH(v, &vs->list, np)
00176     {
00177         if(strcasecmp(u_string_c(v->sname), name) == 0)
00178             c++;
00179     }
00180 
00181     return c;
00182 }
00183 
00196 int vars_add_urlvar(vars_t *vs, const char *cstr, var_t **v)
00197 {
00198     enum { NAMESZ = 256, VALSZ = 4096 };
00199     char sname[NAMESZ], svalue[VALSZ];
00200     char *val, *str = NULL, *name = sname, *value = svalue;
00201     var_t *var = NULL;
00202     ssize_t vsz;
00203 
00204     dbg_return_if (vs == NULL, ~0);
00205     dbg_return_if (cstr == NULL, ~0);
00206     /* v may be NULL */
00207         
00208     /* dup the string so we can modify it */
00209     str = u_strdup(cstr);
00210     dbg_err_if(str == NULL);
00211 
00212     val = strchr(str, '=');
00213     dbg_err_if(val == NULL);
00214 
00215     /* zero-term the name part and set the value pointer */
00216     *val++ = 0; 
00217 
00218     /* if the buffer on the stack is too small alloc a bigger one */
00219     if(strlen(str) >= NAMESZ)
00220         dbg_err_if((name = u_zalloc(1 + strlen(str))) == NULL);
00221 
00222     /* if the buffer on the stack is too small alloc a bigger one */
00223     if(strlen(val) >= VALSZ)
00224         dbg_err_if((value = u_zalloc(1 + strlen(val))) == NULL);
00225 
00226     /* url-decode var name */
00227     dbg_err_if(u_urlncpy(name, str, strlen(str), URLCPY_DECODE) <= 0);
00228 
00229     /* url-decode var value */
00230     dbg_err_if((vsz = u_urlncpy(value, val, strlen(val), URLCPY_DECODE)) <= 0);
00231 
00232     /* dbg("name: [%s]  value: [%s]", name, value); */
00233 
00234     /* u_urlncpy always add a \0 at the end of the resulting data block */
00235     --vsz;
00236 
00237     dbg_err_if(var_bin_create(name, value, vsz, &var));
00238 
00239     /* push into the var list */
00240     dbg_err_if(vars_add(vs, var));
00241 
00242     if(v)
00243         *v = var;
00244 
00245     /* if the buffer has been alloc'd on the heap then free it */
00246     if(value && value != svalue)
00247         U_FREE(value);
00248 
00249     if(name && name != sname)
00250         U_FREE(name);
00251 
00252     U_FREE(str);
00253 
00254     return 0;
00255 err:
00256     if(value && value != svalue)
00257         U_FREE(value);
00258     if(name && name != sname)
00259         U_FREE(name);
00260     if(cstr)
00261         dbg("%s", cstr);
00262     U_FREE(str);
00263     if(var)
00264         var_free(var);
00265     return ~0;
00266 }
00267 
00268 int vars_add_strvar(vars_t *vs, const char *str)
00269 {
00270     char *eq, *dups = NULL;
00271     var_t *var = NULL;
00272 
00273     dbg_err_if (vs == NULL);
00274     dbg_err_if (str == NULL);
00275 
00276     /* dup the string (str is const) */
00277     dups = u_strdup(str);
00278     dbg_err_if(dups == NULL);
00279 
00280     /* search the '=' and replace it with a '\0' */
00281     eq = strchr(dups, '=');
00282     dbg_err_if(eq == NULL);
00283     *eq = 0;
00284 
00285     /* create a new var obj */
00286     dbg_err_if(var_create(dups, eq+1, &var));
00287 
00288     U_FREE(dups);
00289 
00290     /* push into the cookie list */
00291     dbg_err_if(vars_add(vs, var));
00292 
00293     return 0;
00294 err:
00295     U_FREE(dups);
00296     if(var)
00297         var_free(var);
00298     return ~0;
00299 }
00300 
00314 var_t *vars_geti(vars_t *vs, const char *var_name, size_t i)
00315 {
00316     var_t *v;
00317 
00318     dbg_goto_if (vs == NULL, notfound);
00319     dbg_goto_if (var_name == NULL, notfound);
00320 
00321     TAILQ_FOREACH(v, &vs->list, np)
00322     {
00323         if(strcasecmp(u_string_c(v->sname), var_name) == 0)
00324         {
00325             if(i-- == 0)
00326                 return v;
00327         }
00328     }
00329 
00330 notfound:
00331     return NULL;
00332 }
00333 
00346 var_t *vars_get(vars_t *vs, const char *var_name)
00347 {
00348     dbg_return_if (vs == NULL, NULL);
00349     dbg_return_if (var_name == NULL, NULL);
00350 
00351     return vars_geti(vs, var_name, 0);
00352 }
00353 
00368 int vars_geti_value_i(vars_t *vs, const char *name, size_t ith)
00369 {
00370     const char *v;
00371 
00372     dbg_return_if (vs == NULL, 0);
00373     dbg_return_if (name == NULL, 0);
00374 
00375     v = vars_geti_value(vs, name, ith);
00376     if(v == NULL)
00377         return 0;
00378     else
00379         return atoi(v);
00380 }
00381 
00394 u_string_t *vars_geti_value_s(vars_t *vs, const char *name, size_t ith)
00395 {
00396     var_t *v = NULL;
00397 
00398     dbg_err_if (vs == NULL);
00399     dbg_err_if (name == NULL);
00400 
00401     dbg_err_if((v = vars_geti(vs, name, ith)) == NULL);
00402 
00403     return var_get_value_s(v);
00404 err:
00405     return NULL;
00406 }
00407 
00420 int vars_get_value_i(vars_t *vs, const char *name)
00421 {
00422     dbg_return_if (vs == NULL, 0);
00423     dbg_return_if (name == NULL, 0);
00424 
00425     return vars_geti_value_i(vs, name, 0);
00426 }
00427 
00442 const char *vars_geti_value(vars_t *vs, const char *name, size_t ith)
00443 {
00444     var_t *v;
00445 
00446     dbg_return_if (vs == NULL, NULL);
00447     dbg_return_if (name == NULL, NULL);
00448     
00449     v = vars_geti(vs, name, ith);
00450 
00451     return  v ? var_get_value(v) : NULL;
00452 }
00453 
00466 const char *vars_get_value(vars_t *vs, const char *name)
00467 {
00468     dbg_return_if (vs == NULL, NULL);
00469     dbg_return_if (name == NULL, NULL);
00470 
00471     return vars_geti_value(vs, name, 0);
00472 }
00473 
00486 void vars_foreach(vars_t *vs, int (*cb)(var_t *, void *), void *arg)
00487 {
00488     var_t *v;
00489 
00490     dbg_ifb (vs == NULL) return;
00491     dbg_ifb (cb == NULL) return;
00492 
00493     TAILQ_FOREACH(v, &vs->list, np)
00494     {
00495         if(cb(v, arg))
00496             break;
00497     }
00498 
00499     return;
00500 }
00501 

←Products
© 2005-2006 - KoanLogic S.r.l. - All rights reserved