* AM2321的取温度间隔得大于2s,否则,i2c会不工作了 * SimpleTimer有个bug,会导致两次快速的读温度,现在读温度函数里加了保护 * Blynk有个bug,会导致无法把数据传到服务器 * 现在可以正常工作了

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers WString.cpp Source File

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 #include <stdint.h>
00022 #include <stdlib.h>
00023 #include <stdio.h>
00024 #include <math.h>
00025 #include "WString.h"
00026 
00027 /*整形转字符型*/
00028 char *itoa(int value, char *string, int radix)
00029 {
00030     char tmp[33];
00031     char *tp = tmp;
00032     int i;
00033     unsigned v;
00034     int sign;
00035     char *sp;
00036 
00037     if (radix > 36 || radix <= 1) {
00038         //__set_errno(EDOM);
00039         return 0;
00040     }
00041 
00042     sign = (radix == 10 && value < 0);
00043     if (sign)
00044         v = -value;
00045     else
00046         v = (unsigned)value;
00047     while (v || tp == tmp) {
00048         i = v % radix;
00049         v = v / radix;
00050         if (i < 10)
00051             *tp++ = i+'0';
00052         else
00053             *tp++ = i + 'a' - 10;
00054     }
00055 
00056     if (string == 0)
00057         string = (char *)malloc((tp-tmp)+sign+1);
00058     sp = string;
00059 
00060     if (sign)
00061         *sp++ = '-';
00062     while (tp > tmp)
00063         *sp++ = *--tp;
00064     *sp = 0;
00065     return string;
00066 }
00067 
00068 /*长整形转字符型*/
00069 char *ltoa(long value, char *string, int radix)
00070 {
00071     char tmp[33];
00072     char *tp = tmp;
00073     long i;
00074     unsigned long v;
00075     int sign;
00076     char *sp;
00077 
00078     if (radix > 36 || radix <= 1) {
00079         //__set_errno(EDOM);
00080         return 0;
00081     }
00082 
00083     sign = (radix == 10 && value < 0);
00084     if (sign)
00085         v = -value;
00086     else
00087         v = (unsigned long)value;
00088     while (v || tp == tmp) {
00089         i = v % radix;
00090         v = v / radix;
00091         if (i < 10)
00092             *tp++ = i+'0';
00093         else
00094             *tp++ = i + 'a' - 10;
00095     }
00096 
00097     if (string == 0)
00098         string = (char *)malloc((tp-tmp)+sign+1);
00099     sp = string;
00100 
00101     if (sign)
00102         *sp++ = '-';
00103     while (tp > tmp)
00104         *sp++ = *--tp;
00105     *sp = 0;
00106     return string;
00107 }
00108 
00109 /*无符号长整形转字符型*/
00110 char *ultoa(unsigned long value, char *string, int radix)
00111 {
00112     char tmp[33];
00113     char *tp = tmp;
00114     long i;
00115     unsigned long v = value;
00116     char *sp;
00117 
00118     if (radix > 36 || radix <= 1) {
00119         //__set_errno(EDOM);
00120         return 0;
00121     }
00122 
00123 
00124     while (v || tp == tmp) {
00125         i = v % radix;
00126         v = v / radix;
00127         if (i < 10)
00128             *tp++ = i+'0';
00129         else
00130             *tp++ = i + 'a' - 10;
00131     }
00132     if (string == 0)
00133         string = (char *)malloc((tp-tmp)+1);
00134     sp = string;
00135 
00136     while (tp > tmp)
00137         *sp++ = *--tp;
00138     *sp = 0;
00139     return string;
00140 }
00141 
00142 /*字符串转整形*/
00143 //#include "iostream.h"
00144 int toi(const char * s)
00145 {
00146     int n = 0;
00147 
00148     while(!(*s >= '0' && *s <= '9'))
00149         s++;
00150 
00151     while(*s >= '0' && *s <= '9') {
00152         n *= 10;
00153         n += *s - '0';
00154         s++;
00155     }
00156     return n;
00157 }
00158 /*********************************************/
00159 /*  Constructors                             */
00160 /*********************************************/
00161 
00162 String::String(const char *cstr)
00163 {
00164     init();
00165     if (cstr) copy(cstr, strlen(cstr));
00166 }
00167 
00168 String::String(const String &value)
00169 {
00170     init();
00171     *this = value;
00172 }
00173 
00174 #if 0
00175 String::String(const __FlashStringHelper *pstr)
00176 {
00177     init();
00178     *this = pstr;
00179 }
00180 #endif
00181 
00182 #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
00183 String::String(String &&rval)
00184 {
00185     init();
00186     move(rval);
00187 }
00188 String::String(StringSumHelper &&rval)
00189 {
00190     init();
00191     move(rval);
00192 }
00193 #endif
00194 
00195 String::String(char c)
00196 {
00197     init();
00198     char buf[2];
00199     buf[0] = c;
00200     buf[1] = 0;
00201     *this = buf;
00202 }
00203 
00204 String::String(unsigned char value, unsigned char base)
00205 {
00206     init();
00207     char buf[1 + 8 * sizeof(unsigned char)];
00208     //utoa(value, buf, base);
00209     itoa(value, buf, base);
00210     *this = buf;
00211 }
00212 
00213 String::String(int value, unsigned char base)
00214 {
00215     init();
00216     char buf[2 + 8 * sizeof(int)];
00217     itoa(value, buf, base);
00218     //sprintf(buf, "%x", value); //将100转为16进制表示的字符串。
00219     *this = buf;
00220 }
00221 
00222 String::String(unsigned int value, unsigned char base)
00223 {
00224     init();
00225     char buf[1 + 8 * sizeof(unsigned int)];
00226     //utoa(value, buf, base);
00227     itoa(value, buf, base);
00228     *this = buf;
00229 }
00230 
00231 String::String(long value, unsigned char base)
00232 {
00233     init();
00234     char buf[2 + 8 * sizeof(long)];
00235     ltoa(value, buf, base);
00236     *this = buf;
00237 }
00238 
00239 String::String(unsigned long value, unsigned char base)
00240 {
00241     init();
00242     char buf[1 + 8 * sizeof(unsigned long)];
00243     //ultoa(value, buf, base);
00244     ultoa(value, buf, base);
00245     *this = buf;
00246 }
00247 
00248 String::String(float value, unsigned char decimalPlaces)
00249 {
00250     init();
00251     char buf[33];
00252     #if 0 // TODO:
00253     *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
00254     #endif
00255 }
00256 
00257 String::String(double value, unsigned char decimalPlaces)
00258 {
00259     init();
00260     char buf[33];
00261     #if 0 // TODO:
00262     *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf);
00263     #endif
00264 }
00265 
00266 String::~String()
00267 {
00268     free(buffer);
00269 }
00270 
00271 /*********************************************/
00272 /*  Memory Management                        */
00273 /*********************************************/
00274 
00275 inline void String::init(void)
00276 {
00277     buffer = NULL;
00278     capacity = 0;
00279     len = 0;
00280 }
00281 
00282 void String::invalidate(void)
00283 {
00284     if (buffer) free(buffer);
00285     buffer = NULL;
00286     capacity = len = 0;
00287 }
00288 
00289 unsigned char String::reserve(unsigned int size)
00290 {
00291     if (buffer && capacity >= size) return 1;
00292     if (changeBuffer(size)) {
00293         if (len == 0) buffer[0] = 0;
00294         return 1;
00295     }
00296     return 0;
00297 }
00298 
00299 unsigned char String::changeBuffer(unsigned int maxStrLen)
00300 {
00301     char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
00302     if (newbuffer) {
00303         buffer = newbuffer;
00304         capacity = maxStrLen;
00305         return 1;
00306     }
00307     return 0;
00308 }
00309 
00310 /*********************************************/
00311 /*  Copy and Move                            */
00312 /*********************************************/
00313 
00314 String & String::copy(const char *cstr, unsigned int length)
00315 {
00316     if (!reserve(length)) {
00317         invalidate();
00318         return *this;
00319     }
00320     len = length;
00321     strcpy(buffer, cstr);
00322     return *this;
00323 }
00324 
00325 #if 0
00326 String & String::copy(const __FlashStringHelper *pstr, unsigned int length)
00327 {
00328     if (!reserve(length)) {
00329         invalidate();
00330         return *this;
00331     }
00332     len = length;
00333     strcpy_P(buffer, (PGM_P)pstr);
00334     return *this;
00335 }
00336 #endif
00337 
00338 #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
00339 void String::move(String &rhs)
00340 {
00341     if (buffer) {
00342         if (capacity >= rhs.len) {
00343             strcpy(buffer, rhs.buffer);
00344             len = rhs.len;
00345             rhs.len = 0;
00346             return;
00347         } else {
00348             free(buffer);
00349         }
00350     }
00351     buffer = rhs.buffer;
00352     capacity = rhs.capacity;
00353     len = rhs.len;
00354     rhs.buffer = NULL;
00355     rhs.capacity = 0;
00356     rhs.len = 0;
00357 }
00358 #endif
00359 
00360 String & String::operator = (const String &rhs)
00361 {
00362     if (this == &rhs) return *this;
00363 
00364     if (rhs.buffer) copy(rhs.buffer, rhs.len);
00365     else invalidate();
00366 
00367     return *this;
00368 }
00369 
00370 #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
00371 String & String::operator = (String &&rval)
00372 {
00373     if (this != &rval) move(rval);
00374     return *this;
00375 }
00376 
00377 String & String::operator = (StringSumHelper &&rval)
00378 {
00379     if (this != &rval) move(rval);
00380     return *this;
00381 }
00382 #endif
00383 
00384 String & String::operator = (const char *cstr)
00385 {
00386     if (cstr) copy(cstr, strlen(cstr));
00387     else invalidate();
00388 
00389     return *this;
00390 }
00391 
00392 #if 0
00393 String & String::operator = (const __FlashStringHelper *pstr)
00394 {
00395     if (pstr) copy(pstr, strlen_P((PGM_P)pstr));
00396     else invalidate();
00397 
00398     return *this;
00399 }
00400 #endif
00401 
00402 /*********************************************/
00403 /*  concat                                   */
00404 /*********************************************/
00405 
00406 unsigned char String::concat(const String &s)
00407 {
00408     return concat(s.buffer, s.len);
00409 }
00410 
00411 unsigned char String::concat(const char *cstr, unsigned int length)
00412 {
00413     unsigned int newlen = len + length;
00414     if (!cstr) return 0;
00415     if (length == 0) return 1;
00416     if (!reserve(newlen)) return 0;
00417     strcpy(buffer + len, cstr);
00418     len = newlen;
00419     return 1;
00420 }
00421 
00422 unsigned char String::concat(const char *cstr)
00423 {
00424     if (!cstr) return 0;
00425     return concat(cstr, strlen(cstr));
00426 }
00427 
00428 unsigned char String::concat(char c)
00429 {
00430     char buf[2];
00431     buf[0] = c;
00432     buf[1] = 0;
00433     return concat(buf, 1);
00434 }
00435 
00436 unsigned char String::concat(unsigned char num)
00437 {
00438     char buf[1 + 3 * sizeof(unsigned char)];
00439     itoa(num, buf, 10);
00440     return concat(buf, strlen(buf));
00441 }
00442 
00443 unsigned char String::concat(int num)
00444 {
00445     char buf[2 + 3 * sizeof(int)];
00446     itoa(num, buf, 10);
00447     return concat(buf, strlen(buf));
00448 }
00449 
00450 unsigned char String::concat(unsigned int num)
00451 {
00452     char buf[1 + 3 * sizeof(unsigned int)];
00453     //utoa(num, buf, 10);
00454     itoa(num, buf, 10);
00455     return concat(buf, strlen(buf));
00456 }
00457 
00458 unsigned char String::concat(long num)
00459 {
00460     char buf[2 + 3 * sizeof(long)];
00461     ltoa(num, buf, 10);
00462     return concat(buf, strlen(buf));
00463 }
00464 
00465 unsigned char String::concat(unsigned long num)
00466 {
00467     char buf[1 + 3 * sizeof(unsigned long)];
00468     ultoa(num, buf, 10);
00469     return concat(buf, strlen(buf));
00470 }
00471 
00472 unsigned char String::concat(float num)
00473 {
00474     char buf[20];
00475     //char* string = dtostrf(num, 4, 2, buf);
00476     sprintf(buf, "%6.2f", num); //将100转为16进制表示的字符串。
00477     //return concat(string, strlen(string));
00478     return concat(buf, strlen(buf));
00479 }
00480 
00481 unsigned char String::concat(double num)
00482 {
00483     char buf[20];
00484     //char* string = dtostrf(num, 4, 2, buf);
00485     sprintf(buf, "%6.2f", num); //将100转为16进制表示的字符串。
00486     //return concat(string, strlen(string));
00487     return concat(buf, strlen(buf));
00488 }
00489 #if 0
00490 unsigned char String::concat(const __FlashStringHelper * str)
00491 {
00492     if (!str) return 0;
00493     int length = strlen_P((const char *) str);
00494     if (length == 0) return 1;
00495     unsigned int newlen = len + length;
00496     if (!reserve(newlen)) return 0;
00497     strcpy_P(buffer + len, (const char *) str);
00498     len = newlen;
00499     return 1;
00500 }
00501 #endif
00502 /*********************************************/
00503 /*  Concatenate                              */
00504 /*********************************************/
00505 
00506 StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
00507 {
00508     StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
00509     if (!a.concat(rhs.buffer, rhs.len)) a.invalidate();
00510     return a;
00511 }
00512 
00513 StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
00514 {
00515     StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
00516     if (!cstr || !a.concat(cstr, strlen(cstr))) a.invalidate();
00517     return a;
00518 }
00519 
00520 StringSumHelper & operator + (const StringSumHelper &lhs, char c)
00521 {
00522     StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
00523     if (!a.concat(c)) a.invalidate();
00524     return a;
00525 }
00526 
00527 StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char num)
00528 {
00529     StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
00530     if (!a.concat(num)) a.invalidate();
00531     return a;
00532 }
00533 
00534 StringSumHelper & operator + (const StringSumHelper &lhs, int num)
00535 {
00536     StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
00537     if (!a.concat(num)) a.invalidate();
00538     return a;
00539 }
00540 
00541 StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
00542 {
00543     StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
00544     if (!a.concat(num)) a.invalidate();
00545     return a;
00546 }
00547 
00548 StringSumHelper & operator + (const StringSumHelper &lhs, long num)
00549 {
00550     StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
00551     if (!a.concat(num)) a.invalidate();
00552     return a;
00553 }
00554 
00555 StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
00556 {
00557     StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
00558     if (!a.concat(num)) a.invalidate();
00559     return a;
00560 }
00561 
00562 StringSumHelper & operator + (const StringSumHelper &lhs, float num)
00563 {
00564     StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
00565     if (!a.concat(num)) a.invalidate();
00566     return a;
00567 }
00568 
00569 StringSumHelper & operator + (const StringSumHelper &lhs, double num)
00570 {
00571     StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
00572     if (!a.concat(num)) a.invalidate();
00573     return a;
00574 }
00575 
00576 #if 0
00577 StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *rhs)
00578 {
00579     StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
00580     if (!a.concat(rhs)) a.invalidate();
00581     return a;
00582 }
00583 #endif
00584 /*********************************************/
00585 /*  Comparison                               */
00586 /*********************************************/
00587 
00588 int String::compareTo(const String &s) const
00589 {
00590     if (!buffer || !s.buffer) {
00591         if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
00592         if (buffer && len > 0) return *(unsigned char *)buffer;
00593         return 0;
00594     }
00595     return strcmp(buffer, s.buffer);
00596 }
00597 
00598 unsigned char String::equals(const String &s2) const
00599 {
00600     return (len == s2.len && compareTo(s2) == 0);
00601 }
00602 
00603 unsigned char String::equals(const char *cstr) const
00604 {
00605     if (len == 0) return (cstr == NULL || *cstr == 0);
00606     if (cstr == NULL) return buffer[0] == 0;
00607     return strcmp(buffer, cstr) == 0;
00608 }
00609 
00610 unsigned char String::operator<(const String &rhs) const
00611 {
00612     return compareTo(rhs) < 0;
00613 }
00614 
00615 unsigned char String::operator>(const String &rhs) const
00616 {
00617     return compareTo(rhs) > 0;
00618 }
00619 
00620 unsigned char String::operator<=(const String &rhs) const
00621 {
00622     return compareTo(rhs) <= 0;
00623 }
00624 
00625 unsigned char String::operator>=(const String &rhs) const
00626 {
00627     return compareTo(rhs) >= 0;
00628 }
00629 
00630 unsigned char String::equalsIgnoreCase( const String &s2 ) const
00631 {
00632     if (this == &s2) return 1;
00633     if (len != s2.len) return 0;
00634     if (len == 0) return 1;
00635     const char *p1 = buffer;
00636     const char *p2 = s2.buffer;
00637     while (*p1) {
00638         if (tolower(*p1++) != tolower(*p2++)) return 0;
00639     }
00640     return 1;
00641 }
00642 
00643 unsigned char String::startsWith( const String &s2 ) const
00644 {
00645     if (len < s2.len) return 0;
00646     return startsWith(s2, 0);
00647 }
00648 
00649 unsigned char String::startsWith( const String &s2, unsigned int offset ) const
00650 {
00651     if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
00652     return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
00653 }
00654 
00655 unsigned char String::endsWith( const String &s2 ) const
00656 {
00657     if ( len < s2.len || !buffer || !s2.buffer) return 0;
00658     return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
00659 }
00660 
00661 /*********************************************/
00662 /*  Character Access                         */
00663 /*********************************************/
00664 
00665 char String::charAt(unsigned int loc) const
00666 {
00667     return operator[](loc);
00668 }
00669 
00670 void String::setCharAt(unsigned int loc, char c)
00671 {
00672     if (loc < len) buffer[loc] = c;
00673 }
00674 
00675 char & String::operator[](unsigned int index)
00676 {
00677     static char dummy_writable_char;
00678     if (index >= len || !buffer) {
00679         dummy_writable_char = 0;
00680         return dummy_writable_char;
00681     }
00682     return buffer[index];
00683 }
00684 
00685 char String::operator[]( unsigned int index ) const
00686 {
00687     if (index >= len || !buffer) return 0;
00688     return buffer[index];
00689 }
00690 
00691 void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
00692 {
00693     if (!bufsize || !buf) return;
00694     if (index >= len) {
00695         buf[0] = 0;
00696         return;
00697     }
00698     unsigned int n = bufsize - 1;
00699     if (n > len - index) n = len - index;
00700     strncpy((char *)buf, buffer + index, n);
00701     buf[n] = 0;
00702 }
00703 
00704 /*********************************************/
00705 /*  Search                                   */
00706 /*********************************************/
00707 
00708 int String::indexOf(char c) const
00709 {
00710     return indexOf(c, 0);
00711 }
00712 
00713 int String::indexOf( char ch, unsigned int fromIndex ) const
00714 {
00715     if (fromIndex >= len) return -1;
00716     const char* temp = strchr(buffer + fromIndex, ch);
00717     if (temp == NULL) return -1;
00718     return temp - buffer;
00719 }
00720 
00721 int String::indexOf(const String &s2) const
00722 {
00723     return indexOf(s2, 0);
00724 }
00725 
00726 int String::indexOf(const String &s2, unsigned int fromIndex) const
00727 {
00728     if (fromIndex >= len) return -1;
00729     const char *found = strstr(buffer + fromIndex, s2.buffer);
00730     if (found == NULL) return -1;
00731     return found - buffer;
00732 }
00733 
00734 int String::lastIndexOf( char theChar ) const
00735 {
00736     return lastIndexOf(theChar, len - 1);
00737 }
00738 
00739 int String::lastIndexOf(char ch, unsigned int fromIndex) const
00740 {
00741     if (fromIndex >= len) return -1;
00742     char tempchar = buffer[fromIndex + 1];
00743     buffer[fromIndex + 1] = '\0';
00744     char* temp = strrchr( buffer, ch );
00745     buffer[fromIndex + 1] = tempchar;
00746     if (temp == NULL) return -1;
00747     return temp - buffer;
00748 }
00749 
00750 int String::lastIndexOf(const String &s2) const
00751 {
00752     return lastIndexOf(s2, len - s2.len);
00753 }
00754 
00755 int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
00756 {
00757     if (s2.len == 0 || len == 0 || s2.len > len) return -1;
00758     if (fromIndex >= len) fromIndex = len - 1;
00759     int found = -1;
00760     for (char *p = buffer; p <= buffer + fromIndex; p++) {
00761         p = strstr(p, s2.buffer);
00762         if (!p) break;
00763         if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
00764     }
00765     return found;
00766 }
00767 
00768 String String::substring(unsigned int left, unsigned int right) const
00769 {
00770     if (left > right) {
00771         unsigned int temp = right;
00772         right = left;
00773         left = temp;
00774     }
00775     String out;
00776     if (left >= len) return out;
00777     if (right > len) right = len;
00778     char temp = buffer[right];  // save the replaced character
00779     buffer[right] = '\0';
00780     out = buffer + left;  // pointer arithmetic
00781     buffer[right] = temp;  //restore character
00782     return out;
00783 }
00784 
00785 /*********************************************/
00786 /*  Modification                             */
00787 /*********************************************/
00788 
00789 void String::replace(char find, char replace)
00790 {
00791     if (!buffer) return;
00792     for (char *p = buffer; *p; p++) {
00793         if (*p == find) *p = replace;
00794     }
00795 }
00796 
00797 void String::replace(const String& find, const String& replace)
00798 {
00799     if (len == 0 || find.len == 0) return;
00800     int diff = replace.len - find.len;
00801     char *readFrom = buffer;
00802     char *foundAt;
00803     if (diff == 0) {
00804         while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
00805             memcpy(foundAt, replace.buffer, replace.len);
00806             readFrom = foundAt + replace.len;
00807         }
00808     } else if (diff < 0) {
00809         char *writeTo = buffer;
00810         while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
00811             unsigned int n = foundAt - readFrom;
00812             memcpy(writeTo, readFrom, n);
00813             writeTo += n;
00814             memcpy(writeTo, replace.buffer, replace.len);
00815             writeTo += replace.len;
00816             readFrom = foundAt + find.len;
00817             len += diff;
00818         }
00819         strcpy(writeTo, readFrom);
00820     } else {
00821         unsigned int size = len; // compute size needed for result
00822         while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
00823             readFrom = foundAt + find.len;
00824             size += diff;
00825         }
00826         if (size == len) return;
00827         if (size > capacity && !changeBuffer(size)) return; // XXX: tell user!
00828         int index = len - 1;
00829         while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
00830             readFrom = buffer + index + find.len;
00831             memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
00832             len += diff;
00833             buffer[len] = 0;
00834             memcpy(buffer + index, replace.buffer, replace.len);
00835             index--;
00836         }
00837     }
00838 }
00839 
00840 void String::remove(unsigned int index)
00841 {
00842     // Pass the biggest integer as the count. The remove method
00843     // below will take care of truncating it at the end of the
00844     // string.
00845     remove(index, (unsigned int)-1);
00846 }
00847 
00848 void String::remove(unsigned int index, unsigned int count)
00849 {
00850     if (index >= len) {
00851         return;
00852     }
00853     if (count <= 0) {
00854         return;
00855     }
00856     if (count > len - index) {
00857         count = len - index;
00858     }
00859     char *writeTo = buffer + index;
00860     len = len - count;
00861     strncpy(writeTo, buffer + index + count,len - index);
00862     buffer[len] = 0;
00863 }
00864 
00865 void String::toLowerCase(void)
00866 {
00867     if (!buffer) return;
00868     for (char *p = buffer; *p; p++) {
00869         *p = tolower(*p);
00870     }
00871 }
00872 
00873 void String::toUpperCase(void)
00874 {
00875     if (!buffer) return;
00876     for (char *p = buffer; *p; p++) {
00877         *p = toupper(*p);
00878     }
00879 }
00880 
00881 void String::trim(void)
00882 {
00883     if (!buffer || len == 0) return;
00884     char *begin = buffer;
00885     while (isspace(*begin)) begin++;
00886     char *end = buffer + len - 1;
00887     while (isspace(*end) && end >= begin) end--;
00888     len = end + 1 - begin;
00889     if (begin > buffer) memcpy(buffer, begin, len);
00890     buffer[len] = 0;
00891 }
00892 
00893 /*********************************************/
00894 /*  Parsing / Conversion                     */
00895 /*********************************************/
00896 
00897 long String::toInt(void) const
00898 {
00899     if (buffer) return atol(buffer);
00900     return 0;
00901 }
00902 
00903 float String::toFloat(void) const
00904 {
00905     if (buffer) return float(atof(buffer));
00906     return 0;
00907 }
00908