]>
Commit | Line | Data |
---|---|---|
ad80164a | 1 | |
2 | /* | |
3 | * $Id: SqString.cc,v 1.1 2007/05/18 06:44:35 amosjeffries Exp $ | |
4 | * | |
5 | * DEBUG: section 67 String | |
6 | * AUTHOR: Duane Wessels | |
7 | * | |
8 | * SQUID Web Proxy Cache http://www.squid-cache.org/ | |
9 | * ---------------------------------------------------------- | |
10 | * | |
11 | * Squid is the result of efforts by numerous individuals from | |
12 | * the Internet community; see the CONTRIBUTORS file for full | |
13 | * details. Many organizations have provided support for Squid's | |
14 | * development; see the SPONSORS file for full details. Squid is | |
15 | * Copyrighted (C) 2001 by the Regents of the University of | |
16 | * California; see the COPYRIGHT file for full details. Squid | |
17 | * incorporates software developed and/or copyrighted by other | |
18 | * sources; see the CREDITS file for full details. | |
19 | * | |
20 | * This program is free software; you can redistribute it and/or modify | |
21 | * it under the terms of the GNU General Public License as published by | |
22 | * the Free Software Foundation; either version 2 of the License, or | |
23 | * (at your option) any later version. | |
24 | * | |
25 | * This program is distributed in the hope that it will be useful, | |
26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
28 | * GNU General Public License for more details. | |
29 | * | |
30 | * You should have received a copy of the GNU General Public License | |
31 | * along with this program; if not, write to the Free Software | |
32 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. | |
33 | * | |
34 | */ | |
35 | ||
36 | #include "squid.h" | |
37 | #include "SqString.h" | |
38 | #include "Store.h" | |
39 | ||
40 | void | |
41 | SqString::initBuf(size_t sz) | |
42 | { | |
43 | PROF_start(StringInitBuf); | |
44 | clear(); | |
45 | buf_ = (char *)memAllocString(sz, &sz); | |
46 | assert(sz < 65536); | |
47 | size_ = sz; | |
48 | PROF_stop(StringInitBuf); | |
49 | } | |
50 | ||
51 | void | |
52 | SqString::limitInit(const char *str, int len) | |
53 | { | |
54 | PROF_start(StringLimitInit); | |
55 | assert(this && str); | |
56 | initBuf(len + 1); | |
57 | len_ = len; | |
58 | xmemcpy(buf_, str, len); | |
59 | buf_[len] = '\0'; | |
60 | PROF_stop(StringLimitInit); | |
61 | } | |
62 | ||
63 | void | |
64 | SqString::init(char const *str) | |
65 | { | |
66 | assert(this); | |
67 | ||
68 | PROF_start(StringInit); | |
69 | ||
70 | if (str) | |
71 | limitInit(str, strlen(str)); | |
72 | else | |
73 | clear(); | |
74 | PROF_stop(StringInit); | |
75 | } | |
76 | ||
77 | void | |
78 | SqString::clear() | |
79 | { | |
80 | PROF_start(StringClean); | |
81 | assert(this); | |
82 | ||
83 | if (buf_) | |
84 | memFreeString(size_, buf_); | |
85 | ||
86 | len_ = 0; | |
87 | size_ = 0; | |
88 | buf_ = NULL; | |
89 | PROF_stop(StringClean); | |
90 | } | |
91 | ||
92 | SqString::~SqString() | |
93 | { | |
94 | clear(); | |
95 | #if DEBUGSTRINGS | |
96 | ||
97 | SqStringRegistry::Instance().remove(this); | |
98 | #endif | |
99 | } | |
100 | ||
101 | SqString::SqString (char const *aString) | |
102 | { | |
103 | memset(this, 0, sizeof(SqString)); | |
104 | ||
105 | init(aString); | |
106 | #if DEBUGSTRINGS | |
107 | ||
108 | SqStringRegistry::Instance().add(this); | |
109 | #endif | |
110 | } | |
111 | ||
112 | SqString & | |
113 | SqString::operator =(char const *aString) | |
114 | { | |
115 | assert(this); | |
116 | init(aString); | |
117 | return *this; | |
118 | } | |
119 | ||
120 | SqString & | |
121 | SqString::operator = (SqString const &old) | |
122 | { | |
123 | if (old.size()) | |
124 | limitInit(old.c_str(), old.size()); | |
125 | else | |
126 | clear(); | |
127 | ||
128 | return *this; | |
129 | } | |
130 | ||
131 | bool | |
132 | SqString::operator == (SqString const &that) const | |
133 | { | |
134 | return (this->compare(that) == 0); | |
135 | } | |
136 | ||
137 | bool | |
138 | SqString::operator != (SqString const &that) const | |
139 | { | |
140 | return (this->compare(that) != 0); | |
141 | } | |
142 | ||
143 | bool | |
144 | SqString::operator >= (SqString const &that) const | |
145 | { | |
146 | return (this->compare(that) >= 0); | |
147 | } | |
148 | ||
149 | bool | |
150 | SqString::operator <= (SqString const &that) const | |
151 | { | |
152 | return (this->compare(that) <= 0); | |
153 | } | |
154 | ||
155 | bool | |
156 | SqString::operator > (SqString const &that) const | |
157 | { | |
158 | return (this->compare(that) > 0); | |
159 | } | |
160 | ||
161 | bool | |
162 | SqString::operator < (SqString const &that) const | |
163 | { | |
164 | return (this->compare(that) < 0); | |
165 | } | |
166 | ||
167 | SqString::SqString (SqString const &old) | |
168 | { | |
169 | memset(this, 0, sizeof(SqString)); | |
170 | ||
171 | init (old.c_str()); | |
172 | #if DEBUGSTRINGS | |
173 | ||
174 | SqStringRegistry::Instance().add(this); | |
175 | #endif | |
176 | } | |
177 | ||
178 | void | |
179 | SqString::append(const char *str, int len) | |
180 | { | |
181 | assert(this); | |
182 | ||
183 | PROF_start(StringAppend); | |
184 | ||
185 | if(len < 1 || str == NULL) | |
186 | return; | |
187 | ||
188 | if (len_ + len < size_) { | |
189 | strncat(buf_, str, len); | |
190 | len_ += len; | |
191 | } else { | |
192 | unsigned int ssz = len_ + len; | |
193 | unsigned int bsz = len_ + len + 1; | |
194 | char* tmp = (char *)memAllocString(ssz, &bsz); | |
195 | assert(bsz < 65536); | |
196 | ||
197 | if (buf_) | |
198 | xmemcpy(tmp, buf_, len_); | |
199 | ||
200 | if (len) | |
201 | xmemcpy(tmp + len_, str, len); | |
202 | ||
203 | tmp[ssz + 1] = '\0'; | |
204 | ||
205 | clear(); | |
206 | ||
207 | size_ = bsz; | |
208 | len_ = ssz; | |
209 | buf_ = tmp; | |
210 | tmp = NULL; | |
211 | } | |
212 | PROF_stop(StringAppend); | |
213 | } | |
214 | ||
215 | void | |
216 | SqString::append(char const *str) | |
217 | { | |
218 | assert (str); | |
219 | append (str, strlen(str)); | |
220 | } | |
221 | ||
222 | void | |
223 | SqString::append (char chr) | |
224 | { | |
225 | char myString[2]; | |
226 | myString[0]=chr; | |
227 | myString[1]='\0'; | |
228 | append (myString, 1); | |
229 | } | |
230 | ||
231 | void | |
232 | SqString::append(SqString const &old) | |
233 | { | |
234 | append (old.c_str(), old.len_); | |
235 | } | |
236 | ||
237 | char& | |
238 | SqString::operator [](unsigned int pos) | |
239 | { | |
240 | assert(pos < size_ ); | |
241 | ||
242 | return buf_[pos]; | |
243 | } | |
244 | ||
245 | #if DEBUGSTRINGS | |
246 | void | |
247 | SqString::stat(StoreEntry *entry) const | |
248 | { | |
249 | storeAppendPrintf(entry, "%p : %d/%d \"%s\"\n",this,len_, size_, c_str()); | |
250 | } | |
251 | ||
252 | SqStringRegistry & | |
253 | SqStringRegistry::Instance() | |
254 | { | |
255 | return Instance_; | |
256 | } | |
257 | ||
258 | template <class C> | |
259 | int | |
260 | ptrcmp(C const &lhs, C const &rhs) | |
261 | { | |
262 | return lhs - rhs; | |
263 | } | |
264 | ||
265 | void | |
266 | SqStringRegistry::registerWithCacheManager(CacheManager & manager) | |
267 | { | |
268 | manager.registerAction("strings", | |
269 | "Strings in use in squid", Stat, 0, 1); | |
270 | } | |
271 | ||
272 | void | |
273 | SqStringRegistry::add(SqString const *entry) | |
274 | { | |
275 | entries.insert(entry, ptrcmp); | |
276 | } | |
277 | ||
278 | void | |
279 | SqStringRegistry::remove(SqString const *entry) | |
280 | { | |
281 | entries.remove(entry, ptrcmp); | |
282 | } | |
283 | ||
284 | SqStringRegistry SqStringRegistry::Instance_; | |
285 | ||
286 | extern size_t memStringCount(); | |
287 | ||
288 | void | |
289 | SqStringRegistry::Stat(StoreEntry *entry) | |
290 | { | |
291 | storeAppendPrintf(entry, "%lu entries, %lu reported from MemPool\n", (unsigned long) Instance().entries.elements, (unsigned long) memStringCount()); | |
292 | Instance().entries.head->walk(Stater, entry); | |
293 | } | |
294 | ||
295 | void | |
296 | SqStringRegistry::Stater(SqString const * const & nodedata, void *state) | |
297 | { | |
298 | StoreEntry *entry = (StoreEntry *) state; | |
299 | nodedata->stat(entry); | |
300 | } | |
301 | ||
302 | #endif | |
303 | ||
304 | /* | |
305 | * Similar to strtok, but has some rudimentary knowledge | |
306 | * of quoting | |
307 | */ | |
308 | char * | |
309 | strwordtok(char *buf, char **t) | |
310 | { | |
311 | unsigned char *word = NULL; | |
312 | unsigned char *p = (unsigned char *) buf; | |
313 | unsigned char *d; | |
314 | unsigned char ch; | |
315 | int quoted = 0; | |
316 | ||
317 | if (!p) | |
318 | p = (unsigned char *) *t; | |
319 | ||
320 | if (!p) | |
321 | goto error; | |
322 | ||
323 | while (*p && xisspace(*p)) | |
324 | p++; | |
325 | ||
326 | if (!*p) | |
327 | goto error; | |
328 | ||
329 | word = d = p; | |
330 | ||
331 | while ((ch = *p)) { | |
332 | switch (ch) { | |
333 | ||
334 | case '\\': | |
335 | p++; | |
336 | ||
337 | switch (*p) { | |
338 | ||
339 | case 'n': | |
340 | ch = '\n'; | |
341 | ||
342 | break; | |
343 | ||
344 | case 'r': | |
345 | ch = '\r'; | |
346 | ||
347 | break; | |
348 | ||
349 | default: | |
350 | ch = *p; | |
351 | ||
352 | break; | |
353 | ||
354 | } | |
355 | ||
356 | *d++ = ch; | |
357 | ||
358 | if (ch) | |
359 | p++; | |
360 | ||
361 | break; | |
362 | ||
363 | case '"': | |
364 | quoted = !quoted; | |
365 | ||
366 | p++; | |
367 | ||
368 | break; | |
369 | ||
370 | default: | |
371 | if (!quoted && xisspace(*p)) { | |
372 | p++; | |
373 | goto done; | |
374 | } | |
375 | ||
376 | *d++ = *p++; | |
377 | break; | |
378 | } | |
379 | } | |
380 | ||
381 | done: | |
382 | *d++ = '\0'; | |
383 | ||
384 | error: | |
385 | *t = (char *) p; | |
386 | return (char *) word; | |
387 | } | |
388 | ||
389 | #ifndef _USE_INLINE_ | |
390 | #include "SqString.cci" | |
391 | #endif |