~ps10gel/ubuntu/xenial/trafficserver/6.2.0

« back to all changes in this revision

Viewing changes to lib/ts/ink_string++.h

  • Committer: Bazaar Package Importer
  • Author(s): Arno Toell
  • Date: 2011-01-13 11:49:18 UTC
  • Revision ID: james.westby@ubuntu.com-20110113114918-vu422h8dknrgkj15
Tags: upstream-2.1.5-unstable
ImportĀ upstreamĀ versionĀ 2.1.5-unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** @file
 
2
 
 
3
  A brief file description
 
4
 
 
5
  @section license License
 
6
 
 
7
  Licensed to the Apache Software Foundation (ASF) under one
 
8
  or more contributor license agreements.  See the NOTICE file
 
9
  distributed with this work for additional information
 
10
  regarding copyright ownership.  The ASF licenses this file
 
11
  to you under the Apache License, Version 2.0 (the
 
12
  "License"); you may not use this file except in compliance
 
13
  with the License.  You may obtain a copy of the License at
 
14
 
 
15
      http://www.apache.org/licenses/LICENSE-2.0
 
16
 
 
17
  Unless required by applicable law or agreed to in writing, software
 
18
  distributed under the License is distributed on an "AS IS" BASIS,
 
19
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
20
  See the License for the specific language governing permissions and
 
21
  limitations under the License.
 
22
 */
 
23
 
 
24
/****************************************************************************
 
25
 
 
26
  ink_string++.h
 
27
 
 
28
  C++ support for string manipulation.
 
29
 
 
30
 
 
31
 ****************************************************************************/
 
32
 
 
33
#if !defined (_ink_string_pp_h_)
 
34
#define _ink_string_pp_h_
 
35
#include <stdio.h>
 
36
#include <strings.h>
 
37
 
 
38
//////////////////////////////////////////////////////////////////////////////
 
39
//
 
40
//      mem_copy
 
41
//
 
42
//////////////////////////////////////////////////////////////////////////////
 
43
 
 
44
static inline void
 
45
_memcpy(char *dest, const char *src, int nbytes)
 
46
{
 
47
  for (int i = 0; i < nbytes; i++)
 
48
    dest[i] = src[i];
 
49
}
 
50
 
 
51
 
 
52
//////////////////////////////////////////////////////////////////////////////
 
53
//
 
54
//      mem_len
 
55
//
 
56
//////////////////////////////////////////////////////////////////////////////
 
57
 
 
58
static inline int
 
59
_strlen(const char *src)
 
60
{
 
61
  const char *old_src = src;
 
62
  while (*src)
 
63
    src++;
 
64
  return (int) (src - old_src);
 
65
}
 
66
 
 
67
void *ink_memchr(const void *as, int ac, size_t an);
 
68
 
 
69
/***********************************************************************
 
70
 *                                                                     *
 
71
 *                     Str (string/length list cell)                   *
 
72
 *                                                                     *
 
73
 ***********************************************************************/
 
74
 
 
75
struct Str
 
76
{
 
77
  const char *str;              // string pointer
 
78
  size_t len;                   // length of string (not counting NUL)
 
79
  struct Str *next;             // next in list
 
80
  struct Str *prev;             // prev in list
 
81
 
 
82
    Str():str(NULL), len(0), next(NULL), prev(NULL)
 
83
  {
 
84
  }
 
85
  Str(char *s)
 
86
  {
 
87
    str = s;
 
88
    len = strlen(s);
 
89
    next = NULL;
 
90
    prev = NULL;
 
91
  }
 
92
  Str(char *s, int l)
 
93
  {
 
94
    str = s;
 
95
    len = l;
 
96
    next = NULL;
 
97
    prev = NULL;
 
98
  }
 
99
 
 
100
  void clean()
 
101
  {
 
102
    str = NULL;
 
103
    len = 0;
 
104
    next = NULL;
 
105
    prev = NULL;
 
106
  }
 
107
 
 
108
  void dump(FILE * fp = stderr) {
 
109
    fprintf(fp, "Str [\"%.*s\", len %d]\n", (int) len, str, (int) len);
 
110
  }
 
111
};
 
112
 
 
113
/***********************************************************************
 
114
 *                                                                     *
 
115
 *       StrList (doubly-linked list of string/length list cells)      *
 
116
 *                                                                     *
 
117
 ***********************************************************************/
 
118
 
 
119
#define STRLIST_BASE_HEAP_SIZE          128
 
120
#define STRLIST_OVERFLOW_HEAP_SIZE      1024
 
121
#define STRLIST_BASE_CELLS              5
 
122
 
 
123
struct StrListOverflow;
 
124
 
 
125
struct StrList
 
126
{
 
127
public:
 
128
  int count;
 
129
  Str *head;
 
130
  Str *tail;
 
131
 
 
132
public:
 
133
    StrList(bool do_copy_when_adding_string = true);
 
134
   ~StrList();
 
135
 
 
136
  Str *get_idx(int i);
 
137
  void append(Str * str);
 
138
  void prepend(Str * str);
 
139
  void add_after(Str * prev, Str * str);
 
140
  void detach(Str * str);
 
141
 
 
142
  Str *new_cell(const char *s, int len_not_counting_nul);
 
143
  Str *append_string(const char *s, int len_not_counting_nul);
 
144
 
 
145
  void dump(FILE * fp = stderr);
 
146
 
 
147
private:
 
148
  void init();
 
149
  void clean();
 
150
 
 
151
  void *base_heap_alloc(int size);
 
152
  void *alloc(int size);
 
153
  Str *_new_cell(const char *s, int len_not_counting_nul);
 
154
  void *overflow_heap_alloc(int size);
 
155
  void overflow_heap_clean();
 
156
 
 
157
  Str base_cells[STRLIST_BASE_CELLS];
 
158
  char base_heap[STRLIST_BASE_HEAP_SIZE];
 
159
  int cells_allocated;
 
160
  int base_heap_size;
 
161
  int base_heap_used;
 
162
  StrListOverflow *overflow_current;
 
163
  StrListOverflow *overflow_first;
 
164
  bool copy_when_adding_string;
 
165
};
 
