1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef COMMON_BASE_STRING_H 24 #define COMMON_BASE_STRING_H 25 26 #include "common/scummsys.h" 27 #include "common/str-enc.h" 28 29 #include <stdarg.h> 30 31 namespace Common { 32 template<class T> 33 class BaseString { 34 public: 35 static void releaseMemoryPoolMutex(); 36 37 static const uint32 npos = 0xFFFFFFFF; 38 typedef T value_type; 39 typedef T * iterator; 40 typedef const T * const_iterator; 41 42 protected: 43 /** 44 * The size of the internal storage. Increasing this means less heap 45 * allocations are needed, at the cost of more stack memory usage, 46 * and of course lots of wasted memory. 47 */ 48 static const uint32 _builtinCapacity = 32 - (sizeof(uint32) + sizeof(char *)) / sizeof(value_type); 49 50 /** 51 * Length of the string. Stored to avoid having to call strlen 52 * a lot. Yes, we limit ourselves to strings shorter than 4GB -- 53 * on purpose :-). 54 */ 55 uint32 _size; 56 57 /** 58 * Pointer to the actual string storage. Either points to _storage, 59 * or to a block allocated on the heap via malloc. 60 */ 61 value_type *_str; 62 63 64 union { 65 /** 66 * Internal string storage. 67 */ 68 value_type _storage[_builtinCapacity]; 69 /** 70 * External string storage data -- the refcounter, and the 71 * capacity of the string _str points to. 72 */ 73 struct { 74 mutable int *_refCount; 75 uint32 _capacity; 76 } _extern; 77 }; 78 isStorageIntern()79 inline bool isStorageIntern() const { 80 return _str == _storage; 81 } 82 83 public: 84 /** Construct a new empty string. */ BaseString()85 BaseString() : _size(0), _str(_storage) { _storage[0] = 0; } 86 87 /** Construct a copy of the given string. */ 88 BaseString(const BaseString &str); 89 90 /** Construct a new string from the given NULL-terminated C string. */ 91 explicit BaseString(const value_type *str); 92 93 /** Construct a new string containing exactly len characters read from address str. */ 94 BaseString(const value_type *str, uint32 len); 95 96 /** Construct a new string containing the characters between beginP (including) and endP (excluding). */ 97 BaseString(const value_type *beginP, const value_type *endP); 98 99 bool operator==(const BaseString &x) const; 100 bool operator==(const value_type *x) const; 101 bool operator!=(const BaseString &x) const; 102 bool operator!=(const value_type *x) const; 103 104 bool operator<(const BaseString &x) const; 105 bool operator<(const value_type *x) const; 106 bool operator<=(const BaseString &x) const; 107 bool operator<=(const value_type *x) const; 108 bool operator>(const BaseString &x) const; 109 bool operator>(const value_type *x) const; 110 bool operator>=(const BaseString &x) const; 111 bool operator>=(const value_type *x) const; 112 113 /** 114 * Compares whether two BaseString are the same based on memory comparison. 115 * This does *not* do comparison based on canonical equivalence. 116 */ 117 bool equals(const BaseString &x) const; 118 bool equals(const value_type *x) const; 119 bool equalsC(const char *x) const; 120 int compareTo(const BaseString &x) const; // strcmp clone 121 int compareTo(const value_type *x) const; // strcmp clone 122 int compareToC(const char *x) const; // strcmp clone 123 124 /** Set character c at position p, replacing the previous character there. */ 125 void setChar(value_type c, uint32 p); 126 127 /** 128 * Removes the value at position p from the string. 129 * Using this on decomposed characters will not remove the whole 130 * character! 131 */ 132 void deleteChar(uint32 p); 133 134 /** Remove the last character from the string. */ 135 void deleteLastChar(); 136 137 /** Remove all characters from position p to the p + len. If len = String::npos, removes all characters to the end */ 138 void erase(uint32 p, uint32 len = npos); 139 140 /** Erases the character at the given iterator location */ 141 iterator erase(iterator it); 142 143 /** Clears the string, making it empty. */ 144 void clear(); 145 begin()146 iterator begin() { 147 // Since the user could potentially 148 // change the string via the returned 149 // iterator we have to assure we are 150 // pointing to a unique storage. 151 makeUnique(); 152 153 return _str; 154 } 155 end()156 iterator end() { 157 return begin() + size(); 158 } 159 begin()160 const_iterator begin() const { 161 return _str; 162 } 163 end()164 const_iterator end() const { 165 return begin() + size(); 166 } 167 c_str()168 inline const value_type *c_str() const { return _str; } size()169 inline uint size() const { return _size; } 170 empty()171 inline bool empty() const { return (_size == 0); } firstChar()172 value_type firstChar() const { return (_size > 0) ? _str[0] : 0; } lastChar()173 value_type lastChar() const { return (_size > 0) ? _str[_size - 1] : 0; } 174 175 value_type operator[](int idx) const { 176 assert(_str && idx >= 0 && idx < (int)_size); 177 return _str[idx]; 178 } 179 180 /** 181 * Checks if a given string is present in the internal string or not. 182 */ 183 bool contains(const BaseString &otherString) const; 184 bool contains(value_type x) const; 185 186 /** Insert character c before position p. */ 187 void insertChar(value_type c, uint32 p); 188 void insertString(const value_type *s, uint32 p); 189 void insertString(const BaseString &s, uint32 p); 190 191 /** Finds the index of a character in the string */ 192 uint32 find(value_type x, uint32 pos = 0) const; 193 /** Does a find for the passed string */ 194 size_t find(const value_type *s, uint32 pos = 0) const; 195 uint32 find(const BaseString &str, uint32 pos = 0) const; 196 197 /** 198 * Wraps the text in the string to the given line maximum. Lines will be 199 * broken at any whitespace character. New lines are assumed to be 200 * represented using '\n'. 201 * 202 * This is a very basic line wrap which does not perform tab stop 203 * calculation, consecutive whitespace collapsing, auto-hyphenation, or line 204 * balancing. 205 */ 206 void wordWrap(const uint32 maxLength); 207 208 /** Return uint64 corrensponding to String's contents. */ 209 uint64 asUint64() const; 210 211 /** Return uint64 corrensponding to String's contents. This variant recognizes 0 (oct) and 0x (hex) prefixes. */ 212 uint64 asUint64Ext() const; 213 214 /** 215 * Convert all characters in the string to lowercase. 216 * 217 * Be aware that this only affects the case of ASCII characters. All 218 * other characters will not be touched at all. 219 */ 220 void toLowercase(); 221 222 /** 223 * Convert all characters in the string to uppercase. 224 * 225 * Be aware that this only affects the case of ASCII characters. All 226 * other characters will not be touched at all. 227 */ 228 void toUppercase(); 229 230 /** 231 * Removes trailing and leading whitespaces. Uses isspace() to decide 232 * what is whitespace and what not. 233 */ 234 void trim(); 235 236 uint hash() const; 237 238 protected: 239 ~BaseString(); 240 241 void makeUnique(); 242 void ensureCapacity(uint32 new_size, bool keep_old); 243 void incRefCount() const; 244 void decRefCount(int *oldRefCount); 245 void initWithValueTypeStr(const value_type *str, uint32 len); 246 247 void assignAppend(const value_type *str); 248 void assignAppend(value_type c); 249 void assignAppend(const BaseString &str); 250 void assign(const BaseString &str); 251 void assign(value_type c); 252 void assign(const value_type *str); 253 254 bool pointerInOwnBuffer(const value_type *str) const; 255 256 uint getUnsignedValue(uint pos) const; 257 }; 258 } 259 #endif 260