You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
443 lines
9.3 KiB
443 lines
9.3 KiB
/* |
|
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 <stdlib.h> |
|
#include "WProgram.h" |
|
#include "WString.h" |
|
|
|
|
|
String::String( const char *value ) |
|
{ |
|
if ( value == NULL ) |
|
value = ""; |
|
getBuffer( _length = strlen( value ) ); |
|
if ( _buffer != NULL ) |
|
strcpy( _buffer, value ); |
|
} |
|
|
|
String::String( const String &value ) |
|
{ |
|
getBuffer( _length = value._length ); |
|
if ( _buffer != NULL ) |
|
strcpy( _buffer, value._buffer ); |
|
} |
|
|
|
String::String( const char value ) |
|
{ |
|
_length = 1; |
|
getBuffer(1); |
|
if ( _buffer != NULL ) { |
|
_buffer[0] = value; |
|
_buffer[1] = 0; |
|
} |
|
} |
|
|
|
String::String( const unsigned char value ) |
|
{ |
|
_length = 1; |
|
getBuffer(1); |
|
if ( _buffer != NULL) { |
|
_buffer[0] = value; |
|
_buffer[1] = 0; |
|
} |
|
} |
|
|
|
String::String( const int value, const int base ) |
|
{ |
|
char buf[33]; |
|
itoa((signed long)value, buf, base); |
|
getBuffer( _length = strlen(buf) ); |
|
if ( _buffer != NULL ) |
|
strcpy( _buffer, buf ); |
|
} |
|
|
|
String::String( const unsigned int value, const int base ) |
|
{ |
|
char buf[33]; |
|
ultoa((unsigned long)value, buf, base); |
|
getBuffer( _length = strlen(buf) ); |
|
if ( _buffer != NULL ) |
|
strcpy( _buffer, buf ); |
|
} |
|
|
|
String::String( const long value, const int base ) |
|
{ |
|
char buf[33]; |
|
ltoa(value, buf, base); |
|
getBuffer( _length = strlen(buf) ); |
|
if ( _buffer != NULL ) |
|
strcpy( _buffer, buf ); |
|
} |
|
|
|
String::String( const unsigned long value, const int base ) |
|
{ |
|
char buf[33]; |
|
ultoa(value, buf, 10); |
|
getBuffer( _length = strlen(buf) ); |
|
if ( _buffer != NULL ) |
|
strcpy( _buffer, buf ); |
|
} |
|
|
|
char String::charAt( unsigned int loc ) const |
|
{ |
|
return operator[]( loc ); |
|
} |
|
|
|
void String::setCharAt( unsigned int loc, const char aChar ) |
|
{ |
|
if(_buffer == NULL) return; |
|
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 ) |
|
{ |
|
if ( this == &rhs ) |
|
return *this; |
|
|
|
if ( rhs._length > _length ) |
|
{ |
|
free(_buffer); |
|
getBuffer( rhs._length ); |
|
} |
|
|
|
if ( _buffer != NULL ) { |
|
_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; |
|
//} |
|
|
|
const String & String::operator+=( const String &other ) |
|
{ |
|
_length += other._length; |
|
if ( _length > _capacity ) |
|
{ |
|
char *temp = (char *)realloc(_buffer, _length + 1); |
|
if ( temp != NULL ) { |
|
_buffer = temp; |
|
_capacity = _length; |
|
} else { |
|
_length -= other._length; |
|
return *this; |
|
} |
|
} |
|
strcat( _buffer, other._buffer ); |
|
return *this; |
|
} |
|
|
|
|
|
int String::operator==( const String &rhs ) const |
|
{ |
|
return ( _length == rhs._length && strcmp( _buffer, rhs._buffer ) == 0 ); |
|
} |
|
|
|
int String::operator!=( const String &rhs ) const |
|
{ |
|
return ( _length != rhs.length() || strcmp( _buffer, rhs._buffer ) != 0 ); |
|
} |
|
|
|
int String::operator<( const String &rhs ) const |
|
{ |
|
return strcmp( _buffer, rhs._buffer ) < 0; |
|
} |
|
|
|
int String::operator>( const String &rhs ) const |
|
{ |
|
return strcmp( _buffer, rhs._buffer ) > 0; |
|
} |
|
|
|
int String::operator<=( const String &rhs ) const |
|
{ |
|
return strcmp( _buffer, rhs._buffer ) <= 0; |
|
} |
|
|
|
int String::operator>=( const String & rhs ) const |
|
{ |
|
return strcmp( _buffer, rhs._buffer ) >= 0; |
|
} |
|
|
|
char & String::operator[]( unsigned int index ) |
|
{ |
|
static char dummy_writable_char; |
|
if (index >= _length || !_buffer) { |
|
dummy_writable_char = 0; |
|
return dummy_writable_char; |
|
} |
|
return _buffer[ index ]; |
|
} |
|
|
|
char String::operator[]( unsigned int index ) const |
|
{ |
|
// need to check for valid index, to do later |
|
return _buffer[ index ]; |
|
} |
|
|
|
boolean String::endsWith( const String &s2 ) const |
|
{ |
|
if ( _length < s2._length ) |
|
return 0; |
|
|
|
return strcmp( &_buffer[ _length - s2._length], s2._buffer ) == 0; |
|
} |
|
|
|
boolean String::equals( const String &s2 ) const |
|
{ |
|
return ( _length == s2._length && strcmp( _buffer,s2._buffer ) == 0 ); |
|
} |
|
|
|
boolean String::equalsIgnoreCase( const String &s2 ) const |
|
{ |
|
if ( this == &s2 ) |
|
return true; //1; |
|
else if ( _length != s2._length ) |
|
return false; //0; |
|
|
|
return strcmp(toLowerCase()._buffer, s2.toLowerCase()._buffer) == 0; |
|
} |
|
|
|
String String::replace( char findChar, char replaceChar ) |
|
{ |
|
if ( _buffer == NULL ) return *this; |
|
String theReturn = _buffer; |
|
char* temp = theReturn._buffer; |
|
while( (temp = strchr( temp, findChar )) != 0 ) |
|
*temp = replaceChar; |
|
|
|
return theReturn; |
|
} |
|
|
|
String String::replace( const String& match, const String& rep ) |
|
{ |
|
if ( _buffer == NULL ) return *this; |
|
String temp = _buffer, newString; |
|
|
|
int loc; |
|
while ( (loc = temp.indexOf( match )) != -1 ) |
|
{ |
|
newString += temp.substring( 0, loc ); |
|
newString += rep; |
|
temp = temp.substring( loc + match._length ); |
|
} |
|
newString += temp; |
|
return newString; |
|
} |
|
|
|
int String::indexOf( char temp ) const |
|
{ |
|
return indexOf( temp, 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 &s2 ) const |
|
{ |
|
return indexOf( s2, 0 ); |
|
} |
|
|
|
int String::indexOf( const String &s2, unsigned int fromIndex ) const |
|
{ |
|
if ( fromIndex >= _length ) |
|
return -1; |
|
|
|
const char *theFind = strstr( &_buffer[ fromIndex ], s2._buffer ); |
|
|
|
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._buffer, 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 |
|
{ |
|
if ( _buffer == NULL ) return *this; |
|
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); |
|
} |
|
|
|
void String::getBytes(unsigned char *buf, unsigned int bufsize) |
|
{ |
|
if (!bufsize || !buf) return; |
|
unsigned int len = bufsize - 1; |
|
if (len > _length) len = _length; |
|
strncpy((char *)buf, _buffer, len); |
|
buf[len] = 0; |
|
} |
|
|
|
void String::toCharArray(char *buf, unsigned int bufsize) |
|
{ |
|
if (!bufsize || !buf) return; |
|
unsigned int len = bufsize - 1; |
|
if (len > _length) len = _length; |
|
strncpy(buf, _buffer, len); |
|
buf[len] = 0; |
|
} |
|
|
|
|
|
long String::toInt() { |
|
return atol(_buffer); |
|
}
|
|
|