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