166
 
 
167
struct StrListOverflow
 
168
{
 
169
  StrListOverflow *next;
 
170
  int heap_size;
 
171
  int heap_used;
 
172
 
 
173
  void init();
 
174
  void clean();
 
175
  void *alloc(int size, StrListOverflow ** new_heap_ptr);
 
176
  static StrListOverflow *create_heap(int user_size);
 
177
};
 
178
 
 
179
inline void
 
180
StrList::init()
 
181
{
 
182
  count = 0;
 
183
  cells_allocated = 0;
 
184
  head = tail = NULL;
 
185
  base_heap_size = STRLIST_BASE_HEAP_SIZE;
 
186
  base_heap_used = 0;
 
187
  overflow_first = NULL;
 
188
  overflow_current = NULL;
 
189
}
 
190
 
 
191
inline void
 
192
StrList::clean()
 
193
{
 
194
  if (overflow_first)
 
195
    overflow_heap_clean();
 
196
  init();
 
197
}
 
198
 
 
199
inline
 
200
StrList::StrList(bool do_copy_when_adding_string)
 
201
{
 
202
  memset(base_heap, 0, sizeof(base_heap));
 
203
  copy_when_adding_string = do_copy_when_adding_string;
 
204
  init();
 
205
}
 
206
 
 
207
inline
 
208
StrList::~
 
209
StrList()
 
210
{
 
211
  clean();
 
212
}
 
213
 
 
214
inline void *
 
215
StrList::base_heap_alloc(int size)
 
216
{
 
217
  char *p;
 
218
 
 
219
  if (size <= (base_heap_size - base_heap_used)) {
 
220
    p = &(base_heap[base_heap_used]);
 
221
    base_heap_used += size;
 
222
    return ((void *) p);
 
223
  } else
 
224
    return (NULL);
 
225
}
 
226
 
 
227
inline void *
 
228
StrList::alloc(int size)
 
229
{
 
230
  void *p = base_heap_alloc(size);
 
231
  if (p == NULL)
 
232
    p = overflow_heap_alloc(size);
 
233
  return (p);
 
234
}
 
235
 
 
236
inline Str *
 
237
StrList::new_cell(const char *s, int len_not_counting_nul)
 
238
{
 
239
  Str *cell;
 
240
  int l = len_not_counting_nul;
 
241
 
 
242
  // allocate a cell from the array or heap
 
243
  if ((cells_allocated < STRLIST_BASE_CELLS) && (!copy_when_adding_string)) {
 
244
    cell = &(base_cells[cells_allocated++]);
 
245
    cell->str = s;
 
246
    cell->len = l;
 
247
    return (cell);
 
248
  } else {
 
249
    return (_new_cell(s, len_not_counting_nul));
 
250
  }
 
251
}
 
252
 
 
253
inline Str *
 
254
StrList::get_idx(int i)
 
255
{
 
256
  Str *s;
 
257
 
 
258
  for (s = head; ((s != NULL) && i); s = s->next, i--);
 
259
  return ((i == 0) ? s : NULL);
 
260
}
 
261
 
 
262
inline void
 
263
StrList::append(Str * str)
 
264
{
 
265
  // do nothing if str is NULL to avoid pointer chasing below
 
266
  if (str == NULL)
 
267
    return;
 
268
  ++count;
 
269
  str->next = NULL;
 
270
  str->prev = tail;
 
271
 
 
272
  if (tail == NULL) {
 
273
    head = tail = str;
 
274
  } else {
 
275
    tail->next = str;
 
276
    tail = str;
 
277
  }
 
278
}
 
279
 
 
280
inline void
 
281
StrList::prepend(Str * str)
 
282
{
 
283
  if (str == NULL)
 
284
    return;
 
285
  ++count;
 
286
  str->next = head;
 
287
  str->prev = NULL;
 
288
 
 
289
  if (tail == NULL) {
 
290
    head = tail = str;
 
291
  } else {
 
292
    head->prev = str;
 
293
    head = str;
 
294
  }
 
295
}
 
296
 
 
297
inline void
 
298
StrList::add_after(Str * prev, Str * str)
 
299
{
 
300
  if (str == NULL || prev == NULL)
 
301
    return;
 
302
  ++count;
 
303
  str->next = prev->next;
 
304
  str->prev = prev;
 
305
  prev->next = str;
 
306
  if (tail == prev)
 
307
    tail = str;
 
308
}
 
309
 
 
310
inline void
 
311
StrList::detach(Str * str)
 
312
{
 
313
  if (str == NULL)
 
314
    return;
 
315
  --count;
 
316
 
 
317
  if (head == str)
 
318
    head = str->next;
 
319
  if (tail == str)
 
320
    tail = str->prev;
 
321
  if (str->prev)
 
322
    str->prev->next = str->next;
 
323
  if (str->next)
 
324
    str->next->prev = str->prev;
 
325
}
 
326
 
 
327
inline Str *
 
328
StrList::append_string(const char *s, int len_not_counting_nul)
 
329
{
 
330
  Str *cell;
 
331
 
 
332
  cell = new_cell(s, len_not_counting_nul);
 
333
  append(cell);
 
334
  return (cell);
 
335
}
 
336
 
 
337
#endif