]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/String.cc
2 * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
9 /* DEBUG: section 67 String */
12 #include "base/TextException.h"
14 #include "mgr/Registration.h"
15 #include "profiler/Profiler.h"
23 Must(size() < INT_MAX
);
27 // low-level buffer allocation,
28 // does not free old buffer and does not adjust or look at len_
30 String::allocBuffer(String::size_type sz
)
32 PROF_start(StringInitBuf
);
34 char *newBuffer
= (char*)memAllocString(sz
, &sz
);
35 setBuffer(newBuffer
, sz
);
36 PROF_stop(StringInitBuf
);
39 // low-level buffer assignment
40 // does not free old buffer and does not adjust or look at len_
42 String::setBuffer(char *aBuf
, String::size_type aSize
)
45 assert(aSize
< 65536);
50 String::String(char const *aString
) : size_(0), len_(0), buf_(NULL
)
53 allocAndFill(aString
, strlen(aString
));
56 StringRegistry::Instance().add(this);
61 String::operator =(char const *aString
)
68 String::operator =(String
const &old
)
70 clean(); // TODO: optimize to avoid cleaning the buffer we can use
72 allocAndFill(old
.rawBuf(), old
.size());
77 String::operator ==(String
const &that
) const
79 if (0 == this->cmp(that
))
86 String::operator !=(String
const &that
) const
88 if (0 == this->cmp(that
))
94 // public interface, makes sure that we clean the old buffer first
96 String::limitInit(const char *str
, int len
)
98 clean(); // TODO: optimize to avoid cleaning the buffer we can use
99 allocAndFill(str
, len
);
102 // Allocates the buffer to fit the supplied string and fills it.
105 String::allocAndFill(const char *str
, int len
)
107 PROF_start(StringAllocAndFill
);
109 allocBuffer(len
+ 1);
111 memcpy(buf_
, str
, len
);
113 PROF_stop(StringAllocAndFill
);
116 String::String(String
const &old
) : size_(0), len_(0), buf_(NULL
)
119 allocAndFill(old
.rawBuf(), old
.size());
122 StringRegistry::Instance().add(this);
129 PROF_start(StringClean
);
132 /* TODO if mempools has already closed this will FAIL!! */
134 memFreeString(size_
, buf_
);
141 PROF_stop(StringClean
);
149 StringRegistry::Instance().remove(this);
154 String::reset(char const *str
)
156 PROF_start(StringReset
);
157 clean(); // TODO: optimize to avoid cleaning the buffer if we can reuse it
159 allocAndFill(str
, strlen(str
));
160 PROF_stop(StringReset
);
164 String::append( char const *str
, int len
)
167 assert(str
&& len
>= 0);
169 PROF_start(StringAppend
);
170 if (len_
+ len
< size_
) {
171 strncat(buf_
, str
, len
);
174 // Create a temporary string and absorb it later.
176 assert(len_
+ len
< 65536); // otherwise snew.len_ overflows below
177 snew
.len_
= len_
+ len
;
178 snew
.allocBuffer(snew
.len_
+ 1);
181 memcpy(snew
.buf_
, rawBuf(), len_
);
184 memcpy(snew
.buf_
+ len_
, str
, len
);
186 snew
.buf_
[snew
.len_
] = '\0';
190 PROF_stop(StringAppend
);
194 String::append(char const *str
)
197 append(str
, strlen(str
));
201 String::append(char const chr
)
210 String::append(String
const &old
)
212 append(old
.rawBuf(), old
.len_
);
216 String::absorb(String
&old
)
219 setBuffer(old
.buf_
, old
.size_
);
227 String::substr(String::size_type from
, String::size_type to
) const
229 // Must(from >= 0 && from < size());
231 Must(to
> 0 && to
<= size());
235 rv
.limitInit(rawBuf()+from
,to
-from
);
241 String::stat(StoreEntry
*entry
) const
243 storeAppendPrintf(entry
, "%p : %d/%d \"%.*s\"\n",this,len_
, size_
, size(), rawBuf());
247 StringRegistry::Instance()
254 ptrcmp(C
const &lhs
, C
const &rhs
)
259 StringRegistry::StringRegistry()
262 Mgr::RegisterAction("strings",
263 "Strings in use in squid", Stat
, 0, 1);
268 StringRegistry::add(String
const *entry
)
270 entries
.insert(entry
, ptrcmp
);
274 StringRegistry::remove(String
const *entry
)
276 entries
.remove(entry
, ptrcmp
);
279 StringRegistry
StringRegistry::Instance_
;
281 String::size_type
memStringCount();
284 StringRegistry::Stat(StoreEntry
*entry
)
286 storeAppendPrintf(entry
, "%lu entries, %lu reported from MemPool\n", (unsigned long) Instance().entries
.elements
, (unsigned long) memStringCount());
287 Instance().entries
.head
->walk(Stater
, entry
);
291 StringRegistry::Stater(String
const * const & nodedata
, void *state
)
293 StoreEntry
*entry
= (StoreEntry
*) state
;
294 nodedata
->stat(entry
);
299 /* TODO: move onto String */
301 stringHasWhitespace(const char *s
)
303 return strpbrk(s
, w_space
) != NULL
;
306 /* TODO: move onto String */
308 stringHasCntl(const char *s
)
312 while ((c
= (unsigned char) *s
++) != '\0') {
316 if (c
>= 0x7f && c
<= 0x9f)
324 * Similar to strtok, but has some rudimentary knowledge
328 strwordtok(char *buf
, char **t
)
330 unsigned char *word
= NULL
;
331 unsigned char *p
= (unsigned char *) buf
;
337 p
= (unsigned char *) *t
;
342 while (*p
&& xisspace(*p
))
392 if (!quoted
&& xisspace(*p
)) {
409 return (char *) word
;
413 checkNullString(const char *p
)
415 return p
? p
: "(NULL)";
419 String::pos(char const *aString
) const
423 return strstr(termedBuf(), aString
);
427 String::pos(char const ch
) const
431 return strchr(termedBuf(), ch
);
435 String::rpos(char const ch
) const
439 return strrchr(termedBuf(), (ch
));
443 String::find(char const ch
) const
453 String::find(char const *aString
) const
463 String::rfind(char const ch
) const
473 #include "String.cci"