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

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 = calloc(1, sizeof(cp_vector));
00020     if (v == NULL) 
00021     {
00022         errno = ENOMEM;
00023         return NULL;
00024     }
00025 
00026     v->mem = 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 = 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         v->size = index + 2;
00118         v->mem = realloc(v->mem, v->size * sizeof(void *));
00119     }
00120 
00121     if ((v->mode & COLLECTION_MODE_DEEP) && 
00122             v->mem[index] != NULL && v->free_item != NULL)
00123         (*v->free_item)(v->mem[index]);
00124 
00125     if ((v->mode & COLLECTION_MODE_COPY) && element != NULL && v->copy_item != NULL)
00126         v->mem[index] = (*v->copy_item)(element);
00127     else
00128         v->mem[index] = element;
00129     
00130     return element;
00131 }
00132 
00133 void *cp_vector_add_element(cp_vector *v, void *element)
00134 {
00135     void *addr = NULL;
00136 
00137     if (v->head + 1 >= v->tail + v->size)
00138     {
00139         void **newptr = realloc(v->mem, 2 * v->size * sizeof(void *));
00140         if (newptr == NULL) return NULL;
00141         v->mem = newptr;
00142         if (v->head < v->tail)
00143         {
00144             memcpy(v->mem, &v->mem[v->size], v->head * sizeof(void *));
00145             v->head += v->size;
00146         }
00147         v->size *= 2;
00148     }
00149             
00150     if (v->mode & COLLECTION_MODE_COPY)
00151         v->mem[v->head] = (*v->copy_item)(element);
00152     else
00153         v->mem[v->head] = element;
00154     addr = v->mem[v->head];
00155     v->head = (v->head + 1) % v->size;
00156 
00157     return addr;
00158 }
00159 
00160 void *cp_vector_remove_element_at(cp_vector *v, int index)
00161 {
00162     void *rm = NULL;
00163     if (index >= v->head || index < 0) return NULL;
00164     rm = v->mem[index];
00165     memmove(&v->mem[index], &v->mem[index + 1], 
00166             (v->head - index) * sizeof(void *));
00167     v->head--;
00168     return rm;
00169 }
00170 
00171 int cp_vector_size(cp_vector *v)
00172 {
00173     return (v->head - v->tail + v->size) % v->size;
00174 }
00175 

Generated on Sat Dec 1 10:25:30 2007 for cprops by  doxygen 1.3.9.1