vector.c

00001 
00005 #include <stdlib.h>
00006 #include <string.h>
00007 #include <errno.h>
00008 
00009 #include "log.h"
00010 #include "common.h"
00011 
00012 #include "vector.h"
00013 
00014 cp_vector *cp_vector_create_by_option(int size, 
00015                                       int mode, 
00016                                       cp_copy_fn copy_item,
00017                                       cp_destructor_fn free_item)
00018 {
00019     cp_vector *v = (cp_vector *) calloc(1, sizeof(cp_vector));
00020     if (v == NULL) 
00021     {
00022         errno = ENOMEM;
00023         return NULL;
00024     }
00025 
00026     v->mem = (void **) calloc(size, sizeof(void *));
00027     if (v->mem == NULL)
00028     {
00029         errno = ENOMEM;
00030         return NULL;
00031     }
00032 
00033     v->size = size;
00034     v->mode = mode;
00035     v->copy_item = copy_item;
00036     v->free_item = free_item;
00037     v->head = v->tail = 0;
00038 
00039     return v;
00040 }
00041 
00042 cp_vector *cp_vector_create(int size)
00043 {
00044     return cp_vector_create_by_option(size, 0, NULL, NULL);
00045 }
00046 
00047 cp_vector *cp_vector_wrap(void **data, int len, int mode)
00048 {
00049     cp_vector *v = (cp_vector *) calloc(1, sizeof(cp_vector));
00050     if (v == NULL) return NULL;
00051 
00052     v->mem = data;
00053     v->size = len;
00054     v->mode = mode;
00055     v->head = len;
00056     v->tail = 0;
00057 
00058     return v;
00059 }
00060 
00061 void cp_vector_destroy(cp_vector *v)
00062 {
00063     if (v)
00064     {
00065         if ((v->mode & COLLECTION_MODE_DEEP) && v->free_item != NULL)
00066         {
00067             int i;
00068             int n = cp_vector_size(v);
00069             void *item;
00070             for (i = 0; i < n; i++)
00071             {
00072                 item = cp_vector_element_at(v, i);
00073                 if (item) (*v->free_item)(item);
00074             }
00075         }
00076         free(v->mem);
00077         free(v);
00078     }
00079 }
00080 
00081 void cp_vector_destroy_custom(cp_vector *v, cp_destructor_fn dtr)
00082 {
00083     if (v)
00084     {
00085         int i;
00086         int n = cp_vector_size(v);
00087 
00088         if (dtr)
00089         {
00090             for (i = 0; i < n; i++)
00091                 if (v->mem[i]) (*dtr)(v->mem[i]);
00092         }
00093     
00094         free(v->mem);
00095         free(v);
00096     }
00097 }
00098 
00099 void *cp_vector_element_at(cp_vector *v, int index)
00100 {
00101     return index >= 0 && index <= cp_vector_size(v) ? v->mem[index] : NULL;
00102 }
00103 
00104 void *cp_vector_set_element(cp_vector *v, int index, void *element)
00105 {
00106     if (index < 0)
00107     {
00108         errno = EINVAL;
00109         return NULL;
00110     }
00111 
00112     if (index >= v->head)
00113         v->head = index + 1;
00114 
00115     if (v->head >= v->size)
00116     {
00117         void **p;
00118         v->size = index + 2;
00119         p = (void **) realloc(v->mem, v->size * sizeof(void *));
00120         if (p == NULL)
00121         {
00122             errno = ENOMEM;
00123             return NULL;
00124         }
00125         v->mem = p;
00126     }
00127 
00128     if ((v->mode & COLLECTION_MODE_DEEP) && 
00129             v->mem[index] != NULL && v->free_item != NULL)
00130         (*v->free_item)(v->mem[index]);
00131 
00132     if ((v->mode & COLLECTION_MODE_COPY) && element != NULL && v->copy_item != NULL)
00133         v->mem[index] = (*v->copy_item)(element);
00134     else
00135         v->mem[index] = element;
00136     
00137     return element;
00138 }
00139 
00140 void *cp_vector_add_element(cp_vector *v, void *element)
00141 {
00142     void *addr = NULL;
00143 
00144     if (v->head + 1 >= v->tail + v->size)
00145     {
00146         void **newptr = (void **) realloc(v->mem, 2 * v->size * sizeof(void *));
00147         if (newptr == NULL) 
00148         {
00149             errno = ENOMEM;
00150             return NULL;
00151         }
00152         v->mem = newptr;
00153         if (v->head < v->tail)
00154         {
00155             memcpy(v->mem, &v->mem[v->size], v->head * sizeof(void *));
00156             v->head += v->size;
00157         }
00158         v->size *= 2;
00159     }
00160             
00161     if (v->mode & COLLECTION_MODE_COPY)
00162         v->mem[v->head] = (*v->copy_item)(element);
00163     else
00164         v->mem[v->head] = element;
00165     addr = v->mem[v->head];
00166     v->head = (v->head + 1) % v->size;
00167 
00168     return addr;
00169 }
00170 
00171 void *cp_vector_remove_element_at(cp_vector *v, int index)
00172 {
00173     void *rm = NULL;
00174     if (index >= v->head || index < 0) return NULL;
00175     rm = v->mem[index];
00176     memmove(&v->mem[index], &v->mem[index + 1], 
00177             (v->head - index) * sizeof(void *));
00178     v->head--;
00179     return rm;
00180 }
00181 
00182 int cp_vector_size(cp_vector *v)
00183 {
00184     return (v->head - v->tail + v->size) % v->size;
00185 }
00186 

Generated on Mon Dec 5 23:00:22 2011 for cprops by  doxygen 1.4.7