/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * 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 2 * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #ifndef COMMON_USTR_H #define COMMON_USTR_H #include "common/scummsys.h" #include "common/str-enc.h" namespace Common { class String; /** * Very simple string class for UTF-32 strings in ScummVM. The main intention * behind this class is to feature a simple way of displaying UTF-32 strings * through the Graphics::Font API. * * Please note that operations like equals, deleteCharacter, toUppercase, etc. * are only very simplified convenience operations. They might not fully work * as you would expect for a proper UTF-32 string class. * * The presence of \0 characters in the string will cause undefined * behavior in some operations. */ class U32String { public: static const uint32 npos = 0xFFFFFFFF; typedef uint32 value_type; typedef uint32 unsigned_type; private: /** * The size of the internal storage. Increasing this means less heap * allocations are needed, at the cost of more stack memory usage, * and of course lots of wasted memory. */ static const uint32 _builtinCapacity = 32; /** * Length of the string. */ uint32 _size; /** * Pointer to the actual string storage. Either points to _storage, * or to a block allocated on the heap via malloc. */ value_type *_str; union { /** * Internal string storage. */ value_type _storage[_builtinCapacity]; /** * External string storage data -- the refcounter, and the * capacity of the string _str points to. */ struct { mutable int *_refCount; uint32 _capacity; } _extern; }; inline bool isStorageIntern() const { return _str == _storage; } public: /** Construct a new empty string. */ U32String() : _size(0), _str(_storage) { _storage[0] = 0; } /** Construct a new string from the given NULL-terminated C string. */ explicit U32String(const value_type *str); /** Construct a new string containing exactly len characters read from address str. */ U32String(const value_type *str, uint32 len); /** Construct a new string containing the characters between beginP (including) and endP (excluding). */ U32String(const value_type *beginP, const value_type *endP); /** Construct a copy of the given string. */ U32String(const U32String &str); /** Construct a new string from the given NULL-terminated C string. */ explicit U32String(const char *str); /** Construct a new string containing exactly len characters read from address str. */ U32String(const char *str, uint32 len); /** Construct a new string containing the characters between beginP (including) and endP (excluding). */ U32String(const char *beginP, const char *endP); /** Construct a copy of the given string. */ U32String(const String &str); ~U32String(); U32String &operator=(const U32String &str); U32String &operator=(const String &str); U32String &operator=(const value_type *str); U32String &operator=(const char *str); U32String &operator+=(const U32String &str); U32String &operator+=(value_type c); bool operator==(const U32String &x) const; bool operator==(const String &x) const; bool operator==(const value_type *x) const; bool operator==(const char *x) const; bool operator!=(const U32String &x) const; bool operator!=(const String &x) const; bool operator!=(const value_type *x) const; bool operator!=(const char *x) const; /** * Compares whether two U32String are the same based on memory comparison. * This does *not* do comparison based on canonical equivalence. */ bool equals(const U32String &x) const; /** * Compares whether two U32String are the same based on memory comparison. * This does *not* do comparison based on canonical equivalence. */ bool equals(const String &x) const; bool contains(value_type x) const; inline const value_type *c_str() const { return _str; } inline uint32 size() const { return _size; } inline bool empty() const { return (_size == 0); } value_type operator[](int idx) const { assert(_str && idx >= 0 && idx < (int)_size); return _str[idx]; } /** Set character c at position p, replacing the previous character there. */ void setChar(value_type c, uint32 p) { _str[p] = c; } /** * Removes the value at position p from the string. * Using this on decomposed characters will not remove the whole * character! */ void deleteChar(uint32 p); /** Remove the last character from the string. */ void deleteLastChar(); /** Remove all characters from position p to the p + len. If len = String::npos, removes all characters to the end */ void erase(uint32 p, uint32 len = npos); /** Clears the string, making it empty. */ void clear(); /** * Convert all characters in the string to lowercase. * * Be aware that this only affects the case of ASCII characters. All * other characters will not be touched at all. */ void toLowercase(); /** * Convert all characters in the string to uppercase. * * Be aware that this only affects the case of ASCII characters. All * other characters will not be touched at all. */ void toUppercase(); uint32 find(value_type x, uint32 pos = 0) const; uint32 find(const U32String &str, uint32 pos = 0) const; typedef value_type * iterator; typedef const value_type * const_iterator; iterator begin() { // Since the user could potentially // change the string via the returned // iterator we have to assure we are // pointing to a unique storage. makeUnique(); return _str; } iterator end() { return begin() + size(); } const_iterator begin() const { return _str; } const_iterator end() const { return begin() + size(); } /** Python-like method **/ String encode(CodePage page = kUtf8) const; private: void makeUnique(); void ensureCapacity(uint32 new_size, bool keep_old); void incRefCount() const; void decRefCount(int *oldRefCount); void initWithCStr(const value_type *str, uint32 len); void initWithCStr(const char *str, uint32 len); void encodeUTF8(String &dst) const; void encodeOneByte(String &dst, CodePage page) const; }; U32String operator+(const U32String &x, const U32String &y); } // End of namespace Common #endif