source: rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/WString.cpp@ 136

Last change on this file since 136 was 136, checked in by ertl-honda, 8 years ago

ライブラリとOS及びベーシックなサンプルの追加.

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