Skip to content

Commit 70222c2

Browse files
committed
fixup replace() for diff>0
incorrectly using lastIndexOf, when should be using deduced search func since there is no reverse indexOf nor lastIndexOf allows end boundary, adjust buffer end pointer manually by swapping it w/ the found one plus, reinit read ptr after possibly changing buffer() location
1 parent 50956de commit 70222c2

File tree

1 file changed

+40
-10
lines changed

1 file changed

+40
-10
lines changed

cores/esp8266/WString.cpp

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,7 @@ void String::replace(char find, char replace) {
911911

912912
void String::replaceImpl(internal_memmem_t impl, const char *find, unsigned int find_len, const char *replace, unsigned int replace_len) {
913913
const char *readFrom = buffer();
914-
const char *const readEnd = readFrom + len();
914+
const char *readEnd = readFrom + len();
915915
if ((readFrom == readEnd) || find_len == 0)
916916
return;
917917

@@ -961,16 +961,46 @@ void String::replaceImpl(internal_memmem_t impl, const char *find, unsigned int
961961
return;
962962
if (size > capacity() && !changeBuffer(size))
963963
return;
964-
int index = len() - 1;
965-
while (index >= 0 && (index = lastIndexOf(find, find_len, index)) >= 0) {
966-
readFrom = wbuffer() + index + find_len;
967-
memmove_P(const_cast<char *>(readFrom) + diff, readFrom, len() - (readFrom - buffer()));
968-
int newLen = len() + diff;
969-
memmove_P(wbuffer() + index, replace, replace_len);
970-
setLen(newLen);
971-
wbuffer()[newLen] = 0;
972-
index--;
964+
965+
readFrom = buffer();
966+
readEnd = readFrom + len();
967+
968+
const char *foundFrom = readFrom;
969+
const char *foundEnd = readEnd;
970+
971+
auto last_found = [impl](const char *hs, size_t hs_len, const char *needle, size_t needle_len) {
972+
const char *last = nullptr;
973+
974+
const char *current = hs;
975+
const char *end = hs + hs_len;
976+
for (;;) {
977+
current = static_cast<const char *>(impl(current, end - current, needle, needle_len));
978+
if (!current)
979+
break;
980+
981+
last = current;
982+
current += needle_len;
983+
}
984+
985+
return last;
986+
};
987+
988+
for (;;) {
989+
foundAt = last_found(foundFrom, foundEnd - foundFrom, find, find_len);
990+
if (!foundAt)
991+
break;
992+
993+
readFrom = foundAt + find_len;
994+
memmove_P(const_cast<char *>(readFrom) + diff, readFrom, readEnd - readFrom);
995+
memmove_P(const_cast<char *>(foundAt), replace, replace_len);
996+
997+
foundEnd = foundAt;
998+
readEnd += diff;
973999
}
1000+
1001+
auto newLen = readEnd - buffer();
1002+
setLen(newLen);
1003+
wbuffer()[newLen] = 0;
9741004
}
9751005
}
9761006

0 commit comments

Comments
 (0)