/* PIP - Platform Independent Primitives String Copyright (C) 2013 Ivan Pelipenko peri4ko@gmail.com This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef PISTRING_H #define PISTRING_H #include "pibytearray.h" #include "pichar.h" #include "math.h" class PIStringList; class PIString: public PIVector { public: PIString() {piMonitor.strings++; piMonitor.containers--;} //inline PIString & operator +=(const char c) {push_back(c); return *this;} PIString & operator +=(const PIChar c) {push_back(c); return *this;} PIString & operator +=(const char * str); PIString & operator +=(const wchar_t * str); PIString & operator +=(const string & str) {appendFromChars(str.c_str(), str.length()); return *this;} PIString & operator +=(const PIByteArray & ba) {appendFromChars((const char * )ba.data(), ba.size_s()); return *this;} PIString & operator +=(const PIString & str); #ifdef HAS_LOCALE PIString & operator +=(const wstring & str); #endif //PIString(const char c) {*this += c;} PIString(const PIChar c) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += c;} PIString(const char * str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;} PIString(const wchar_t * str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;} PIString(const string & str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;} #ifdef HAS_LOCALE PIString(const wstring & str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;} #endif PIString(const PIByteArray & ba) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += ba;} PIString(const char * str, const int len) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += string(str, len);} PIString(const int len, const char c) {reserve(256); piMonitor.strings++; piMonitor.containers--; for (int i = 0; i < len; ++i) push_back(c);} PIString(const int len, const PIChar & c) {reserve(256); piMonitor.strings++; piMonitor.containers--; for (int i = 0; i < len; ++i) push_back(c);} PIString(const PIString & str) {reserve(256); piMonitor.strings++; piMonitor.containers--; *this += str;} ~PIString() {piMonitor.strings--; piMonitor.containers++;} operator const char*() {return data();} operator const string() {if (size() == 0) return string(); string s; for (int i = 0; i < length(); ++i) s.push_back(at(i).toAscii()); return s;} PIChar operator [](const int pos) const {return at(pos);} PIChar & operator [](const int pos) {return at(pos);} bool operator ==(const PIString & str) const; bool operator ==(const PIChar c) const {return *this == PIString(c);} //inline bool operator ==(const char c) const {return *this == PIString(c);} bool operator ==(const char * str) const {return *this == PIString(str);} bool operator ==(const string & str) const {return *this == PIString(str);} bool operator !=(const PIString & str) const; bool operator !=(const PIChar c) const {return *this != PIString(c);} //inline bool operator !=(const char c) const {return *this != PIString(c);} bool operator !=(const char * str) const {return *this != PIString(str);} bool operator !=(const string & str) const {return *this != PIString(str);} bool operator <(const PIString & str) const; bool operator <(const PIChar c) const {return *this < PIString(c);} //inline bool operator <(const char c) const {return *this < PIString(c);} bool operator <(const char * str) const {return *this < PIString(str);} bool operator <(const string & str) const {return *this < PIString(str);} bool operator >(const PIString & str) const; bool operator >(const PIChar c) const {return *this > PIString(c);} //inline bool operator >(const char c) const {return *this > PIString(c);} bool operator >(const char * str) const {return *this > PIString(str);} bool operator >(const string & str) const {return *this > PIString(str);} bool operator <=(const PIString & str) const {return !(*this > str);} bool operator <=(const PIChar c) const {return *this <= PIString(c);} //inline bool operator <=(const char c) const {return *this <= PIString(c);} bool operator <=(const char * str) const {return *this <= PIString(str);} bool operator <=(const string & str) const {return *this <= PIString(str);} bool operator >=(const PIString & str) const {return !(*this < str);} bool operator >=(const PIChar c) const {return *this >= PIString(c);} //inline bool operator >=(const char c) const {return *this >= PIString(c);} bool operator >=(const char * str) const {return *this >= PIString(str);} bool operator >=(const string & str) const {return *this >= PIString(str);} PIString & operator <<(const PIString & str) {*this += str; return *this;} //inline PIString & operator <<(const char c) {*this += c; return *this;} PIString & operator <<(const PIChar c) {*this += c; return *this;} PIString & operator <<(const char * str) {*this += str; return *this;} PIString & operator <<(const wchar_t * str) {*this += str; return *this;} PIString & operator <<(const string & str) {*this += str; return *this;} PIString & operator <<(const int & num) {*this += PIString::fromNumber(num); return *this;} PIString & operator <<(const short & num) {*this += PIString::fromNumber(num); return *this;} PIString & operator <<(const long & num) {*this += PIString::fromNumber(num); return *this;} PIString & operator <<(const float & num) {*this += PIString::fromNumber(num); return *this;} PIString & operator <<(const double & num) {*this += PIString::fromNumber(num); return *this;} PIString mid(const int start, const int len = -1) const; PIString left(const int len) const {return len <= 0 ? PIString() : mid(0, len);} PIString right(const int len) const {return len <= 0 ? PIString() : mid(size() - len, len);} PIString & cutMid(const int start, const int len); PIString & cutLeft(const int len) {return len <= 0 ? *this : cutMid(0, len);} PIString & cutRight(const int len) {return len <= 0 ? *this : cutMid(size() - len, len);} PIString & trim(); PIString trimmed() const; PIString & replace(const int from, const int count, const PIString & with); PIString replaced(const int from, const int count, const PIString & with) const {PIString str(*this); str.replace(from, count, with); return str;} PIString & replace(const PIString & what, const PIString & with, bool * ok = 0); PIString replaced(const PIString & what, const PIString & with, bool * ok = 0) const {PIString str(*this); str.replace(what, with, ok); return str;} PIString & replaceAll(const PIString & what, const PIString & with); PIString replaceAll(const PIString & what, const PIString & with) const {PIString str(*this); str.replaceAll(what, with); return str;} PIString & insert(const int index, const PIChar & c) {PIVector::insert(index, c); return *this;} PIString & insert(const int index, const char & c) {return insert(index, PIChar(c));} PIString & insert(const int index, const PIString & str); PIString & insert(const int index, const char * c) {return insert(index, PIString(c));} PIString & expandRightTo(const int len, const PIChar & c) {if (len > length()) resize(len, c); return *this;} PIString & expandLeftTo(const int len, const PIChar & c) {if (len > length()) insert(0, PIString(len - length(), c)); return *this;} PIString & reverse() {PIString str(*this); clear(); piForeachR (const PIChar & c, str) push_back(c); return *this;} PIString reversed() const {PIString str(*this); str.reverse(); return str;} //const char * data() {return convertToStd().c_str();} int lengthAscii() const; const char * data() const; const string stdString() const {return convertToStd();} #ifdef HAS_LOCALE wstring stdWString() const {return convertToWString();} #endif PIByteArray toByteArray() const {const char * d = data(); return PIByteArray(d, lengthAscii());} PIStringList split(const PIString & delim) const; PIString toUpperCase() const; PIString toLowerCase() const; #ifdef HAS_LOCALE PIString toNativeDecimalPoints() const {PIString s(*this); if (currentLocale == 0) return s; return s.replaceAll(".", currentLocale->decimal_point);} #else PIString toNativeDecimalPoints() const {PIString s(*this); return s;} #endif int find(const char str, const int start = 0) const; int find(const PIString str, const int start = 0) const; int find(const char * str, const int start = 0) const {return find(PIString(str), start);} int find(const string str, const int start = 0) const {return find(PIString(str), start);} int findLast(const char str, const int start = 0) const; int findLast(const PIString str, const int start = 0) const; int findLast(const char * str, const int start = 0) const {return findLast(PIString(str), start);} int findLast(const string str, const int start = 0) const {return findLast(PIString(str), start);} int length() const {return size();} bool isEmpty() const {return (size() == 0 || *this == "");} bool toBool() const {PIString s(*this); if (atof(s.toNativeDecimalPoints().data()) > 0. || s.trimmed().toLowerCase() == "true" || s.trimmed().toLowerCase() == "on") return true; return false;} char toChar() const; short toShort(int base = -1, bool * ok = 0) const {return short(toNumberBase(*this, base, ok));} ushort toUShort(int base = -1, bool * ok = 0) const {return ushort(toNumberBase(*this, base, ok));} int toInt(int base = -1, bool * ok = 0) const {return int(toNumberBase(*this, base, ok));} uint toUInt(int base = -1, bool * ok = 0) const {return uint(toNumberBase(*this, base, ok));} long toLong(int base = -1, bool * ok = 0) const {return long(toNumberBase(*this, base, ok));} ulong toULong(int base = -1, bool * ok = 0) const {return ulong(toNumberBase(*this, base, ok));} llong toLLong(int base = -1, bool * ok = 0) const {return toNumberBase(*this, base, ok);} ullong toULLong(int base = -1, bool * ok = 0) const {return ullong(toNumberBase(*this, base, ok));} float toFloat() const {PIString s(*this); return (float)atof(s.toNativeDecimalPoints().data());} double toDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().data());} ldouble toLDouble() const {PIString s(*this); return atof(s.toNativeDecimalPoints().data());} //inline PIString & setNumber(const char value) {clear(); *this += itos(value); return *this;} PIString & setNumber(const short value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;} PIString & setNumber(const ushort value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;} PIString & setNumber(const int value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;} PIString & setNumber(const uint value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;} PIString & setNumber(const long value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;} PIString & setNumber(const ulong value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;} PIString & setNumber(const llong value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;} PIString & setNumber(const ullong value, int base = 10, bool * ok = 0) {clear(); *this += PIString::fromNumber(value, base, ok); return *this;} PIString & setNumber(const float value) {clear(); *this += ftos(value); return *this;} PIString & setNumber(const double value) {clear(); *this += dtos(value); return *this;} PIString & setNumber(const ldouble value) {clear(); *this += dtos(value); return *this;} PIString & setReadableSize(long bytes); //inline static PIString fromNumber(const char value) {return PIString(itos(value));} static PIString fromNumber(const short value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);} static PIString fromNumber(const ushort value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);} static PIString fromNumber(const int value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);} static PIString fromNumber(const uint value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);} static PIString fromNumber(const long value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);} static PIString fromNumber(const ulong value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);} static PIString fromNumber(const llong value, int base = 10, bool * ok = 0) {return fromNumberBase(value, base, ok);} static PIString fromNumber(const ullong value, int base = 10, bool * ok = 0) {return fromNumberBase(llong(value), base, ok);} static PIString fromNumber(const float value) {return PIString(ftos(value));} static PIString fromNumber(const double value) {return PIString(dtos(value));} static PIString fromNumber(const ldouble value) {return PIString(dtos(value));} static PIString fromBool(const bool value) {return PIString(value ? "true" : "false");} static PIString readableSize(long bytes) {PIString s; s.setReadableSize(bytes); return s;} private: static const char toBaseN[]; static const int fromBaseN[]; static PIString fromNumberBase(const llong value, int base = 10, bool * ok = 0) { if (base < 2 || base > 40) {if (ok != 0) *ok = false; return PIString();} if (ok != 0) *ok = true; if (base == 10) return itos(value); PIString ret; llong v = value < 0 ? -value : value, cn, b = base; while (v >= base) { cn = v % b; v /= b; //cout << int(cn) << ", " << int(v) << endl; ret.push_front(PIChar(toBaseN[cn])); } if (v > 0) ret.push_front(PIChar(toBaseN[v])); if (value < 0) ret.push_front('-'); return ret; } static llong toNumberBase(const PIString & value, int base = -1, bool * ok = 0) { PIString v = value.trimmed(); if (base < 0) { int ind = v.find("0x"); if (ind == 0 || ind == 1) {v.remove(ind, 2); base = 16;} else base = 10; } else if (base < 2 || base > 40) {if (ok != 0) *ok = false; return 0;} v.reverse(); if (ok != 0) *ok = true; llong ret = 0, m = 1; int cs; piForeachC (PIChar & i, v) { if (i == PIChar('-')) {ret = -ret; continue;} //cout << i << ", " << fromBaseN[int(i.toAscii())] << ", " << m << endl; cs = fromBaseN[int(i.toAscii())]; if (cs < 0 || cs >= base) break; ret += cs * m; m *= base; } return ret; } void appendFromChars(const char * c, int s); string convertToStd() const; #ifdef HAS_LOCALE wstring convertToWString() const {wstring s; for (int i = 0; i < length(); ++i) s.push_back(at(i).toWChar()); return s;} #endif PIByteArray data_; //string std_string; //wstring std_wstring; }; inline std::ostream & operator <<(std::ostream & s, const PIString & v) {for (int i = 0; i < v.length(); ++i) s << v[i]; return s;} inline std::istream & operator >>(std::istream & s, PIString & v) {string ss; s >> ss; v << PIString(ss); return s;} inline PIByteArray & operator <<(PIByteArray & s, const PIString & v) {s << v.size_s(); for (int i = 0; i < v.length(); ++i) s << v[i]; return s;} inline PIByteArray & operator >>(PIByteArray & s, PIString & v) {int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;} inline PIString operator +(const PIString & str, const PIString & f) {PIString s(str); s += f; return s;} //inline PIString operator +(const PIString & f, const char c) {PIString s(f); s.push_back(c); return s;} inline PIString operator +(const PIString & f, const char * str) {PIString s(f); s += str; return s;} inline PIString operator +(const PIString & f, const string & str) {PIString s(f); s += str; return s;} //inline PIString operator +(const char c, const PIString & f) {return PIString(c) + f;} inline PIString operator +(const char * str, const PIString & f) {return PIString(str) + f;} inline PIString operator +(const string & str, const PIString & f) {return PIString(str) + f;} inline char chrUpr(char c); inline char chrLwr(char c); class PIStringList: public PIVector { public: PIStringList() {;} PIStringList(const PIString & str) {push_back(str);} PIStringList(const PIString & s0, const PIString & s1) {push_back(s0); push_back(s1);} PIStringList(const PIString & s0, const PIString & s1, const PIString & s2) {push_back(s0); push_back(s1); push_back(s2);} PIStringList(const PIString & s0, const PIString & s1, const PIString & s2, const PIString & s3) {push_back(s0); push_back(s1); push_back(s2); push_back(s3);} PIString join(const PIString & delim) const {PIString s; for (uint i = 0; i < size(); ++i) {s += at(i); if (i < size() - 1) s += delim;} return s;} PIStringList & removeStrings(const PIString & value) {for (uint i = 0; i < size(); ++i) {if (at(i) == value) {remove(i); --i;}} return *this;} PIStringList & remove(uint num) {PIVector::remove(num); return *this;} PIStringList & remove(uint num, uint count) {PIVector::remove(num, count); return *this;} PIStringList & removeDuplicates(); uint contentSize() {uint s = 0; for (uint i = 0; i < size(); ++i) s += at(i).size(); return s;} PIStringList & operator <<(const PIString & str) {push_back(str); return *this;} PIStringList & operator <<(const PIStringList & sl) {piForeachC (PIString & i, sl) push_back(i); return *this;} //inline PIStringList & operator <<(const char c) {push_back(PIString(c)); return *this;} PIStringList & operator <<(const char * str) {push_back(PIString(str)); return *this;} PIStringList & operator <<(const string & str) {push_back(str); return *this;} PIStringList & operator <<(const int & num) {push_back(PIString::fromNumber(num)); return *this;} PIStringList & operator <<(const short & num) {push_back(PIString::fromNumber(num)); return *this;} PIStringList & operator <<(const long & num) {push_back(PIString::fromNumber(num)); return *this;} PIStringList & operator <<(const float & num) {push_back(PIString::fromNumber(num)); return *this;} PIStringList & operator <<(const double & num) {push_back(PIString::fromNumber(num)); return *this;} }; inline std::ostream & operator <<(std::ostream & s, const PIStringList & v) {s << "{"; for (uint i = 0; i < v.size(); ++i) {s << '\"' << v[i] << '\"'; if (i < v.size() - 1) s << ", ";} s << "}"; return s;} #endif // PISTRING_H