Arduino Core API Library besed on mbed platform.
Dependents: WeeESP8266 ESP8266_moj
WString.cpp
00001 /* 00002 WString.cpp - String library for Wiring & Arduino 00003 ...mostly rewritten by Paul Stoffregen... 00004 Copyright (c) 2009-10 Hernando Barragan. All rights reserved. 00005 Copyright 2011, Paul Stoffregen, paul@pjrc.com 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Lesser General Public 00009 License as published by the Free Software Foundation; either 00010 version 2.1 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public 00018 License along with this library; if not, write to the Free Software 00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 #include "WString.h" 00023 00024 00025 /*********************************************/ 00026 /* Constructors */ 00027 /*********************************************/ 00028 00029 String::String(const char *cstr) 00030 { 00031 init(); 00032 if (cstr) copy(cstr, strlen(cstr)); 00033 } 00034 00035 String::String(const String &value) 00036 { 00037 init(); 00038 *this = value; 00039 } 00040 00041 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00042 String::String(String &&rval) 00043 { 00044 init(); 00045 move(rval); 00046 } 00047 String::String(StringSumHelper &&rval) 00048 { 00049 init(); 00050 move(rval); 00051 } 00052 #endif 00053 00054 String::String(char c) 00055 { 00056 init(); 00057 char buf[2]; 00058 buf[0] = c; 00059 buf[1] = 0; 00060 *this = buf; 00061 } 00062 00063 String::String(unsigned char value, unsigned char base) 00064 { 00065 init(); 00066 char buf[9]; 00067 utoa(value, buf, base); 00068 *this = buf; 00069 } 00070 00071 String::String(int value, unsigned char base) 00072 { 00073 init(); 00074 char buf[18]; 00075 itoa(value, buf, base); 00076 *this = buf; 00077 } 00078 00079 String::String(unsigned int value, unsigned char base) 00080 { 00081 init(); 00082 char buf[17]; 00083 utoa(value, buf, base); 00084 *this = buf; 00085 } 00086 00087 String::String(long value, unsigned char base) 00088 { 00089 init(); 00090 char buf[34]; 00091 ltoa(value, buf, base); 00092 *this = buf; 00093 } 00094 00095 String::String(unsigned long value, unsigned char base) 00096 { 00097 init(); 00098 char buf[33]; 00099 ultoa(value, buf, base); 00100 *this = buf; 00101 } 00102 00103 String::~String() 00104 { 00105 free(buffer); 00106 } 00107 00108 /*********************************************/ 00109 /* Memory Management */ 00110 /*********************************************/ 00111 00112 inline void String::init(void) 00113 { 00114 buffer = NULL; 00115 capacity = 0; 00116 len = 0; 00117 flags = 0; 00118 } 00119 00120 void String::invalidate(void) 00121 { 00122 if (buffer) free(buffer); 00123 buffer = NULL; 00124 capacity = len = 0; 00125 } 00126 00127 unsigned char String::reserve(unsigned int size) 00128 { 00129 if (buffer && capacity >= size) return 1; 00130 if (changeBuffer(size)) { 00131 if (len == 0) buffer[0] = 0; 00132 return 1; 00133 } 00134 return 0; 00135 } 00136 00137 unsigned char String::changeBuffer(unsigned int maxStrLen) 00138 { 00139 char *newbuffer = (char *)realloc(buffer, maxStrLen + 1); 00140 if (newbuffer) { 00141 buffer = newbuffer; 00142 capacity = maxStrLen; 00143 return 1; 00144 } 00145 return 0; 00146 } 00147 00148 /*********************************************/ 00149 /* Copy and Move */ 00150 /*********************************************/ 00151 00152 String & String::copy(const char *cstr, unsigned int length) 00153 { 00154 if (!reserve(length)) { 00155 invalidate(); 00156 return *this; 00157 } 00158 len = length; 00159 strcpy(buffer, cstr); 00160 return *this; 00161 } 00162 00163 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00164 void String::move(String &rhs) 00165 { 00166 if (buffer) { 00167 if (capacity >= rhs.len) { 00168 strcpy(buffer, rhs.buffer); 00169 len = rhs.len; 00170 rhs.len = 0; 00171 return; 00172 } else { 00173 free(buffer); 00174 } 00175 } 00176 buffer = rhs.buffer; 00177 capacity = rhs.capacity; 00178 len = rhs.len; 00179 rhs.buffer = NULL; 00180 rhs.capacity = 0; 00181 rhs.len = 0; 00182 } 00183 #endif 00184 00185 String & String::operator = (const String &rhs) 00186 { 00187 if (this == &rhs) return *this; 00188 00189 if (rhs.buffer) copy(rhs.buffer, rhs.len); 00190 else invalidate(); 00191 00192 return *this; 00193 } 00194 00195 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00196 String & String::operator = (String &&rval) 00197 { 00198 if (this != &rval) move(rval); 00199 return *this; 00200 } 00201 00202 String & String::operator = (StringSumHelper &&rval) 00203 { 00204 if (this != &rval) move(rval); 00205 return *this; 00206 } 00207 #endif 00208 00209 String & String::operator = (const char *cstr) 00210 { 00211 if (cstr) copy(cstr, strlen(cstr)); 00212 else invalidate(); 00213 00214 return *this; 00215 } 00216 00217 /*********************************************/ 00218 /* concat */ 00219 /*********************************************/ 00220 00221 unsigned char String::concat(const String &s) 00222 { 00223 return concat(s.buffer, s.len); 00224 } 00225 00226 unsigned char String::concat(const char *cstr, unsigned int length) 00227 { 00228 unsigned int newlen = len + length; 00229 if (!cstr) return 0; 00230 if (length == 0) return 1; 00231 if (!reserve(newlen)) return 0; 00232 strcpy(buffer + len, cstr); 00233 len = newlen; 00234 return 1; 00235 } 00236 00237 unsigned char String::concat(const char *cstr) 00238 { 00239 if (!cstr) return 0; 00240 return concat(cstr, strlen(cstr)); 00241 } 00242 00243 unsigned char String::concat(char c) 00244 { 00245 char buf[2]; 00246 buf[0] = c; 00247 buf[1] = 0; 00248 return concat(buf, 1); 00249 } 00250 00251 unsigned char String::concat(unsigned char num) 00252 { 00253 char buf[4]; 00254 itoa(num, buf, 10); 00255 return concat(buf, strlen(buf)); 00256 } 00257 00258 unsigned char String::concat(int num) 00259 { 00260 char buf[7]; 00261 itoa(num, buf, 10); 00262 return concat(buf, strlen(buf)); 00263 } 00264 00265 unsigned char String::concat(unsigned int num) 00266 { 00267 char buf[6]; 00268 utoa(num, buf, 10); 00269 return concat(buf, strlen(buf)); 00270 } 00271 00272 unsigned char String::concat(long num) 00273 { 00274 char buf[12]; 00275 ltoa(num, buf, 10); 00276 return concat(buf, strlen(buf)); 00277 } 00278 00279 unsigned char String::concat(unsigned long num) 00280 { 00281 char buf[11]; 00282 ultoa(num, buf, 10); 00283 return concat(buf, strlen(buf)); 00284 } 00285 00286 /*********************************************/ 00287 /* Concatenate */ 00288 /*********************************************/ 00289 00290 StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs) 00291 { 00292 StringSumHelper &a = const_cast<StringSumHelper&>(lhs); 00293 if (!a.concat(rhs.buffer, rhs.len)) a.invalidate(); 00294 return a; 00295 } 00296 00297 StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr) 00298 { 00299 StringSumHelper &a = const_cast<StringSumHelper&>(lhs); 00300 if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate(); 00301 return a; 00302 } 00303 00304 StringSumHelper & operator + (const StringSumHelper &lhs, char c) 00305 { 00306 StringSumHelper &a = const_cast<StringSumHelper&>(lhs); 00307 if (!a.concat(c)) a.invalidate(); 00308 return a; 00309 } 00310 00311 StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num) 00312 { 00313 StringSumHelper &a = const_cast<StringSumHelper&>(lhs); 00314 if (!a.concat(num)) a.invalidate(); 00315 return a; 00316 } 00317 00318 StringSumHelper & operator + (const StringSumHelper &lhs, int num) 00319 { 00320 StringSumHelper &a = const_cast<StringSumHelper&>(lhs); 00321 if (!a.concat(num)) a.invalidate(); 00322 return a; 00323 } 00324 00325 StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num) 00326 { 00327 StringSumHelper &a = const_cast<StringSumHelper&>(lhs); 00328 if (!a.concat(num)) a.invalidate(); 00329 return a; 00330 } 00331 00332 StringSumHelper & operator + (const StringSumHelper &lhs, long num) 00333 { 00334 StringSumHelper &a = const_cast<StringSumHelper&>(lhs); 00335 if (!a.concat(num)) a.invalidate(); 00336 return a; 00337 } 00338 00339 StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num) 00340 { 00341 StringSumHelper &a = const_cast<StringSumHelper&>(lhs); 00342 if (!a.concat(num)) a.invalidate(); 00343 return a; 00344 } 00345 00346 /*********************************************/ 00347 /* Comparison */ 00348 /*********************************************/ 00349 00350 int String::compareTo(const String &s) const 00351 { 00352 if (!buffer || !s.buffer) { 00353 if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer; 00354 if (buffer && len > 0) return *(unsigned char *)buffer; 00355 return 0; 00356 } 00357 return strcmp(buffer, s.buffer); 00358 } 00359 00360 unsigned char String::equals(const String &s2) const 00361 { 00362 return (len == s2.len && compareTo(s2) == 0); 00363 } 00364 00365 unsigned char String::equals(const char *cstr) const 00366 { 00367 if (len == 0) return (cstr == NULL || *cstr == 0); 00368 if (cstr == NULL) return buffer[0] == 0; 00369 return strcmp(buffer, cstr) == 0; 00370 } 00371 00372 unsigned char String::operator<(const String &rhs) const 00373 { 00374 return compareTo(rhs) < 0; 00375 } 00376 00377 unsigned char String::operator>(const String &rhs) const 00378 { 00379 return compareTo(rhs) > 0; 00380 } 00381 00382 unsigned char String::operator<=(const String &rhs) const 00383 { 00384 return compareTo(rhs) <= 0; 00385 } 00386 00387 unsigned char String::operator>=(const String &rhs) const 00388 { 00389 return compareTo(rhs) >= 0; 00390 } 00391 00392 unsigned char String::equalsIgnoreCase( const String &s2 ) const 00393 { 00394 if (this == &s2) return 1; 00395 if (len != s2.len) return 0; 00396 if (len == 0) return 1; 00397 const char *p1 = buffer; 00398 const char *p2 = s2.buffer; 00399 while (*p1) { 00400 if (tolower(*p1++) != tolower(*p2++)) return 0; 00401 } 00402 return 1; 00403 } 00404 00405 unsigned char String::startsWith( const String &s2 ) const 00406 { 00407 if (len < s2.len) return 0; 00408 return startsWith(s2, 0); 00409 } 00410 00411 unsigned char String::startsWith( const String &s2, unsigned int offset ) const 00412 { 00413 if (offset > len - s2.len || !buffer || !s2.buffer) return 0; 00414 return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0; 00415 } 00416 00417 unsigned char String::endsWith( const String &s2 ) const 00418 { 00419 if ( len < s2.len || !buffer || !s2.buffer) return 0; 00420 return strcmp(&buffer[len - s2.len], s2.buffer) == 0; 00421 } 00422 00423 /*********************************************/ 00424 /* Character Access */ 00425 /*********************************************/ 00426 00427 char String::charAt(unsigned int loc) const 00428 { 00429 return operator[](loc); 00430 } 00431 00432 void String::setCharAt(unsigned int loc, char c) 00433 { 00434 if (loc < len) buffer[loc] = c; 00435 } 00436 00437 char & String::operator[](unsigned int index) 00438 { 00439 static char dummy_writable_char; 00440 if (index >= len || !buffer) { 00441 dummy_writable_char = 0; 00442 return dummy_writable_char; 00443 } 00444 return buffer[index]; 00445 } 00446 00447 char String::operator[]( unsigned int index ) const 00448 { 00449 if (index >= len || !buffer) return 0; 00450 return buffer[index]; 00451 } 00452 00453 void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const 00454 { 00455 if (!bufsize || !buf) return; 00456 if (index >= len) { 00457 buf[0] = 0; 00458 return; 00459 } 00460 unsigned int n = bufsize - 1; 00461 if (n > len - index) n = len - index; 00462 strncpy((char *)buf, buffer + index, n); 00463 buf[n] = 0; 00464 } 00465 00466 /*********************************************/ 00467 /* Search */ 00468 /*********************************************/ 00469 00470 int String::indexOf(char c) const 00471 { 00472 return indexOf(c, 0); 00473 } 00474 00475 int String::indexOf( char ch, unsigned int fromIndex ) const 00476 { 00477 if (fromIndex >= len) return -1; 00478 const char* temp = strchr(buffer + fromIndex, ch); 00479 if (temp == NULL) return -1; 00480 return temp - buffer; 00481 } 00482 00483 int String::indexOf(const String &s2) const 00484 { 00485 return indexOf(s2, 0); 00486 } 00487 00488 int String::indexOf(const String &s2, unsigned int fromIndex) const 00489 { 00490 if (fromIndex >= len) return -1; 00491 const char *found = strstr(buffer + fromIndex, s2.buffer); 00492 if (found == NULL) return -1; 00493 return found - buffer; 00494 } 00495 00496 int String::lastIndexOf( char theChar ) const 00497 { 00498 return lastIndexOf(theChar, len - 1); 00499 } 00500 00501 int String::lastIndexOf(char ch, unsigned int fromIndex) const 00502 { 00503 if (fromIndex >= len) return -1; 00504 char tempchar = buffer[fromIndex + 1]; 00505 buffer[fromIndex + 1] = '\0'; 00506 char* temp = strrchr( buffer, ch ); 00507 buffer[fromIndex + 1] = tempchar; 00508 if (temp == NULL) return -1; 00509 return temp - buffer; 00510 } 00511 00512 int String::lastIndexOf(const String &s2) const 00513 { 00514 return lastIndexOf(s2, len - s2.len); 00515 } 00516 00517 int String::lastIndexOf(const String &s2, unsigned int fromIndex) const 00518 { 00519 if (s2.len == 0 || len == 0 || s2.len > len) return -1; 00520 if (fromIndex >= len) fromIndex = len - 1; 00521 int found = -1; 00522 for (char *p = buffer; p <= buffer + fromIndex; p++) { 00523 p = strstr(p, s2.buffer); 00524 if (!p) break; 00525 if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer; 00526 } 00527 return found; 00528 } 00529 00530 String String::substring( unsigned int left ) const 00531 { 00532 return substring(left, len); 00533 } 00534 00535 String String::substring(unsigned int left, unsigned int right) const 00536 { 00537 if (left > right) { 00538 unsigned int temp = right; 00539 right = left; 00540 left = temp; 00541 } 00542 String out; 00543 if (left > len) return out; 00544 if (right > len) right = len; 00545 char temp = buffer[right]; // save the replaced character 00546 buffer[right] = '\0'; 00547 out = buffer + left; // pointer arithmetic 00548 buffer[right] = temp; //restore character 00549 return out; 00550 } 00551 00552 /*********************************************/ 00553 /* Modification */ 00554 /*********************************************/ 00555 00556 void String::replace(char find, char replace) 00557 { 00558 if (!buffer) return; 00559 for (char *p = buffer; *p; p++) { 00560 if (*p == find) *p = replace; 00561 } 00562 } 00563 00564 void String::replace(const String& find, const String& replace) 00565 { 00566 if (len == 0 || find.len == 0) return; 00567 int diff = replace.len - find.len; 00568 char *readFrom = buffer; 00569 char *foundAt; 00570 if (diff == 0) { 00571 while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { 00572 memcpy(foundAt, replace.buffer, replace.len); 00573 readFrom = foundAt + replace.len; 00574 } 00575 } else if (diff < 0) { 00576 char *writeTo = buffer; 00577 while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { 00578 unsigned int n = foundAt - readFrom; 00579 memcpy(writeTo, readFrom, n); 00580 writeTo += n; 00581 memcpy(writeTo, replace.buffer, replace.len); 00582 writeTo += replace.len; 00583 readFrom = foundAt + find.len; 00584 len += diff; 00585 } 00586 strcpy(writeTo, readFrom); 00587 } else { 00588 unsigned int size = len; // compute size needed for result 00589 while ((foundAt = strstr(readFrom, find.buffer)) != NULL) { 00590 readFrom = foundAt + find.len; 00591 size += diff; 00592 } 00593 if (size == len) return; 00594 if (size > capacity && !changeBuffer(size)) return; // XXX: tell user! 00595 int index = len - 1; 00596 while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) { 00597 readFrom = buffer + index + find.len; 00598 memmove(readFrom + diff, readFrom, len - (readFrom - buffer)); 00599 len += diff; 00600 buffer[len] = 0; 00601 memcpy(buffer + index, replace.buffer, replace.len); 00602 index--; 00603 } 00604 } 00605 } 00606 00607 void String::toLowerCase(void) 00608 { 00609 if (!buffer) return; 00610 for (char *p = buffer; *p; p++) { 00611 *p = tolower(*p); 00612 } 00613 } 00614 00615 void String::toUpperCase(void) 00616 { 00617 if (!buffer) return; 00618 for (char *p = buffer; *p; p++) { 00619 *p = toupper(*p); 00620 } 00621 } 00622 00623 void String::trim(void) 00624 { 00625 if (!buffer || len == 0) return; 00626 char *begin = buffer; 00627 while (isspace(*begin)) begin++; 00628 char *end = buffer + len - 1; 00629 while (isspace(*end) && end >= begin) end--; 00630 len = end + 1 - begin; 00631 if (begin > buffer) memcpy(buffer, begin, len); 00632 buffer[len] = 0; 00633 } 00634 00635 /*********************************************/ 00636 /* Parsing / Conversion */ 00637 /*********************************************/ 00638 00639 long String::toInt(void) const 00640 { 00641 if (buffer) return atol(buffer); 00642 return 0; 00643 } 00644
Generated on Mon Jul 25 2022 12:21:32 by 1.7.2