From 445d1688c9274e7fd35ac95fe5c3a694703eaa87 Mon Sep 17 00:00:00 2001 From: Tom Igoe Date: Tue, 27 Jul 2010 10:06:43 +0000 Subject: Checked in Xiaoyang's changes to String library --- cores/arduino/WString.cpp | 666 +++++++++++++++++++++++++++------------------- 1 file changed, 397 insertions(+), 269 deletions(-) (limited to 'cores') diff --git a/cores/arduino/WString.cpp b/cores/arduino/WString.cpp index 5af89e3..b07edc3 100644 --- a/cores/arduino/WString.cpp +++ b/cores/arduino/WString.cpp @@ -1,396 +1,524 @@ /* - WString.cpp - String library for Wiring & Arduino - Copyright (c) 2009-10 Hernando Barragan. All rights reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + WString.cpp - String library for Wiring & Arduino + Copyright (c) 2009-10 Hernando Barragan. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ #include #include "WProgram.h" #include "WString.h" - String::String( const char *value ) { - if ( value == NULL ) - value = ""; - getBuffer( _length = strlen( value ) ); - strcpy( _buffer, value ); + if ( value == NULL ) + value = ""; + getBuffer( _length = strlen( value ) ); + if(_buffer != NULL) //added + strcpy( _buffer, value ); } String::String( const String &value ) { - getBuffer( _length = value._length ); - strcpy( _buffer, value._buffer ); + getBuffer( _length = value._length ); + if(_buffer != NULL) //added + strcpy( _buffer, value._buffer ); } String::String( const char value ) { - _length = 1; - getBuffer(1); - _buffer[0] = value; - _buffer[1] = 0; + _length = 1; + getBuffer(1); + if(_buffer != NULL){ //added + _buffer[0] = value; + _buffer[1] = '\0'; //_buffer[1] = 0; + } } String::String( const unsigned char value ) { - _length = 1; - getBuffer(1); - _buffer[0] = value; - _buffer[1] = 0; + _length = 1; + getBuffer(1); + if(_buffer != NULL){ //added + _buffer[0] = value; + _buffer[1] = '\0'; //_buffer[1] = 0; + } } String::String( const int value, const int base ) { - char buf[33]; - itoa((signed long)value, buf, base); - getBuffer( _length = strlen(buf) ); - strcpy( _buffer, buf ); + //char buf[33]; + char* buf = (char *) malloc(33); + if(buf != NULL){ //added + itoa(value,buf,base); + getBuffer( _length = strlen(buf) ); + strcpy( _buffer, buf ); + free(buf); //added + } } String::String( const unsigned int value, const int base ) { - char buf[33]; - ultoa((unsigned long)value, buf, base); - getBuffer( _length = strlen(buf) ); - strcpy( _buffer, buf ); + //char buf[33]; + char* buf = (char *) malloc(33); + if(buf != NULL){ //added + ultoa((unsigned long)value, buf, base); + getBuffer( _length = strlen(buf) ); + strcpy( _buffer, buf ); + free(buf); //added + } } String::String( const long value, const int base ) { - char buf[33]; - ltoa(value, buf, base); - getBuffer( _length = strlen(buf) ); - strcpy( _buffer, buf ); + //char buf[33]; + char* buf = (char *) malloc(33); + if(buf != NULL){ //added + ltoa(value, buf, base); + getBuffer( _length = strlen(buf) ); + strcpy( _buffer, buf ); + free(buf); //added + } } String::String( const unsigned long value, const int base ) { - char buf[33]; - ultoa(value, buf, 10); - getBuffer( _length = strlen(buf) ); - strcpy( _buffer, buf ); -} - -char String::charAt( unsigned int loc ) const -{ - return operator[]( loc ); -} - -void String::setCharAt( unsigned int loc, const char aChar ) -{ - if(_length > loc) { - _buffer[loc] = aChar; - } -} - -int String::compareTo( const String &s2 ) const -{ - return strcmp( _buffer, s2._buffer ); -} - -const String & String::concat( const String &s2 ) -{ - return (*this) += s2; + //char buf[33]; + char* buf = (char *) malloc(33); + if(buf != NULL){ //added + ultoa(value, buf, 10); + getBuffer( _length = strlen(buf) ); + strcpy( _buffer, buf ); + free(buf); //added + } } const String & String::operator=( const String &rhs ) { - if ( this == &rhs ) - return *this; - - if ( rhs._length > _length ) - { - free(_buffer); - getBuffer( rhs._length ); - } - _length = rhs._length; - strcpy( _buffer, rhs._buffer ); - return *this; -} - -const String & String::operator+=( const char aChar ) -{ - if ( _length == _capacity ) - doubleBuffer(); - - _buffer[ _length++ ] = aChar; - _buffer[ _length ] = '\0'; - return *this; + if ( this == &rhs ) + return *this; + + if ( rhs._length > _length ) + { + free(_buffer); + getBuffer( rhs._length ); + } + _length = rhs._length; + strcpy( _buffer, rhs._buffer ); + return *this; +} + +const String & String::operator+=( const char ch ) +{ + if ( _length == _capacity ) + { //doubleBuffer(); //only place to use + char *temp = _buffer; + _length++; + getBuffer(_length); + if(_buffer == NULL) + return "/*NOT ENOUGH MEMORY*/"; + strcpy(_buffer,temp); + } + _buffer[ _length-1 ] = ch; + _buffer[ _length ] = '\0'; + return *this; +} +const String & String::operator+=( const String &rhs ) +{ + _length += rhs._length; + if ( _length > _capacity ) + { + char *temp = _buffer; + getBuffer( _length ); + strcpy( _buffer, temp ); + _buffer[_length] = '\0'; + free(temp); + } + strcat( _buffer, rhs._buffer ); + return *this; } -const String & String::operator+=( const String &other ) -{ - _length += other._length; - if ( _length > _capacity ) - { - char *temp = _buffer; - getBuffer( _length ); - strcpy( _buffer, temp ); - free(temp); - } - strcat( _buffer, other._buffer ); - return *this; -} - - int String::operator==( const String &rhs ) const { - return ( _length == rhs._length && strcmp( _buffer, rhs._buffer ) == 0 ); + return ( _length == rhs._length && strcmp( _buffer, rhs._buffer ) == 0 ); } int String::operator!=( const String &rhs ) const { - return ( _length != rhs.length() || strcmp( _buffer, rhs.toCharArray() ) != 0 ); + return ( _length != rhs._length || strcmp( _buffer, rhs._buffer ) != 0 ); + //return ( _length != rhs.length() || strcmp( _buffer, rhs.toCharArray() ) != 0 ); } int String::operator<( const String &rhs ) const { - return strcmp( _buffer, rhs._buffer ) < 0; + return strcmp( _buffer, rhs._buffer ) < 0; } int String::operator>( const String &rhs ) const { - return strcmp( _buffer, rhs._buffer ) > 0; + return strcmp( _buffer, rhs._buffer ) > 0; } int String::operator<=( const String &rhs ) const { - return strcmp( _buffer, rhs._buffer ) <= 0; + return strcmp( _buffer, rhs._buffer ) <= 0; } int String::operator>=( const String & rhs ) const { - return strcmp( _buffer, rhs._buffer ) >= 0; + return strcmp( _buffer, rhs._buffer ) >= 0; } char & String::operator[]( unsigned int index ) { - // need to check for valid index, to do later - return _buffer[ index ]; + if(index < 0 || index >= _length) exit(1); //added + return _buffer[ index ]; } char String::operator[]( unsigned int index ) const { - // need to check for valid index, to do later - return _buffer[ index ]; + if(index < 0 || index >= _length) exit(1); //added + return _buffer[ index ]; } -boolean String::endsWith( const String &s2 ) const +char String::charAt( unsigned int index ) const { - if ( _length < s2._length ) - return 0; - - return strcmp( &_buffer[ _length - s2._length], s2.toCharArray() ) == 0; + return operator[]( index ); } -boolean String::equals( const String &s2 ) const +void String::setCharAt( unsigned int index, const char ch ) { - return ( _length == s2._length && strcmp( _buffer,s2._buffer ) == 0 ); + if(_length > index) { + _buffer[index] = ch; + } + else{ + exit(1); //added + } } -boolean String::equalsIgnoreCase( const String &s2 ) const +boolean String::startsWith( const String &prefix ) const { - if ( this == &s2 ) - return true; //1; - else if ( _length != s2._length ) - return false; //0; - - return strcmp(toLowerCase().toCharArray(), s2.toLowerCase().toCharArray()) == 0; + if ( _length < prefix._length ) + return false; + + return startsWith( prefix, 0 ); } -String String::replace( char findChar, char replaceChar ) +boolean String::startsWith( const String &prefix, unsigned int offset ) const { - String theReturn = _buffer; - char* temp = theReturn._buffer; - while( (temp = strchr( temp, findChar )) != 0 ) - *temp = replaceChar; - - return theReturn; + if ( offset > _length - prefix._length ) + return false; + + return (strncmp( &_buffer[offset], prefix._buffer, prefix._length ) == 0); } -String String::replace( const String& match, const String& replace ) +boolean String::endsWith( const String &suffix ) const { - String temp = _buffer, newString; - - int loc; - while ( (loc = temp.indexOf( match )) != -1 ) - { - newString += temp.substring( 0, loc ); - newString += replace; - temp = temp.substring( loc + match._length ); - } - newString += temp; - return newString; + if ( _length < suffix._length ) + return false; + + return (strcmp( &_buffer[ _length - suffix._length], suffix._buffer ) == 0); } -int String::indexOf( char temp ) const +boolean String::contains( const String &str ) const { - return indexOf( temp, 0 ); + return (strstr(_buffer, str._buffer) != NULL ); } -int String::indexOf( char ch, unsigned int fromIndex ) const +boolean String::equals( const String &str ) const { - if ( fromIndex >= _length ) - return -1; - - const char* temp = strchr( &_buffer[fromIndex], ch ); - if ( temp == NULL ) - return -1; - - return temp - _buffer; + return ( _length == str._length && strcmp( _buffer,str._buffer ) == 0 ); } -int String::indexOf( const String &s2 ) const +boolean String::equalsIgnoreCase( const String &str ) const { - return indexOf( s2, 0 ); + if ( this == &str ) + return true; + else if ( _length != str._length ) + return false; + //return strcmp(toLowerCase().toCharArray(), s2.toLowerCase().toCharArray()) == 0; + for(unsigned int i = 0; i < _length; i++ ){ + if(tolower( _buffer[i]) != tolower(str._buffer[i])) + return false; + } + return true; } -int String::indexOf( const String &s2, unsigned int fromIndex ) const -{ - if ( fromIndex >= _length ) - return -1; - - const char *theFind = strstr( &_buffer[ fromIndex ], s2.toCharArray() ); - - if ( theFind == NULL ) - return -1; - - return theFind - _buffer; // pointer subtraction -} - -int String::lastIndexOf( char theChar ) const +String String::trim() const { - return lastIndexOf( theChar, _length - 1 ); + /* + String temp = _buffer; + unsigned int i,j; + + for ( i = 0; i < _length; i++ ) + { + if ( !isspace(_buffer[i]) ) + break; + } + + for ( j = temp._length - 1; j > i; j-- ) + { + if ( !isspace(_buffer[j]) ) + break; + } + + return temp.substring( i, j + 1); + */ + String temp = _buffer; + unsigned int index = 0; + unsigned int tempIndex = 0; + while( index < _length ) + { + if(_buffer[index] == '\t' || + _buffer[index] == '\r' || + _buffer[index] == '\n' || + _buffer[index] == ' ' || + _buffer[index] == 0x11) + { + memcpy(temp._buffer+tempIndex, _buffer+index+1, strlen(_buffer)-index-1); + temp._buffer[temp._length-1] = '\0'; + temp._length--; + } + else{ + tempIndex++; + } + index++; + } + return temp; } -int String::lastIndexOf( char ch, unsigned int fromIndex ) const +String String::toLowerCase() const { - if ( fromIndex >= _length ) - return -1; - - char tempchar = _buffer[fromIndex + 1]; - _buffer[fromIndex + 1] = '\0'; - char* temp = strrchr( _buffer, ch ); - _buffer[fromIndex + 1] = tempchar; - - if ( temp == NULL ) - return -1; - - return temp - _buffer; + String temp = _buffer; + + for ( unsigned int i = 0; i < _length; i++ ) + temp._buffer[ i ] = (char)tolower( temp._buffer[ i ] ); + return temp; } -int String::lastIndexOf( const String &s2 ) const +String String::toUpperCase() const { - return lastIndexOf( s2, _length - s2._length ); + String temp = _buffer; + + for ( unsigned int i = 0; i < _length; i++ ) + temp._buffer[ i ] = (char)toupper( temp._buffer[ i ] ); + return temp; } -int String::lastIndexOf( const String &s2, unsigned int fromIndex ) const +String String::replace( char oldChar, char newChar ) { - // check for empty strings - if ( s2._length == 0 || s2._length - 1 > fromIndex || fromIndex >= _length ) - return -1; - - // matching first character - char temp = s2[ 0 ]; - - for ( int i = fromIndex; i >= 0; i-- ) - { - if ( _buffer[ i ] == temp && (*this).substring( i, i + s2._length ).equals( s2 ) ) - return i; - } - return -1; + String newString = _buffer; + char* temp = newString._buffer; + while( temp = strchr( temp, oldChar ) ) + *temp = newChar; + + return newString; } -boolean String::startsWith( const String &s2 ) const -{ - if ( _length < s2._length ) - return 0; - - return startsWith( s2, 0 ); -} - -boolean String::startsWith( const String &s2, unsigned int offset ) const +String String::replace( const String& match, const String& replace ) { - if ( offset > _length - s2._length ) - return 0; - - return strncmp( &_buffer[offset], s2.toCharArray(), s2._length ) == 0; + /* + String newString; + String temp = _buffer; + int loc; + while ( (loc = temp.indexOf( match )) != -1 ) + { + newString += temp.substring( 0, loc ); + newString += replace; + temp = temp.substring( loc + match._length ); + } + newString += temp; + return newString; + */ + + const char* temp = strstr( _buffer, match._buffer); + if(temp == NULL || match._length == 0){ + String newString = _buffer; + return newString; + } + else{ + //get new buffer + int count = 0; + int lastIndex = 0; + while(temp != NULL){ + count ++; + lastIndex = temp - _buffer; + temp = strstr( &_buffer[ lastIndex + match._length ], match._buffer ); + } + String newString; + newString._length = newString._capacity = _length + (replace._length - match._length)*count; + char* _buf = (char*)malloc(newString._length + 1); + if(_buf == NULL) + exit(1); + newString._buffer = _buf; + //string copy + int fromIndex = 0; + int tempLength = 0; + lastIndex = 0; + temp = strstr( &_buffer[ lastIndex ], match._buffer); + while (temp != NULL){ + fromIndex = temp - _buffer; + memcpy(newString._buffer+tempLength, _buffer+lastIndex, fromIndex-lastIndex); + memcpy(newString._buffer+tempLength+fromIndex-lastIndex, replace._buffer, replace._length); + tempLength += (fromIndex-lastIndex + replace._length); + lastIndex = fromIndex + match._length; + temp = strstr( &_buffer[ lastIndex ], match._buffer); + } + memcpy(newString._buffer+tempLength, _buffer+lastIndex, _length-lastIndex); + tempLength += (_length - lastIndex); + newString._buffer[tempLength] = '\0'; + newString._length = newString._capacity = strlen(newString._buffer); + return newString; + } +} + +String String::substring( unsigned int beginIndex ) const +{ + return substring( beginIndex, _length ); +} + +String String::substring( unsigned int beginIndex, unsigned int endIndex ) const +{ + if ( beginIndex > endIndex ) + { + int temp = endIndex; + endIndex = beginIndex; + beginIndex = temp; + } + if ( endIndex > _length ) + { + endIndex = _length; + } + + char temp = _buffer[ endIndex ]; // save the replaced character + _buffer[ endIndex ] = '\0'; + String outPut = ( _buffer + beginIndex ); // pointer arithmetic + _buffer[ endIndex ] = temp; //restore character + return outPut; +} + +const String & String::append( const String &str ) +{ + return (*this) += str; +} + +const String & String::append( const char ch) +{ + return (*this) += ch; +} + +int String::compareTo( const String &str ) const +{ + return strcmp( _buffer, str._buffer ); +} + +int String::compareTo( const char* str ) const +{ + return strcmp( _buffer, str ); +} + +int String::indexOf( char ch ) const +{ + return indexOf( ch, 0 ); } -String String::substring( unsigned int left ) const +int String::indexOf( char ch, unsigned int fromIndex ) const { - return substring( left, _length ); + if ( fromIndex >= _length ) + return -1; + + const char* temp = strchr( &_buffer[fromIndex], ch ); + if ( temp == NULL ) + return -1; + + return temp - _buffer; } -String String::substring( unsigned int left, unsigned int right ) const +int String::indexOf( const String &str ) const { - if ( left > right ) - { - int temp = right; - right = left; - left = temp; - } - - if ( right > _length ) - { - right = _length; - } - - char temp = _buffer[ right ]; // save the replaced character - _buffer[ right ] = '\0'; - String outPut = ( _buffer + left ); // pointer arithmetic - _buffer[ right ] = temp; //restore character - return outPut; + return indexOf( str, 0 ); } -String String::toLowerCase() const +int String::indexOf( const String &str, unsigned int fromIndex ) const { - String temp = _buffer; - - for ( unsigned int i = 0; i < _length; i++ ) - temp._buffer[ i ] = (char)tolower( temp._buffer[ i ] ); - return temp; + if ( fromIndex >= _length ) + return -1; + + const char *temp = strstr( &_buffer[ fromIndex ], str._buffer ); + + if ( temp == NULL ) + return -1; + + return temp - _buffer; // pointer subtraction } -String String::toUpperCase() const +int String::lastIndexOf( char ch ) const { - String temp = _buffer; - - for ( unsigned int i = 0; i < _length; i++ ) - temp._buffer[ i ] = (char)toupper( temp._buffer[ i ] ); - return temp; + return lastIndexOf( ch, _length - 1 ); } -String String::trim() const +int String::lastIndexOf( char ch, unsigned int fromIndex ) const { - String temp = _buffer; - unsigned int i,j; - - for ( i = 0; i < _length; i++ ) - { - if ( !isspace(_buffer[i]) ) - break; - } - - for ( j = temp._length - 1; j > i; j-- ) - { - if ( !isspace(_buffer[j]) ) - break; - } - - return temp.substring( i, j + 1); + if ( fromIndex >= _length ) + return -1; + + char tempchar = _buffer[fromIndex + 1]; + _buffer[fromIndex + 1] = '\0'; + char* temp = strrchr( _buffer, ch ); + _buffer[fromIndex + 1] = tempchar; + + if ( temp == NULL ) + return -1; + + return temp - _buffer; +} + +int String::lastIndexOf( const String &str ) const +{ + return lastIndexOf( str, _length - str._length ); +} + +int String::lastIndexOf( const String &str, unsigned int fromIndex ) const +{ + // check for empty strings + if ( str._length == 0 || str._length - 1 > fromIndex || fromIndex >= _length ) + return -1; + /* + // matching first character + char temp = str[ 0 ]; + + for ( unsigned int i = fromIndex; i >= 0; i-- ) + { + if ( _buffer[ i ] == temp && (*this).substring( i, i + str._length ).equals( str ) ) + return i; + } + return -1; + */ + char *temp = strstr(&_buffer[_length-fromIndex], str._buffer); + if(temp == NULL) + return -1; + int index; + while( temp != NULL){ + index = temp - _buffer; + temp = strstr(&_buffer[index+1],str._buffer); + } + return index-_length+fromIndex; +} + +//version() returns the version of the library: +String String::version(void) +{ + return "1.0"; } - -- cgit v1.2.3-18-g5258