@@ -150,11 +150,8 @@ void String::invalidate(void) {
150
150
bool String::reserve (unsigned int size) {
151
151
if (buffer () && capacity () >= size)
152
152
return true ;
153
- if (changeBuffer (size)) {
154
- if (len () == 0 )
155
- wbuffer ()[0 ] = 0 ;
153
+ if (changeBuffer (size))
156
154
return true ;
157
- }
158
155
return false ;
159
156
}
160
157
@@ -163,17 +160,17 @@ bool String::changeBuffer(unsigned int maxStrLen) {
163
160
if (maxStrLen < sizeof (sso.buff ) - 1 ) {
164
161
if (isSSO () || !buffer ()) {
165
162
// Already using SSO, nothing to do
166
- uint16_t oldLen = len ();
163
+ unsigned int oldLen = len ();
167
164
setSSO (true );
168
165
setLen (oldLen);
169
166
} else { // if bufptr && !isSSO()
170
167
// Using bufptr, need to shrink into sso.buff
171
168
const char *temp = buffer ();
172
- uint16_t oldLen = len ();
169
+ unsigned int oldLen = len ();
173
170
setSSO (true );
174
- setLen (oldLen);
175
171
memcpy (wbuffer (), temp, maxStrLen);
176
172
free ((void *)temp);
173
+ setLen (oldLen);
177
174
}
178
175
return true ;
179
176
}
@@ -191,7 +188,7 @@ bool String::changeBuffer(unsigned int maxStrLen) {
191
188
if (newSize > CAPACITY_MAX) {
192
189
return false ;
193
190
}
194
- uint16_t oldLen = len ();
191
+ unsigned int oldLen = len ();
195
192
char *newbuffer = (char *)realloc (isSSO () ? nullptr : wbuffer (), newSize);
196
193
if (newbuffer) {
197
194
size_t oldSize = capacity () + 1 ; // include NULL.
@@ -220,8 +217,8 @@ String &String::copy(const char *cstr, unsigned int length) {
220
217
invalidate ();
221
218
return *this ;
222
219
}
220
+ memmove_P (wbuffer (), cstr, length);
223
221
setLen (length);
224
- memmove_P (wbuffer (), cstr, length + 1 );
225
222
return *this ;
226
223
}
227
224
@@ -230,8 +227,8 @@ String &String::copy(const __FlashStringHelper *pstr, unsigned int length) {
230
227
invalidate ();
231
228
return *this ;
232
229
}
230
+ memcpy_P (wbuffer (), (PGM_P)pstr, length); // We know wbuffer() cannot ever be in PROGMEM, so memcpy safe here
233
231
setLen (length);
234
- memcpy_P (wbuffer (), (PGM_P)pstr, length + 1 ); // We know wbuffer() cannot ever be in PROGMEM, so memcpy safe here
235
232
return *this ;
236
233
}
237
234
@@ -282,15 +279,15 @@ bool String::concat(const String &s) {
282
279
// realloc'ing the buffer and moving s.buffer in the method called
283
280
if (&s == this ) {
284
281
unsigned int newlen = 2 * len ();
285
- if (!s. buffer ())
282
+ if (!buffer ())
286
283
return false ;
287
- if (s. len () == 0 )
284
+ if (len () == 0 )
288
285
return true ;
289
286
if (!reserve (newlen))
290
287
return false ;
291
- memmove_P (wbuffer () + len (), buffer (), len ());
288
+ char *writeTo = wbuffer ();
289
+ memmove_P (writeTo + len (), writeTo, len ());
292
290
setLen (newlen);
293
- wbuffer ()[newlen] = 0 ;
294
291
return true ;
295
292
} else {
296
293
return concat (s.buffer (), s.len ());
@@ -305,9 +302,8 @@ bool String::concat(const char *cstr, unsigned int length) {
305
302
return true ;
306
303
if (!reserve (newlen))
307
304
return false ;
308
- memmove_P (wbuffer () + len (), cstr, length + 1 );
305
+ memmove_P (wbuffer () + len (), cstr, length);
309
306
setLen (newlen);
310
- wbuffer ()[newlen] = 0 ;
311
307
return true ;
312
308
}
313
309
@@ -371,15 +367,14 @@ bool String::concat(double num) {
371
367
}
372
368
373
369
bool String::concat (const __FlashStringHelper *str) {
370
+ unsigned int length = strlen_P ((PGM_P)str), newlen = len () + length;
374
371
if (!str)
375
372
return false ;
376
- int length = strlen_P ((PGM_P)str);
377
373
if (length == 0 )
378
374
return true ;
379
- unsigned int newlen = len () + length;
380
375
if (!reserve (newlen))
381
376
return false ;
382
- memcpy_P (wbuffer () + len (), (PGM_P)str, length + 1 );
377
+ memcpy_P (wbuffer () + len (), (PGM_P)str, length);
383
378
setLen (newlen);
384
379
return true ;
385
380
}
@@ -398,12 +393,10 @@ String &String::insert(size_t position, const char *other, size_t other_length)
398
393
return *this ;
399
394
400
395
auto left = len - position;
401
- setLen (total);
402
-
403
396
auto *start = wbuffer () + position;
404
397
memmove (start + other_length, start, left);
405
398
memmove_P (start, other, other_length);
406
- wbuffer ()[ total] = ' \0 ' ;
399
+ setLen ( total) ;
407
400
408
401
return *this ;
409
402
}
@@ -414,8 +407,7 @@ String &String::insert(size_t position, const __FlashStringHelper *other) {
414
407
}
415
408
416
409
String &String::insert (size_t position, char other) {
417
- char tmp[2 ] { other, ' \0 ' };
418
- return insert (position, tmp, 1 );
410
+ return insert (position, &other, 1 );
419
411
}
420
412
421
413
String &String::insert (size_t position, const char *other) {
@@ -565,6 +557,14 @@ bool String::startsWith(const String &s2) const {
565
557
return startsWith (s2, 0 );
566
558
}
567
559
560
+ bool String::startsWith (const char *prefix) const {
561
+ return this ->startsWith (String (prefix));
562
+ }
563
+
564
+ bool String::startsWith (const __FlashStringHelper *prefix) const {
565
+ return this ->startsWith (String (prefix));
566
+ }
567
+
568
568
bool String::startsWith (const String &s2, unsigned int offset) const {
569
569
if (offset > (unsigned )(len () - s2.len ()) || !buffer () || !s2.buffer ())
570
570
return false ;
@@ -577,6 +577,14 @@ bool String::endsWith(const String &s2) const {
577
577
return strcmp (&buffer ()[len () - s2.len ()], s2.buffer ()) == 0 ;
578
578
}
579
579
580
+ bool String::endsWith (const char *suffix) const {
581
+ return this ->endsWith (String (suffix));
582
+ }
583
+
584
+ bool String::endsWith (const __FlashStringHelper *suffix) const {
585
+ return this ->endsWith (String (suffix));
586
+ }
587
+
580
588
/* ********************************************/
581
589
/* Character Access */
582
590
/* ********************************************/
@@ -684,16 +692,12 @@ String String::substring(unsigned int left, unsigned int right) const {
684
692
right = left;
685
693
left = temp;
686
694
}
687
- String out;
688
- if (left >= len ())
689
- return out;
695
+ if (left > len ())
696
+ left = len ();
690
697
if (right > len ())
691
698
right = len ();
692
- char *writeTo = wbuffer ();
693
- char tempchar = writeTo[right]; // save the replaced character
694
- writeTo[right] = ' \0 ' ;
695
- out = writeTo + left; // pointer arithmetic
696
- writeTo[right] = tempchar; // restore character
699
+ String out;
700
+ out.concat (buffer () + left, right - left);
697
701
return out;
698
702
}
699
703
@@ -702,41 +706,41 @@ String String::substring(unsigned int left, unsigned int right) const {
702
706
/* ********************************************/
703
707
704
708
void String::replace (char find, char replace) {
705
- if (!buffer ())
706
- return ;
707
- for (char *p = wbuffer (); *p; p++) {
708
- if (*p == find)
709
- *p = replace;
709
+ for (auto &c : *this ) {
710
+ if (c == find)
711
+ c = replace;
710
712
}
711
713
}
712
714
713
715
void String::replace (const String &find, const String &replace) {
714
- if (len () == 0 || find.len () == 0 )
716
+ unsigned int find_len = find.len (), replace_len = replace.len ();
717
+ const char *find_buffer = find.buffer (), *replace_buffer = replace.buffer ();
718
+ if (len () == 0 || find_len == 0 )
715
719
return ;
716
- int diff = replace. len () - find. len () ;
720
+ int diff = replace_len - find_len ;
717
721
char *readFrom = wbuffer ();
718
722
char *foundAt;
719
723
if (diff == 0 ) {
720
- while ((foundAt = strstr (readFrom, find. buffer () )) != NULL ) {
721
- memmove_P (foundAt, replace. buffer (), replace. len () );
722
- readFrom = foundAt + replace. len () ;
724
+ while ((foundAt = strstr (readFrom, find_buffer )) != NULL ) {
725
+ memmove_P (foundAt, replace_buffer, replace_len );
726
+ readFrom = foundAt + replace_len ;
723
727
}
724
728
} else if (diff < 0 ) {
725
729
char *writeTo = wbuffer ();
726
- while ((foundAt = strstr (readFrom, find. buffer () )) != NULL ) {
730
+ while ((foundAt = strstr (readFrom, find_buffer )) != NULL ) {
727
731
unsigned int n = foundAt - readFrom;
728
732
memmove_P (writeTo, readFrom, n);
729
733
writeTo += n;
730
- memmove_P (writeTo, replace. buffer (), replace. len () );
731
- writeTo += replace. len () ;
732
- readFrom = foundAt + find. len () ;
734
+ memmove_P (writeTo, replace_buffer, replace_len );
735
+ writeTo += replace_len ;
736
+ readFrom = foundAt + find_len ;
733
737
setLen (len () + diff);
734
738
}
735
739
memmove_P (writeTo, readFrom, strlen (readFrom) + 1 );
736
740
} else {
737
741
unsigned int size = len (); // compute size needed for result
738
- while ((foundAt = strstr (readFrom, find. buffer () )) != NULL ) {
739
- readFrom = foundAt + find. len () ;
742
+ while ((foundAt = strstr (readFrom, find_buffer )) != NULL ) {
743
+ readFrom = foundAt + find_len ;
740
744
size += diff;
741
745
}
742
746
if (size == len ())
@@ -745,64 +749,75 @@ void String::replace(const String &find, const String &replace) {
745
749
return ; // XXX: tell user!
746
750
int index = len () - 1 ;
747
751
while (index >= 0 && (index = lastIndexOf (find, index )) >= 0 ) {
748
- readFrom = wbuffer () + index + find. len () ;
752
+ readFrom = wbuffer () + index + find_len ;
749
753
memmove_P (readFrom + diff, readFrom, len () - (readFrom - buffer ()));
750
754
int newLen = len () + diff;
751
- memmove_P (wbuffer () + index , replace. buffer (), replace. len () );
755
+ memmove_P (wbuffer () + index , replace_buffer, replace_len );
752
756
setLen (newLen);
753
- wbuffer ()[newLen] = 0 ;
754
757
index --;
755
758
}
756
759
}
757
760
}
758
761
762
+ void String::replace (const char *find, const String &replace) {
763
+ this ->replace (String (find), replace);
764
+ }
765
+
766
+ void String::replace (const __FlashStringHelper *find, const String &replace) {
767
+ this ->replace (String (find), replace);
768
+ }
769
+
770
+ void String::replace (const char *find, const char *replace) {
771
+ this ->replace (String (find), String (replace));
772
+ }
773
+
774
+ void String::replace (const __FlashStringHelper *find, const char *replace) {
775
+ this ->replace (String (find), String (replace));
776
+ }
777
+
778
+ void String::replace (const __FlashStringHelper *find, const __FlashStringHelper *replace) {
779
+ this ->replace (String (find), String (replace));
780
+ }
781
+
759
782
void String::remove (unsigned int index, unsigned int count) {
760
- if (index >= len ()) {
761
- return ;
762
- }
763
- if (count <= 0 ) {
783
+ if (count == 0 || index >= len ()) {
764
784
return ;
765
785
}
766
786
if (count > len () - index ) {
767
787
count = len () - index ;
768
788
}
769
- char *writeTo = wbuffer () + index ;
770
789
unsigned int newlen = len () - count;
790
+ char *writeTo = wbuffer ();
791
+ memmove_P (writeTo + index , writeTo + index + count, newlen - index );
771
792
setLen (newlen);
772
- memmove_P (writeTo, wbuffer () + index + count, newlen - index );
773
- wbuffer ()[newlen] = 0 ;
774
793
}
775
794
776
795
void String::toLowerCase (void ) {
777
- if (!buffer ())
778
- return ;
779
- for (char *p = wbuffer (); *p; p++) {
780
- *p = tolower (*p);
796
+ for (auto &c : *this ) {
797
+ c = tolower (c);
781
798
}
782
799
}
783
800
784
801
void String::toUpperCase (void ) {
785
- if (!buffer ())
786
- return ;
787
- for (char *p = wbuffer (); *p; p++) {
788
- *p = toupper (*p);
802
+ for (auto &c : *this ) {
803
+ c = toupper (c);
789
804
}
790
805
}
791
806
792
807
void String::trim (void ) {
793
- if (!buffer () || len () == 0 )
808
+ char *writeTo = wbuffer ();
809
+ if (!writeTo || len () == 0 )
794
810
return ;
795
- char *begin = wbuffer () ;
811
+ char *begin = writeTo ;
796
812
while (isspace (*begin))
797
813
begin++;
798
- char *end = wbuffer () + len () - 1 ;
814
+ char *end = writeTo + len () - 1 ;
799
815
while (isspace (*end) && end >= begin)
800
816
end--;
801
817
unsigned int newlen = end + 1 - begin;
818
+ if (begin > writeTo)
819
+ memmove_P (writeTo, begin, newlen);
802
820
setLen (newlen);
803
- if (begin > buffer ())
804
- memmove_P (wbuffer (), begin, newlen);
805
- wbuffer ()[newlen] = 0 ;
806
821
}
807
822
808
823
/* ********************************************/
0 commit comments