Subversion Repositories spk

Rev

Rev 14 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "String.h"

#include <sstream>
#include <stdarg.h>

namespace Utils {

String operator+(const char *str1, const String &str2)
{
        return String(str1) + str2;
}


String::String(void)                                            { this->assign(""); }
String::String(const char *str)                         { this->assign(str); }
String::String(const unsigned char *str)        { this->assign((const char *)str); }
String::String(const std::string &str)          { this->assign(str);}
String::String(const unsigned char c)           { this->assign(1, c); }
String::String(const char c)                            { this->assign(1, c); }
String::String(const String &str)                       { this->assign(str); }
String::String(long l)                                          { this->fromLong(l); }
String::String(unsigned long l)                         { this->fromLong((long)l); }
String::String(float f)                                         { this->fromFloat(f); }
String::String(double f)                                        { this->fromDouble(f); }

String::~String(void)
{
}

/////////////////////////////////////////////////////////////////
// Conversion functions

void String::fromLong(long l)
{
        std::stringstream strstream;
        strstream << l;
        *this = strstream.str();
}

void String::fromFloat(float f, int dp)
{
        std::stringstream strstream;
        strstream.precision(dp);
        strstream << std::fixed << f;
        *this = strstream.str();
}

void String::fromFloat(float f)
{
        std::stringstream strstream;
        strstream << f;
        *this = strstream.str();
}
void String::fromDouble(double f)
{
        std::stringstream strstream;
        strstream << f;
        *this = strstream.str();
}

const String &String::format(const char *sFormat, ...)
{
        char buffer[1024];
        va_list args;
        va_start (args, sFormat);
        vsprintf (buffer, sFormat, args);
        va_end (args);

        this->assign(buffer);
        return (*this);
}

String String::fromFormat(const char *sFormat, ...)
{
        char buffer[1024];
        va_list args;
        va_start (args, sFormat);
        vsprintf (buffer, sFormat, args);
        va_end (args);

        return String(buffer);
}

long String::toLong() const
{
        return atoi(this->c_str());
}
double String::toDouble() const
{
        return atof(this->c_str());
}
float String::toFloat() const
{
        return (float)atof(this->c_str());
}


const String &String::operator= ( const char *str )                             { this->assign(str); return (*this); }
const String &String::operator= ( const unsigned char *str )    { this->assign((const char *)str); return (*this); }
const String &String::operator= ( const String &str )                   { this->assign((std::string &)str); return (*this); }
const String &String::operator= ( const std::string &str )              { this->assign(str); return (*this); }
const String &String::operator= ( unsigned char c )                             { this->assign(1, c); return (*this); }
const String &String::operator= ( char c )                                              { this->assign(1, c); return (*this); }
const String &String::operator= ( long l )                                              { this->fromLong(l); return (*this); }
const String &String::operator= ( unsigned long l )                             { this->fromLong(l); return (*this); }
const String &String::operator= ( float f )                                             { this->fromFloat(f); return (*this); }
const String &String::operator= ( double f )                                    { this->fromDouble(f); return (*this); }

const unsigned char String::operator[] ( int num ) const                        { return this->at(num); }
unsigned char &String::operator[] ( int num )                                           { return (unsigned char &)this->at(num); }

const String &String::operator+= ( const char *str )                    { this->append(str); return (*this); }
const String &String::operator+= ( const unsigned char *str )   { this->append((const char *)str); return (*this); }
const String &String::operator+= ( const std::string &str )             { this->append(str); return (*this); }
const String &String::operator+= ( const String &str )          { this->append(str); return (*this); }
const String &String::operator+= ( const char c )                               { this->append(1, c); return (*this); }
const String &String::operator+= ( const unsigned char c )              { this->append(1, c); return (*this); }
const String &String::operator+= ( const unsigned long l )              
{ 
        std::stringstream strm;
        strm << (*this) << l;
        strm >> (*this);
        return (*this); 
}
const String &String::operator+= ( const long l )               
{ 
        std::stringstream strm;
        strm << (*this) << l;
        *this = strm.str();
        return (*this); 
}
const String &String::operator+= ( const float f )              
{ 
        std::stringstream strm;
        strm << (*this) << f;
        *this = strm.str();
        return (*this); 
}
const String &String::operator+= ( const double f )             
{ 
        std::stringstream strm;
        strm << (*this) << f;
        *this = strm.str();
        return (*this); 
}


String String::operator+ ( const char *str ) const                      { return String(*this) += str; }
String String::operator+ ( const unsigned char *str ) const     { return String(*this) += str; }
String String::operator+ ( const std::string &str ) const       { return String(*this) += str; }
String String::operator+ ( const String &str ) const            { return String(*this) += str; }
String String::operator+ ( const char c ) const                         { return String(*this) += c; }
String String::operator+ ( const unsigned char c ) const        { return String(*this) += c; }
String String::operator+ ( const long l ) const                         { return String(*this) += l; }
String String::operator+ ( const unsigned long l ) const        { return String(*this) += l; }
String String::operator+ ( const float f ) const                        { return String(*this) += f; }
String String::operator+ ( const double f ) const                       { return String(*this) += f; }

bool String::operator== ( const char *str ) const                               { return (this->compare(str)) ? false : true; }
bool String::operator== ( const unsigned char *str ) const      { return (this->compare((const char *)str)) ? false : true; }
bool String::operator== ( const std::string &str ) const                { return (this->compare(str)) ? false : true; }
bool String::operator== ( const String &str ) const                     { return (this->compare(str)) ? false : true; }

bool String::operator!= ( const char *str ) const                               { return (this->compare(str)) ? true : false; }
bool String::operator!= ( const unsigned char *str ) const      { return (this->compare((const char *)str)) ? true : false; }
bool String::operator!= ( const std::string &str ) const                { return (this->compare(str)) ? true : false; }
bool String::operator!= ( const String &str ) const                     { return (this->compare(str)) ? true : false; }

bool String::Compare(const String &str, bool bCaseSensative) const
{
        if ( bCaseSensative ) {
                return (this->compare(str) == 0) ? true : false;
        }

        if ( str.length() != this->length() ) return false;
        for ( unsigned int i = 0; i < str.length(); i++ ) {
                if ( tolower(this->at(i)) != tolower(str[i]) ) {
                        return false;
                }
        }
        return true;
}

bool String::Compare(const unsigned char *str, bool bCaseSensative) const
{
        return this->Compare((const char *)str, bCaseSensative);
}

bool String::Compare(const char *str, bool bCaseSensative) const
{
        if ( bCaseSensative ) {
                return (this->compare(str) == 0) ? true : false;
        }

        if ( strlen(str) != this->length() ) return false;
        for ( unsigned int i = 0; i < this->length(); i++ ) {
                if ( tolower(this->at(i)) != tolower(*(str + i)) ) {
                        return false;
                }
        }

        return true;
}

String String::token(const char *token, int tok) const
{
        return this->tokens(token, tok, tok);
}

String String::tokens(const char *token, int from, int to) const
{
        if ( this->empty() ) return "";

        int max = this->countToken(token);

        std::string newstr;

        int whichtok = 1;
        std::string::size_type lastPos = 0;
        std::string::size_type pos     = _token_nextPos(token, 0);

        if ( from < 0 )
                from = max + (from + 1);
        if ( to < 0 )
                to = max + (to + 1);

        while (std::string::npos != pos || std::string::npos != lastPos)
        {
                if ( to == 0 )
                {
                        if ( whichtok >= from )
                        {
                                if ( newstr != "" ) newstr = newstr + token;
                                newstr = newstr + this->substr(lastPos, pos - lastPos);
                        }
                }
                else
                {
                        if ( (whichtok >= from) && (whichtok <= to) )
                        {
                                if ( newstr != "" ) newstr = newstr + token;
                                newstr = newstr + this->substr(lastPos, pos - lastPos);
                        }
                        if ( whichtok > to )
                                break;
                }
                // Found a token, add it to the vector.
                whichtok++;

                if ( pos >= this->length() )
                        break;

                // skip past token
                size_t i = 0;
                size_t max = strlen(token);
                lastPos = pos;
                while ( (i < max) && (token[i] == this->at(lastPos)) )
                {
                        ++i;
                        ++lastPos;
                }

                // get the next token
                pos = _token_nextPos(token, lastPos);
        }
        return newstr;
}

int String::countToken(const char *token) const
{
        if ( this->empty() )
                return 0;

        // finds the number of tokens in a string
        int found = 1;

        std::string tmpstr = *this;

        // ignore the initial spaces
        std::string::size_type pos = this->find_first_not_of(token, 0);

        // remove end spaces
        size_t i = tmpstr.size() - 1;
        while ( tmpstr[i] == ' ' && i > 0 )
                i--;
        if ( i <= 0 ) return 0;
        tmpstr.erase ( i + 1, tmpstr.size() - i );

        // count tokens
        pos = tmpstr.find (token,pos + 1);
        while ( pos < std::string::npos )
        {
                while (tmpstr[pos] == ' ')
                        pos++;
                found++;
                pos = tmpstr.find (token,pos + 1);
        }

        // return number of tokens
        return found;
}

std::string::size_type String::_token_nextPos(const char *token, std::string::size_type curPos) const
{
        bool found = false;
        std::string::size_type startPos = 0;
        size_t max = strlen(token);
        while ( !found ) {
                found = true;
                startPos = this->find_first_of(token[0], curPos);
                if ( startPos == std::string::npos ) {
                        startPos = this->length();
                        break;
                }

                std::string::size_type pos = startPos;
                size_t i = 1;
                while ( i < max )
                {
                        ++pos;
                        if ( this->at(pos) != token[i] )
                        {
                                found = false;
                                break;
                        }
                        ++i;
                }
                curPos = pos;
        }
        return startPos;
}

String String::findReplace(const String &find, const String &replace ) const
{
        std::string newstr = *this;
        std::string::size_type pos = newstr.find(find, 0);
        while ( pos < std::string::npos ) {
                newstr.replace(pos, find.length(), replace);
                pos = newstr.find(find, pos + replace.length());
        }

        return newstr;
}

bool String::isin(const String &str, bool bCaseSensative) const
{
        unsigned int check = 0;
        for ( unsigned int i = 0; i < this->length(); i++ )
        {
                bool bCheck     = (bCaseSensative) ? (this->at(i) == str[check]) : (tolower(this->at(i)) == tolower(str[check]));
                if ( bCheck )
                        ++check;
                else
                        check = 0;

                if ( check >= str.length() )
                        return true;
        }
        return false;
}

bool String::isin(char c, bool bCaseSensative) const
{
        bool f = false;
        for ( unsigned int i = 0; i < this->length(); i++ )
        {
                bool bCheck = (bCaseSensative) ? (this->at(i) == c) : (tolower(this->at(i)) == tolower(c));
                if ( bCheck ) {
                        f = true;
                        break;
                }
        }
        return f;
}

String String::left(long num) const
{
        if ( num < 0 )
                num = (long)this->length() + num;
        if ( num > (long)this->length() )
                num = (long)this->length();

        return this->substr(0, num);
}

String String::right(int num) const
{
        if ( num > 0 ) num -= (int)this->length();
        if ( num < -(int)this->length() ) num = -(int)this->length();

        return this->substr(-num);
}

char *String::readToEndOfLine(char *data)
{
        return (char *)this->readToEndOfLine((unsigned char *)data);
}
unsigned char *String::readToEndOfLine(unsigned char *data)
{
        int pos = 0;

        // do until we get a line break
        while ( (data[pos] != 13) && (data[pos] != 0) && (data[pos] != '\n') ) {
                ++pos;
        }

        if ( !pos ) {
                this->clear();
        }
        else {
                if ( pos > 2000 ) {
                        char *d = new char[pos + 1];
                        memcpy(d, data, pos);
                        d[pos] = 0;
                        *this = d;
                        delete d;
                }
                else {
                        char d[2000];
                        memcpy(d, data, pos);
                        d[pos] = 0;
                        *this = d;
                }
        }

        if ( data[pos] == 0 ) return NULL;
        return data + (pos + 1);
}

String String::replaceToken(const char *token, int from, const String &replace) const
{
        std::string newstr;

        int whichtok = 1;
        std::string::size_type lastPos = 0;
        std::string::size_type pos     = _token_nextPos(token, 0);

        while (std::string::npos != pos || std::string::npos != lastPos)
        {
                if ( whichtok == from )
                {
                        if ( newstr != "" ) newstr = newstr + token;
                        newstr = newstr + replace;
                }
                else
                {
                        if ( newstr != "" ) newstr = newstr + token;
                        newstr = newstr + this->substr(lastPos, pos - lastPos);
                }

                // Found a token, add it to the vector.
                whichtok++;

                if ( pos >= this->length() )
                        break;

                // skip past token
                size_t i = 0;
                size_t max = strlen(token);
                lastPos = pos;
                while ( (i < max) && (token[i] == this->at(lastPos)) )
                {
                        ++i;
                        ++lastPos;
                }

                // get the next token
                pos = _token_nextPos(token, lastPos);
        }
        return newstr;
}


String *String::tokenise(const char *token, int *max) const
{
        if ( empty() ) {
                *max = 0;
                return NULL;
        }

        *max = this->countToken(token);

        if ( (*max) <= 0 ) {
                *max = 0;
                return NULL;
        }

        String *newstr = (*max == 1) ? new String : new String[*max];

        int whichtok = 0;
        // get first token
        std::string::size_type lastPos = 0;
        std::string::size_type pos     = this->_token_nextPos(token, 0);

        while (std::string::npos != pos || std::string::npos != lastPos)
        {
                // set token
                if ( *max == 1 ) *newstr = this->substr(lastPos, pos - lastPos);
                else                      newstr[whichtok] = this->substr(lastPos, pos - lastPos);

                // move to next token
                whichtok++;
                if ( whichtok >= *max )
                        break;

                if ( pos >= this->length() )
                        break;

                // skip past token
                size_t i = 0;
                size_t max = strlen(token);
                lastPos = pos;
                while ( (i < max) && (token[i] == this->at(lastPos)) ) {
                        ++i;
                        ++lastPos;
                }

                // get the next token
                pos = _token_nextPos(token, lastPos);
        }

        return newstr;
}

const String &String::remove(char c)
{
        std::string::size_type pos = this->find_first_of(c, 0);
        while(pos != std::string::npos) {
                this->erase(pos, 1);
                pos = this->find_first_of(c, 0);
        }

        return (*this);
}

String String::removeChar(char c) const
{
        String newStr = *this;

        std::string::size_type pos = newStr.find_first_of(c, 0);
        while(pos != std::string::npos) {
                newStr.erase(pos, 1);
                pos = newStr.find_first_of(c, 0);
        }

        return newStr;
}

bool String::_isCharNumber(char c) const
{
        return (c >= '0' && c <= '9') ? true : false;
}

bool String::isCharNumber(int c) const
{
        return _isCharNumber(this->at(c));
}

bool String::isNumber(bool integer) const
{
        bool foundpoint = integer;
        for ( int i = 0; i < (int)this->length(); i++ )
        {
                // check for a decimal point (floating point value)
                // only allow 1 decimal point, or none if just checking for an integer
                if ( this->at(i) == '.' && !foundpoint ) foundpoint = true;
                // check if it is a number, 0-9
                else if ( !this->isCharNumber(i) ) return false;
        }
        return true;
}

const String &String::removeFirstSpace()
{
        std::string::size_type pos = this->find_first_not_of(" ", 0);
        if ( pos != std::string::npos ) {
                this->erase(0, pos);
        }
        return (*this);
}

}//NAMESPACE