BALL
1.4.1
|
00001 // -*- Mode: C++; tab-width: 2; -*- 00002 // vi: set ts=2: 00003 // 00004 // $Id: string.h,v 1.56 2005/12/23 17:01:43 amoll Exp $ 00005 // 00006 00007 #ifndef BALL_DATATYPE_STRING_H 00008 #define BALL_DATATYPE_STRING_H 00009 00010 #ifndef BALL_CONFIG_CONFIG_H 00011 # include <BALL/CONFIG/config.h> 00012 #endif 00013 #ifndef BALL_COMMON_GLOBAL_H 00014 # include <BALL/COMMON/global.h> 00015 #endif 00016 #ifndef BALL_COMMON_CREATE_H 00017 # include <BALL/COMMON/create.h> 00018 #endif 00019 #ifndef BALL_COMMON_MACROS_H 00020 # include <BALL/COMMON/macros.h> 00021 #endif 00022 #ifndef BALL_COMMON_EXCEPTION_H 00023 # include <BALL/COMMON/exception.h> 00024 #endif 00025 #ifndef BALL_COMMON_DEBUG_H 00026 # include <BALL/COMMON/debug.h> 00027 #endif 00028 00029 #include <string> 00030 #include <ctype.h> 00031 #include <errno.h> 00032 #include <stdlib.h> 00033 #include <string.h> 00034 #include <iostream> 00035 #include <vector> 00036 00037 #ifdef BALL_HAS_SSTREAM 00038 # include <sstream> 00039 #else 00040 # include <strstream> 00041 #endif 00042 00043 using std::string; 00044 00045 class QString; 00046 class QByteArray; 00047 00048 namespace BALL 00049 { 00050 // forward declaration 00051 class Substring; 00052 00059 00063 class BALL_EXPORT String 00064 : public string 00065 { 00067 friend class Substring; 00068 00069 public: 00070 00071 // String has no copy constructor taking String&, bool as arguments. 00072 // the compiler would confuse it with another copy constructor, 00073 // cast true to 1 and copy only the string from the second character 00074 // on! We could use BALL_CREATE_NODEEP, but this leads to trouble with 00075 // inline constructors, so we code it by hand (here and in string.C) 00076 virtual void* create(bool /* deep */ = true, bool empty = false) const; 00077 00080 00088 enum CompareMode 00089 { 00091 CASE_SENSITIVE = 0, 00092 00094 CASE_INSENSITIVE = 1 00095 }; 00096 00102 static const Size EndPos; 00103 00105 00111 00113 static const char* CHARACTER_CLASS__ASCII_ALPHA; 00114 00116 static const char* CHARACTER_CLASS__ASCII_ALPHANUMERIC; 00117 00119 static const char* CHARACTER_CLASS__ASCII_LOWER; 00120 00122 static const char* CHARACTER_CLASS__ASCII_UPPER; 00123 00125 static const char* CHARACTER_CLASS__ASCII_NUMERIC; 00126 00128 static const char* CHARACTER_CLASS__ASCII_FLOAT; 00129 00141 static const char* CHARACTER_CLASS__WHITESPACE; 00142 00145 static const char* CHARACTER_CLASS__QUOTES; 00146 00148 00151 00153 String(); 00154 00156 String(const string& string); 00157 00158 #ifdef BALL_STD_STRING_HAS_RVALUE_REFERENCES 00159 00160 String(String&& s); 00161 00163 String(string&& s); 00164 00166 String& operator=(String&& s); 00167 00169 String& operator=(string&& s); 00170 #endif 00171 00173 explicit String(const QString& string); 00174 00176 explicit String(const QByteArray& string); 00177 00183 String(const String& s, Index from, Size len = EndPos); 00184 00194 String(const char* char_ptr, Index from = 0, Size len = EndPos); 00195 00206 String(Size buffer_size, const char* format, ... ); 00207 00213 #ifdef BALL_HAS_SSTREAM 00214 String(std::stringstream& s); 00215 #else 00216 String(std::strstream& s); 00217 #endif 00218 00221 String(const char c, Size len = 1); 00222 00224 String(const unsigned char uc); 00225 00227 String(short s); 00228 00230 String(unsigned short us); 00231 00233 String(int i); 00234 00236 String(unsigned int ui); 00237 00239 String(long l); 00240 00242 String(unsigned long); 00243 00244 #ifdef BALL_ALLOW_LONG64_TYPE_OVERLOADS 00245 00246 String(LongIndex l); 00247 00249 String(LongSize); 00250 #endif 00251 00253 String(float f); 00254 00256 String(double d); 00257 00259 virtual ~String(); 00260 00262 void destroy(); 00263 00265 virtual void clear(); 00267 00271 00273 void set(const String& s); 00274 00279 void set(const String& string, Index from, Size len = EndPos); 00280 00286 void set(const char* char_ptr, Index from = 0, Size len = EndPos); 00287 00292 void set(Size buffer_size, const char *format, ...); 00293 00297 #ifdef BALL_HAS_SSTREAM 00298 void set(std::stringstream& s); 00299 #else 00300 void set(std::strstream& s); 00301 #endif 00302 00304 void set(char c, Size len = 1); 00305 00307 void set(unsigned char uc); 00308 00310 void set(short s); 00311 00313 void set(unsigned short us); 00314 00316 void set(int i); 00317 00319 void set(unsigned int ui); 00320 00322 void set(long l); 00323 00325 void set(unsigned long ul); 00326 00327 #ifdef BALL_ALLOW_LONG64_TYPE_OVERLOADS 00328 00329 void set(LongIndex l); 00330 00332 void set(LongSize ul); 00333 #endif 00334 00336 void set(float f); 00337 00339 void set(double d); 00340 00350 void get(char* char_ptr, Index from = 0, Size len = EndPos) const; 00351 00353 const String& operator = (const String& s); 00354 00358 const String& operator = (const char* pc); 00359 00363 #ifdef BALL_HAS_SSTREAM 00364 const String& operator = (std::stringstream& s); 00365 #else 00366 const String& operator = (std::strstream& s); 00367 #endif 00368 00370 const String& operator = (char c); 00371 00373 const String& operator = (unsigned char uc); 00374 00376 const String& operator = (short s); 00377 00379 const String& operator = (unsigned short us); 00380 00382 const String& operator = (int i); 00383 00385 const String& operator = (unsigned int ui); 00386 00388 const String& operator = (long l); 00389 00391 const String& operator = (unsigned long ul); 00392 00393 #ifdef BALL_ALLOW_LONG64_TYPE_OVERLOADS 00394 00395 const String& operator = (LongIndex l); 00396 00398 const String& operator = (LongSize ul); 00399 #endif 00400 00402 const String& operator = (float f); 00403 00405 const String& operator = (double d); 00407 00414 00415 static void setCompareMode(CompareMode compare_mode); 00416 00418 static CompareMode getCompareMode(); 00420 00424 00429 bool toBool() const; 00430 00432 char toChar() const; 00433 00435 unsigned char toUnsignedChar() const; 00436 00440 short toShort() const; 00441 00445 unsigned short toUnsignedShort() const; 00446 00450 int toInt() const; 00451 00455 unsigned int toUnsignedInt() const; 00456 00460 long toLong() const; 00461 00465 unsigned long toUnsignedLong() const; 00466 00470 float toFloat() const; 00471 00475 double toDouble() const; 00477 00478 00482 00487 void toLower(Index from = 0, Size len = EndPos); 00488 00493 void toUpper(Index from = 0, Size len = EndPos); 00494 00496 00499 00504 Substring getSubstring(Index from = 0, Size len = EndPos) const; 00505 00510 Substring operator () (Index from, Size len = EndPos) const; 00511 00514 Substring before(const String& s, Index from = 0) const; 00515 00518 Substring through(const String& s, Index from = 0) const; 00519 00522 Substring from(const String& s, Index from = 0) const; 00523 00526 Substring after(const String& s, Index from = 0) const; 00527 00529 00532 00536 Size countFields(const char* delimiters = CHARACTER_CLASS__WHITESPACE) const; 00537 00541 Size countFieldsQuoted(const char* delimiters = CHARACTER_CLASS__WHITESPACE, 00542 const char* quotes = CHARACTER_CLASS__QUOTES) const; 00543 00548 String getField(Index index, const char* delimiters = CHARACTER_CLASS__WHITESPACE, Index* from = 0) const; 00549 00554 String getFieldQuoted(Index index, const char* delimiters = CHARACTER_CLASS__WHITESPACE, 00555 const char* quotes = CHARACTER_CLASS__QUOTES, Index* from = 0) const; 00556 00561 Size split(String string_array[], Size array_size, const char* delimiters = CHARACTER_CLASS__WHITESPACE, Index from = 0) const; 00562 00568 Size split(std::vector<String>& strings, const char* delimiters = CHARACTER_CLASS__WHITESPACE, Index from = 0) const; 00569 00577 Size splitQuoted(std::vector<String>& strings, const char* delimiters = CHARACTER_CLASS__WHITESPACE, 00578 const char* quotes = CHARACTER_CLASS__QUOTES, Index from = 0) const; 00579 00581 00584 00591 String& trimLeft(const char* trimmed = CHARACTER_CLASS__WHITESPACE); 00592 00599 String& trimRight(const char* trimmed = CHARACTER_CLASS__WHITESPACE); 00600 00604 String& trim(const char* trimmed = CHARACTER_CLASS__WHITESPACE); 00605 00606 // ????? 00610 String trim(const char* trimmed = CHARACTER_CLASS__WHITESPACE) const; 00611 00613 String& truncate(Size size); 00614 00616 Substring left(Size len) const; 00617 00619 Substring right(Size len) const; 00620 00629 Substring instr(const String& pattern, Index from = 0) const; 00630 00632 00635 00636 // NOTE: please, please, pretty please, only try to optimize away operator+ definitions 00637 // if you *really* know what you are doing. We didn't, and we definitely don't want 00638 // to touch this stinking heap of C++ garbage ever again! 00639 // (dstoeckel & anhi) 00641 BALL_EXPORT 00642 friend String operator + (const String& s1, const string& s2); 00643 00645 BALL_EXPORT 00646 friend String operator + (const string& s1, const String& s2); 00647 00649 BALL_EXPORT 00650 friend String operator + (const String& s1, const String& s2); 00651 00653 BALL_EXPORT 00654 friend String operator + (const String& s1, const char* char_ptr); 00655 00657 BALL_EXPORT 00658 friend String operator + (const char* char_ptr, const String& s); 00659 00661 BALL_EXPORT 00662 friend String operator + (const String& s, char c); 00663 00665 BALL_EXPORT 00666 friend String operator + (char c, const String& s); 00667 00668 #ifdef BALL_STD_STRING_HAS_RVALUE_REFERENCES 00669 00670 BALL_EXPORT 00671 friend String operator + (String&& s1, const string& s2); 00672 00674 BALL_EXPORT 00675 friend String operator + (String&& s1, const String& s2); 00676 00678 BALL_EXPORT 00679 friend String operator + (String&& s1, String&& s2); 00680 00681 BALL_EXPORT 00682 friend String operator + (const String& s1, string&& s2); 00683 00684 BALL_EXPORT 00685 friend String operator + (string&& s1, const String& s2); 00686 00687 BALL_EXPORT 00688 friend String operator + (const string& s1, String&& s2); 00689 00691 BALL_EXPORT 00692 friend String operator + (const String& s1, String&& s2); 00693 00695 BALL_EXPORT 00696 friend String operator + (String&& s1, const char* char_ptr); 00697 00699 BALL_EXPORT 00700 friend String operator + (const char* char_ptr, String&& s); 00701 00703 BALL_EXPORT 00704 friend String operator + (String&& s, char c); 00705 00707 BALL_EXPORT 00708 friend String operator + (char c, String&& s); 00709 #endif 00710 00712 void swap(String& s); 00713 00723 String& reverse(Index from = 0, Size len = EndPos); 00724 00728 Size substitute(const String& to_replace, const String& replacing); 00729 00731 00735 00737 bool has(char c) const; 00738 00740 bool hasSubstring(const String& s, Index from = 0) const; 00741 00743 bool hasPrefix(const String& s) const; 00744 00746 bool hasSuffix(const String& s) const; 00747 00749 bool isEmpty() const; 00750 00754 bool isAlpha() const; 00755 00759 bool isAlnum() const; 00760 00764 bool isDigit() const; 00765 00770 bool isFloat() const; 00771 00775 bool isSpace() const; 00776 00781 bool isWhitespace() const; 00782 00784 static bool isAlpha(char c); 00785 00787 static bool isAlnum(char c); 00788 00790 static bool isDigit(char c); 00791 00793 static bool isSpace(char c); 00794 00798 static bool isWhitespace(char c); 00799 00801 00804 00806 String encodeBase64(); 00807 00811 String decodeBase64(); 00812 00814 00817 00822 int compare(const String& string, Index from = 0) const; 00823 00828 int compare(const String& string, Index from, Size len) const; 00829 00830 00836 int compare(const char* char_ptr, Index from = 0) const; 00837 00843 int compare(const char* char_ptr, Index from, Size len) const; 00844 00849 int compare(char c, Index from = 0) const; 00850 00852 bool operator == (const String& string) const; 00853 00855 bool operator != (const String& string) const; 00856 00858 bool operator < (const String& string) const; 00859 00861 bool operator <= (const String& string) const; 00862 00864 bool operator >= (const String& string) const; 00865 00867 bool operator > (const String& string) const; 00868 00872 BALL_EXPORT 00873 friend bool operator == (const char* char_ptr, const String& string); 00874 00878 BALL_EXPORT 00879 friend bool operator != (const char* char_ptr, const String& string); 00880 00884 BALL_EXPORT 00885 friend bool operator < (const char* char_ptr, const String& string); 00886 00890 BALL_EXPORT 00891 friend bool operator <= (const char* char_ptr, const String& string); 00892 00896 BALL_EXPORT 00897 friend bool operator > (const char* char_ptr, const String& string); 00898 00902 BALL_EXPORT 00903 friend bool operator >= (const char* char_ptr, const String& string); 00904 00908 bool operator == (const char* char_ptr) const; 00909 00913 bool operator != (const char* char_ptr) const; 00914 00918 bool operator < (const char* char_ptr) const; 00919 00923 bool operator <= (const char* char_ptr) const; 00924 00928 bool operator > (const char* char_ptr) const; 00929 00933 bool operator >= (const char* char_ptr) const; 00934 00936 BALL_EXPORT 00937 friend bool operator == (char c, const String& string); 00938 00940 BALL_EXPORT 00941 friend bool operator != (char c, const String& string); 00942 00944 BALL_EXPORT 00945 friend bool operator < (char c, const String& string); 00946 00948 BALL_EXPORT 00949 friend bool operator <= (char c, const String& string); 00950 00952 BALL_EXPORT 00953 friend bool operator > (char c, const String& string); 00954 00956 friend bool operator >= (char c, const String& string); 00957 00959 bool operator == (char c) const; 00960 00962 bool operator != (char c) const; 00963 00965 bool operator < (char c) const; 00966 00968 bool operator <= (char c) const; 00969 00971 bool operator > (char c) const; 00972 00974 bool operator >= (char c) const; 00975 00977 00980 00982 bool isValid() const; 00983 00985 void dump(std::ostream& s = std::cout, Size depth = 0) const; 00986 00988 00991 00993 std::istream& getline(std::istream& s = std::cin, char delimiter = '\n'); 00994 00996 BALL_EXPORT 00997 friend std::istream& getline(std::istream& s, String& string, char delimiter = '\n'); 00998 01000 01002 static const String EMPTY; 01003 01004 protected: 01005 01006 // the validate... methods check perform a thorough 01007 // index checking and an index translation 01008 // Indices below zero are interpreted as indices 01009 // relative to the end of the string 01010 // All methods throw IndexUnder|Overflow exceptions 01011 // 01012 void validateIndex_(Index& index) const; 01013 01014 void validateRange_(Index& from, Size& len) const; 01015 01016 static void validateCharPtrRange_(Index& from, Size& len, const char* char_ptr); 01017 01018 static void valudateCharPtrIndex_(Index& index); 01019 01020 private: 01021 01022 static int compareAscendingly_(const char* a, const char* b); 01023 01024 static int compareDescendingly_(const char* a, const char* b); 01025 01026 static CompareMode compare_mode_; 01027 01028 static char B64Chars_[64]; 01029 01030 static int Index_64_[128]; 01031 }; 01032 01041 class BALL_EXPORT Substring 01042 { 01043 friend class String; 01044 01045 public: 01046 01047 BALL_CREATE_DEEP(Substring) 01048 01049 01052 01057 class BALL_EXPORT UnboundSubstring 01058 : public Exception::GeneralException 01059 { 01060 public: 01061 UnboundSubstring(const char* file, int line); 01062 }; 01063 01069 class BALL_EXPORT InvalidSubstring 01070 : public Exception::GeneralException 01071 { 01072 public: 01073 InvalidSubstring(const char* file, int line); 01074 }; 01075 01077 01080 01084 Substring(); 01085 01091 Substring(const Substring& substring, bool deep = true); 01092 01100 Substring(const String& string, Index from = 0, Size len = String::EndPos); 01101 01105 virtual ~Substring(); 01106 01111 void destroy(); 01112 01117 virtual void clear(); 01118 01120 01123 01128 operator String() const; 01129 01134 String toString() const; 01135 01137 01140 01149 Substring& bind(const String& string, Index from = 0, Size len = String::EndPos); 01150 01156 Substring& bind(const Substring& substring, Index from = 0, Size len = String::EndPos); 01157 01159 void unbind(); 01160 01162 String* getBoundString(); 01163 01165 const String* getBoundString() const 01166 ; 01167 01169 01172 01176 void set(const String& string); 01177 01181 void set(const Substring& s); 01182 01188 void set(const char* char_ptr, Size size = String::EndPos); 01189 01193 const Substring& operator = (const String& string); 01194 01198 const Substring& operator = (const Substring& substring); 01199 01204 const Substring& operator = (const char* char_ptr); 01205 01207 01210 01214 char* c_str(); 01215 01219 const char* c_str() const; 01220 01225 Index getFirstIndex() const; 01226 01231 Index getLastIndex() const; 01232 01234 Size size() const; 01235 01241 char& operator [] (Index index); 01242 01248 char operator [] (Index index) const; 01249 01253 Substring& toLower(); 01254 01258 Substring& toUpper(); 01259 01261 01264 01266 bool isBound() const; 01267 01269 bool isEmpty() const; 01270 01272 01275 01279 bool operator == (const Substring& substring) const; 01280 01284 bool operator != (const Substring& substring) const; 01285 01289 bool operator == (const String& string) const; 01290 01294 bool operator != (const String& string) const; 01295 01299 BALL_EXPORT 01300 friend bool operator == (const String& string, const Substring& substring); 01301 01305 BALL_EXPORT 01306 friend bool operator != (const String& string, const Substring& substring); 01307 01312 bool operator == (const char* char_ptr) const; 01313 01318 bool operator != (const char* char_ptr) const; 01319 01323 bool operator == (char c) const; 01324 01328 bool operator != (char c) const; 01329 01331 01334 01336 BALL_EXPORT 01337 friend std::ostream& operator << (std::ostream& s, const Substring& substring); 01338 01340 01343 01348 bool isValid() const; 01349 01353 void dump(std::ostream& s = std::cout, Size depth = 0) const; 01354 01356 01357 protected: 01358 01359 // throws IndexUnderflow|IndexOverflow 01360 void validateRange_(Index& from, Size& len) const; 01361 01362 private: 01363 01364 /*_ @name Attributes 01365 */ 01366 //_@{ 01367 01368 //_ pointer to the bound String 01369 String* bound_; 01370 01371 //_ start index in the bound String 01372 Index from_; 01373 01374 //_ end index in the bound String 01375 Index to_; 01376 //_@} 01377 }; 01378 01380 01381 # ifndef BALL_NO_INLINE_FUNCTIONS 01382 # include <BALL/DATATYPE/string.iC> 01383 # endif 01384 } // namespace BALL 01385 01386 #endif // BALL_DATATYPE_STRING_H