Ticket #8658: stl_like_algorithm_v1.patch
File stl_like_algorithm_v1.patch, 30.9 KB (added by , 17 years ago) |
---|
-
test/common/array.h
59 59 TS_ASSERT( array[1] == 33 ); 60 60 TS_ASSERT( array[2] == -11 ); 61 61 } 62 63 void test_insert_at( void ) 64 { 65 Common::Array<int> array; 66 67 // First of all some data 68 array.push_back(-12); 69 array.push_back(17); 70 array.push_back(25); 71 array.push_back(-11); 72 73 // Insert some data 74 array.insert_at(2, 33); 75 76 TS_ASSERT( array[0] == -12 ); 77 TS_ASSERT( array[1] == 17 ); 78 TS_ASSERT( array[2] == 33 ); 79 TS_ASSERT( array[3] == 25 ); 80 TS_ASSERT( array[4] == -11 ); 81 } 82 83 void test_remove_at( void ) 84 { 85 Common::Array<int> array; 86 87 // First of all some data 88 array.push_back(-12); 89 array.push_back(17); 90 array.push_back(33); 91 array.push_back(25); 92 array.push_back(-11); 93 94 // Remove some data 95 array.remove_at(1); 96 97 TS_ASSERT( array[0] == -12 ); 98 TS_ASSERT( array[1] == 33 ); 99 TS_ASSERT( array[2] == 25 ); 100 TS_ASSERT( array[3] == -11 ); 101 } 102 103 void test_push_back( void ) 104 { 105 Common::Array<int> array1, array2; 106 107 // Some data for both 108 array1.push_back(-3); 109 array1.push_back(5); 110 array1.push_back(9); 111 112 array2.push_back(3); 113 array2.push_back(-2); 114 array2.push_back(-131); 115 116 array1.push_back(array2); 117 118 TS_ASSERT( array1[0] == -3 ); 119 TS_ASSERT( array1[1] == 5 ); 120 TS_ASSERT( array1[2] == 9 ); 121 TS_ASSERT( array1[3] == 3 ); 122 TS_ASSERT( array1[4] == -2 ); 123 TS_ASSERT( array1[5] == -131 ); 124 } 125 126 void test_copy_constructor( void ) 127 { 128 Common::Array<int> array1; 129 130 // Some data for both 131 array1.push_back(-3); 132 array1.push_back(5); 133 array1.push_back(9); 134 135 Common::Array<int> array2(array1); 136 137 TS_ASSERT( array2[0] == -3 ); 138 TS_ASSERT( array2[1] == 5 ); 139 TS_ASSERT( array2[2] == 9 ); 140 } 62 141 }; -
gui/browser.cpp
27 27 #include "common/config-manager.h" 28 28 #include "common/fs.h" 29 29 #include "common/system.h" 30 #include "common/ func.h"30 #include "common/algorithm.h" 31 31 32 32 namespace GUI { 33 33 -
common/hash-str.h
29 29 30 30 uint hashit(const char *str); 31 31 uint hashit_lower(const char *str); // Generate a hash based on the lowercase version of the string 32 inline uint hashit(const String &str) { return hashit(str.c_str()); } 33 inline uint hashit_lower(const String &str) { return hashit_lower(str.c_str()); } 32 34 33 35 34 36 // FIXME: The following functors obviously are not consistently named -
common/func.h
26 26 27 27 namespace Common { 28 28 29 template <class T> 30 struct EqualTo { 31 bool operator()(const T& x, const T& y) const { return x == y; } 29 template<class Arg, class Result> 30 struct UnaryFunction { 31 typedef Arg ArgumenType; 32 typedef Result ResultType; 32 33 }; 33 34 34 template <class T> 35 struct Less { 36 bool operator()(const T& x, const T& y) const { return x < y; } 35 template<class Arg1, class Arg2, class Result> 36 struct BinaryFunction { 37 typedef Arg1 FirstArgumentType; 38 typedef Arg2 SecondArgumentType; 39 typedef Result ResultType; 37 40 }; 38 41 42 template<class T> 43 struct EqualTo : public BinaryFunction<T, T, bool> { 44 bool operator()(const T& x, const T& y) const { return x == y; } 45 }; 46 47 template<class T> 48 struct Less : public BinaryFunction<T, T, bool> { 49 bool operator()(const T& x, const T& y) const { return x < y; } 50 }; 51 52 template<class Op> 53 class Binder1st : public UnaryFunction<typename Op::SecondArgumentType, typename Op::ResultType> { 54 private: 55 Op _op; 56 typename Op::FirstArgumentType _arg1; 57 public: 58 Binder1st(const Op &op, const typename Op::FirstArgumentType &arg1) : _op(op), _arg1(arg1) {} 59 60 typename Op::ResultType operator()(typename Op::SecondArgumentType v) const { 61 return _op(_arg1, v); 62 } 63 }; 64 65 template<class Op, class T> 66 inline Binder1st<Op> bind1st(const Op &op, const T &t) { 67 return Binder1st<Op>(op, t); 68 } 69 70 template<class Op> 71 class Binder2nd : public UnaryFunction<typename Op::FirstArgumentType, typename Op::ResultType> { 72 private: 73 Op _op; 74 typename Op::SecondArgumentType _arg2; 75 public: 76 Binder2nd(const Op &op, const typename Op::SecondArgumentType &arg2) : _op(op), _arg2(arg2) {} 77 78 typename Op::ResultType operator()(typename Op::FirstArgumentType v) const { 79 return _op(v, _arg2); 80 } 81 }; 82 83 template<class Op, class T> 84 inline Binder2nd<Op> bind2nd(const Op &op, const T &t) { 85 return Binder2nd<Op>(op, t); 86 } 87 88 template<class Arg, class Result> 89 class PointerToUnaryFunc : public UnaryFunction<Arg, Result> { 90 private: 91 Result (*_func)(Arg); 92 public: 93 typedef Result (*FuncType)(Arg); 94 95 PointerToUnaryFunc(const FuncType &func) : _func(func) {} 96 Result operator()(Arg v) const { 97 return _func(v); 98 } 99 }; 100 101 template<class Arg1, class Arg2, class Result> 102 class PointerToBinaryFunc : public BinaryFunction<Arg1, Arg2, Result> { 103 private: 104 Result (*_func)(Arg1, Arg2); 105 public: 106 typedef Result (*FuncType)(Arg1, Arg2); 107 108 PointerToBinaryFunc(const FuncType &func) : _func(func) {} 109 Result operator()(Arg1 v1, Arg2 v2) const { 110 return _func(v1, v2); 111 } 112 }; 113 114 template<class Arg, class Result> 115 inline PointerToUnaryFunc<Arg, Result> ptr_fun(Result (*func)(Arg)) { 116 return PointerToUnaryFunc<Arg, Result>(func); 117 } 118 119 template<class Arg1, class Arg2, class Result> 120 inline PointerToBinaryFunc<Arg1, Arg2, Result> ptr_fun(Result (*func)(Arg1, Arg2)) { 121 return PointerToBinaryFunc<Arg1, Arg2, Result>(func); 122 } 123 124 template<class Result, class T> 125 class MemFunc0 : public UnaryFunction<T*, Result> { 126 private: 127 Result (T::*_func)(); 128 public: 129 typedef Result (T::*FuncType)(); 130 131 MemFunc0(const FuncType &func) : _func(func) {} 132 Result operator()(T *v) const { 133 return (v->*_func)(); 134 } 135 }; 136 137 template<class Result, class T> 138 class ConstMemFunc0 : public UnaryFunction<T*, Result> { 139 private: 140 Result (T::*_func)() const; 141 public: 142 typedef Result (T::*FuncType)() const; 143 144 ConstMemFunc0(const FuncType &func) : _func(func) {} 145 Result operator()(T *v) const { 146 return (v->*_func)(); 147 } 148 }; 149 150 template<class Result, class Arg, class T> 151 class MemFunc1 : public BinaryFunction<T*, Arg, Result> { 152 private: 153 Result (T::*_func)(Arg); 154 public: 155 typedef Result (T::*FuncType)(Arg); 156 157 MemFunc1(const FuncType &func) : _func(func) {} 158 Result operator()(T *v1, Arg v2) const { 159 return (v1->*_func)(v2); 160 } 161 }; 162 163 template<class Result, class Arg, class T> 164 class ConstMemFunc1 : public BinaryFunction<T*, Arg, Result> { 165 private: 166 Result (T::*_func)(Arg) const; 167 public: 168 typedef Result (T::*FuncType)(Arg) const; 169 170 ConstMemFunc1(const FuncType &func) : _func(func) {} 171 Result operator()(T *v1, Arg v2) const { 172 return (v1->*_func)(v2); 173 } 174 }; 175 176 template<class Result, class T> 177 inline MemFunc0<Result, T> mem_fun(Result (T::*f)()) { 178 return MemFunc0<Result, T>(f); 179 } 180 181 template<class Result, class T> 182 inline ConstMemFunc0<Result, T> mem_fun(Result (T::*f)() const) { 183 return ConstMemFunc0<Result, T>(f); 184 } 185 186 template<class Result, class Arg, class T> 187 inline MemFunc1<Result, Arg, T> mem_fun(Result (T::*f)(Arg)) { 188 return MemFunc1<Result, Arg, T>(f); 189 } 190 191 template<class Result, class Arg, class T> 192 inline ConstMemFunc1<Result, Arg, T> mem_fun(Result (T::*f)(Arg) const) { 193 return ConstMemFunc1<Result, Arg, T>(f); 194 } 195 196 template<class Cont> 197 class BackInsertIterator { 198 private: 199 Cont *_container; 200 201 public: 202 BackInsertIterator(Cont &c) : _container(&c) {} 203 204 BackInsertIterator &operator =(const typename Cont::value_type &v) { 205 _container->push_back(v); 206 return *this; 207 } 208 209 BackInsertIterator &operator *() { return *this; } 210 BackInsertIterator &operator ++() { return *this; } 211 BackInsertIterator operator ++(int) { return *this; } 212 }; 213 214 template<class Cont> 215 BackInsertIterator<Cont> back_inserter(Cont &c) { 216 return BackInsertIterator<Cont>(c); 217 } 218 219 template<class Cont> 220 class FrontInsertIterator { 221 private: 222 Cont *_container; 223 224 public: 225 FrontInsertIterator(Cont &c) : _container(&c) {} 226 227 FrontInsertIterator &operator =(const typename Cont::value_type &v) { 228 _container->push_front(v); 229 return *this; 230 } 231 232 FrontInsertIterator &operator *() { return *this; } 233 FrontInsertIterator &operator ++() { return *this; } 234 FrontInsertIterator operator ++(int) { return *this; } 235 }; 236 237 template<class Cont> 238 FrontInsertIterator<Cont> front_inserter(Cont &c) { 239 return FrontInsertIterator<Cont>(c); 240 } 241 39 242 /** 40 243 * Base template for hash functor objects, used by HashMap. 41 244 * This needs to be specialized for every type that you need to hash. … … 61 264 62 265 #undef GENERATE_TRIVIAL_HASH_FUNCTOR 63 266 64 65 // Simple sort function, modelled after std::sort.66 // Use it like this: sort(container.begin(), container.end()).67 // Also work on plain old int arrays etc.68 template <typename T>69 void sort(T first, T last) {70 if (first == last)71 return;72 73 // Simple selection sort74 T i(first);75 for (; i != last; ++i) {76 T minElem(i);77 T j(i);78 ++j;79 for (; j != last; ++j)80 if (*j < *minElem)81 minElem = j;82 if (minElem != i)83 SWAP(*minElem, *i);84 }85 }86 87 88 267 } // End of namespace Common 89 268 90 269 #endif 270 -
common/array.h
23 23 #define COMMON_ARRAY_H 24 24 25 25 #include "common/scummsys.h" 26 #include "common/algorithm.h" 26 27 27 28 namespace Common { 28 29 … … 37 38 typedef T *iterator; 38 39 typedef const T *const_iterator; 39 40 41 typedef T value_type; 42 40 43 public: 41 44 Array() : _capacity(0), _size(0), _data(0) {} 42 45 Array(const Array<T>& array) : _capacity(0), _size(0), _data(0) { 43 46 _size = array._size; 44 47 _capacity = _size + 32; 45 48 _data = new T[_capacity]; 46 for (int i = 0; i < _size; i++) 47 _data[i] = array._data[i]; 49 copy(array._data, array._data + _size, _data); 48 50 } 49 51 50 52 ~Array() { … … 59 61 60 62 void push_back(const Array<T>& array) { 61 63 ensureCapacity(_size + array._size); 62 for (int i = 0; i < array._size; i++)63 _data[_size++] = array._data[i];64 copy(array._data, array._data + array._size, _data + _size); 65 _size += array._size; 64 66 } 65 67 66 68 void insert_at(int idx, const T& element) { 67 69 assert(idx >= 0 && idx <= _size); 68 70 ensureCapacity(_size + 1); 69 // The following loop is not efficient if you can just memcpy things around. 70 // e.g. if you have a list of ints. But for real objects (String...), memcpy 71 // usually isn't correct (specifically, for any class which has a non-default 72 // copy behaviour. E.g. the String class uses a refCounter which has to be 73 // updated whenever a String is copied. 74 for (int i = _size; i > idx; i--) { 75 _data[i] = _data[i-1]; 76 } 71 copy_backward(_data + idx, _data + _size, _data + _size + 1); 77 72 _data[idx] = element; 78 73 _size++; 79 74 } … … 81 76 T remove_at(int idx) { 82 77 assert(idx >= 0 && idx < _size); 83 78 T tmp = _data[idx]; 84 for (int i = idx; i < _size - 1; i++) 85 _data[i] = _data[i+1]; 79 copy(_data + idx + 1, _data + _size, _data + idx); 86 80 _size--; 87 81 return tmp; 88 82 } … … 108 102 _size = array._size; 109 103 _capacity = _size + 32; 110 104 _data = new T[_capacity]; 111 for (int i = 0; i < _size; i++) 112 _data[i] = array._data[i]; 105 copy(array._data, array._data + _size, _data); 113 106 114 107 return *this; 115 108 } … … 149 142 } 150 143 151 144 bool contains(const T &key) const { 152 for (const_iterator i = begin(); i != end(); ++i) { 153 if (*i == key) 154 return true; 155 } 156 return false; 145 return find(begin(), end(), key) != end(); 157 146 } 158 147 159 148 … … 168 157 169 158 if (old_data) { 170 159 // Copy old data 171 for (int i = 0; i < _size; i++) 172 _data[i] = old_data[i]; 160 copy(old_data, old_data + _size, _data); 173 161 delete [] old_data; 174 162 } 175 163 } -
common/algorithm.h
1 /* ScummVM - Scumm Interpreter 2 * Copyright (C) 2007 The ScummVM project 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 * 18 * $URL$ 19 * $Id$ 20 */ 21 22 #ifndef COMMON_ALGORITHM_H 23 #define COMMON_ALGORITHM_H 24 25 #include "common/scummsys.h" 26 27 namespace Common { 28 29 template<class In, class Out> 30 Out copy(In first, In last, Out dst) { 31 while (first != last) 32 *dst++ = *first++; 33 return dst; 34 } 35 36 template<class In, class Out> 37 Out copy_backward(In first, In last, Out dst) { 38 while (first != last) 39 *--dst = *--last; 40 return dst; 41 } 42 43 template<class In, class Out, class Op> 44 Out copy_if(In first, In last, Out dst, Op op) { 45 while (first != last) { 46 if (op(*first)) 47 *dst++ = *first; 48 ++first; 49 } 50 return dst; 51 } 52 53 template<class In, class T> 54 In find(In first, In last, const T &v) { 55 while (first != last) { 56 if (*first == v) 57 return first; 58 ++first; 59 } 60 return last; 61 } 62 63 template<class In, class Pred> 64 In find_if(In first, In last, Pred p) { 65 while (first != last) { 66 if (p(*first)) 67 return first; 68 ++first; 69 } 70 return last; 71 } 72 73 template<class In, class Op> 74 Op for_each(In first, In last, Op f) { 75 while (first != last) f(*first++); 76 return f; 77 } 78 79 // Simple sort function, modelled after std::sort. 80 // Use it like this: sort(container.begin(), container.end()). 81 // Also work on plain old int arrays etc. 82 template<class T> 83 void sort(T first, T last) { 84 if (first == last) 85 return; 86 87 // Simple selection sort 88 T i(first); 89 for (; i != last; ++i) { 90 T minElem(i); 91 T j(i); 92 ++j; 93 for (; j != last; ++j) 94 if (*j < *minElem) 95 minElem = j; 96 if (minElem != i) 97 SWAP(*minElem, *i); 98 } 99 } 100 101 } // end of namespace Common 102 #endif 103 -
common/list.h
Property changes on: common/algorithm.h ___________________________________________________________________ Name: svn:mime-type + text/plain Name: svn:keywords + Date Rev Author URL Id Name: svn:eol-style + native
111 111 NodeBase *_anchor; 112 112 113 113 public: 114 typedef Iterator<T> 115 typedef Iterator<const T> 114 typedef Iterator<T> iterator; 115 typedef Iterator<const T> const_iterator; 116 116 117 typedef T value_type; 118 117 119 public: 118 120 List() { 119 121 _anchor = new NodeBase; -
engines/kyra/resource.h
38 38 ResourceFile() : _open(false), _protected(false), _filename() {} 39 39 virtual ~ResourceFile() {} 40 40 41 virtual uint8 *getFile(uint file) = 0;42 virtual bool getFileHandle(uint file, Common::File &filehandle) = 0;43 virtual uint32 getFileSize(uint file) = 0;41 virtual uint8 *getFile(uint file) const = 0; 42 virtual bool getFileHandle(uint file, Common::File &filehandle) const = 0; 43 virtual uint32 getFileSize(uint file) const = 0; 44 44 45 45 uint filename() const { return _filename; } 46 46 … … 62 62 uint _name; 63 63 uint32 _start; 64 64 uint32 _size; 65 66 operator uint() const { return _name; } 65 67 }; 66 68 67 69 public: 68 70 PAKFile(const char *file, const char *physfile, Common::File &pakfile, bool isAmiga = false); 69 71 ~PAKFile(); 70 72 71 uint8 *getFile(uint file) ;72 bool getFileHandle(uint file, Common::File &filehandle) ;73 uint32 getFileSize(uint file) ;73 uint8 *getFile(uint file) const; 74 bool getFileHandle(uint file, Common::File &filehandle) const; 75 uint32 getFileSize(uint file) const; 74 76 private: 75 bool openFile(Common::File &filehandle) ;77 bool openFile(Common::File &filehandle) const; 76 78 77 79 Common::String _physfile; 78 80 uint32 _physOffset; 79 81 82 typedef Common::List<PakChunk>::iterator PakIterator; 83 typedef Common::List<PakChunk>::const_iterator ConstPakIterator; 80 84 Common::List<PakChunk> _files; // the entries 81 85 }; 82 86 … … 86 90 uint _name; 87 91 uint32 _start; 88 92 uint32 _size; 93 94 operator uint() const { return _name; } 89 95 }; 90 96 public: 91 97 INSFile(const char *file); 92 98 ~INSFile(); 93 99 94 uint8 *getFile(uint file) ;95 bool getFileHandle(uint file, Common::File &filehandle) ;96 uint32 getFileSize(uint file) ;100 uint8 *getFile(uint file) const; 101 bool getFileHandle(uint file, Common::File &filehandle) const; 102 uint32 getFileSize(uint file) const; 97 103 protected: 104 typedef Common::List<FileEntry>::iterator FileIterator; 105 typedef Common::List<FileEntry>::const_iterator ConstFileIterator; 98 106 Common::List<FileEntry> _files; // the entries 99 107 100 108 Common::String _physfile; … … 105 113 Resource(KyraEngine *vm); 106 114 ~Resource(); 107 115 108 bool loadPakFile(const Common::String &filename , const bool forcePC = false);116 bool loadPakFile(const Common::String &filename); 109 117 void unloadPakFile(const Common::String &filename); 110 bool isInPakList(const Common::String &filename) ;118 bool isInPakList(const Common::String &filename) const; 111 119 112 uint32 getFileSize(const char *file) ;113 uint8* fileData(const char *file, uint32 *size) ;120 uint32 getFileSize(const char *file) const; 121 uint8* fileData(const char *file, uint32 *size) const; 114 122 // it gives back a file handle (used for the speech player) 115 123 // it could be that the needed file is embedded in the returned 116 124 // handle … … 119 127 bool loadFileToBuf(const char *file, void *buf, uint32 maxSize); 120 128 121 129 protected: 130 typedef Common::List<ResourceFile*>::iterator ResIterator; 131 typedef Common::List<ResourceFile*>::const_iterator ConstResIterator; 132 122 133 KyraEngine *_vm; 123 134 Common::List<ResourceFile*> _pakfiles; 124 135 }; -
engines/kyra/resource.cpp
26 26 #include "common/file.h" 27 27 #include "common/fs.h" 28 28 #include "common/hash-str.h" 29 #include "common/func.h" 30 #include "common/algorithm.h" 29 31 30 32 #include "gui/message.h" 31 33 … … 35 37 #include "kyra/screen.h" 36 38 37 39 namespace Kyra { 40 41 namespace { 42 struct ResFilenameEqual : public Common::BinaryFunction<ResourceFile*, uint, bool> { 43 uint _filename; 44 ResFilenameEqual(uint file) : _filename(file) {} 45 46 bool operator()(ResourceFile *f) { 47 return f->filename() == _filename; 48 } 49 }; 50 } // end of anonymous namespace 51 38 52 Resource::Resource(KyraEngine *vm) { 39 53 _vm = vm; 40 54 41 55 if (_vm->game() == GI_KYRA1) { 42 56 // we're loading KYRA.DAT here too (but just for Kyrandia 1) 43 if (!loadPakFile("KYRA.DAT" , true) || !StaticResource::checkKyraDat()) {57 if (!loadPakFile("KYRA.DAT") || !StaticResource::checkKyraDat()) { 44 58 GUI::MessageDialog errorMsg("You're missing the 'KYRA.DAT' file or it got corrupted, (re)get it from the ScummVM website"); 45 59 errorMsg.runModal(); 46 60 error("You're missing the 'KYRA.DAT' file or it got corrupted, (re)get it from the ScummVM website"); … … 58 72 INSFile *insFile = new INSFile("WESTWOOD.001"); 59 73 assert(insFile); 60 74 if (!insFile->isValid()) 61 return;75 error("'WESTWOOD.001' file not found or corrupt"); 62 76 _pakfiles.push_back(insFile); 63 77 } 64 78 … … 72 86 static const char *list[] = { 73 87 "ADL.PAK", "CHAPTER1.VRM", "COL.PAK", "FINALE.PAK", "INTRO1.PAK", "INTRO2.PAK", 74 88 "INTRO3.PAK", "INTRO4.PAK", "MISC.PAK", "SND.PAK", "STARTUP.PAK", "XMI.PAK", 75 "CAVE.APK", "DRAGON1.APK", "DRAGON2.APK", "LAGOON.APK" , 089 "CAVE.APK", "DRAGON1.APK", "DRAGON2.APK", "LAGOON.APK" 76 90 }; 77 91 78 for (int i = 0; list[i]; ++i) { 79 if (!loadPakFile(list[i])) 80 error("couldn't open pakfile '%s'", list[i]); 81 } 82 83 Common::List<ResourceFile*>::iterator start = _pakfiles.begin(); 84 for (;start != _pakfiles.end(); ++start) 85 (*start)->protect(); 92 Common::for_each(list, list + ARRAYSIZE(list), Common::bind1st(Common::mem_fun(&Resource::loadPakFile), this)); 93 Common::for_each(_pakfiles.begin(), _pakfiles.end(), Common::bind2nd(Common::mem_fun(&ResourceFile::protect), true)); 86 94 } else { 87 95 for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) { 88 96 Common::String filename = file->name(); … … 99 107 } 100 108 101 109 if (_vm->gameFlags().platform == Common::kPlatformFMTowns) { 102 Common::List<ResourceFile*>::iterator start = _pakfiles.begin();103 110 uint unloadHash = (_vm->gameFlags().lang == Common::EN_ANY) ? Common::hashit_lower("JMC.PAK") : Common::hashit_lower("EMC.PAK"); 104 111 105 for (;start != _pakfiles.end(); ++start) { 106 if ((*start)->filename() == unloadHash) { 107 delete *start; 108 *start = 0; 109 _pakfiles.erase(start); 110 break; 111 } 112 ResIterator file = Common::find_if(_pakfiles.begin(), _pakfiles.end(), ResFilenameEqual(unloadHash)); 113 if (file != _pakfiles.end()) { 114 delete *file; 115 _pakfiles.erase(file); 112 116 } 113 117 } 114 118 } 115 119 } 116 120 117 121 Resource::~Resource() { 118 Common::List<ResourceFile*>::iterator start = _pakfiles.begin(); 119 120 for (;start != _pakfiles.end(); ++start) { 122 for (ResIterator start = _pakfiles.begin() ;start != _pakfiles.end(); ++start) { 121 123 delete *start; 122 124 *start = 0; 123 125 } 124 126 } 125 127 126 bool Resource::loadPakFile(const Common::String &filename, const bool forcePC) { 127 Common::List<ResourceFile*>::iterator start = _pakfiles.begin(); 128 uint hash = Common::hashit_lower(filename.c_str()); 129 130 for (;start != _pakfiles.end(); ++start) { 131 if ((*start)->filename() == hash) { 132 (*start)->open(); 133 return true; 134 } 128 bool Resource::loadPakFile(const Common::String &filename) { 129 ResIterator listFile = Common::find_if(_pakfiles.begin(), _pakfiles.end(), ResFilenameEqual(Common::hashit_lower(filename))); 130 if (listFile != _pakfiles.end()) { 131 (*listFile)->open(); 132 return true; 135 133 } 136 134 135 const bool isKyraDat = filename.equalsIgnoreCase("KYRA.DAT"); 137 136 uint32 size = 0; 138 137 139 138 Common::File handle; 140 139 if (!getFileHandle(filename.c_str(), &size, handle)) { 141 warning("couldn't load file: '%s'", filename.c_str());140 (!isKyraDat ? error : warning)("couldn't load file: '%s'", filename.c_str()); 142 141 return false; 143 142 } 144 143 145 PAKFile *file = new PAKFile(filename.c_str(), handle.name(), handle, (_vm->gameFlags().platform == Common::kPlatformAmiga) && ! forcePC);144 PAKFile *file = new PAKFile(filename.c_str(), handle.name(), handle, (_vm->gameFlags().platform == Common::kPlatformAmiga) && !isKyraDat); 146 145 handle.close(); 147 146 148 147 if (!file) 149 148 return false; 150 149 151 150 if (!file->isValid()) { 152 warning("'%s' is no valid pak file", filename.c_str());151 error("'%s' is no valid pak file", filename.c_str()); 153 152 delete file; 154 153 return false; 155 154 } … … 159 158 } 160 159 161 160 void Resource::unloadPakFile(const Common::String &filename) { 162 Common::List<ResourceFile*>::iterator start = _pakfiles.begin(); 163 uint hash = Common::hashit_lower(filename.c_str()); 164 for (;start != _pakfiles.end(); ++start) { 165 if ((*start)->filename() == hash) { 166 (*start)->close(); 167 break; 168 } 169 } 170 return; 161 ResIterator pak = Common::find_if(_pakfiles.begin(), _pakfiles.end(), ResFilenameEqual(Common::hashit_lower(filename))); 162 if (pak != _pakfiles.end()) 163 (*pak)->close(); 171 164 } 172 165 173 bool Resource::isInPakList(const Common::String &filename) { 174 Common::List<ResourceFile*>::iterator start = _pakfiles.begin(); 175 uint hash = Common::hashit_lower(filename.c_str()); 176 for (;start != _pakfiles.end(); ++start) { 177 if ((*start)->filename() == hash) 178 return true; 179 } 180 return false; 166 bool Resource::isInPakList(const Common::String &filename) const { 167 return (Common::find_if(_pakfiles.begin(), _pakfiles.end(), ResFilenameEqual(Common::hashit_lower(filename))) != _pakfiles.end()); 181 168 } 182 169 183 uint8 *Resource::fileData(const char *file, uint32 *size) {170 uint8 *Resource::fileData(const char *file, uint32 *size) const { 184 171 Common::File fileHandle; 185 172 186 173 if (size) … … 199 186 200 187 return buffer; 201 188 } else { 202 // opens the file in a PAK File 203 Common::List<ResourceFile*>::iterator start = _pakfiles.begin(); 204 189 // opens the file inside a PAK File 205 190 uint fileHash = Common::hashit_lower(file); 206 for ( ;start != _pakfiles.end(); ++start) {207 if (!(* start)->isOpen())191 for (ConstResIterator cur = _pakfiles.begin(); cur != _pakfiles.end(); ++cur) { 192 if (!(*cur)->isOpen()) 208 193 continue; 209 194 210 uint32 fileSize = (* start)->getFileSize(fileHash);195 uint32 fileSize = (*cur)->getFileSize(fileHash); 211 196 212 197 if (!fileSize) 213 198 continue; … … 215 200 if (size) 216 201 *size = fileSize; 217 202 218 return (* start)->getFile(fileHash);203 return (*cur)->getFile(fileHash); 219 204 } 220 205 } 221 206 … … 228 213 if (filehandle.open(file)) 229 214 return true; 230 215 231 Common::List<ResourceFile*>::iterator start = _pakfiles.begin();232 233 216 uint fileHash = Common::hashit_lower(file); 234 for ( ;start != _pakfiles.end(); ++start) {217 for (ResIterator start = _pakfiles.begin() ;start != _pakfiles.end(); ++start) { 235 218 if (!(*start)->isOpen()) 236 219 continue; 237 220 … … 247 230 return false; 248 231 } 249 232 250 uint32 Resource::getFileSize(const char *file) { 251 Common::List<ResourceFile*>::iterator start = _pakfiles.begin(); 252 233 uint32 Resource::getFileSize(const char *file) const { 253 234 Common::File temp; 254 235 if (temp.open(file)) 255 236 return temp.size(); 256 237 257 238 uint fileHash = Common::hashit_lower(file); 258 for ( ;start != _pakfiles.end(); ++start) {239 for (ConstResIterator start = _pakfiles.begin() ;start != _pakfiles.end(); ++start) { 259 240 if (!(*start)->isOpen()) 260 241 continue; 261 242 … … 286 267 287 268 /////////////////////////////////////////// 288 269 // Pak file manager 289 #define PAKFile_Iterate Common::List<PakChunk>::iterator start=_files.begin();start != _files.end(); ++start290 270 PAKFile::PAKFile(const char *file, const char *physfile, Common::File &pakfile, bool isAmiga) : ResourceFile() { 291 271 _open = false; 292 272 … … 300 280 301 281 uint32 pos = 0, startoffset = 0, endoffset = 0; 302 282 303 if (!isAmiga) 304 startoffset = pakfile.readUint32LE(); 305 else 283 if (isAmiga) 306 284 startoffset = pakfile.readUint32BE(); 285 else 286 startoffset = pakfile.readUint32LE(); 307 287 308 288 if (startoffset > filesize) { 309 289 warning("PAK file '%s' is corrupted", file); … … 338 318 return; 339 319 } 340 320 341 if (!isAmiga) 342 endoffset = READ_LE_UINT32(buffer + nameLength); 343 else 321 if (isAmiga) 344 322 endoffset = READ_BE_UINT32(buffer + nameLength); 323 else 324 endoffset = READ_LE_UINT32(buffer + nameLength); 345 325 346 326 if (!endoffset) { 347 327 endoffset = filesize; … … 378 358 _files.clear(); 379 359 } 380 360 381 uint8 *PAKFile::getFile(uint hash) { 382 for (PAKFile_Iterate) { 383 if (start->_name == hash) { 384 Common::File pakfile; 385 if (!openFile(pakfile)) 386 return false; 361 uint8 *PAKFile::getFile(uint hash) const { 362 ConstPakIterator file = Common::find_if(_files.begin(), _files.end(), Common::bind2nd(Common::EqualTo<uint>(), hash)); 363 if (file == _files.end()) 364 return 0; 387 365 388 pakfile.seek(start->_start, SEEK_CUR); 389 uint8 *buffer = new uint8[start->_size]; 390 assert(buffer); 391 pakfile.read(buffer, start->_size); 392 return buffer; 393 } 394 } 395 return 0; 366 Common::File pakfile; 367 if (!openFile(pakfile)) 368 return false; 369 370 pakfile.seek(file->_start, SEEK_CUR); 371 uint8 *buffer = new uint8[file->_size]; 372 assert(buffer); 373 pakfile.read(buffer, file->_size); 374 return buffer; 396 375 } 397 376 398 bool PAKFile::getFileHandle(uint hash, Common::File &filehandle) {377 bool PAKFile::getFileHandle(uint hash, Common::File &filehandle) const { 399 378 filehandle.close(); 400 379 401 for (PAKFile_Iterate) { 402 if (start->_name == hash) { 403 if (!openFile(filehandle)) 404 return false; 380 ConstPakIterator file = Common::find_if(_files.begin(), _files.end(), Common::bind2nd(Common::EqualTo<uint>(), hash)); 381 if (file == _files.end()) 382 return false; 405 383 406 filehandle.seek(start->_start, SEEK_CUR);407 return true;408 } 409 }410 return false;384 if (!openFile(filehandle)) 385 return false; 386 387 filehandle.seek(file->_start, SEEK_CUR); 388 return true; 411 389 } 412 390 413 uint32 PAKFile::getFileSize(uint hash) { 414 for (PAKFile_Iterate) { 415 if (start->_name == hash) 416 return start->_size; 417 } 418 return 0; 391 uint32 PAKFile::getFileSize(uint hash) const { 392 ConstPakIterator file = Common::find_if(_files.begin(), _files.end(), Common::bind2nd(Common::EqualTo<uint>(), hash)); 393 return (file != _files.end()) ? file->_size : 0; 419 394 } 420 395 421 bool PAKFile::openFile(Common::File &filehandle) {396 bool PAKFile::openFile(Common::File &filehandle) const { 422 397 filehandle.close(); 423 398 424 399 if (!filehandle.open(_physfile)) … … 430 405 431 406 /////////////////////////////////////////// 432 407 // Ins file manager 433 #define INSFile_Iterate Common::List<FileEntry>::iterator start=_files.begin();start != _files.end(); ++start434 408 INSFile::INSFile(const char *file) : ResourceFile(), _files() { 435 409 Common::File pakfile; 436 410 _open = false; … … 475 449 476 450 pakfile.seek(3); 477 451 478 for ( INSFile_Iterate) {452 for (FileIterator start = _files.begin(); start != _files.end(); ++start) { 479 453 filesize = pakfile.readUint32LE(); 480 454 start->_size = filesize; 481 455 start->_start = pakfile.pos(); … … 493 467 _files.clear(); 494 468 } 495 469 496 uint8 *INSFile::getFile(uint hash) { 497 for (INSFile_Iterate) { 498 if (start->_name == hash) { 499 Common::File pakfile; 500 if (!pakfile.open(_physfile)) 501 return false; 470 uint8 *INSFile::getFile(uint hash) const { 471 ConstFileIterator file = Common::find_if(_files.begin(), _files.end(), Common::bind2nd(Common::EqualTo<uint>(), hash)); 472 if (file == _files.end()) 473 return 0; 502 474 503 pakfile.seek(start->_start); 504 uint8 *buffer = new uint8[start->_size]; 505 assert(buffer); 506 pakfile.read(buffer, start->_size); 507 return buffer; 508 } 509 } 510 return 0; 475 Common::File pakfile; 476 if (!pakfile.open(_physfile)) 477 return false; 478 479 pakfile.seek(file->_start); 480 uint8 *buffer = new uint8[file->_size]; 481 assert(buffer); 482 pakfile.read(buffer, file->_size); 483 return buffer; 511 484 } 512 485 513 bool INSFile::getFileHandle(uint hash, Common::File &filehandle) { 514 for (INSFile_Iterate) { 515 if (start->_name == hash) { 516 if (!filehandle.open(_physfile)) 517 return false; 486 bool INSFile::getFileHandle(uint hash, Common::File &filehandle) const { 487 ConstFileIterator file = Common::find_if(_files.begin(), _files.end(), Common::bind2nd(Common::EqualTo<uint>(), hash)); 518 488 519 filehandle.seek(start->_start, SEEK_CUR); 520 return true; 521 } 522 } 523 return false; 489 if (file == _files.end()) 490 return false; 491 492 if (!filehandle.open(_physfile)) 493 return false; 494 495 filehandle.seek(file->_start, SEEK_CUR); 496 return true; 524 497 } 525 498 526 uint32 INSFile::getFileSize(uint hash) { 527 for (INSFile_Iterate) { 528 if (start->_name == hash) 529 return start->_size; 530 } 531 return 0; 499 uint32 INSFile::getFileSize(uint hash) const { 500 ConstFileIterator file = Common::find_if(_files.begin(), _files.end(), Common::bind2nd(Common::EqualTo<uint>(), hash)); 501 return (file != _files.end()) ? file->_size : 0; 532 502 } 533 503 534 504 } // end of namespace Kyra