Checked in Xiaoyang's changes to String library

This commit is contained in:
Tom Igoe 2010-07-27 10:06:43 +00:00
parent cd94d8dc6e
commit 445d1688c9
1 changed files with 417 additions and 289 deletions

View File

@ -1,396 +1,524 @@
/* /*
WString.cpp - String library for Wiring & Arduino WString.cpp - String library for Wiring & Arduino
Copyright (c) 2009-10 Hernando Barragan. All rights reserved. Copyright (c) 2009-10 Hernando Barragan. All rights reserved.
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. 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, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details. Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include <stdlib.h> #include <stdlib.h>
#include "WProgram.h" #include "WProgram.h"
#include "WString.h" #include "WString.h"
String::String( const char *value ) String::String( const char *value )
{ {
if ( value == NULL ) if ( value == NULL )
value = ""; value = "";
getBuffer( _length = strlen( value ) ); getBuffer( _length = strlen( value ) );
strcpy( _buffer, value ); if(_buffer != NULL) //added
strcpy( _buffer, value );
} }
String::String( const String &value ) String::String( const String &value )
{ {
getBuffer( _length = value._length ); getBuffer( _length = value._length );
strcpy( _buffer, value._buffer ); if(_buffer != NULL) //added
strcpy( _buffer, value._buffer );
} }
String::String( const char value ) String::String( const char value )
{ {
_length = 1; _length = 1;
getBuffer(1); getBuffer(1);
_buffer[0] = value; if(_buffer != NULL){ //added
_buffer[1] = 0; _buffer[0] = value;
_buffer[1] = '\0'; //_buffer[1] = 0;
}
} }
String::String( const unsigned char value ) String::String( const unsigned char value )
{ {
_length = 1; _length = 1;
getBuffer(1); getBuffer(1);
_buffer[0] = value; if(_buffer != NULL){ //added
_buffer[1] = 0; _buffer[0] = value;
_buffer[1] = '\0'; //_buffer[1] = 0;
}
} }
String::String( const int value, const int base ) String::String( const int value, const int base )
{ {
char buf[33]; //char buf[33];
itoa((signed long)value, buf, base); char* buf = (char *) malloc(33);
getBuffer( _length = strlen(buf) ); if(buf != NULL){ //added
strcpy( _buffer, buf ); itoa(value,buf,base);
getBuffer( _length = strlen(buf) );
strcpy( _buffer, buf );
free(buf); //added
}
} }
String::String( const unsigned int value, const int base ) String::String( const unsigned int value, const int base )
{ {
char buf[33]; //char buf[33];
ultoa((unsigned long)value, buf, base); char* buf = (char *) malloc(33);
getBuffer( _length = strlen(buf) ); if(buf != NULL){ //added
strcpy( _buffer, buf ); ultoa((unsigned long)value, buf, base);
getBuffer( _length = strlen(buf) );
strcpy( _buffer, buf );
free(buf); //added
}
} }
String::String( const long value, const int base ) String::String( const long value, const int base )
{ {
char buf[33]; //char buf[33];
ltoa(value, buf, base); char* buf = (char *) malloc(33);
getBuffer( _length = strlen(buf) ); if(buf != NULL){ //added
strcpy( _buffer, buf ); ltoa(value, buf, base);
getBuffer( _length = strlen(buf) );
strcpy( _buffer, buf );
free(buf); //added
}
} }
String::String( const unsigned long value, const int base ) String::String( const unsigned long value, const int base )
{ {
char buf[33]; //char buf[33];
ultoa(value, buf, 10); char* buf = (char *) malloc(33);
getBuffer( _length = strlen(buf) ); if(buf != NULL){ //added
strcpy( _buffer, buf ); ultoa(value, buf, 10);
} getBuffer( _length = strlen(buf) );
strcpy( _buffer, buf );
char String::charAt( unsigned int loc ) const free(buf); //added
{ }
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;
} }
const String & String::operator=( const String &rhs ) const String & String::operator=( const String &rhs )
{ {
if ( this == &rhs ) if ( this == &rhs )
return *this; return *this;
if ( rhs._length > _length ) if ( rhs._length > _length )
{ {
free(_buffer); free(_buffer);
getBuffer( rhs._length ); getBuffer( rhs._length );
} }
_length = rhs._length; _length = rhs._length;
strcpy( _buffer, rhs._buffer ); strcpy( _buffer, rhs._buffer );
return *this; return *this;
} }
const String & String::operator+=( const char aChar ) const String & String::operator+=( const char ch )
{ {
if ( _length == _capacity ) if ( _length == _capacity )
doubleBuffer(); { //doubleBuffer(); //only place to use
char *temp = _buffer;
_buffer[ _length++ ] = aChar; _length++;
_buffer[ _length ] = '\0'; getBuffer(_length);
return *this; 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 )
const String & String::operator+=( const String &other )
{ {
_length += other._length; _length += rhs._length;
if ( _length > _capacity ) if ( _length > _capacity )
{ {
char *temp = _buffer; char *temp = _buffer;
getBuffer( _length ); getBuffer( _length );
strcpy( _buffer, temp ); strcpy( _buffer, temp );
free(temp); _buffer[_length] = '\0';
} free(temp);
strcat( _buffer, other._buffer ); }
return *this; strcat( _buffer, rhs._buffer );
return *this;
} }
int String::operator==( const String &rhs ) const 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 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 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 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 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 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 ) char & String::operator[]( unsigned int index )
{ {
// need to check for valid index, to do later if(index < 0 || index >= _length) exit(1); //added
return _buffer[ index ]; return _buffer[ index ];
} }
char String::operator[]( unsigned int index ) const char String::operator[]( unsigned int index ) const
{ {
// need to check for valid index, to do later if(index < 0 || index >= _length) exit(1); //added
return _buffer[ index ]; return _buffer[ index ];
} }
boolean String::endsWith( const String &s2 ) const char String::charAt( unsigned int index ) const
{ {
if ( _length < s2._length ) return operator[]( index );
return 0;
return strcmp( &_buffer[ _length - s2._length], s2.toCharArray() ) == 0;
} }
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 ) if ( _length < prefix._length )
return true; //1; return false;
else if ( _length != s2._length )
return false; //0; return startsWith( prefix, 0 );
return strcmp(toLowerCase().toCharArray(), s2.toLowerCase().toCharArray()) == 0;
} }
String String::replace( char findChar, char replaceChar ) boolean String::startsWith( const String &prefix, unsigned int offset ) const
{ {
String theReturn = _buffer; if ( offset > _length - prefix._length )
char* temp = theReturn._buffer; return false;
while( (temp = strchr( temp, findChar )) != 0 )
*temp = replaceChar; return (strncmp( &_buffer[offset], prefix._buffer, prefix._length ) == 0);
return theReturn;
} }
String String::replace( const String& match, const String& replace ) boolean String::endsWith( const String &suffix ) const
{ {
String temp = _buffer, newString; if ( _length < suffix._length )
return false;
int loc;
while ( (loc = temp.indexOf( match )) != -1 ) return (strcmp( &_buffer[ _length - suffix._length], suffix._buffer ) == 0);
{
newString += temp.substring( 0, loc );
newString += replace;
temp = temp.substring( loc + match._length );
}
newString += temp;
return newString;
} }
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 ( _length == str._length && strcmp( _buffer,str._buffer ) == 0 );
return -1;
const char* temp = strchr( &_buffer[fromIndex], ch );
if ( temp == NULL )
return -1;
return temp - _buffer;
} }
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 )
int String::indexOf( const String &s2, unsigned int fromIndex ) const return false;
{ //return strcmp(toLowerCase().toCharArray(), s2.toLowerCase().toCharArray()) == 0;
if ( fromIndex >= _length ) for(unsigned int i = 0; i < _length; i++ ){
return -1; if(tolower( _buffer[i]) != tolower(str._buffer[i]))
return false;
const char *theFind = strstr( &_buffer[ fromIndex ], s2.toCharArray() ); }
return true;
if ( theFind == NULL )
return -1;
return theFind - _buffer; // pointer subtraction
}
int String::lastIndexOf( char theChar ) const
{
return lastIndexOf( theChar, _length - 1 );
}
int String::lastIndexOf( char ch, unsigned int fromIndex ) 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;
}
int String::lastIndexOf( const String &s2 ) const
{
return lastIndexOf( s2, _length - s2._length );
}
int String::lastIndexOf( const String &s2, unsigned int fromIndex ) const
{
// 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;
}
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
{
if ( offset > _length - s2._length )
return 0;
return strncmp( &_buffer[offset], s2.toCharArray(), s2._length ) == 0;
}
String String::substring( unsigned int left ) const
{
return substring( left, _length );
}
String String::substring( unsigned int left, unsigned int right ) 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;
}
String String::toLowerCase() const
{
String temp = _buffer;
for ( unsigned int i = 0; i < _length; i++ )
temp._buffer[ i ] = (char)tolower( temp._buffer[ i ] );
return temp;
}
String String::toUpperCase() const
{
String temp = _buffer;
for ( unsigned int i = 0; i < _length; i++ )
temp._buffer[ i ] = (char)toupper( temp._buffer[ i ] );
return temp;
} }
String String::trim() const String String::trim() const
{ {
String temp = _buffer; /*
unsigned int i,j; String temp = _buffer;
unsigned int i,j;
for ( i = 0; i < _length; i++ )
{ for ( i = 0; i < _length; i++ )
if ( !isspace(_buffer[i]) ) {
break; if ( !isspace(_buffer[i]) )
} break;
}
for ( j = temp._length - 1; j > i; j-- )
{ for ( j = temp._length - 1; j > i; j-- )
if ( !isspace(_buffer[j]) ) {
break; if ( !isspace(_buffer[j]) )
} break;
}
return temp.substring( i, j + 1);
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;
} }
String String::toLowerCase() const
{
String temp = _buffer;
for ( unsigned int i = 0; i < _length; i++ )
temp._buffer[ i ] = (char)tolower( temp._buffer[ i ] );
return temp;
}
String String::toUpperCase() const
{
String temp = _buffer;
for ( unsigned int i = 0; i < _length; i++ )
temp._buffer[ i ] = (char)toupper( temp._buffer[ i ] );
return temp;
}
String String::replace( char oldChar, char newChar )
{
String newString = _buffer;
char* temp = newString._buffer;
while( temp = strchr( temp, oldChar ) )
*temp = newChar;
return newString;
}
String String::replace( const String& match, const String& replace )
{
/*
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 );
}
int String::indexOf( char ch, unsigned int fromIndex ) const
{
if ( fromIndex >= _length )
return -1;
const char* temp = strchr( &_buffer[fromIndex], ch );
if ( temp == NULL )
return -1;
return temp - _buffer;
}
int String::indexOf( const String &str ) const
{
return indexOf( str, 0 );
}
int String::indexOf( const String &str, unsigned int fromIndex ) const
{
if ( fromIndex >= _length )
return -1;
const char *temp = strstr( &_buffer[ fromIndex ], str._buffer );
if ( temp == NULL )
return -1;
return temp - _buffer; // pointer subtraction
}
int String::lastIndexOf( char ch ) const
{
return lastIndexOf( ch, _length - 1 );
}
int String::lastIndexOf( char ch, unsigned int fromIndex ) 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;
}
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";
}