1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

WString: avoid writing to const storage (#8463)

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.
This commit is contained in:
Paulo Cabral Sanz 2022-01-28 09:51:45 -03:00 committed by GitHub
parent 30b0450d2b
commit 9f536e68f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 6 additions and 15 deletions

View File

@ -682,14 +682,9 @@ int String::lastIndexOf(char ch) const {
int String::lastIndexOf(char ch, unsigned int fromIndex) const { int String::lastIndexOf(char ch, unsigned int fromIndex) const {
if (fromIndex >= len()) if (fromIndex >= len())
return -1; return -1;
char *writeTo = wbuffer(); int index = fromIndex + 1;
char tempchar = writeTo[fromIndex + 1]; // save the replaced character while (index-- > 0 && buffer()[index] != ch);
writeTo[fromIndex + 1] = '\0'; return index;
char *temp = strrchr(writeTo, ch);
writeTo[fromIndex + 1] = tempchar; // restore character
if (temp == NULL)
return -1;
return temp - writeTo;
} }
int String::lastIndexOf(const String &s2) const { int String::lastIndexOf(const String &s2) const {
@ -732,11 +727,7 @@ String String::substring(unsigned int left, unsigned int right) const {
return out; return out;
if (right > len()) if (right > len())
right = len(); right = len();
char *writeTo = wbuffer(); out.concat(buffer() + left, right - left);
char tempchar = writeTo[right]; // save the replaced character
writeTo[right] = '\0';
out = writeTo + left; // pointer arithmetic
writeTo[right] = tempchar; // restore character
return out; return out;
} }

View File

@ -263,8 +263,8 @@ class String {
void setCapacity(int cap) { if (!isSSO()) ptr.cap = cap; } void setCapacity(int cap) { if (!isSSO()) ptr.cap = cap; }
void setBuffer(char *buff) { if (!isSSO()) ptr.buff = buff; } void setBuffer(char *buff) { if (!isSSO()) ptr.buff = buff; }
// Buffer accessor functions // Buffer accessor functions
const char *buffer() const { return wbuffer(); } const char *buffer() const { return isSSO() ? sso.buff : ptr.buff; }
char *wbuffer() const { return isSSO() ? const_cast<char *>(sso.buff) : ptr.buff; } // Writable version of buffer char *wbuffer() { return const_cast<char *>(buffer()); } // Writable version of buffer
// concatenation is done via non-member functions // 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 // 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