WString.cpp
Go to the documentation of this file.
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  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 }
GLboolean GLboolean GLboolean GLboolean a
GLuint GLsizei GLsizei * length
void BASE_IMPEXP memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) MRPT_NO_THROWS
const GLfloat * c
int toLowerCase(int c) __attribute__((always_inline))
Definition: WCharacter.h:156
GLuint GLuint num
EIGEN_STRONG_INLINE iterator begin()
char BASE_IMPEXP * strcpy(char *dest, size_t destSize, const char *source) MRPT_NO_THROWS
GLsizei const GLfloat * value
s2
GLdouble s
int toUpperCase(int c) __attribute__((always_inline))
Definition: WCharacter.h:163
GLuint GLuint end
StringSumHelper & operator+(const StringSumHelper &lhs, const String &rhs)
Definition: WString.cpp:353
GLsizei n
GLenum GLsizei len
VALUE & operator[](const KEY &key)
GLuint buffer
GLfloat GLfloat p
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
GLsizeiptr size
void init(void)
Definition: wiring.c:241
GLuint index
const_iterator find(const KEY &key) const
std::string BASE_IMPEXP trim(const std::string &str)
GLuint GLuint GLsizei count
GLintptr offset
if(f >=FRACT_MAX)
Definition: wiring.c:55
const T & move(const T &t)


arduino_daq
Author(s):
autogenerated on Mon Jun 10 2019 12:46:03