diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/algorithm.h | 21 | ||||
-rw-r--r-- | common/array.h | 78 | ||||
-rw-r--r-- | common/recorderfile.cpp | 4 | ||||
-rw-r--r-- | common/scummsys.h | 7 | ||||
-rw-r--r-- | common/str.cpp | 87 | ||||
-rw-r--r-- | common/str.h | 52 |
6 files changed, 219 insertions, 30 deletions
diff --git a/common/algorithm.h b/common/algorithm.h index cbd6eae708..13cdd9f991 100644 --- a/common/algorithm.h +++ b/common/algorithm.h @@ -270,5 +270,26 @@ T gcd(T a, T b) { #pragma warning(pop) #endif +/** + * Replacement algorithm for iterables. + * + * Replaces all occurrences of "original" in [begin, end) with occurrences of "replaced". + * + * @param[in, out] begin: First element to be examined. + * @param[in] end: Last element in the seubsection. Not examined. + * @param[in] original: Elements to be replaced. + * @param[in] replaced: Element to replace occurrences of "original". + * + * @note Usage examples and unit tests may be found in "test/common/algorithm.h" + */ +template<class It, class Dat> +void replace(It begin, It end, const Dat &original, const Dat &replaced) { + for (; begin != end; ++begin) { + if (*begin == original) { + *begin = replaced; + } + } +} + } // End of namespace Common #endif diff --git a/common/array.h b/common/array.h index db1a62ba34..e9b97aa38a 100644 --- a/common/array.h +++ b/common/array.h @@ -361,6 +361,84 @@ protected: }; +/** + * Double linked list with sorted nodes. + */ +template<class T> +class SortedArray : public Array<T> { +public: + typedef T *iterator; + typedef uint size_type; + + SortedArray(int (*comparator)(const void *, const void *)) { + _comparator = comparator; + } + + /** + * Inserts element at the sorted position. + */ + void insert(const T &element) { + if (!this->_size) { + this->insert_aux(this->_storage, &element, &element + 1); + return; + } + + T *where = (T *)bsearchMin(element, this->front(), this->_size, sizeof(T), _comparator); + insert(where, element); + } + + T &operator[](size_type idx) { + error("Operation not allowed with SortedArray"); + } + + void insert_at(size_type idx, const T &element) { + error("Operation not allowed with SortedArray"); + } + + void insert_at(size_type idx, const Array<T> &array) { + error("Operation not allowed with SortedArray"); + } + + void insert(iterator pos, const T &element) { + error("Operation not allowed with SortedArray"); + } + + void push_back(const T &element) { + error("Operation not allowed with SortedArray"); + } + + void push_back(const Array<T> &array) { + error("Operation not allowed with SortedArray"); + } + +private: + // Based on code Copyright (C) 2008-2009 Ksplice, Inc. + // Author: Tim Abbott <tabbott@ksplice.com> + // Licensed under GPLv2+ + void *bsearchMin(void *key, void *base, uint num, uint size_, + int (*cmp)(const void *key, const void *elt)) { + uint start_ = 0, end_ = num; + int result; + + while (start_ < end_) { + uint mid = start_ + (end_ - start_) / 2; + + result = cmp(key, (byte *)base + mid * size_); + if (result < 0) + end_ = mid; + else if (result > 0) + start_ = mid + 1; + else + return (void *)((byte *)base + mid * size_); + } + + return (void *)((byte *)base + start_ * size_); + } + +private: + int (*_comparator)(const void *, const void *); +}; + } // End of namespace Common #endif diff --git a/common/recorderfile.cpp b/common/recorderfile.cpp index 71f8272b44..04802aa0c8 100644 --- a/common/recorderfile.cpp +++ b/common/recorderfile.cpp @@ -30,6 +30,8 @@ #include "graphics/surface.h" #include "graphics/scaler.h" +#ifdef ENABLE_EVENTRECORDER + #define RECORD_VERSION 1 namespace Common { @@ -714,3 +716,5 @@ void PlaybackFile::checkRecordedMD5() { } + +#endif // ENABLE_EVENTRECORDER diff --git a/common/scummsys.h b/common/scummsys.h index 7c2978f173..3513ee2d7d 100644 --- a/common/scummsys.h +++ b/common/scummsys.h @@ -215,6 +215,10 @@ #include "config.h" #endif +// Now we need to adjust some settings when running tests +#ifdef COMPILING_TESTS +#undef ENABLE_EVENTRECORDER +#endif // In the following we configure various targets, in particular those // which can't use our "configure" tool and hence don't use config.h. @@ -251,6 +255,7 @@ #if defined(__DC__) || \ defined(__DS__) || \ + defined(__3DS__) || \ defined(__GP32__) || \ defined(IPHONE) || \ defined(__PLAYSTATION2__) || \ @@ -367,7 +372,7 @@ #endif #ifndef STRINGBUFLEN - #if defined(__N64__) || defined(__DS__) + #if defined(__N64__) || defined(__DS__) || defined(__3DS__) #define STRINGBUFLEN 256 #else #define STRINGBUFLEN 1024 diff --git a/common/str.cpp b/common/str.cpp index ae3a965c70..c41e958349 100644 --- a/common/str.cpp +++ b/common/str.cpp @@ -75,7 +75,7 @@ void String::initWithCStr(const char *str, uint32 len) { } String::String(const String &str) - : _size(str._size) { + : _size(str._size) { if (str.isStorageIntern()) { // String in internal storage: just copy it memcpy(_storage, str._storage, _builtinCapacity); @@ -91,7 +91,7 @@ String::String(const String &str) } String::String(char c) - : _size(0), _str(_storage) { + : _size(0), _str(_storage) { _storage[0] = c; _storage[1] = 0; @@ -132,24 +132,19 @@ void String::ensureCapacity(uint32 new_size, bool keep_old) { if (!isShared && new_size < curCapacity) return; - if (isShared && new_size < _builtinCapacity) { - // We share the storage, but there is enough internal storage: Use that. - newStorage = _storage; - newCapacity = _builtinCapacity; - } else { - // We need to allocate storage on the heap! - - // Compute a suitable new capacity limit - // If the current capacity is sufficient we use the same capacity - if (new_size < curCapacity) - newCapacity = curCapacity; - else - newCapacity = MAX(curCapacity * 2, computeCapacity(new_size+1)); - - // Allocate new storage - newStorage = new char[newCapacity]; - assert(newStorage); - } + // We need to allocate storage on the heap! + + // Compute a suitable new capacity limit + // If the current capacity is sufficient we use the same capacity + if (new_size < curCapacity) + newCapacity = curCapacity; + else + newCapacity = MAX(curCapacity * 2, computeCapacity(new_size+1)); + + // Allocate new storage + newStorage = new char[newCapacity]; + assert(newStorage); + // Copy old data if needed, elsewise reset the new storage. if (keep_old) { @@ -444,6 +439,58 @@ uint String::hash() const { return hashit(c_str()); } +void String::replace(uint32 pos, uint32 count, const String &str) { + replace(pos, count, str, 0, str._size); +} + +void String::replace(uint32 pos, uint32 count, const char *str) { + replace(pos, count, str, 0, strlen(str)); +} + +void String::replace(iterator begin, iterator end, const String &str) { + replace(begin - _str, end - begin, str._str, 0, str._size); +} + +void String::replace(iterator begin, iterator end, const char *str) { + replace(begin - _str, end - begin, str, 0, strlen(str)); +} + +void String::replace(uint32 posOri, uint32 countOri, const String &str, + uint32 posDest, uint32 countDest) { + replace(posOri, countOri, str._str, posDest, countDest); +} + +void String::replace(uint32 posOri, uint32 countOri, const char *str, + uint32 posDest, uint32 countDest) { + + ensureCapacity(_size + countDest - countOri, true); + + // Prepare string for the replaced text. + if (countOri < countDest) { + uint32 offset = countDest - countOri; ///< Offset to copy the characters + uint32 newSize = _size + offset; + _size = newSize; + + // Push the old characters to the end of the string + for (uint32 i = _size; i >= posOri + countDest; i--) + _str[i] = _str[i - offset]; + + } else if (countOri > countDest){ + uint32 offset = countOri - countDest; ///< Number of positions that we have to pull back + + // Pull the remainder string back + for (uint32 i = posOri + countDest; i < _size; i++) + _str[i] = _str[i + offset]; + + _size -= offset; + } + + // Copy the replaced part of the string + for (uint32 i = 0; i < countDest; i++) + _str[posOri + i] = str[posDest + i]; + +} + // static String String::format(const char *fmt, ...) { String output; diff --git a/common/str.h b/common/str.h index 1b41c481c7..9ada8aaaa0 100644 --- a/common/str.h +++ b/common/str.h @@ -46,6 +46,17 @@ namespace Common { class String { public: static const uint32 npos = 0xFFFFFFFF; + + typedef char value_type; + /** + * Unsigned version of the underlying type. This can be used to cast + * individual string characters to bigger integer types without sign + * extension happening. + */ + typedef unsigned char unsigned_type; + typedef char * iterator; + typedef const char * const_iterator; + protected: /** * The size of the internal storage. Increasing this means less heap @@ -222,6 +233,38 @@ public: void trim(); uint hash() const; + + /**@{ + * Functions to replace some amount of chars with chars from some other string. + * + * @note The implementation follows that of the STL's std::string: + * http://www.cplusplus.com/reference/string/string/replace/ + * + * @param pos Starting position for the replace in the original string. + * @param count Number of chars to replace from the original string. + * @param str Source of the new chars. + * @param posOri Same as pos + * @param countOri Same as count + * @param posDest Initial position to read str from. + * @param countDest Number of chars to read from str. npos by default. + */ + // Replace 'count' bytes, starting from 'pos' with str. + void replace(uint32 pos, uint32 count, const String &str); + // The same as above, but accepts a C-like array of characters. + void replace(uint32 pos, uint32 count, const char *str); + // Replace the characters in [begin, end) with str._str. + void replace(iterator begin, iterator end, const String &str); + // Replace the characters in [begin, end) with str. + void replace(iterator begin, iterator end, const char *str); + // Replace _str[posOri, posOri + countOri) with + // str._str[posDest, posDest + countDest) + void replace(uint32 posOri, uint32 countOri, const String &str, + uint32 posDest, uint32 countDest); + // Replace _str[posOri, posOri + countOri) with + // str[posDest, posDest + countDest) + void replace(uint32 posOri, uint32 countOri, const char *str, + uint32 posDest, uint32 countDest); + /**@}*/ /** * Print formatted data into a String object. Similar to sprintf, @@ -238,15 +281,6 @@ public: static String vformat(const char *fmt, va_list args); public: - typedef char value_type; - /** - * Unsigned version of the underlying type. This can be used to cast - * individual string characters to bigger integer types without sign - * extension happening. - */ - typedef unsigned char unsigned_type; - typedef char * iterator; - typedef const char * const_iterator; iterator begin() { // Since the user could potentially |