Go to the documentation of this file.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
00027
00028
00029
00030
00031
00032
00033 #if !defined (_ink_string_pp_h_)
00034 #define _ink_string_pp_h_
00035 #include <stdio.h>
00036 #include <strings.h>
00037
00038
00039
00040
00041
00042
00043
00044 static inline void
00045 _memcpy(char *dest, const char *src, int nbytes)
00046 {
00047 for (int i = 0; i < nbytes; i++)
00048 dest[i] = src[i];
00049 }
00050
00051
00052
00053
00054
00055
00056
00057
00058 static inline int
00059 _strlen(const char *src)
00060 {
00061 const char *old_src = src;
00062 while (*src)
00063 src++;
00064 return (int) (src - old_src);
00065 }
00066
00067
00068
00069
00070
00071
00072
00073 struct Str
00074 {
00075 const char *str;
00076 size_t len;
00077 struct Str *next;
00078 struct Str *prev;
00079
00080 Str():str(NULL), len(0), next(NULL), prev(NULL)
00081 {
00082 }
00083 Str(char *s)
00084 {
00085 str = s;
00086 len = strlen(s);
00087 next = NULL;
00088 prev = NULL;
00089 }
00090 Str(char *s, int l)
00091 {
00092 str = s;
00093 len = l;
00094 next = NULL;
00095 prev = NULL;
00096 }
00097
00098 void clean()
00099 {
00100 str = NULL;
00101 len = 0;
00102 next = NULL;
00103 prev = NULL;
00104 }
00105
00106 void dump(FILE * fp = stderr) {
00107 fprintf(fp, "Str [\"%.*s\", len %d]\n", (int) len, str, (int) len);
00108 }
00109 };
00110
00111
00112
00113
00114
00115
00116
00117 #define STRLIST_BASE_HEAP_SIZE 128
00118 #define STRLIST_OVERFLOW_HEAP_SIZE 1024
00119 #define STRLIST_BASE_CELLS 5
00120
00121 struct StrListOverflow;
00122
00123 struct StrList
00124 {
00125 public:
00126 int count;
00127 Str *head;
00128 Str *tail;
00129
00130 public:
00131 StrList(bool do_copy_when_adding_string = true);
00132 ~StrList();
00133
00134 Str *get_idx(int i);
00135 void append(Str * str);
00136 void prepend(Str * str);
00137 void add_after(Str * prev, Str * str);
00138 void detach(Str * str);
00139
00140 Str *new_cell(const char *s, int len_not_counting_nul);
00141 Str *append_string(const char *s, int len_not_counting_nul);
00142
00143 void dump(FILE * fp = stderr);
00144
00145 private:
00146 void init();
00147 void clean();
00148
00149 void *base_heap_alloc(int size);
00150 void *alloc(int size);
00151 Str *_new_cell(const char *s, int len_not_counting_nul);
00152 void *overflow_heap_alloc(int size);
00153 void overflow_heap_clean();
00154
00155 Str base_cells[STRLIST_BASE_CELLS];
00156 char base_heap[STRLIST_BASE_HEAP_SIZE];
00157 int cells_allocated;
00158 int base_heap_size;
00159 int base_heap_used;
00160 StrListOverflow *overflow_current;
00161 StrListOverflow *overflow_first;
00162 bool copy_when_adding_string;
00163 };
00164
00165 struct StrListOverflow
00166 {
00167 StrListOverflow *next;
00168 int heap_size;
00169 int heap_used;
00170
00171 void init();
00172 void clean();
00173 void *alloc(int size, StrListOverflow ** new_heap_ptr);
00174 static StrListOverflow *create_heap(int user_size);
00175 };
00176
00177 inline void
00178 StrList::init()
00179 {
00180 count = 0;
00181 cells_allocated = 0;
00182 head = tail = NULL;
00183 base_heap_size = STRLIST_BASE_HEAP_SIZE;
00184 base_heap_used = 0;
00185 overflow_first = NULL;
00186 overflow_current = NULL;
00187 }
00188
00189 inline void
00190 StrList::clean()
00191 {
00192 if (overflow_first)
00193 overflow_heap_clean();
00194 init();
00195 }
00196
00197 inline
00198 StrList::StrList(bool do_copy_when_adding_string)
00199 {
00200 memset(base_heap, 0, sizeof(base_heap));
00201 copy_when_adding_string = do_copy_when_adding_string;
00202 init();
00203 }
00204
00205 inline
00206 StrList::~
00207 StrList()
00208 {
00209 clean();
00210 }
00211
00212 inline void *
00213 StrList::base_heap_alloc(int size)
00214 {
00215 char *p;
00216
00217 if (size <= (base_heap_size - base_heap_used)) {
00218 p = &(base_heap[base_heap_used]);
00219 base_heap_used += size;
00220 return ((void *) p);
00221 } else
00222 return (NULL);
00223 }
00224
00225 inline void *
00226 StrList::alloc(int size)
00227 {
00228 void *p = base_heap_alloc(size);
00229 if (p == NULL)
00230 p = overflow_heap_alloc(size);
00231 return (p);
00232 }
00233
00234 inline Str *
00235 StrList::new_cell(const char *s, int len_not_counting_nul)
00236 {
00237 Str *cell;
00238 int l = len_not_counting_nul;
00239
00240
00241 if ((cells_allocated < STRLIST_BASE_CELLS) && (!copy_when_adding_string)) {
00242 cell = &(base_cells[cells_allocated++]);
00243 cell->str = s;
00244 cell->len = l;
00245 return (cell);
00246 } else {
00247 return (_new_cell(s, len_not_counting_nul));
00248 }
00249 }
00250
00251 inline Str *
00252 StrList::get_idx(int i)
00253 {
00254 Str *s;
00255
00256 for (s = head; ((s != NULL) && i); s = s->next, i--);
00257 return ((i == 0) ? s : NULL);
00258 }
00259
00260 inline void
00261 StrList::append(Str * str)
00262 {
00263
00264 if (str == NULL)
00265 return;
00266 ++count;
00267 str->next = NULL;
00268 str->prev = tail;
00269
00270 if (tail == NULL) {
00271 head = tail = str;
00272 } else {
00273 tail->next = str;
00274 tail = str;
00275 }
00276 }
00277
00278 inline void
00279 StrList::prepend(Str * str)
00280 {
00281 if (str == NULL)
00282 return;
00283 ++count;
00284 str->next = head;
00285 str->prev = NULL;
00286
00287 if (tail == NULL) {
00288 head = tail = str;
00289 } else {
00290 head->prev = str;
00291 head = str;
00292 }
00293 }
00294
00295 inline void
00296 StrList::add_after(Str * prev, Str * str)
00297 {
00298 if (str == NULL || prev == NULL)
00299 return;
00300 ++count;
00301 str->next = prev->next;
00302 str->prev = prev;
00303 prev->next = str;
00304 if (tail == prev)
00305 tail = str;
00306 }
00307
00308 inline void
00309 StrList::detach(Str * str)
00310 {
00311 if (str == NULL)
00312 return;
00313 --count;
00314
00315 if (head == str)
00316 head = str->next;
00317 if (tail == str)
00318 tail = str->prev;
00319 if (str->prev)
00320 str->prev->next = str->next;
00321 if (str->next)
00322 str->next->prev = str->prev;
00323 }
00324
00325 inline Str *
00326 StrList::append_string(const char *s, int len_not_counting_nul)
00327 {
00328 Str *cell;
00329
00330 cell = new_cell(s, len_not_counting_nul);
00331 append(cell);
00332 return (cell);
00333 }
00334
00335 #endif