Skip to content

Commit

Permalink
WString: avoid writing to const storage (#8463)
Browse files Browse the repository at this point in the history
This avoids the null termination requirement of both String::substring and String::lastIndexOf by using APIs that don't require it. So we can stop writing to the buffer inside of const functions.

I also changed wbuffer to make it non const.
  • Loading branch information
paulocsanz authored Jan 28, 2022
1 parent 30b0450 commit 9f536e6
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 15 deletions.
17 changes: 4 additions & 13 deletions cores/esp8266/WString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -682,14 +682,9 @@ int String::lastIndexOf(char ch) const {
int String::lastIndexOf(char ch, unsigned int fromIndex) const {
if (fromIndex >= len())
return -1;
char *writeTo = wbuffer();
char tempchar = writeTo[fromIndex + 1]; // save the replaced character
writeTo[fromIndex + 1] = '\0';
char *temp = strrchr(writeTo, ch);
writeTo[fromIndex + 1] = tempchar; // restore character
if (temp == NULL)
return -1;
return temp - writeTo;
int index = fromIndex + 1;
while (index-- > 0 && buffer()[index] != ch);
return index;
}

int String::lastIndexOf(const String &s2) const {
Expand Down Expand Up @@ -732,11 +727,7 @@ String String::substring(unsigned int left, unsigned int right) const {
return out;
if (right > len())
right = len();
char *writeTo = wbuffer();
char tempchar = writeTo[right]; // save the replaced character
writeTo[right] = '\0';
out = writeTo + left; // pointer arithmetic
writeTo[right] = tempchar; // restore character
out.concat(buffer() + left, right - left);
return out;
}

Expand Down
4 changes: 2 additions & 2 deletions cores/esp8266/WString.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,8 @@ class String {
void setCapacity(int cap) { if (!isSSO()) ptr.cap = cap; }
void setBuffer(char *buff) { if (!isSSO()) ptr.buff = buff; }
// Buffer accessor functions
const char *buffer() const { return wbuffer(); }
char *wbuffer() const { return isSSO() ? const_cast<char *>(sso.buff) : ptr.buff; } // Writable version of buffer
const char *buffer() const { return isSSO() ? sso.buff : ptr.buff; }
char *wbuffer() { return const_cast<char *>(buffer()); } // Writable version of buffer

// concatenation is done via non-member functions
// make sure we still have access to internal methods, since we optimize based on capacity of both sides and want to manipulate internal buffers directly
Expand Down

0 comments on commit 9f536e6

Please sign in to comment.