• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

ink_string++.h

Go to the documentation of this file.
00001 /** @file
00002 
00003   A brief file description
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022  */
00023 
00024 /****************************************************************************
00025 
00026   ink_string++.h
00027 
00028   C++ support for string manipulation.
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 //      mem_copy
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 //      mem_len
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  *                     Str (string/length list cell)                   *
00070  *                                                                     *
00071  ***********************************************************************/
00072 
00073 struct Str
00074 {
00075   const char *str;              // string pointer
00076   size_t len;                   // length of string (not counting NUL)
00077   struct Str *next;             // next in list
00078   struct Str *prev;             // prev in list
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  *       StrList (doubly-linked list of string/length list cells)      *
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   // allocate a cell from the array or heap
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   // do nothing if str is NULL to avoid pointer chasing below
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

Generated by  doxygen 1.7.1