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

ks_assoc.c

Go to the documentation of this file.
00001 /*
00002  * libkarmaclient - A C Library to the Karmasphere Reputation Server
00003  * Copyright (C) 2006 Karmasphere <http://www.karmasphere.com/>
00004  *  - Shevek <shevek@karmasphere.com>
00005  *  - Dave Stewart <dave.stewart@karmasphere.com>
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00020  */
00021 
00030 #include "ks_config.h"
00031 #include "ks_assoc.h"
00032 #include "ks_string.h"
00033 
00034 #ifdef HAVE_STRING_H
00035 #include <string.h>
00036 #endif
00037 
00038 #ifdef HAVE_STDIO_H
00039 #include <stdio.h>
00040 #endif
00041 
00042 static ks_type_t * ks_bucket_type(void);
00043 
00052 static void
00053 ks_bucket_free(ks_bucket_t *b)
00054 {
00055         ks_free(b->key);
00056         ks_destroy(b->data);
00057         ks_free(b);
00058 }
00059 
00070 static void
00071 ks_bucket_bappend(ks_string_t *r, ks_base_t *b)
00072 {
00073         ks_bucket_t     *u = KS_CAST(ks_bucket, b);
00074         char             buf[32];
00075 
00076         snprintf(buf, 31, "%d", u->klen);
00077         buf[31] = '\0';
00078         ks_string_append(r, buf, strlen(buf));
00079         ks_string_append(r, ":", 1);
00080         ks_string_append(r, u->key, u->klen);
00081         ks_bappend(r, u->data);
00082 }
00083 
00094 static int
00095 ks_bucket_keycompare(const ks_base_t *a, const ks_base_t *b)
00096 {
00097 #if 0
00098         const ks_bucket_t       *aa = KS_CAST(ks_bucket, a);
00099         const ks_bucket_t       *bb = KS_CAST(ks_bucket, b);
00100 #else
00101         const ks_bucket_t       *aa = (ks_bucket_t *)a;
00102         const ks_bucket_t       *bb = (ks_bucket_t *)b;
00103 #endif
00104         size_t   len = aa->klen;
00105         int              cmp;
00106         if (bb->klen < len)
00107                 len = bb->klen;
00108         cmp = memcmp(aa->key, bb->key, len);
00109         if (cmp != 0)
00110                 return cmp;
00111         return bb->klen - aa->klen;
00112 }
00113 
00124 static void
00125 ks_assoc_bappend(ks_string_t *r, ks_base_t *b)
00126 {
00127         ks_assoc_t      *s = KS_CAST(ks_assoc, b);
00128         ks_array_t      *a = &(s->array);
00129         int                      i;
00130         ks_string_append(r, "d", 1);
00131         ks_array_sort(a, ks_bucket_keycompare);
00132         for (i = 0; i < ks_array_length(a); i++)
00133                 ks_bappend(r, ks_array_get(a, i));
00134         ks_string_append(r, "e", 1);
00135 }
00136 
00140 static ks_type_t ks_type_bucket = {
00141         "ks_bucket",                    
00142         (ks_destroy_t)ks_bucket_free,   
00143         (ks_bappend_t)ks_bucket_bappend 
00144 };
00145 
00151 static ks_type_t *
00152 ks_bucket_type(void)
00153 {
00154         return &ks_type_bucket;
00155 }
00156 
00160 static ks_type_t ks_type_assoc = {
00161         "ks_assoc",                    
00162         (ks_destroy_t)ks_assoc_free,   
00163         (ks_bappend_t)ks_assoc_bappend 
00164 };
00165 
00171 ks_type_t *
00172 ks_assoc_type(void)
00173 {
00174         return &ks_type_assoc;
00175 }
00176 
00187 static ks_bucket_t *
00188 ks_bucket_new(const char *key, size_t len, ks_base_t *data)
00189 {
00190         ks_bucket_t     *b = (ks_bucket_t *)ks_malloc(sizeof(ks_bucket_t));
00191         b->base.type = &ks_type_bucket;
00192         b->key = (char *) ks_malloc(len);
00193         b->klen = len;
00194         memcpy(b->key, key, len);
00195         b->data = data;
00196         return b;
00197 }
00198 
00209 void
00210 ks_assoc_init(ks_assoc_t *s)
00211 {
00212         s->base.type = &ks_type_assoc;
00213         ks_array_init(&(s->array));
00214 }
00215 
00221 ks_assoc_t *
00222 ks_assoc_new(void)
00223 {
00224         ks_assoc_t      *s = (ks_assoc_t *)ks_malloc(sizeof(ks_assoc_t));
00225         ks_assoc_init(s);
00226         return s;
00227 }
00228 
00237 void
00238 ks_assoc_fini(ks_assoc_t *s)
00239 {
00240         ks_array_fini(&(s->array));
00241 }
00242 
00250 void
00251 ks_assoc_free(ks_assoc_t *s)
00252 {
00253         ks_assoc_fini(s);
00254         ks_free(s);
00255 }
00256 
00267 static ks_bucket_t *
00268 ks_assoc_bucket_find(ks_assoc_t *s, const char *key, size_t klen)
00269 {
00270         ks_array_t      *a = &(s->array);
00271         int     i;
00272         for (i = 0; i < ks_array_length(a); i++) {
00273                 ks_bucket_t     *b = KS_CAST(ks_bucket, ks_array_get(a, i));
00274                 if (klen == b->klen)
00275                         if (memcmp(key, b->key, b->klen) == 0)
00276                                 return b;
00277         }
00278         return NULL;
00279 }
00280 
00294 void
00295 ks_assoc_put(ks_assoc_t *s, const char *key, size_t len, ks_base_t *ptr)
00296 {
00297         ks_bucket_t     *b = ks_assoc_bucket_find(s, key, len);
00298         if (b == NULL) {
00299                 ks_array_t      *a = &(s->array);
00300                 b = ks_bucket_new(key, len, ptr);
00301                 ks_array_add(a, (ks_base_t *)b);
00302         }
00303         else {
00304                 ks_destroy(b->data);
00305                 b->data = ptr;
00306         }
00307 }
00308 
00318 ks_base_t *
00319 ks_assoc_get(ks_assoc_t *s, const char *key, size_t len)
00320 {
00321         ks_bucket_t     *b = ks_assoc_bucket_find(s, key, len);
00322         if (b == NULL)
00323                 return NULL;
00324         return b->data;
00325 }
00326 
00334 int
00335 ks_assoc_size(ks_assoc_t *s)
00336 {
00337         ks_array_t      *a = &(s->array);
00338         return ks_array_length(a);
00339 }
00340 
00349 ks_array_t *
00350 ks_assoc_keys(ks_assoc_t *s)
00351 {
00352         ks_array_t      *a = &(s->array);
00353         ks_array_t      *o = ks_array_new();
00354         int     i;
00355         for (i = 0; i < ks_array_length(a); i++) {
00356                 ks_bucket_t     *b = KS_CAST(ks_bucket, ks_array_get(a, i));
00357                 ks_string_t     *r = ks_string_new(b->key, b->klen);
00358                 ks_array_add(o, (ks_base_t *)r);
00359         }
00360         return o;
00361 }

Generated on Tue Aug 7 21:11:30 2007 for libkarmaclient by  doxygen 1.4.4