String.cc revision 10447
110447Snilay@cs.wisc.edu#include "String.h" 210447Snilay@cs.wisc.edu 310447Snilay@cs.wisc.edu#include <cstdarg> 410447Snilay@cs.wisc.edu#include <cstdio> 510447Snilay@cs.wisc.edu#include <iostream> 610447Snilay@cs.wisc.edu#include <ios> 710447Snilay@cs.wisc.edu 810447Snilay@cs.wisc.edunamespace LibUtil 910447Snilay@cs.wisc.edu{ 1010447Snilay@cs.wisc.edu const unsigned int String::msBufferSize = 4096; 1110447Snilay@cs.wisc.edu 1210447Snilay@cs.wisc.edu String String::format(const String& format_, ...) 1310447Snilay@cs.wisc.edu { 1410447Snilay@cs.wisc.edu char buffer[msBufferSize]; 1510447Snilay@cs.wisc.edu 1610447Snilay@cs.wisc.edu va_list args; 1710447Snilay@cs.wisc.edu va_start(args, format_); 1810447Snilay@cs.wisc.edu vsnprintf(buffer, msBufferSize, format_.c_str(), args); 1910447Snilay@cs.wisc.edu va_end(args); 2010447Snilay@cs.wisc.edu 2110447Snilay@cs.wisc.edu return (String)(buffer); 2210447Snilay@cs.wisc.edu } 2310447Snilay@cs.wisc.edu 2410447Snilay@cs.wisc.edu String String::format(const String& format_, va_list args_) 2510447Snilay@cs.wisc.edu { 2610447Snilay@cs.wisc.edu char buffer[msBufferSize]; 2710447Snilay@cs.wisc.edu 2810447Snilay@cs.wisc.edu vsnprintf(buffer, msBufferSize, format_.c_str(), args_); 2910447Snilay@cs.wisc.edu 3010447Snilay@cs.wisc.edu return (String)(buffer); 3110447Snilay@cs.wisc.edu } 3210447Snilay@cs.wisc.edu 3310447Snilay@cs.wisc.edu String::String() 3410447Snilay@cs.wisc.edu {} 3510447Snilay@cs.wisc.edu 3610447Snilay@cs.wisc.edu String::String(const string& str_) 3710447Snilay@cs.wisc.edu : string(str_) 3810447Snilay@cs.wisc.edu {} 3910447Snilay@cs.wisc.edu 4010447Snilay@cs.wisc.edu String::String(const char* str_, size_t n_) 4110447Snilay@cs.wisc.edu : string(str_, n_) 4210447Snilay@cs.wisc.edu {} 4310447Snilay@cs.wisc.edu 4410447Snilay@cs.wisc.edu String::String(const char* str_) 4510447Snilay@cs.wisc.edu : string(str_) 4610447Snilay@cs.wisc.edu {} 4710447Snilay@cs.wisc.edu 4810447Snilay@cs.wisc.edu String::String(size_t n_, char c_) 4910447Snilay@cs.wisc.edu : string(n_, c_) 5010447Snilay@cs.wisc.edu {} 5110447Snilay@cs.wisc.edu 5210447Snilay@cs.wisc.edu String::String(int value_) 5310447Snilay@cs.wisc.edu : string(toString<int>(value_)) 5410447Snilay@cs.wisc.edu {} 5510447Snilay@cs.wisc.edu 5610447Snilay@cs.wisc.edu String::String(unsigned int value_) 5710447Snilay@cs.wisc.edu : string(toString<unsigned int>(value_)) 5810447Snilay@cs.wisc.edu {} 5910447Snilay@cs.wisc.edu 6010447Snilay@cs.wisc.edu String::String(long value_) 6110447Snilay@cs.wisc.edu : string(toString<long>(value_)) 6210447Snilay@cs.wisc.edu {} 6310447Snilay@cs.wisc.edu 6410447Snilay@cs.wisc.edu String::String(unsigned long value_) 6510447Snilay@cs.wisc.edu : string(toString<unsigned long>(value_)) 6610447Snilay@cs.wisc.edu {} 6710447Snilay@cs.wisc.edu 6810447Snilay@cs.wisc.edu String::String(float value_) 6910447Snilay@cs.wisc.edu : string(toString<float>(value_)) 7010447Snilay@cs.wisc.edu {} 7110447Snilay@cs.wisc.edu 7210447Snilay@cs.wisc.edu String::String(double value_) 7310447Snilay@cs.wisc.edu : string(toString<double>(value_)) 7410447Snilay@cs.wisc.edu {} 7510447Snilay@cs.wisc.edu 7610447Snilay@cs.wisc.edu String::String(bool value_) 7710447Snilay@cs.wisc.edu : string(toString<bool>(value_)) 7810447Snilay@cs.wisc.edu {} 7910447Snilay@cs.wisc.edu 8010447Snilay@cs.wisc.edu String::~String() 8110447Snilay@cs.wisc.edu {} 8210447Snilay@cs.wisc.edu 8310447Snilay@cs.wisc.edu String& String::trim() 8410447Snilay@cs.wisc.edu { 8510447Snilay@cs.wisc.edu // Remove leading and trailing whitespace 8610447Snilay@cs.wisc.edu static const char whitespace[] = " \n\t\v\r\f"; 8710447Snilay@cs.wisc.edu erase(0, find_first_not_of(whitespace)); 8810447Snilay@cs.wisc.edu erase(find_last_not_of(whitespace) + 1U); 8910447Snilay@cs.wisc.edu return (*this); 9010447Snilay@cs.wisc.edu } 9110447Snilay@cs.wisc.edu 9210447Snilay@cs.wisc.edu String& String::substitute(const String& str1_, const String& str2_) 9310447Snilay@cs.wisc.edu { 9410447Snilay@cs.wisc.edu size_t str1Size = str1_.size(); 9510447Snilay@cs.wisc.edu size_t str2Size = str2_.size(); 9610447Snilay@cs.wisc.edu 9710447Snilay@cs.wisc.edu size_t pos; 9810447Snilay@cs.wisc.edu pos = find(str1_); 9910447Snilay@cs.wisc.edu while(pos != string::npos) 10010447Snilay@cs.wisc.edu { 10110447Snilay@cs.wisc.edu replace(pos, str1Size, str2_); 10210447Snilay@cs.wisc.edu pos += str2Size; 10310447Snilay@cs.wisc.edu pos = find(str1_, pos); 10410447Snilay@cs.wisc.edu } 10510447Snilay@cs.wisc.edu return (*this); 10610447Snilay@cs.wisc.edu } 10710447Snilay@cs.wisc.edu 10810447Snilay@cs.wisc.edu vector<String> String::split(const char* delimiters_) const 10910447Snilay@cs.wisc.edu { 11010447Snilay@cs.wisc.edu vector<String> result; 11110447Snilay@cs.wisc.edu 11210447Snilay@cs.wisc.edu if(size() == 0) 11310447Snilay@cs.wisc.edu { 11410447Snilay@cs.wisc.edu return result; 11510447Snilay@cs.wisc.edu } 11610447Snilay@cs.wisc.edu 11710447Snilay@cs.wisc.edu size_t currPos, nextPos; 11810447Snilay@cs.wisc.edu currPos = 0; 11910447Snilay@cs.wisc.edu nextPos = find_first_of(delimiters_); 12010447Snilay@cs.wisc.edu while(1) 12110447Snilay@cs.wisc.edu { 12210447Snilay@cs.wisc.edu if(nextPos == string::npos) 12310447Snilay@cs.wisc.edu { 12410447Snilay@cs.wisc.edu if(currPos != size()) 12510447Snilay@cs.wisc.edu { 12610447Snilay@cs.wisc.edu result.push_back(substr(currPos)); 12710447Snilay@cs.wisc.edu } 12810447Snilay@cs.wisc.edu break; 12910447Snilay@cs.wisc.edu } 13010447Snilay@cs.wisc.edu 13110447Snilay@cs.wisc.edu if(nextPos != currPos) 13210447Snilay@cs.wisc.edu { 13310447Snilay@cs.wisc.edu result.push_back(substr(currPos, nextPos - currPos)); 13410447Snilay@cs.wisc.edu } 13510447Snilay@cs.wisc.edu currPos = nextPos + 1; 13610447Snilay@cs.wisc.edu nextPos = find_first_of(delimiters_, currPos); 13710447Snilay@cs.wisc.edu } 13810447Snilay@cs.wisc.edu 13910447Snilay@cs.wisc.edu return result; 14010447Snilay@cs.wisc.edu } 14110447Snilay@cs.wisc.edu 14210447Snilay@cs.wisc.edu vector<String> String::split(const String* delimiters_, unsigned int num_delimiters_) const 14310447Snilay@cs.wisc.edu { 14410447Snilay@cs.wisc.edu vector<String> result; 14510447Snilay@cs.wisc.edu 14610447Snilay@cs.wisc.edu if(size() == 0) 14710447Snilay@cs.wisc.edu { 14810447Snilay@cs.wisc.edu return result; 14910447Snilay@cs.wisc.edu } 15010447Snilay@cs.wisc.edu 15110447Snilay@cs.wisc.edu if(num_delimiters_ == 1) 15210447Snilay@cs.wisc.edu { 15310447Snilay@cs.wisc.edu size_t currPos, nextPos; 15410447Snilay@cs.wisc.edu currPos = 0; 15510447Snilay@cs.wisc.edu nextPos = find(delimiters_[0]); 15610447Snilay@cs.wisc.edu while(1) 15710447Snilay@cs.wisc.edu { 15810447Snilay@cs.wisc.edu if(nextPos == String::npos) 15910447Snilay@cs.wisc.edu { 16010447Snilay@cs.wisc.edu result.push_back(substr(currPos)); 16110447Snilay@cs.wisc.edu break; 16210447Snilay@cs.wisc.edu } 16310447Snilay@cs.wisc.edu 16410447Snilay@cs.wisc.edu if(nextPos != currPos) 16510447Snilay@cs.wisc.edu { 16610447Snilay@cs.wisc.edu result.push_back(substr(currPos, nextPos - currPos)); 16710447Snilay@cs.wisc.edu } 16810447Snilay@cs.wisc.edu currPos = nextPos + delimiters_[0].size(); 16910447Snilay@cs.wisc.edu nextPos = find(delimiters_[0], currPos); 17010447Snilay@cs.wisc.edu } 17110447Snilay@cs.wisc.edu } 17210447Snilay@cs.wisc.edu else 17310447Snilay@cs.wisc.edu { 17410447Snilay@cs.wisc.edu // Currently the length of the delimiters are not checked 17510447Snilay@cs.wisc.edu unsigned int delimiterLength = 0; 17610447Snilay@cs.wisc.edu size_t currPos, nextPos; 17710447Snilay@cs.wisc.edu currPos = 0; 17810447Snilay@cs.wisc.edu nextPos = size(); 17910447Snilay@cs.wisc.edu for(unsigned int i = 0; i < num_delimiters_; ++i) 18010447Snilay@cs.wisc.edu { 18110447Snilay@cs.wisc.edu size_t tempPos = find(delimiters_[i], currPos); 18210447Snilay@cs.wisc.edu if((tempPos != String::npos) && (tempPos < nextPos)) 18310447Snilay@cs.wisc.edu { 18410447Snilay@cs.wisc.edu nextPos = tempPos; 18510447Snilay@cs.wisc.edu delimiterLength = delimiters_[i].size(); 18610447Snilay@cs.wisc.edu } 18710447Snilay@cs.wisc.edu } 18810447Snilay@cs.wisc.edu while(1) 18910447Snilay@cs.wisc.edu { 19010447Snilay@cs.wisc.edu if((nextPos == String::npos) || (nextPos == size())) 19110447Snilay@cs.wisc.edu { 19210447Snilay@cs.wisc.edu result.push_back(substr(currPos)); 19310447Snilay@cs.wisc.edu break; 19410447Snilay@cs.wisc.edu } 19510447Snilay@cs.wisc.edu 19610447Snilay@cs.wisc.edu if(nextPos != currPos) 19710447Snilay@cs.wisc.edu { 19810447Snilay@cs.wisc.edu result.push_back(substr(currPos, nextPos - currPos)); 19910447Snilay@cs.wisc.edu } 20010447Snilay@cs.wisc.edu currPos = nextPos + delimiterLength; 20110447Snilay@cs.wisc.edu nextPos = size(); 20210447Snilay@cs.wisc.edu delimiterLength = 0; 20310447Snilay@cs.wisc.edu for(unsigned int i = 0; i < num_delimiters_; ++i) 20410447Snilay@cs.wisc.edu { 20510447Snilay@cs.wisc.edu size_t tempPos = find(delimiters_[i], currPos); 20610447Snilay@cs.wisc.edu if((tempPos != String::npos) && (tempPos < nextPos)) 20710447Snilay@cs.wisc.edu { 20810447Snilay@cs.wisc.edu nextPos = tempPos; 20910447Snilay@cs.wisc.edu delimiterLength = delimiters_[i].size(); 21010447Snilay@cs.wisc.edu } 21110447Snilay@cs.wisc.edu } 21210447Snilay@cs.wisc.edu } 21310447Snilay@cs.wisc.edu } 21410447Snilay@cs.wisc.edu return result; 21510447Snilay@cs.wisc.edu } 21610447Snilay@cs.wisc.edu 21710447Snilay@cs.wisc.edu vector<String> String::splitByString(const String& delimiter_) const 21810447Snilay@cs.wisc.edu { 21910447Snilay@cs.wisc.edu return split(&delimiter_, 1); 22010447Snilay@cs.wisc.edu } 22110447Snilay@cs.wisc.edu 22210447Snilay@cs.wisc.edu bool String::contain(const String& str_) const 22310447Snilay@cs.wisc.edu { 22410447Snilay@cs.wisc.edu return (find(str_) != String::npos); 22510447Snilay@cs.wisc.edu } 22610447Snilay@cs.wisc.edu 22710447Snilay@cs.wisc.edu const char* String::toCString() const 22810447Snilay@cs.wisc.edu { 22910447Snilay@cs.wisc.edu return this->c_str(); 23010447Snilay@cs.wisc.edu } 23110447Snilay@cs.wisc.edu 23210447Snilay@cs.wisc.edu int String::toInt() const 23310447Snilay@cs.wisc.edu { 23410447Snilay@cs.wisc.edu return fromString<int>(*this); 23510447Snilay@cs.wisc.edu } 23610447Snilay@cs.wisc.edu 23710447Snilay@cs.wisc.edu unsigned int String::toUInt() const 23810447Snilay@cs.wisc.edu { 23910447Snilay@cs.wisc.edu return fromString<unsigned int>(*this); 24010447Snilay@cs.wisc.edu } 24110447Snilay@cs.wisc.edu 24210447Snilay@cs.wisc.edu long String::toLong() const 24310447Snilay@cs.wisc.edu { 24410447Snilay@cs.wisc.edu return fromString<long>(*this); 24510447Snilay@cs.wisc.edu } 24610447Snilay@cs.wisc.edu 24710447Snilay@cs.wisc.edu unsigned long String::toULong() const 24810447Snilay@cs.wisc.edu { 24910447Snilay@cs.wisc.edu return fromString<unsigned long>(*this); 25010447Snilay@cs.wisc.edu } 25110447Snilay@cs.wisc.edu 25210447Snilay@cs.wisc.edu float String::toFloat() const 25310447Snilay@cs.wisc.edu { 25410447Snilay@cs.wisc.edu return fromString<float>(*this); 25510447Snilay@cs.wisc.edu } 25610447Snilay@cs.wisc.edu 25710447Snilay@cs.wisc.edu double String::toDouble() const 25810447Snilay@cs.wisc.edu { 25910447Snilay@cs.wisc.edu return fromString<double>(*this); 26010447Snilay@cs.wisc.edu } 26110447Snilay@cs.wisc.edu 26210447Snilay@cs.wisc.edu bool String::toBool() const 26310447Snilay@cs.wisc.edu { 26410447Snilay@cs.wisc.edu return fromString<bool>(*this); 26510447Snilay@cs.wisc.edu } 26610447Snilay@cs.wisc.edu 26710447Snilay@cs.wisc.edu String::operator const char*() const 26810447Snilay@cs.wisc.edu { 26910447Snilay@cs.wisc.edu return this->c_str(); 27010447Snilay@cs.wisc.edu } 27110447Snilay@cs.wisc.edu 27210447Snilay@cs.wisc.edu String::operator int() const 27310447Snilay@cs.wisc.edu { 27410447Snilay@cs.wisc.edu return fromString<int>(*this); 27510447Snilay@cs.wisc.edu } 27610447Snilay@cs.wisc.edu 27710447Snilay@cs.wisc.edu String::operator unsigned int() const 27810447Snilay@cs.wisc.edu { 27910447Snilay@cs.wisc.edu return fromString<unsigned int>(*this); 28010447Snilay@cs.wisc.edu } 28110447Snilay@cs.wisc.edu 28210447Snilay@cs.wisc.edu String::operator long() const 28310447Snilay@cs.wisc.edu { 28410447Snilay@cs.wisc.edu return fromString<long>(*this); 28510447Snilay@cs.wisc.edu } 28610447Snilay@cs.wisc.edu 28710447Snilay@cs.wisc.edu String::operator unsigned long() const 28810447Snilay@cs.wisc.edu { 28910447Snilay@cs.wisc.edu return fromString<unsigned long>(*this); 29010447Snilay@cs.wisc.edu } 29110447Snilay@cs.wisc.edu 29210447Snilay@cs.wisc.edu String::operator float() const 29310447Snilay@cs.wisc.edu { 29410447Snilay@cs.wisc.edu return fromString<float>(*this); 29510447Snilay@cs.wisc.edu } 29610447Snilay@cs.wisc.edu 29710447Snilay@cs.wisc.edu String::operator double() const 29810447Snilay@cs.wisc.edu { 29910447Snilay@cs.wisc.edu return fromString<double>(*this); 30010447Snilay@cs.wisc.edu } 30110447Snilay@cs.wisc.edu 30210447Snilay@cs.wisc.edu String::operator bool() const 30310447Snilay@cs.wisc.edu { 30410447Snilay@cs.wisc.edu return fromString<bool>(*this); 30510447Snilay@cs.wisc.edu } 30610447Snilay@cs.wisc.edu 30710447Snilay@cs.wisc.edu String& String::operator=(char c_) 30810447Snilay@cs.wisc.edu { 30910447Snilay@cs.wisc.edu this->assign(1, c_); 31010447Snilay@cs.wisc.edu return *this; 31110447Snilay@cs.wisc.edu } 31210447Snilay@cs.wisc.edu 31310447Snilay@cs.wisc.edu std::istream& safeGetline(std::istream& is_, String& str_) 31410447Snilay@cs.wisc.edu { 31510447Snilay@cs.wisc.edu str_.clear(); 31610447Snilay@cs.wisc.edu 31710447Snilay@cs.wisc.edu // The characters in the stream are read one-by-one using a std::streambuf. 31810447Snilay@cs.wisc.edu // That is faster than reading them one-by-one using the std::istream. 31910447Snilay@cs.wisc.edu // Code that uses streambuf this way must be guarded by a sentry object. 32010447Snilay@cs.wisc.edu // The sentry object performs various tasks, 32110447Snilay@cs.wisc.edu // such as thread synchronization and updating the stream state. 32210447Snilay@cs.wisc.edu 32310447Snilay@cs.wisc.edu std::istream::sentry se(is_, true); 32410447Snilay@cs.wisc.edu std::streambuf* sb = is_.rdbuf(); 32510447Snilay@cs.wisc.edu 32610447Snilay@cs.wisc.edu while(1) 32710447Snilay@cs.wisc.edu { 32810447Snilay@cs.wisc.edu int c = sb->sbumpc(); 32910447Snilay@cs.wisc.edu switch(c) 33010447Snilay@cs.wisc.edu { 33110447Snilay@cs.wisc.edu case '\r': 33210447Snilay@cs.wisc.edu c = sb->sgetc(); 33310447Snilay@cs.wisc.edu if(c == '\n') 33410447Snilay@cs.wisc.edu sb->sbumpc(); 33510447Snilay@cs.wisc.edu return is_; 33610447Snilay@cs.wisc.edu case '\n': 33710447Snilay@cs.wisc.edu return is_; 33810447Snilay@cs.wisc.edu case EOF: 33910447Snilay@cs.wisc.edu is_.setstate(std::ios_base::failbit|std::ios_base::eofbit); 34010447Snilay@cs.wisc.edu return is_; 34110447Snilay@cs.wisc.edu default: 34210447Snilay@cs.wisc.edu str_ += String(1, (char)c); 34310447Snilay@cs.wisc.edu } 34410447Snilay@cs.wisc.edu } 34510447Snilay@cs.wisc.edu } 34610447Snilay@cs.wisc.edu} // namespace LibUtil 34710447Snilay@cs.wisc.edu 348