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

ink_string++.cc

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++.cc
00027 
00028   C++ support for string manipulation.
00029 
00030 
00031  ****************************************************************************/
00032 
00033 #include "libts.h"
00034 
00035 /***********************************************************************
00036  *                                                                     *
00037  *       StrList (doubly-linked list of string/length list cells)      *
00038  *                                                                     *
00039  ***********************************************************************/
00040 
00041 /*-------------------------------------------------------------------------
00042   -------------------------------------------------------------------------*/
00043 
00044 void
00045 StrList::dump(FILE * fp)
00046 {
00047   Str *str;
00048 
00049   for (str = head; str != NULL; str = str->next)
00050     str->dump(fp);
00051 }
00052 
00053 /*-------------------------------------------------------------------------
00054   -------------------------------------------------------------------------*/
00055 
00056 Str *
00057 StrList::_new_cell(const char *s, int len_not_counting_nul)
00058 {
00059   Str *cell;
00060   char *p;
00061   int l = len_not_counting_nul;
00062 
00063   // allocate a cell from the array or heap
00064   if (cells_allocated < STRLIST_BASE_CELLS) {
00065     cell = &(base_cells[cells_allocated]);
00066   } else {
00067     p = (char *) alloc(sizeof(Str) + 7);
00068     if (p == NULL)
00069       return (NULL);            // FIX: scale heap
00070     p = (char *) ((((uintptr_t)p) + 7) & ~7);       // round up to multiple of 8
00071     cell = (Str *) p;
00072   }
00073   ++cells_allocated;
00074 
00075   // are we supposed to copy the string?
00076   if (copy_when_adding_string) {
00077     char *buf = (char *) alloc(l + 1);
00078     if (buf == NULL)
00079       return (NULL);            // FIX: need to grow heap!
00080     memcpy(buf, s, l);
00081     buf[l] = '\0';
00082 
00083     cell->str = (const char *) buf;
00084   } else {
00085     cell->str = s;
00086   }
00087 
00088   cell->len = l;
00089 
00090   return (cell);
00091 }
00092 
00093 /*-------------------------------------------------------------------------
00094   -------------------------------------------------------------------------*/
00095 
00096 void *
00097 StrList::overflow_heap_alloc(int size)
00098 {
00099   if (!overflow_first) {
00100     overflow_first = overflow_current = StrListOverflow::create_heap(STRLIST_OVERFLOW_HEAP_SIZE);
00101   }
00102 
00103   return overflow_current->alloc(size, &overflow_current);
00104 }
00105 
00106 /*-------------------------------------------------------------------------
00107   -------------------------------------------------------------------------*/
00108 
00109 void
00110 StrList::overflow_heap_clean()
00111 {
00112   if (overflow_first)
00113     overflow_first->clean();
00114 }
00115 
00116 
00117 #define INIT_OVERFLOW_ALIGNMENT      8
00118 // XXX: This is basically INK_ALIGN_DEFAULT
00119 const int overflow_head_hdr_size = INK_ALIGN(sizeof(StrListOverflow), INIT_OVERFLOW_ALIGNMENT);
00120 
00121 void
00122 StrListOverflow::init()
00123 {
00124   next = NULL;
00125   heap_size = 0;
00126   heap_used = 0;
00127 }
00128 
00129 void
00130 StrListOverflow::clean()
00131 {
00132   StrListOverflow *current_free = this;
00133   StrListOverflow *next_free;
00134 
00135   while (current_free) {
00136     next_free = current_free->next;
00137     ats_free(current_free);
00138     current_free = next_free;
00139   }
00140 }
00141 
00142 void *
00143 StrListOverflow::alloc(int size, StrListOverflow ** new_heap_ptr)
00144 {
00145 
00146   if (size > (heap_size - heap_used)) {
00147     int new_heap_size = heap_size * 2;
00148 
00149     if (new_heap_size < size) {
00150       new_heap_size = INK_ALIGN(size, 2048);
00151       ink_release_assert(new_heap_size >= size);
00152     }
00153 
00154     ink_assert(next == NULL);
00155     *new_heap_ptr = next = create_heap(new_heap_size);
00156     return next->alloc(size, new_heap_ptr);
00157   }
00158 
00159   char *start = ((char *) this) + overflow_head_hdr_size;
00160   char *rval = start + heap_used;
00161   heap_used += size;
00162   ink_assert(heap_used <= heap_size);
00163   return (void *) rval;
00164 }
00165 
00166 StrListOverflow *
00167 StrListOverflow::create_heap(int user_size)
00168 {
00169   // I'm aligning the first allocation since the old implementation
00170   //  used to do this by calling ats_malloc.  I assume it doesn't
00171   //  matter since we are talking about strings but since this is a
00172   //  last minute emergency bug fix, I'm not take any changes.  If
00173   //  allocations are not of aligned values then subsequents allocations
00174   //  aren't aligned, again mirroring the previous implemnetation
00175   int total_size = overflow_head_hdr_size + user_size;
00176 
00177   StrListOverflow *o = (StrListOverflow *)ats_malloc(total_size);
00178   o->init();
00179   o->heap_size = user_size;
00180 
00181   return o;
00182 }

Generated by  doxygen 1.7.1