]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - tmk_core/protocol/usb_hid/arduino-1.8.13/cores/arduino/WString.cpp
usb_hid: Update arduino cores to 1.8.13
[max/tmk_keyboard.git] / tmk_core / protocol / usb_hid / arduino-1.8.13 / cores / arduino / WString.cpp
1 /*
2   WString.cpp - String library for Wiring & Arduino
3   ...mostly rewritten by Paul Stoffregen...
4   Copyright (c) 2009-10 Hernando Barragan.  All rights reserved.
5   Copyright 2011, Paul Stoffregen, paul@pjrc.com
6
7   This library is free software; you can redistribute it and/or
8   modify it under the terms of the GNU Lesser General Public
9   License as published by the Free Software Foundation; either
10   version 2.1 of the License, or (at your option) any later version.
11
12   This library is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   Lesser General Public License for more details.
16
17   You should have received a copy of the GNU Lesser General Public
18   License along with this library; if not, write to the Free Software
19   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 #include "WString.h"
23
24 /*********************************************/
25 /*  Constructors                             */
26 /*********************************************/
27
28 String::String(const char *cstr)
29 {
30         init();
31         if (cstr) copy(cstr, strlen(cstr));
32 }
33
34 String::String(const String &value)
35 {
36         init();
37         *this = value;
38 }
39
40 String::String(const __FlashStringHelper *pstr)
41 {
42         init();
43         *this = pstr;
44 }
45
46 #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
47 String::String(String &&rval)
48 {
49         init();
50         move(rval);
51 }
52 String::String(StringSumHelper &&rval)
53 {
54         init();
55         move(rval);
56 }
57 #endif
58
59 String::String(char c)
60 {
61         init();
62         char buf[2];
63         buf[0] = c;
64         buf[1] = 0;
65         *this = buf;
66 }
67
68 String::String(unsigned char value, unsigned char base)
69 {
70         init();
71         char buf[1 + 8 * sizeof(unsigned char)];
72         utoa(value, buf, base);
73         *this = buf;
74 }
75
76 String::String(int value, unsigned char base)
77 {
78         init();
79         char buf[2 + 8 * sizeof(int)];
80         itoa(value, buf, base);
81         *this = buf;
82 }
83
84 String::String(unsigned int value, unsigned char base)
85 {
86         init();
87         char buf[1 + 8 * sizeof(unsigned int)];
88         utoa(value, buf, base);
89         *this = buf;
90 }
91
92 String::String(long value, unsigned char base)
93 {
94         init();
95         char buf[2 + 8 * sizeof(long)];
96         ltoa(value, buf, base);
97         *this = buf;
98 }
99
100 String::String(unsigned long value, unsigned char base)
101 {
102         init();
103         char buf[1 + 8 * sizeof(unsigned long)];
104         ultoa(value, buf, base);
105         *this = buf;
106 }
107
108 String::String(float value, unsigned char decimalPlaces)
109 {
110         init();
111         char buf[33];
112         *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
113 }
114
115 String::String(double value, unsigned char decimalPlaces)
116 {
117         init();
118         char buf[33];
119         *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
120 }
121
122 String::~String()
123 {
124         if (buffer) free(buffer);
125 }
126
127 /*********************************************/
128 /*  Memory Management                        */
129 /*********************************************/
130
131 inline void String::init(void)
132 {
133         buffer = NULL;
134         capacity = 0;
135         len = 0;
136 }
137
138 void String::invalidate(void)
139 {
140         if (buffer) free(buffer);
141         buffer = NULL;
142         capacity = len = 0;
143 }
144
145 unsigned char String::reserve(unsigned int size)
146 {
147         if (buffer && capacity >= size) return 1;
148         if (changeBuffer(size)) {
149                 if (len == 0) buffer[0] = 0;
150                 return 1;
151         }
152         return 0;
153 }
154
155 unsigned char String::changeBuffer(unsigned int maxStrLen)
156 {
157         char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
158         if (newbuffer) {
159                 buffer = newbuffer;
160                 capacity = maxStrLen;
161                 return 1;
162         }
163         return 0;
164 }
165
166 /*********************************************/
167 /*  Copy and Move                            */
168 /*********************************************/
169
170 String & String::copy(const char *cstr, unsigned int length)
171 {
172         if (!reserve(length)) {
173                 invalidate();
174                 return *this;
175         }
176         len = length;
177         strcpy(buffer, cstr);
178         return *this;
179 }
180
181 String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
182 {
183         if (!reserve(length)) {
184                 invalidate();
185                 return *this;
186         }
187         len = length;
188         strcpy_P(buffer, (PGM_P)pstr);
189         return *this;
190 }
191
192 #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
193 void String::move(String &rhs)
194 {
195         if (buffer) {
196                 if (rhs && capacity >= rhs.len) {
197                         strcpy(buffer, rhs.buffer);
198                         len = rhs.len;
199                         rhs.len = 0;
200                         return;
201                 } else {
202                         free(buffer);
203                 }
204         }
205         buffer = rhs.buffer;
206         capacity = rhs.capacity;
207         len = rhs.len;
208         rhs.buffer = NULL;
209         rhs.capacity = 0;
210         rhs.len = 0;
211 }
212 #endif
213
214 String & String::operator = (const String &rhs)
215 {
216         if (this == &rhs) return *this;
217         
218         if (rhs.buffer) copy(rhs.buffer, rhs.len);
219         else invalidate();
220         
221         return *this;
222 }
223
224 #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
225 String & String::operator = (String &&rval)
226 {
227         if (this != &rval) move(rval);
228         return *this;
229 }
230
231 String & String::operator = (StringSumHelper &&rval)
232 {
233         if (this != &rval) move(rval);
234         return *this;
235 }
236 #endif
237
238 String & String::operator = (const char *cstr)
239 {
240         if (cstr) copy(cstr, strlen(cstr));
241         else invalidate();
242         
243         return *this;
244 }
245
246 String & String::operator = (const __FlashStringHelper *pstr)
247 {
248         if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
249         else invalidate();
250
251         return *this;
252 }
253
254 /*********************************************/
255 /*  concat                                   */
256 /*********************************************/
257
258 unsigned char String::concat(const String &s)
259 {
260         return concat(s.buffer, s.len);
261 }
262
263 unsigned char String::concat(const char *cstr, unsigned int length)
264 {
265         unsigned int newlen = len + length;
266         if (!cstr) return 0;
267         if (length == 0) return 1;
268         if (!reserve(newlen)) return 0;
269         strcpy(buffer + len, cstr);
270         len = newlen;
271         return 1;
272 }
273
274 unsigned char String::concat(const char *cstr)
275 {
276         if (!cstr) return 0;
277         return concat(cstr, strlen(cstr));
278 }
279
280 unsigned char String::concat(char c)
281 {
282         char buf[2];
283         buf[0] = c;
284         buf[1] = 0;
285         return concat(buf, 1);
286 }
287
288 unsigned char String::concat(unsigned char num)
289 {
290         char buf[1 + 3 * sizeof(unsigned char)];
291         itoa(num, buf, 10);
292         return concat(buf, strlen(buf));
293 }
294
295 unsigned char String::concat(int num)
296 {
297         char buf[2 + 3 * sizeof(int)];
298         itoa(num, buf, 10);
299         return concat(buf, strlen(buf));
300 }
301
302 unsigned char String::concat(unsigned int num)
303 {
304         char buf[1 + 3 * sizeof(unsigned int)];
305         utoa(num, buf, 10);
306         return concat(buf, strlen(buf));
307 }
308
309 unsigned char String::concat(long num)
310 {
311         char buf[2 + 3 * sizeof(long)];
312         ltoa(num, buf, 10);
313         return concat(buf, strlen(buf));
314 }
315
316 unsigned char String::concat(unsigned long num)
317 {
318         char buf[1 + 3 * sizeof(unsigned long)];
319         ultoa(num, buf, 10);
320         return concat(buf, strlen(buf));
321 }
322
323 unsigned char String::concat(float num)
324 {
325         char buf[20];
326         char* string = dtostrf(num, 4, 2, buf);
327         return concat(string, strlen(string));
328 }
329
330 unsigned char String::concat(double num)
331 {
332         char buf[20];
333         char* string = dtostrf(num, 4, 2, buf);
334         return concat(string, strlen(string));
335 }
336
337 unsigned char String::concat(const __FlashStringHelper * str)
338 {
339         if (!str) return 0;
340         int length = strlen_P((const char *) str);
341         if (length == 0) return 1;
342         unsigned int newlen = len + length;
343         if (!reserve(newlen)) return 0;
344         strcpy_P(buffer + len, (const char *) str);
345         len = newlen;
346         return 1;
347 }
348
349 /*********************************************/
350 /*  Concatenate                              */
351 /*********************************************/
352
353 StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
354 {
355         StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
356         if (!a.concat(rhs.buffer, rhs.len)) a.invalidate();
357         return a;
358 }
359
360 StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
361 {
362         StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
363         if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate();
364         return a;
365 }
366
367 StringSumHelper & operator + (const StringSumHelper &lhs, char c)
368 {
369         StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
370         if (!a.concat(c)) a.invalidate();
371         return a;
372 }
373
374 StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num)
375 {
376         StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
377         if (!a.concat(num)) a.invalidate();
378         return a;
379 }
380
381 StringSumHelper & operator + (const StringSumHelper &lhs, int num)
382 {
383         StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
384         if (!a.concat(num)) a.invalidate();
385         return a;
386 }
387
388 StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
389 {
390         StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
391         if (!a.concat(num)) a.invalidate();
392         return a;
393 }
394
395 StringSumHelper & operator + (const StringSumHelper &lhs, long num)
396 {
397         StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
398         if (!a.concat(num)) a.invalidate();
399         return a;
400 }
401
402 StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
403 {
404         StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
405         if (!a.concat(num)) a.invalidate();
406         return a;
407 }
408
409 StringSumHelper & operator + (const StringSumHelper &lhs, float num)
410 {
411         StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
412         if (!a.concat(num)) a.invalidate();
413         return a;
414 }
415
416 StringSumHelper & operator + (const StringSumHelper &lhs, double num)
417 {
418         StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
419         if (!a.concat(num)) a.invalidate();
420         return a;
421 }
422
423 StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
424 {
425         StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
426         if (!a.concat(rhs))     a.invalidate();
427         return a;
428 }
429
430 /*********************************************/
431 /*  Comparison                               */
432 /*********************************************/
433
434 int String::compareTo(const String &s) const
435 {
436         if (!buffer || !s.buffer) {
437                 if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
438                 if (buffer && len > 0) return *(unsigned char *)buffer;
439                 return 0;
440         }
441         return strcmp(buffer, s.buffer);
442 }
443
444 unsigned char String::equals(const String &s2) const
445 {
446         return (len == s2.len && compareTo(s2) == 0);
447 }
448
449 unsigned char String::equals(const char *cstr) const
450 {
451         if (len == 0) return (cstr == NULL || *cstr == 0);
452         if (cstr == NULL) return buffer[0] == 0;
453         return strcmp(buffer, cstr) == 0;
454 }
455
456 unsigned char String::operator<(const String &rhs) const
457 {
458         return compareTo(rhs) < 0;
459 }
460
461 unsigned char String::operator>(const String &rhs) const
462 {
463         return compareTo(rhs) > 0;
464 }
465
466 unsigned char String::operator<=(const String &rhs) const
467 {
468         return compareTo(rhs) <= 0;
469 }
470
471 unsigned char String::operator>=(const String &rhs) const
472 {
473         return compareTo(rhs) >= 0;
474 }
475
476 unsigned char String::equalsIgnoreCase( const String &s2 ) const
477 {
478         if (this == &s2) return 1;
479         if (len != s2.len) return 0;
480         if (len == 0) return 1;
481         const char *p1 = buffer;
482         const char *p2 = s2.buffer;
483         while (*p1) {
484                 if (tolower(*p1++) != tolower(*p2++)) return 0;
485         } 
486         return 1;
487 }
488
489 unsigned char String::startsWith( const String &s2 ) const
490 {
491         if (len < s2.len) return 0;
492         return startsWith(s2, 0);
493 }
494
495 unsigned char String::startsWith( const String &s2, unsigned int offset ) const
496 {
497         if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
498         return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
499 }
500
501 unsigned char String::endsWith( const String &s2 ) const
502 {
503         if ( len < s2.len || !buffer || !s2.buffer) return 0;
504         return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
505 }
506
507 /*********************************************/
508 /*  Character Access                         */
509 /*********************************************/
510
511 char String::charAt(unsigned int loc) const
512 {
513         return operator[](loc);
514 }
515
516 void String::setCharAt(unsigned int loc, char c) 
517 {
518         if (loc < len) buffer[loc] = c;
519 }
520
521 char & String::operator[](unsigned int index)
522 {
523         static char dummy_writable_char;
524         if (index >= len || !buffer) {
525                 dummy_writable_char = 0;
526                 return dummy_writable_char;
527         }
528         return buffer[index];
529 }
530
531 char String::operator[]( unsigned int index ) const
532 {
533         if (index >= len || !buffer) return 0;
534         return buffer[index];
535 }
536
537 void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
538 {
539         if (!bufsize || !buf) return;
540         if (index >= len) {
541                 buf[0] = 0;
542                 return;
543         }
544         unsigned int n = bufsize - 1;
545         if (n > len - index) n = len - index;
546         strncpy((char *)buf, buffer + index, n);
547         buf[n] = 0;
548 }
549
550 /*********************************************/
551 /*  Search                                   */
552 /*********************************************/
553
554 int String::indexOf(char c) const
555 {
556         return indexOf(c, 0);
557 }
558
559 int String::indexOf( char ch, unsigned int fromIndex ) const
560 {
561         if (fromIndex >= len) return -1;
562         const char* temp = strchr(buffer + fromIndex, ch);
563         if (temp == NULL) return -1;
564         return temp - buffer;
565 }
566
567 int String::indexOf(const String &s2) const
568 {
569         return indexOf(s2, 0);
570 }
571
572 int String::indexOf(const String &s2, unsigned int fromIndex) const
573 {
574         if (fromIndex >= len) return -1;
575         const char *found = strstr(buffer + fromIndex, s2.buffer);
576         if (found == NULL) return -1;
577         return found - buffer;
578 }
579
580 int String::lastIndexOf( char theChar ) const
581 {
582         return lastIndexOf(theChar, len - 1);
583 }
584
585 int String::lastIndexOf(char ch, unsigned int fromIndex) const
586 {
587         if (fromIndex >= len) return -1;
588         char tempchar = buffer[fromIndex + 1];
589         buffer[fromIndex + 1] = '\0';
590         char* temp = strrchr( buffer, ch );
591         buffer[fromIndex + 1] = tempchar;
592         if (temp == NULL) return -1;
593         return temp - buffer;
594 }
595
596 int String::lastIndexOf(const String &s2) const
597 {
598         return lastIndexOf(s2, len - s2.len);
599 }
600
601 int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
602 {
603         if (s2.len == 0 || len == 0 || s2.len > len) return -1;
604         if (fromIndex >= len) fromIndex = len - 1;
605         int found = -1;
606         for (char *p = buffer; p <= buffer + fromIndex; p++) {
607                 p = strstr(p, s2.buffer);
608                 if (!p) break;
609                 if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
610         }
611         return found;
612 }
613
614 String String::substring(unsigned int left, unsigned int right) const
615 {
616         if (left > right) {
617                 unsigned int temp = right;
618                 right = left;
619                 left = temp;
620         }
621         String out;
622         if (left >= len) return out;
623         if (right > len) right = len;
624         char temp = buffer[right];  // save the replaced character
625         buffer[right] = '\0';   
626         out = buffer + left;  // pointer arithmetic
627         buffer[right] = temp;  //restore character
628         return out;
629 }
630
631 /*********************************************/
632 /*  Modification                             */
633 /*********************************************/
634
635 void String::replace(char find, char replace)
636 {
637         if (!buffer) return;
638         for (char *p = buffer; *p; p++) {
639                 if (*p == find) *p = replace;
640         }
641 }
642
643 void String::replace(const String& find, const String& replace)
644 {
645         if (len == 0 || find.len == 0) return;
646         int diff = replace.len - find.len;
647         char *readFrom = buffer;
648         char *foundAt;
649         if (diff == 0) {
650                 while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
651                         memcpy(foundAt, replace.buffer, replace.len);
652                         readFrom = foundAt + replace.len;
653                 }
654         } else if (diff < 0) {
655                 char *writeTo = buffer;
656                 while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
657                         unsigned int n = foundAt - readFrom;
658                         memcpy(writeTo, readFrom, n);
659                         writeTo += n;
660                         memcpy(writeTo, replace.buffer, replace.len);
661                         writeTo += replace.len;
662                         readFrom = foundAt + find.len;
663                         len += diff;
664                 }
665                 strcpy(writeTo, readFrom);
666         } else {
667                 unsigned int size = len; // compute size needed for result
668                 while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
669                         readFrom = foundAt + find.len;
670                         size += diff;
671                 }
672                 if (size == len) return;
673                 if (size > capacity && !changeBuffer(size)) return; // XXX: tell user!
674                 int index = len - 1;
675                 while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
676                         readFrom = buffer + index + find.len;
677                         memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
678                         len += diff;
679                         buffer[len] = 0;
680                         memcpy(buffer + index, replace.buffer, replace.len);
681                         index--;
682                 }
683         }
684 }
685
686 void String::remove(unsigned int index){
687         // Pass the biggest integer as the count. The remove method
688         // below will take care of truncating it at the end of the
689         // string.
690         remove(index, (unsigned int)-1);
691 }
692
693 void String::remove(unsigned int index, unsigned int count){
694         if (index >= len) { return; }
695         if (count <= 0) { return; }
696         if (count > len - index) { count = len - index; }
697         char *writeTo = buffer + index;
698         len = len - count;
699         strncpy(writeTo, buffer + index + count,len - index);
700         buffer[len] = 0;
701 }
702
703 void String::toLowerCase(void)
704 {
705         if (!buffer) return;
706         for (char *p = buffer; *p; p++) {
707                 *p = tolower(*p);
708         }
709 }
710
711 void String::toUpperCase(void)
712 {
713         if (!buffer) return;
714         for (char *p = buffer; *p; p++) {
715                 *p = toupper(*p);
716         }
717 }
718
719 void String::trim(void)
720 {
721         if (!buffer || len == 0) return;
722         char *begin = buffer;
723         while (isspace(*begin)) begin++;
724         char *end = buffer + len - 1;
725         while (isspace(*end) && end >= begin) end--;
726         len = end + 1 - begin;
727         if (begin > buffer) memcpy(buffer, begin, len);
728         buffer[len] = 0;
729 }
730
731 /*********************************************/
732 /*  Parsing / Conversion                     */
733 /*********************************************/
734
735 long String::toInt(void) const
736 {
737         if (buffer) return atol(buffer);
738         return 0;
739 }
740
741 float String::toFloat(void) const
742 {
743         return float(toDouble());
744 }
745
746 double String::toDouble(void) const
747 {
748         if (buffer) return atof(buffer);
749         return 0;
750 }