+ SString &insert(lenpos_t pos, const char *sOther, lenpos_t sLenOther=measure_length) {
+ if (!sOther) {
+ return *this;
+ }
+ if (sLenOther == measure_length) {
+ sLenOther = strlen(sOther);
+ }
+ lenpos_t lenNew = sLen + sLenOther;
+ // Conservative about growing the buffer: don't do it, unless really needed
+ 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 = lenNew;
+ }
+ return *this;
+ }
+ /** 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;
+ }
+ }
+ SString &change(lenpos_t pos, char ch) {
+ if (pos >= sLen) { // character changed must be in string bounds
+ return *this;
+ }
+ *(s + pos) = ch;
+ return *this;
+ }
+ /** Read an integral numeric value from the string. */