aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/SString.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/SString.h')
-rw-r--r--include/SString.h174
1 files changed, 84 insertions, 90 deletions
diff --git a/include/SString.h b/include/SString.h
index 5c6723556..5374f26e5 100644
--- a/include/SString.h
+++ b/include/SString.h
@@ -6,6 +6,8 @@
#ifndef SSTRING_H
#define SSTRING_H
+bool EqualCaseInsensitive(const char *a, const char *b);
+
#if PLAT_WIN
#define strcasecmp stricmp
#define strncasecmp strnicmp
@@ -13,6 +15,7 @@
// Define another string class.
// While it would be 'better' to use std::string, that doubles the executable size.
+// An SString may contain embedded nul characters.
inline char *StringDup(const char *s, int len=-1) {
if (!s)
@@ -28,75 +31,90 @@ inline char *StringDup(const char *s, int len=-1) {
}
class SString {
- char *s;
- int ssize;
+ char *s; ///< The C string
+ int ssize; ///< The size of the buffer, less 1: ie. the maximum size of the string
+ int slen; ///< The size of the string in s
+
+ enum { sizingGranularity = 64 }; // Minimum growth size when appending strings
+
public:
typedef const char* const_iterator;
typedef int size_type;
- static size_type npos;
- const char* begin(void) const {
- return s;
- }
- const char* end(void) const {
- return &s[ssize];
- }
- size_type size(void) const {
- if (s)
- return ssize;
- else
- return 0;
- }
- SString &assign(const char* sother, int size_ = -1) {
- char *t = s;
- s = StringDup(sother,size_);
- ssize = (s) ? strlen(s) : 0;
- delete []t;
- return *this;
- }
- SString &assign(const SString& sother, int size_ = -1) {
- return assign(sother.s,size_);
- }
- SString &assign(const_iterator ibeg, const_iterator iend) {
- return assign(ibeg,iend - ibeg);
- }
+
SString() {
s = 0;
ssize = 0;
+ slen = 0;
}
SString(const SString &source) {
s = StringDup(source.s);
- ssize = (s) ? strlen(s) : 0;
+ ssize = slen = (s) ? strlen(s) : 0;
}
SString(const char *s_) {
s = StringDup(s_);
- ssize = (s) ? strlen(s) : 0;
+ ssize = slen = (s) ? strlen(s) : 0;
}
SString(const char *s_, int first, int last) {
s = StringDup(s_ + first, last - first);
- ssize = (s) ? strlen(s) : 0;
+ ssize = slen = (s) ? strlen(s) : 0;
}
SString(int i) {
char number[100];
sprintf(number, "%0d", i);
s = StringDup(number);
- ssize = (s) ? strlen(s) : 0;
+ ssize = slen = (s) ? strlen(s) : 0;
}
~SString() {
delete []s;
s = 0;
ssize = 0;
+ slen = 0;
}
void clear(void) {
if (s) {
*s = '\0';
}
- ssize = 0;
+ slen = 0;
+ }
+ const char* begin(void) const {
+ return s;
+ }
+ const char* end(void) const {
+ return &s[slen]; // Point after the last character
+ }
+ size_type size(void) const { // Size of buffer
+ if (s)
+ return ssize;
+ else
+ return 0;
+ }
+ int length() const { // Size of string in buffer
+ return slen;
+ }
+ SString &assign(const char* sother, int size_ = -1) {
+ if (size_ < 0) {
+ size_ = strlen(sother);
+ }
+ if (ssize > 0 && size_ <= ssize) { // Does not allocate new buffer if the current is big enough
+ strncpy(s, sother, size_);
+ s[size_] = '\0';
+ } else {
+ delete []s;
+ s = StringDup(sother, size_);
+ ssize = size_; // Allow buffer bigger than real string, thus providing space to grow
+ slen = (s) ? strlen(s) : 0;
+ }
+ return *this;
+ }
+ SString &assign(const SString& sother, int size_ = -1) {
+ return assign(sother.s, size_);
+ }
+ SString &assign(const_iterator ibeg, const_iterator iend) {
+ return assign(ibeg, iend - ibeg);
}
SString &operator=(const SString &source) {
if (this != &source) {
- delete []s;
- s = StringDup(source.s);
- ssize = (s) ? strlen(s) : 0;
+ assign(source.c_str());
}
return *this;
}
@@ -126,47 +144,50 @@ public:
else
return "";
}
- int length() const {
- if (s)
- return strlen(s);
- else
- return 0;
- }
char operator[](int i) const {
- if (s)
+ if (s && i < ssize) // Or < slen? Depends on the use, both are OK
return s[i];
else
return '\0';
}
+ SString &append(const char* sother, int lenOther = -1) {
+ if (lenOther < 0)
+ lenOther = strlen(sother);
+ if (slen + lenOther + 1 < ssize) {
+ // Conservative about growing the buffer: don't do it, unless really needed
+ strncpy(&s[slen], sother, lenOther);
+ s[slen + lenOther] = '\0';
+ slen += lenOther;
+ } else {
+ // Grow the buffer bigger than really needed, to have room for other appends
+ char *sNew = new char[slen + lenOther + sizingGranularity + 1];
+ if (sNew) {
+ if (s) {
+ memcpy(sNew, s, slen);
+ delete []s;
+ }
+ strncpy(&sNew[slen], sother, lenOther);
+ sNew[slen + lenOther] = '\0';
+ s = sNew;
+ ssize = slen + lenOther + sizingGranularity;
+ slen += lenOther;
+ }
+ }
+ return *this;
+ }
SString &operator +=(const char *sother) {
- return append(sother,-1);
+ return append(sother, -1);
}
SString &operator +=(const SString &sother) {
- return append(sother.s,sother.ssize);
+ return append(sother.s, sother.ssize);
}
SString &operator +=(char ch) {
- return append(&ch,1);
- }
- SString &append(const char* sother, int lenOther) {
- int len = length();
- if(lenOther < 0)
- lenOther = strlen(sother);
- char *sNew = new char[len + lenOther + 1];
- if (sNew) {
- if (s)
- memcpy(sNew, s, len);
- strncpy(&sNew[len], sother, lenOther);
- sNew[len + lenOther] = '\0';
- delete []s;
- s = sNew;
- ssize = (s) ? strlen(s) : 0;
- }
- return *this;
+ return append(&ch, 1);
}
int value() const {
if (s)
return atoi(s);
- else
+ else
return 0;
}
void substitute(char find, char replace) {
@@ -179,33 +200,6 @@ public:
}
}
}
- //added by ajkc - 08122000
- char charAt(int i) {
- return s[i];
- }
- //added by ajkc - 08122000
- SString substring(int startPos, int endPos = -1) {
- SString result;
-
- //do some checks first so we do the "right" thing
- if (endPos > this->size() || endPos == -1)
- endPos = this->size();
-
- if (startPos < 0)
- startPos = 0;
-
- if (startPos == endPos) {
- return SString("");
- }
-
- if (startPos > endPos) {
- int tmp = endPos;
- endPos = startPos;
- startPos = tmp;
- }
-
- return SString(s, startPos, endPos);
- }
// I don't think this really belongs here -- Neil
void correctPath() {
#ifdef unix