00001
00002
00003
00004
00005
00006
00007
00008 #ifndef __SP_IO_STRING_H__
00009 #define __SP_IO_STRING_H__
00010
00011
00012 #include "Base/spStandard.hpp"
00013
00014 #include <cstdlib>
00015 #include <sstream>
00016 #include <string>
00017 #include <vector>
00018 #include <list>
00019 #include <algorithm>
00020
00021
00022 namespace sp
00023 {
00024 namespace io
00025 {
00026
00027
00029 template <typename T> class string
00030 {
00031
00032 public:
00033
00034 string<T>()
00035 {
00036 }
00037 string<T>(const string<T> &Str) :
00038 Str_(Str.Str_)
00039 {
00040 }
00041 string<T>(const std::basic_string<T> &Str) :
00042 Str_(Str)
00043 {
00044 }
00045 string<T>(const std::stringstream &Str) :
00046 Str_(Str.str())
00047 {
00048 }
00049 template <typename B> string<T>(const B Value)
00050 {
00051 std::stringstream SStr;
00052 SStr << Value;
00053 Str_ = SStr.str();
00054 }
00055 ~string<T>()
00056 {
00057 }
00058
00059
00060
00061 string<T>& operator = (const string<T> &Str)
00062 {
00063 Str_ = Str.Str_;
00064 return *this;
00065 }
00066
00067 bool operator == (const string<T> &Str) const
00068 {
00069 return Str_ == Str.Str_;
00070 }
00071 bool operator != (const string<T> &Str) const
00072 {
00073 return Str_ != Str.Str_;
00074 }
00075
00076 string<T> operator + (const string<T> &Str) const
00077 {
00078 return Str_ + Str.Str_;
00079 }
00080 string<T>& operator += (const string<T> &Str)
00081 {
00082 Str_ += Str.Str_;
00083 return *this;
00084 }
00085
00086 inline T& operator [] (u32 Index)
00087 {
00088 return Str_[Index];
00089 }
00090
00091 inline const T& operator [] (u32 Index) const
00092 {
00093 return Str_[Index];
00094 }
00095
00096
00097
00099 inline std::basic_string<T>& str()
00100 {
00101 return Str_;
00102 }
00104 inline const std::basic_string<T>& str() const
00105 {
00106 return Str_;
00107 }
00109 inline const T* c_str() const
00110 {
00111 return Str_.c_str();
00112 }
00114 inline u32 size() const
00115 {
00116 return Str_.size();
00117 }
00119 inline u32 length() const
00120 {
00121 return Str_.length();
00122 }
00123
00124 inline void resize(u32 Size)
00125 {
00126 Str_.resize(Size);
00127 }
00128 inline void clear()
00129 {
00130 Str_.clear();
00131 }
00132
00133 inline bool empty() const
00134 {
00135 return Str_.empty();
00136 }
00137
00138 template <typename B> B val() const
00139 {
00140 B Value = B(0);
00141 std::istringstream sstr(Str_);
00142 sstr >> Value;
00143 return Value;
00144 }
00145
00146 string<T> left(u32 Len) const
00147 {
00148 if (Len > size())
00149 return *this;
00150 return string<T>(Str_.substr(0, Len));
00151 }
00152
00153 string<T> right(u32 Len) const
00154 {
00155 if (Len > size())
00156 return *this;
00157 return string<T>(Str_.substr(Str_.size() - Len, Len));
00158 }
00159
00160 string<T> mid(u32 Pos, u32 Len) const
00161 {
00162 if (Pos > size())
00163 return "";
00164 if (Pos + Len > size())
00165 Len = size() - Pos;
00166 return string<T>(Str_.substr(Pos, Len));
00167 }
00168
00169 string<T> section(u32 Pos1, u32 Pos2) const
00170 {
00171 if (Pos1 > size() || Pos2 > size() || Pos1 > Pos2)
00172 return "";
00173 return string<T>(Str_.substr(Pos1, Pos2 - Pos1));
00174 }
00175
00177 string<T> trim() const
00178 {
00179 std::string NewStr = Str_;
00180
00181 for (u32 i = 0; i < NewStr.size();)
00182 {
00183 if (NewStr[i] == ' ' || NewStr[i] == '\t')
00184 NewStr = NewStr.substr(0, i) + NewStr.substr(i + 1, NewStr.size() - 1);
00185 else
00186 ++i;
00187 }
00188
00189 return string<T>(NewStr);
00190 }
00191
00193 string<T> ltrim() const
00194 {
00195 u32 i = 0;
00196
00197 while ( i < Str_.size() && ( Str_[i] == ' ' || Str_[i] == '\t' ) )
00198 ++i;
00199
00200 return string<T>(Str_.substr(i, Str_.size() - i));
00201 }
00202
00204 string<T> rtrim() const
00205 {
00206 s32 i = static_cast<s32>(Str_.size()) - 1;
00207
00208 while ( i >= 0 && ( Str_[i] == ' ' || Str_[i] == '\t' ) )
00209 --i;
00210
00211 return string<T>(Str_.substr(0, static_cast<u32>(i + 1)));
00212 }
00213
00215 bool leftEqual(const string<T> &Str, u32 Len) const
00216 {
00217 if (Len > size())
00218 Len = size();
00219 if (Len > Str.size())
00220 Len = Str.size();
00221
00222 for (u32 i = 0; i < Len; ++i)
00223 {
00224 if (Str_[i] != Str.Str_[i])
00225 return false;
00226 }
00227
00228 return true;
00229 }
00230
00232 bool rightEqual(const string<T> &Str, u32 Len) const
00233 {
00234 if (Len > size())
00235 Len = size();
00236 if (Len > Str.size())
00237 Len = Str.size();
00238
00239 const u32 LenA = Str_.size();
00240 const u32 LenB = Str.Str_.size();
00241
00242 for (u32 i = 0; i < Len; ++i)
00243 {
00244 if (Str_[LenA - i - 1] != Str.Str_[LenB - i - 1])
00245 return false;
00246 }
00247
00248 return true;
00249 }
00250
00252 u32 getLeftEquality(const string<T> &Str) const
00253 {
00254 u32 i = 0;
00255
00256 for (u32 c = std::min(Str_.size(), Str.Str_.size()); i < c; ++i)
00257 {
00258 if (Str_[i] != Str.Str_[i])
00259 break;
00260 }
00261
00262 return i;
00263 }
00264
00266 u32 getRightEquality(const string<T> &Str) const
00267 {
00268 u32 i = 0;
00269
00270 const u32 LenA = Str_.size();
00271 const u32 LenB = Str.Str_.size();
00272
00273 for (u32 c = std::min(Str_.size(), Str.Str_.size()); i < c; ++i)
00274 {
00275 if (Str_[LenA - i - 1] != Str.Str_[LenB - i - 1])
00276 break;
00277 }
00278
00279 return i;
00280 }
00281
00288 inline s32 find(const string<T> &Str, u32 PosBegin = 0) const
00289 {
00290 return static_cast<s32>(Str_.find(Str.Str_, PosBegin));
00291 }
00292
00293 inline s32 rfind(const string<T> &Str, u32 PosBegin = -1) const
00294 {
00295 return static_cast<s32>(Str_.rfind(Str.Str_, PosBegin));
00296 }
00297
00298 s32 findChar(const T &SearchChar, u32 PosBegin = 0) const
00299 {
00300 for (u32 i = PosBegin, c = Str_.size(); i < c; ++i)
00301 {
00302 if (Str_[i] == SearchChar)
00303 return i;
00304 }
00305 return -1;
00306 }
00307
00308 s32 rfindChar(const T &SearchChar, u32 PosBegin = -1) const
00309 {
00310 if (PosBegin > 0)
00311 {
00312 for (s32 c = static_cast<s32>(Str_.size()), i = (PosBegin < c ? PosBegin : c); i >= 0; --i)
00313 {
00314 if (Str_[i] == SearchChar)
00315 return i;
00316 }
00317 }
00318 return -1;
00319 }
00320
00327 s32 findNot(const string<T> &Str, u32 PosBegin = 0) const
00328 {
00329 u32 i = PosBegin, j;
00330
00331 while (i < Str_.size())
00332 {
00333 for (j = 0; j < Str.size(); ++j)
00334 {
00335 if (Str_[i] != Str[i])
00336 return i;
00337 }
00338 ++i;
00339 }
00340
00341 return -1;
00342 }
00343
00348 s32 findNotSpaces(u32 PosBegin = 0) const
00349 {
00350 u32 i = PosBegin;
00351
00352 while (i < Str_.size())
00353 {
00354 if (Str_[i] != ' ' && Str_[i] != '\t')
00355 return i;
00356 ++i;
00357 }
00358
00359 return -1;
00360 }
00361
00362 static inline T getUpperChar(T AscChar)
00363 {
00364 return (AscChar >= 97 && AscChar <= 122) ? AscChar - 32 : AscChar;
00365 }
00366
00367 static inline T getLowerChar(T AscChar)
00368 {
00369 return (AscChar >= 65 && AscChar <= 90) ? AscChar + 32 : AscChar;
00370 }
00371
00373 string<T>& makeUpper()
00374 {
00375 for (u32 i = 0, c = Str_.size(); i < c; ++i)
00376 {
00377 if (Str_[i] >= 97 && Str_[i] <= 122)
00378 Str_[i] -= 32;
00379 }
00380 return *this;
00381 }
00383 string<T>& makeLower()
00384 {
00385 for (u32 i = 0, c = Str_.size(); i < c; ++i)
00386 {
00387 if (Str_[i] >= 65 && Str_[i] <= 90)
00388 Str_[i] += 32;
00389 }
00390 return *this;
00391 }
00392
00394 string<T> upper() const
00395 {
00396 string<T> NewStr(*this);
00397 NewStr.makeUpper();
00398 return NewStr;
00399 }
00401 string<T> lower() const
00402 {
00403 string<T> NewStr(*this);
00404 NewStr.makeLower();
00405 return NewStr;
00406 }
00407
00408 string<T> replace(const string<T> &StrFind, const string<T> &StrReplace, u32 PosBegin = 0) const
00409 {
00410 std::string NewStr = Str_;
00411 s32 Pos = PosBegin;
00412
00413 while ( ( Pos = NewStr.find(StrFind.str(), Pos) ) != -1)
00414 {
00415 NewStr =
00416 NewStr.substr(0, Pos) +
00417 StrReplace.str() +
00418 NewStr.substr( Pos + StrFind.size(), NewStr.size() - (Pos + StrFind.size()) );
00419 Pos += StrReplace.size();
00420 }
00421
00422 return string<T>(NewStr);
00423 }
00424
00425
00426
00427 static string<T> ascii(u8 Character)
00428 {
00429 return string<T>(std::string(1, Character));
00430 }
00431
00432 static string<T> space(u32 Count, c8 Ascii = ' ')
00433 {
00434 return string<T>(std::string(Count, Ascii));
00435 }
00436
00437 static string<T> create(const string<T> &Str, u32 Count = 1)
00438 {
00439 std::string NewStr;
00440
00441 for (u32 i = 0; i < Count; ++i)
00442 NewStr += Str.Str_;
00443
00444 return string<T>(NewStr);
00445 }
00446
00454 static string<T> number(u32 Number, u32 DigitsCount, const c8 Ascii = '0')
00455 {
00456 string<T> Str(Number);
00457
00458 if (Str.size() < DigitsCount)
00459 {
00460 DigitsCount -= Str.size();
00461 Str = string<T>::space(DigitsCount, Ascii) + Str;
00462 }
00463
00464 return Str;
00465 }
00466
00479 static string<T> numberFloat(f32 Number, u32 DecimalPlaces, bool isFillBlanks = false)
00480 {
00481 string<T> Str(Number);
00482
00483 for (s32 i = static_cast<s32>(Str.size()) - 1, j = 0; i >= 0; --i, ++j)
00484 {
00485 if (Str[i] == '.')
00486 {
00487 const s32 Count = (DecimalPlaces > 0 ? i + DecimalPlaces + 1 : i);
00488
00489 if (isFillBlanks && static_cast<s32>(DecimalPlaces) > j)
00490 return Str.left(Count) + string<T>::space(DecimalPlaces - j, '0');
00491
00492 return Str.left(Count);
00493 }
00494 }
00495
00496 if (isFillBlanks && DecimalPlaces > 0)
00497 return Str + "." + string<T>::space(DecimalPlaces, '0');
00498
00499 return Str;
00500 }
00501
00512 static string<T> numberSeperators(const string<T> &Str, const c8 Sep = ',')
00513 {
00514 std::basic_string<T> NewStr(Str.Str_);
00515
00516 s32 i = 3 - (NewStr.size() % 3);
00517
00518 for (typename std::basic_string<T>::iterator it = NewStr.begin(); it != NewStr.end(); ++it)
00519 {
00520 if (i == 3)
00521 {
00522 i = 0;
00523 if (it != NewStr.begin())
00524 {
00525 it = NewStr.insert(it, Sep);
00526 --i;
00527 }
00528 }
00529 ++i;
00530 }
00531
00532 return string<T>(NewStr);
00533 }
00534
00535
00536
00538 string<T> getPathPart() const
00539 {
00540 for (s32 i = static_cast<s32>(Str_.size()) - 1; i >= 0; --i)
00541 {
00542 if (Str_[i] == '/' || Str_[i] == '\\')
00543 return left(static_cast<u32>(i + 1));
00544 }
00545 return string<T>("");
00546 }
00547
00549 string<T> getExtensionPart() const
00550 {
00551 u32 j = 0;
00552
00553 for (s32 i = static_cast<s32>(Str_.size()) - 1; i >= 0; --i, ++j)
00554 {
00555 if (Str_[i] == '.')
00556 return right(j);
00557 }
00558
00559 return string<T>("");
00560 }
00561
00563 string<T> getFilePart() const
00564 {
00565 u32 j = 0;
00566
00567 for (s32 i = static_cast<s32>(Str_.size()) - 1; i >= 0; --i, ++j)
00568 {
00569 if (Str_[i] == '/' || Str_[i] == '\\')
00570 return right(j);
00571 }
00572
00573 return *this;
00574 }
00575
00576
00577 string<T> getStrictFilePart() const
00578 {
00579 s32 i, j, c = static_cast<s32>(Str_.size()) - 1;
00580
00581 for (i = j = c; i >= 0; --i)
00582 {
00583 if (j == c && Str_[i] == '.')
00584 j = i;
00585 else if (Str_[i] == '/' || Str_[i] == '\\')
00586 return section(static_cast<u32>(i + 1), static_cast<u32>(j));
00587 }
00588
00589 return *this;
00590 }
00591
00601 string<T> getRelativePath(string<T> RootPath) const
00602 {
00603 if (RootPath.empty())
00604 return Str_;
00605
00606 const T LastChar = RootPath[RootPath.size() - 1];
00607
00608 if (LastChar != '/' && LastChar != '\\')
00609 RootPath += "/";
00610
00611
00612 u32 i = 0, j = 0;
00613
00614 for (u32 c = std::min(Str_.size(), RootPath.Str_.size()); i < c; ++i)
00615 {
00616 if (string<T>::getLowerChar(Str_[i]) != string<T>::getLowerChar(RootPath.Str_[i]))
00617 {
00618 if ( !( ( Str_[i] == '/' || Str_[i] == '\\' ) &&
00619 ( RootPath.Str_[i] == '/' || RootPath.Str_[i] == '\\' ) ) )
00620 {
00621 break;
00622 }
00623 }
00624
00625 if (Str_[i] == '/' || Str_[i] == '\\')
00626 j = i;
00627 }
00628
00629
00630 ++j;
00631 string<T> NewStr = right(size() - j);
00632
00633
00634 for (; j < RootPath.size(); ++j)
00635 {
00636 if (RootPath[j] == '/' || RootPath[j] == '\\')
00637 NewStr = "../" + NewStr;
00638 }
00639
00640 return NewStr;
00641 }
00642
00647 void adjustPath()
00648 {
00649 *this = replace("\\", "/");
00650
00651
00652
00653
00654
00655
00656 *this = replace("../", "?");
00657 *this = replace("./", "");
00658 *this = replace("?", "../");
00659 }
00660
00661 string<c8> toAscii() const
00662 {
00663 string<c8> ascii;
00664 ascii.resize(Str_.size());
00665
00666 for (u32 i = 0; i < Str_.size(); ++i)
00667 ascii[i] = static_cast<c8>(Str_[i]);
00668
00669 return ascii;
00670 }
00671
00672 string<c16> toUnicode() const
00673 {
00674 string<c16> unicode;
00675 unicode.resize(Str_.size());
00676
00677 for (u32 i = 0; i < Str_.size(); ++i)
00678 unicode[i] = static_cast<c16>(Str_[i]);
00679
00680 return unicode;
00681 }
00682
00683 private:
00684
00685
00686
00687 std::basic_string<T> Str_;
00688
00689 };
00690
00691 typedef string<c8> stringc;
00692 typedef string<c16> stringw;
00693
00694
00695
00696
00698 template <typename T> stringc getHexString(const T &Number)
00699 {
00700 stringc Str;
00701
00702 for (s32 i = 2*sizeof(T) - 1; i >= 0; --i)
00703 Str += "0123456789ABCDEF"[((Number >> i*4) & 0xF)];
00704
00705 return Str;
00706 }
00707
00708 template <typename T> T getHexNumber(const io::stringc &Str)
00709 {
00710 T Result;
00711 std::stringstream SStr;
00712 SStr << std::hex << Str.str();
00713 SStr >> Result;
00714 return Result;
00715 }
00716
00717 template <typename T> string<T> operator + (const c8* cStr, const string<T> &spStr)
00718 {
00719 return string<T>(cStr) + spStr;
00720 }
00721
00723 template < class T, template < class TL, class Allocator = std::allocator<TL> > class L > void getListFromString(
00724 const stringc &Str, L<T> &List, s32 MaxCount = -1)
00725 {
00726 s32 Pos1 = 0, Pos2 = 0;
00727
00728
00729 while ( ( MaxCount == -1 || MaxCount > 0 ) && Pos1 < Str.size() - 1 && ( Pos1 = Str.find(";", Pos2) ) != -1 )
00730 {
00731 List.push_back(Str.section(Pos2, Pos1).val<T>());
00732 Pos2 = Pos1 + 1;
00733 if (MaxCount > 0)
00734 --MaxCount;
00735 }
00736 }
00737
00738 template <class T> void getListFromString(const stringc &Str, std::vector<T> &List, s32 MaxCount = -1)
00739 {
00740 getListFromString<T, std::vector>(Str, List, MaxCount);
00741 }
00742
00743 template <class T> void getListFromString(const stringc &Str, std::list<T> &List, s32 MaxCount = -1)
00744 {
00745 getListFromString<T, std::list>(Str, List, MaxCount);
00746 }
00747
00748
00749 }
00750
00751 }
00752
00753
00754 #endif
00755
00756
00757
00758