/ teensy / WString.cpp
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  /*********************************************/
 26  /*  Constructors                             */
 27  /*********************************************/
 28  
 29  String::String(const char *cstr)
 30  {
 31  	init();
 32  	if (cstr) copy(cstr, strlen(cstr));
 33  }
 34  
 35  String::String(const __FlashStringHelper *pgmstr)
 36  {
 37  	init();
 38  	*this = pgmstr;
 39  }
 40  
 41  String::String(const String &value)
 42  {
 43  	init();
 44  	*this = value;
 45  }
 46  
 47  #ifdef __GXX_EXPERIMENTAL_CXX0X__
 48  String::String(String &&rval)
 49  {
 50  	init();
 51  	move(rval);
 52  }
 53  String::String(StringSumHelper &&rval)
 54  {
 55  	init();
 56  	move(rval);
 57  }
 58  #endif
 59  
 60  String::String(char c)
 61  {
 62  	init();
 63  	*this = c;
 64  }
 65  
 66  String::String(unsigned char c)
 67  {
 68  	init();
 69  	*this = (char)c;
 70  }
 71  
 72  String::String(const int value, unsigned char base)
 73  {
 74  	init();
 75  	char buf[18];
 76  	itoa(value, buf, base);
 77  	*this = buf;
 78  }
 79  
 80  String::String(unsigned int value, unsigned char base)
 81  {
 82  	init();
 83  	char buf[17];
 84    	utoa(value, buf, base);
 85  	*this = buf;
 86  }
 87  
 88  String::String(long value, unsigned char base)
 89  {
 90  	init();
 91  	char buf[34];
 92  	ltoa(value, buf, base);
 93  	*this = buf;
 94  }
 95  
 96  String::String(unsigned long value, unsigned char base)
 97  {
 98  	init();
 99  	char buf[33];
100  	ultoa(value, buf, base);
101  	*this = buf;
102  }
103  
104  String::String(float num, unsigned char digits)
105  {
106  	init();
107  	char buf[40];
108  	*this = dtostrf(num, digits + 2, digits, buf);
109  }
110  
111  String::String(double num, unsigned char digits)
112  {
113  	init();
114  	char buf[40];
115  	*this = dtostrf(num, digits + 2, digits, buf);
116  }
117  
118  String::~String()
119  {
120  	free(buffer);
121  }
122  
123  /*********************************************/
124  /*  Memory Management                        */
125  /*********************************************/
126  
127  inline void String::init(void)
128  {
129  	buffer = NULL;
130  	capacity = 0;
131  	len = 0;
132  	flags = 0;
133  }
134  
135  unsigned char String::reserve(unsigned int size)
136  {
137  	if (capacity >= size) return 1;
138  	if (changeBuffer(size)) {
139  		if (len == 0) buffer[0] = 0;
140  		return 1;
141  	}
142  	return 0;
143  }
144  
145  unsigned char String::changeBuffer(unsigned int maxStrLen)
146  {
147  	char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
148  	if (newbuffer) {
149  		buffer = newbuffer;
150  		capacity = maxStrLen;
151  		return 1;
152  	}
153  	return 0;
154  }
155  
156  /*********************************************/
157  /*  Copy and Move                            */
158  /*********************************************/
159  
160  String & String::copy(const char *cstr, unsigned int length)
161  {
162  	if (length == 0) {
163  		if (buffer) buffer[0] = 0;
164  		len = 0;
165  		return *this;
166  	}
167  	if (!reserve(length)) {
168  		if (buffer) {
169  			free(buffer);
170  			buffer = NULL;
171  		}
172  		len = capacity = 0;
173  		return *this;
174  	}
175  	len = length;
176  	strcpy(buffer, cstr);
177  	return *this;
178  }
179  
180  String & String::copy(const __FlashStringHelper *pgmstr)
181  {
182  	unsigned int length = strlen_P((const char PROGMEM *)pgmstr);
183  	if (!reserve(length)) {
184  		if (buffer) {
185  			free(buffer);
186  			buffer = NULL;
187  		}
188  		len = capacity = 0;
189  		return *this;
190  	}
191  	len = length;
192  	strcpy_P(buffer, (const char PROGMEM *)pgmstr);
193  	return *this;
194  }
195  
196  void String::move(String &rhs)
197  {
198  	if (buffer) {
199  		if (capacity >= rhs.len) {
200  			strcpy(buffer, rhs.buffer);
201  			len = rhs.len;
202  			rhs.len = 0;
203  			return;
204  		} else {
205  			free(buffer);
206  		}
207  	}
208  	buffer = rhs.buffer;
209  	capacity = rhs.capacity;
210  	len = rhs.len;
211  	rhs.buffer = NULL;
212  	rhs.capacity = 0;
213  	rhs.len = 0;
214  }
215  
216  String & String::operator = (const String &rhs)
217  {
218  	if (this == &rhs) return *this;
219  	return copy(rhs.buffer, rhs.len);
220  }
221  
222  #ifdef __GXX_EXPERIMENTAL_CXX0X__
223  String & String::operator = (String &&rval)
224  {
225  	if (this != &rval) move(rval);
226  	return *this;
227  }
228  
229  String & String::operator = (StringSumHelper &&rval)
230  {
231  	if (this != &rval) move(rval);
232  	return *this;
233  }
234  #endif
235  
236  String & String::operator = (const char *cstr)
237  {
238  	if (cstr) {
239  		copy(cstr, strlen(cstr));
240  	} else {
241  		len = 0;
242  	}
243  	return *this;
244  }
245  
246  String & String::operator = (const __FlashStringHelper *pgmstr)
247  {
248  	copy(pgmstr);
249  	return *this;
250  }
251  
252  String & String::operator = (char c)
253  {
254  	char buf[2];
255  	buf[0] = c;
256  	buf[1] = 0;
257  	return copy(buf, 1);
258  }
259  
260  /*********************************************/
261  /*  Append                                   */
262  /*********************************************/
263  
264  String & String::append(const String &s)
265  {
266  	return append(s.buffer, s.len);
267  }
268  
269  String & String::append(const char *cstr, unsigned int length)
270  {
271  	unsigned int newlen = len + length;
272  	if (length == 0 || !reserve(newlen)) return *this;
273  	strcpy(buffer + len, cstr);
274  	len = newlen;
275  	return *this;
276  }
277  
278  String & String::append(const char *cstr)
279  {
280  	if (cstr) append(cstr, strlen(cstr));
281  	return *this;
282  }
283  
284  String & String::append(const __FlashStringHelper *pgmstr)
285  {
286  	unsigned int length = strlen_P((const char PROGMEM *)pgmstr);
287  	unsigned int newlen = len + length;
288  	if (length == 0 || !reserve(newlen)) return *this;
289  	strcpy_P(buffer + len, (const char PROGMEM *)pgmstr);
290  	len = newlen;
291  	return *this;
292  }
293  
294  String & String::append(char c)
295  {
296  	char buf[2];
297  	buf[0] = c;
298  	buf[1] = 0;
299  	append(buf, 1);
300  	return *this;
301  }
302  
303  String & String::append(int num)
304  {
305  	char buf[7];
306  	itoa(num, buf, 10);
307  	append(buf, strlen(buf));
308  	return *this;
309  }
310  
311  String & String::append(unsigned int num)
312  {
313  	char buf[6];
314  	utoa(num, buf, 10);
315  	append(buf, strlen(buf));
316  	return *this;
317  }
318  
319  String & String::append(long num)
320  {
321  	char buf[12];
322  	ltoa(num, buf, 10);
323  	append(buf, strlen(buf));
324  	return *this;
325  }
326  
327  String & String::append(unsigned long num)
328  {
329  	char buf[11];
330  	ultoa(num, buf, 10);
331  	append(buf, strlen(buf));
332  	return *this;
333  }
334  
335  String & String::append(float num)
336  {
337  	char buf[30];
338  	dtostrf(num, 4, 2, buf);
339  	append(buf, strlen(buf));
340  	return *this;
341  }
342  
343  /*********************************************/
344  /*  Concatenate                              */
345  /*********************************************/
346  
347  StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
348  {
349  	StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
350  	a.append(rhs.buffer, rhs.len);
351  	return a;
352  }
353  
354  StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
355  {
356  	StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
357  	if (cstr) a.append(cstr, strlen(cstr));
358  	return a;
359  }
360  
361  StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *pgmstr)
362  {
363  	StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
364  	a.append(pgmstr);
365  	return a;
366  }
367  
368  StringSumHelper & operator + (const StringSumHelper &lhs, char c)
369  {
370  	StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
371  	a.append(c);
372  	return a;
373  }
374  
375  StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char c)
376  {
377  	StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
378  	a.append(c);
379  	return a;
380  }
381  
382  StringSumHelper & operator + (const StringSumHelper &lhs, int num)
383  {
384  	StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
385  	a.append(num);
386  	return a;
387  }
388  
389  StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
390  {
391  	StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
392  	a.append(num);
393  	return a;
394  }
395  
396  StringSumHelper & operator + (const StringSumHelper &lhs, long num)
397  {
398  	StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
399  	a.append(num);
400  	return a;
401  }
402  
403  StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
404  {
405  	StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
406  	a.append(num);
407  	return a;
408  }
409  
410  StringSumHelper & operator + (const StringSumHelper &lhs, float num)
411  {
412  	StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
413  	a.append(num);
414  	return a;
415  }
416  
417  StringSumHelper & operator + (const StringSumHelper &lhs, double num)
418  {
419  	StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
420  	a.append(num);
421  	return a;
422  }
423  
424  /*********************************************/
425  /*  Comparison                               */
426  /*********************************************/
427  
428  int String::compareTo(const String &s) const
429  {
430  	if (!buffer || !s.buffer) {
431  		if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
432  		if (buffer && len > 0) return *(unsigned char *)buffer;
433  		return 0;
434  	}
435  	return strcmp(buffer, s.buffer);
436  }
437  
438  unsigned char String::equals(const String &s2) const
439  {
440  	return (len == s2.len && compareTo(s2) == 0);
441  }
442  
443  unsigned char String::equals(const char *cstr) const
444  {
445  	if (len == 0) return (cstr == NULL || *cstr == 0);
446  	if (cstr == NULL) return buffer[0] == 0;
447  	return strcmp(buffer, cstr) == 0;
448  }
449  
450  unsigned char String::equals(const __FlashStringHelper *pgmstr) const
451  {
452  	if (len == 0) return pgm_read_byte(pgmstr) == 0;
453  	return strcmp_P(buffer, (const char PROGMEM *)pgmstr) == 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 || fromIndex < 0) 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 || fromIndex < 0) 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 ) const
615  {
616  	return substring(left, len);
617  }
618  
619  String String::substring(unsigned int left, unsigned int right) const
620  {
621  	if (left > right) {
622  		unsigned int temp = right;
623  		right = left;
624  		left = temp;
625  	}
626  	String out;
627  	if (left > len) return out;
628  	if (right > len) right = len;
629  	char temp = buffer[right];  // save the replaced character
630  	buffer[right] = '\0';	
631  	out = buffer + left;  // pointer arithmetic
632  	buffer[right] = temp;  //restore character
633  	return out;
634  }
635  
636  /*********************************************/
637  /*  Modification                             */
638  /*********************************************/
639  
640  String & String::replace(char find, char replace)
641  {
642  	if (!buffer) return *this;
643  	for (char *p = buffer; *p; p++) {
644  		if (*p == find) *p = replace;
645  	}
646  	return *this;
647  }
648  
649  String & String::replace(const String& find, const String& replace)
650  {
651  	if (len == 0 || find.len == 0) return *this;
652  	int diff = replace.len - find.len;
653  	char *readFrom = buffer;
654  	char *foundAt;
655  	if (diff == 0) {
656  		while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
657  			memcpy(foundAt, replace.buffer, replace.len);
658  			readFrom = foundAt + replace.len;
659  		}
660  	} else if (diff < 0) {
661  		char *writeTo = buffer;
662  		while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
663  			unsigned int n = foundAt - readFrom;
664  			memcpy(writeTo, readFrom, n);
665  			writeTo += n;
666  			memcpy(writeTo, replace.buffer, replace.len);
667  			writeTo += replace.len;
668  			readFrom = foundAt + find.len;
669  			len += diff;
670  		}
671  		strcpy(writeTo, readFrom);
672  	} else {
673  		unsigned int size = len; // compute size needed for result
674  		while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
675  			readFrom = foundAt + find.len;
676  			size += diff;
677  		}
678  		if (size == len) return *this;
679  		if (size > capacity && !changeBuffer(size)) return *this;
680  		int index = len - 1;
681  		while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
682  			readFrom = buffer + index + find.len;
683  			memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
684  			len += diff;
685  			buffer[len] = 0;
686  			memcpy(buffer + index, replace.buffer, replace.len);
687  			index--;
688  		}
689  	}
690  	return *this;
691  }
692  
693  String & String::remove(unsigned int index)
694  {
695  	if (index < len) {
696  		len = index;
697  		buffer[len] = 0;
698  	}
699  	return *this;
700  }
701  
702  String & String::remove(unsigned int index, unsigned int count)
703  {
704  	if (index < len && count > 0) {
705  		if (index + count > len) count = len - index;
706  		len = len - count;
707  		memmove(buffer + index, buffer + index + count, len - index);
708  		buffer[len] = 0;
709  	}
710  	return *this;
711  }
712  
713  String & String::toLowerCase(void)
714  {
715  	if (!buffer) return *this;
716  	for (char *p = buffer; *p; p++) {
717  		*p = tolower(*p);
718  	}
719  	return *this;
720  }
721  
722  String & String::toUpperCase(void)
723  {
724  	if (!buffer) return *this;
725  	for (char *p = buffer; *p; p++) {
726  		*p = toupper(*p);
727  	}
728  	return *this;
729  }
730  
731  String & String::trim(void)
732  {
733  	if (!buffer || len == 0) return *this;
734  	char *begin = buffer;
735  	while (isspace(*begin)) begin++;
736  	char *end = buffer + len - 1;
737  	while (isspace(*end) && end >= begin) end--;
738  	len = end + 1 - begin;
739  	if (begin > buffer) memcpy(buffer, begin, len);
740  	buffer[len] = 0;
741  	return *this;
742  }
743  
744  /*********************************************/
745  /*  Parsing / Conversion                     */
746  /*********************************************/
747  
748  long String::toInt(void) const
749  {
750  	if (buffer) return atol(buffer);
751  	return 0;
752  }
753  
754  float String::toFloat(void) const
755  {
756  	if (buffer) return atof(buffer);
757  	return 0.0;
758  }
759