aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/SString.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/SString.h')
-rw-r--r--include/SString.h171
1 files changed, 105 insertions, 66 deletions
diff --git a/include/SString.h b/include/SString.h
index 2f096bfb0..7eac12c0c 100644
--- a/include/SString.h
+++ b/include/SString.h
@@ -18,28 +18,6 @@ bool EqualCaseInsensitive(const char *a, const char *b);
// An SString may contain embedded nul characters.
/**
- * Duplicate a C string.
- * Allocate memory of the given size, or big enough to fit the string if length isn't given;
- * then copy the given string in the allocated memory.
- * @return the pointer to the new string
- */
-inline char *StringDup(
- const char *s, ///< The string to duplicate
- int len=-1) ///< The length of memory to allocate. Optional.
-{
- if (!s)
- return 0;
- if (len == -1)
- len = strlen(s);
- char *sNew = new char[len + 1];
- if (sNew) {
- strncpy(sNew, s, len);
- sNew[len] = '\0';
- }
- return sNew;
-}
-
-/**
* @brief A simple string class.
*
* Hold the length of the string for quick operations,
@@ -48,14 +26,21 @@ inline char *StringDup(
* functions to allow reliable manipulations of these strings.
**/
class SString {
- 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
- int sizeGrowth; ///< Minimum growth size when appending strings
+public:
+ /** Type of string lengths (sizes) and positions (indexes) */
+ typedef unsigned int lenpos_t;
+ enum { measure_length=0xffffffffU};
+
+private:
+ char *s; ///< The C string
+ lenpos_t sSize; ///< The size of the buffer, less 1: ie. the maximum size of the string
+ lenpos_t sLen; ///< The size of the string in s
+ lenpos_t sizeGrowth; ///< Minimum growth size when appending strings
enum { sizeGrowthDefault = 64 };
- bool grow(int lenNew) {
- while (sizeGrowth * 6 < lenNew)
+ bool grow(lenpos_t lenNew) {
+ while (sizeGrowth * 6 < lenNew) {
sizeGrowth *= 2;
+ }
char *sNew = new char[lenNew + sizeGrowth + 1];
if (sNew) {
if (s) {
@@ -68,33 +53,32 @@ class SString {
}
return sNew != 0;
}
-public:
- typedef int size_type;
+public:
SString() : s(0), sSize(0), sLen(0), sizeGrowth(sizeGrowthDefault) {
}
SString(const SString &source) : sizeGrowth(sizeGrowthDefault) {
- s = StringDup(source.s);
+ s = StringAllocate(source.s);
sSize = sLen = (s) ? strlen(s) : 0;
}
SString(const char *s_) : sizeGrowth(sizeGrowthDefault) {
- s = StringDup(s_);
+ s = StringAllocate(s_);
sSize = sLen = (s) ? strlen(s) : 0;
}
- SString(const char *s_, int first, int last) : sizeGrowth(sizeGrowthDefault) {
- s = StringDup(s_ + first, last - first);
+ SString(const char *s_, lenpos_t first, lenpos_t last) : sizeGrowth(sizeGrowthDefault) {
+ s = StringAllocate(s_ + first, last - first);
sSize = sLen = (s) ? strlen(s) : 0;
}
SString(int i) : sizeGrowth(sizeGrowthDefault) {
char number[32];
sprintf(number, "%0d", i);
- s = StringDup(number);
+ s = StringAllocate(number);
sSize = sLen = (s) ? strlen(s) : 0;
}
SString(double d, int precision) : sizeGrowth(sizeGrowthDefault) {
char number[32];
sprintf(number, "%.*f", precision, d);
- s = StringDup(number);
+ s = StringAllocate(number);
sSize = sLen = (s) ? strlen(s) : 0;
}
~SString() {
@@ -110,7 +94,7 @@ public:
sLen = 0;
}
/** Size of buffer. */
- size_type size(void) const { ///<
+ lenpos_t size(void) const {
if (s)
return sSize;
else
@@ -120,11 +104,10 @@ public:
int length() const {
return sLen;
}
- SString &assign(const char *sOther, int sSize_ = -1) {
+ SString &assign(const char *sOther, lenpos_t sSize_=measure_length) {
if (!sOther) {
sSize_ = 0;
- }
- if (sSize_ < 0) {
+ } else if (sSize_ == 0) {
sSize_ = strlen(sOther);
}
if (sSize > 0 && sSize_ <= sSize) { // Does not allocate new buffer if the current is big enough
@@ -135,7 +118,7 @@ public:
sLen = sSize_;
} else {
delete []s;
- s = StringDup(sOther, sSize_);
+ s = StringAllocate(sOther, sSize_);
if (s) {
sSize = sSize_; // Allow buffer bigger than real string, thus providing space to grow
sLen = strlen(s);
@@ -145,7 +128,7 @@ public:
}
return *this;
}
- SString &assign(const SString& sOther, int sSize_ = -1) {
+ SString &assign(const SString& sOther, lenpos_t sSize_=measure_length) {
return assign(sOther.s, sSize_);
}
SString &operator=(const char *source) {
@@ -183,7 +166,7 @@ public:
else
return false;
}
- void setsizegrowth(int sizeGrowth_) {
+ void setsizegrowth(lenpos_t sizeGrowth_) {
sizeGrowth = sizeGrowth_;
}
const char *c_str() const {
@@ -200,21 +183,24 @@ public:
sLen = 0;
return sRet;
}
- char operator[](int i) const {
+ char operator[](lenpos_t i) const {
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 sLenOther=-1, char sep=0) {
- if (sLenOther < 0) {
+ SString &append(const char *sOther, lenpos_t sLenOther=measure_length, char sep = '\0') {
+ if (!sOther) {
+ return *this;
+ }
+ if (sLenOther == 0) {
sLenOther = strlen(sOther);
}
int lenSep = 0;
if (sLen && sep) { // Only add a separator if not empty
lenSep = 1;
}
- int lenNew = sLen + sLenOther + lenSep;
+ lenpos_t lenNew = sLen + sLenOther + lenSep;
// Conservative about growing the buffer: don't do it, unless really needed
if ((lenNew + 1 < sSize) || (grow(lenNew))) {
if (lenSep) {
@@ -228,7 +214,7 @@ public:
return *this;
}
SString &operator+=(const char *sOther) {
- return append(sOther, -1);
+ return append(sOther, 0);
}
SString &operator+=(const SString &sOther) {
return append(sOther.s, sOther.sSize);
@@ -239,24 +225,40 @@ public:
SString &appendwithseparator(const char *sOther, char sep) {
return append(sOther, strlen(sOther), sep);
}
- SString &insert(int pos, const char *sOther, int sLenOther=-1) {
- if (sLenOther < 0)
+ SString &insert(lenpos_t pos, const char *sOther, lenpos_t sLenOther=measure_length) {
+ if (!sOther) {
+ return *this;
+ }
+ if (sLenOther == 0) {
sLenOther = strlen(sOther);
- int lenNew = sLen + sLenOther;
+ }
+ lenpos_t lenNew = sLen + sLenOther;
// Conservative about growing the buffer: don't do it, unless really needed
- if ((lenNew + 1 < sSize) || (grow(lenNew))) {
- int moveChars = sLen-pos;
- for (int i=moveChars; i>=0; i--)
- s[lenNew-moveChars+i] = s[pos+i];
+ if ((lenNew + 1 < sSize) || grow(lenNew)) {
+ lenpos_t moveChars = sLen - pos + 1;
+ for (lenpos_t i = moveChars; i > 0; i--) {
+ s[pos + sLenOther + i - 1] = s[pos + i - 1];
+ }
memcpy(s + pos, sOther, sLenOther);
- sLen += sLenOther;
+ sLen = lenNew;
}
return *this;
}
- void remove(int pos, int len=1) {
- for (int i=pos; i<sLen-len+1; i++)
- s[i] = s[i+len];
- sLen -= len;
+ /** Remove @a len characters from the @a pos position, included.
+ * Characters at pos + len and beyond replace characters at pos.
+ * If @a len is 0, or greater than the length of the string
+ * starting at @a pos, the string is just truncated at @a pos.
+ */
+ void remove(lenpos_t pos, lenpos_t len) {
+ if (len < 1 || pos + len >= sLen) {
+ s[pos] = '\0';
+ sLen = pos;
+ } else {
+ for (lenpos_t i = pos; i < sLen - len + 1; i++) {
+ s[i] = s[i+len];
+ }
+ sLen -= len;
+ }
}
int value() const {
if (s)
@@ -264,11 +266,12 @@ public:
else
return 0;
}
- int search(const char *sFind, int start=0) {
- if ((start >= 0) && (start < sLen)) {
- const char *sFound = strstr(s+start, sFind);
- if (sFound)
+ int search(const char *sFind, lenpos_t start = 0) {
+ if (start < sLen) {
+ const char *sFound = strstr(s + start, sFind);
+ if (sFound) {
return sFound - s;
+ }
}
return -1;
}
@@ -290,8 +293,8 @@ public:
}
int substitute(const char *sFind, const char *sReplace) {
int c = 0;
- int lenFind = strlen(sFind);
- int lenReplace = strlen(sReplace);
+ lenpos_t lenFind = strlen(sFind);
+ lenpos_t lenReplace = strlen(sReplace);
int posFound = search(sFind);
while (posFound >= 0) {
remove(posFound, lenFind);
@@ -304,6 +307,42 @@ public:
int remove(const char *sFind) {
return substitute(sFind, "");
}
+ /**
+ * Duplicate a C string.
+ * Allocate memory of the given size, or big enough to fit the string if length isn't given;
+ * then copy the given string in the allocated memory.
+ * @return the pointer to the new string
+ */
+ static char *StringAllocate(
+ const char *s, ///< The string to duplicate
+ lenpos_t len=measure_length) ///< The length of memory to allocate. Optional.
+ {
+ if (s == 0) {
+ return 0;
+ }
+ if (len == 0) {
+ len = strlen(s);
+ }
+ char *sNew = new char[len + 1];
+ if (sNew) {
+ strncpy(sNew, s, len);
+ sNew[len] = '\0';
+ }
+ return sNew;
+ }
};
+/**
+ * Duplicate a C string.
+ * Allocate memory of the given size, or big enough to fit the string if length isn't given;
+ * then copy the given string in the allocated memory.
+ * @return the pointer to the new string
+ */
+inline char *StringDup(
+ const char *s, ///< The string to duplicate
+ SString::lenpos_t len=SString::measure_length) ///< The length of memory to allocate. Optional.
+{
+ return SString::StringAllocate(s, len);
+}
+
#endif