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 /*
24  * This code is based on Broken Sword 2.5 engine
25  *
26  * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
27  *
28  * Licensed under GNU GPL v2
29  *
30  */
31 
32 /*
33  * BS_PackageManager
34  * -----------------
35  * This is the package manager interface, that contains all the methods that a package manager
36  * must implement.
37  * In the package manager, note the following:
38  * 1. It creates a completely new (virtual) directory tree in the packages and directories
39  *    can be mounted.
40  * 2. To seperate elements of a directory path '/' must be used rather than '\'
41  * 3. LoadDirectoryAsPackage should only be used for testing. The final release will be
42  *    have all files in packages.
43  *
44  * Autor: Malte Thiesen, $author$
45  */
46 
47 #ifndef SWORD25_PACKAGE_MANAGER_H
48 #define SWORD25_PACKAGE_MANAGER_H
49 
50 #include "common/archive.h"
51 #include "common/array.h"
52 #include "common/fs.h"
53 #include "common/str.h"
54 
55 #include "sword25/kernel/common.h"
56 #include "sword25/kernel/kernel.h"
57 #include "sword25/kernel/service.h"
58 
59 namespace Sword25 {
60 
61 // Class definitions
62 
63 /**
64  * The Package Manager interface
65  *
66  * 1. It creates a completely new (virtual) directory tree in the packages and directories
67  *    can be mounted.
68  * 2. To seperate elements of a directory path '/' must be used rather than '\'
69  * 3. LoadDirectoryAsPackage should only be used for testing. The final release will be
70  *    have all files in packages.
71  */
72 class PackageManager : public Service {
73 private:
74 	class ArchiveEntry {
75 	public:
76 		Common::Archive *archive;
77 		Common::String _mountPath;
78 
ArchiveEntry(Common::Archive * archive_,const Common::String & mountPath_)79 		ArchiveEntry(Common::Archive *archive_, const Common::String &mountPath_):
80 			archive(archive_), _mountPath(mountPath_) {
81 		}
~ArchiveEntry()82 		~ArchiveEntry() {
83 			delete archive;
84 		}
85 	};
86 
87 	Common::String _currentDirectory;
88 	Common::FSNode _rootFolder;
89 	Common::List<ArchiveEntry *> _archiveList;
90 
91 	bool _useEnglishSpeech;
92 	Common::String ensureSpeechLang(const Common::String &fileName);
93 
94 	Common::ArchiveMemberPtr getArchiveMember(const Common::String &fileName);
95 
96 public:
97 	PackageManager(Kernel *pKernel);
98 	~PackageManager();
99 
100 	enum FILE_TYPES {
101 		FT_DIRECTORY    = (1 << 0),
102 		FT_FILE         = (1 << 1)
103 	};
104 
105 	/**
106 	 * Mounts the contents of a package in the directory specified in the directory tree.
107 	 * @param FileName      The filename of the package to mount
108 	 * @param MountPosition The directory name under which the package should be mounted
109 	 * @return              Returns true if the mount was successful, otherwise false.
110 	 */
111 	bool loadPackage(const Common::String &fileName, const Common::String &mountPosition);
112 	/**
113 	 * Mounts the contents of a directory in the specified directory in the directory tree.
114 	 * @param               The name of the directory to mount
115 	 * @param MountPosition The directory name under which the package should be mounted
116 	 * @return              Returns true if the mount was successful, otherwise false.
117 	 */
118 	bool loadDirectoryAsPackage(const Common::String &directoryName, const Common::String &mountPosition);
119 	/**
120 	 * Downloads a file from the directory tree
121 	 * @param FileName      The filename of the file to load
122 	 * @param pFileSize     Pointer to the variable that will contain the size of the loaded file. The deafult is NULL.
123 	 * @return              Specifies a pointer to the loaded data of the file
124 	 * @remark              The client must not forget to release the data of the file using BE_DELETE_A.
125 	 */
126 	byte *getFile(const Common::String &fileName, uint *pFileSize = NULL);
127 
128 	/**
129 	 * Returns a stream from file file from the directory tree
130 	 * @param FileName      The filename of the file to load
131 	 * @return              Pointer to the stream object
132 	 */
133 	Common::SeekableReadStream *getStream(const Common::String &fileName);
134 	/**
135 	 * Downloads an XML file and prefixes it with an XML Version key, since the XML files don't contain it,
136 	 * and it is required for ScummVM to correctly parse the XML.
137 	 * @param FileName      The filename of the file to load
138 	 * @param pFileSize     Pointer to the variable that will contain the size of the loaded file. The deafult is NULL.
139 	 * @return              Specifies a pointer to the loaded data of the file
140 	 * @remark              The client must not forget to release the data of the file using BE_DELETE_A.
141 	 */
142 	char *getXmlFile(const Common::String &fileName, uint *pFileSize = NULL) {
143 		const char *versionStr = "<?xml version=\"1.0\"?>";
144 		uint fileSize;
145 		char *data = (char *)getFile(fileName, &fileSize);
146 		char *result = (char *)malloc(fileSize + strlen(versionStr) + 1);
147 		if (!result)
148 			error("[PackageManager::getXmlFile] Cannot allocate memory");
149 
150 		strcpy(result, versionStr);
151 		Common::copy(data, data + fileSize, result + strlen(versionStr));
152 		result[fileSize + strlen(versionStr)] = '\0';
153 
154 		delete[] data;
155 		if (pFileSize)
156 			*pFileSize = fileSize + strlen(versionStr);
157 
158 		return result;
159 	}
160 
161 	/**
162 	 * Returns the path to the current directory.
163 	 * @return              Returns a string containing the path to the current directory.
164 	 * If the path could not be determined, an empty string is returned.
165 	 * @remark              For cutting path elements '\' is used rather than '/' elements.
166 	 */
getCurrentDirectory()167 	Common::String getCurrentDirectory() { return _currentDirectory; }
168 	/**
169 	 * Changes the current directory.
170 	 * @param Directory     The path to the new directory. The path can be relative.
171 	 * @return              Returns true if the operation was successful, otherwise false.
172 	 * @remark              For cutting path elements '\' is used rather than '/' elements.
173 	 */
174 	bool changeDirectory(const Common::String &directory);
175 	/**
176 	 * Returns the absolute path to a file in the directory tree.
177 	 * @param FileName      The filename of the file whose absolute path is to be determined.
178 	 * These parameters may include both relative and absolute paths.
179 	 * @return              Returns an absolute path to the given file.
180 	 * @remark              For cutting path elements '\' is used rather than '/' elements.
181 	 */
182 	Common::String getAbsolutePath(const Common::String &fileName);
183 	/**
184 	 * Creates a BS_PackageManager::FileSearch object to search for files
185 	 * @param Filter        Specifies the search string. Wildcards of '*' and '?' are allowed
186 	 * @param Path          Specifies the directory that should be searched.
187 	 * @param TypeFilter    A combination of flags BS_PackageManager::FT_DIRECTORY and BS_PackageManager::FT_FILE.
188 	 * These flags indicate whether to search for files, directories, or both.
189 	 * The default is BS_PackageManager::FT_DIRECTORY | BS_PackageManager::FT_FILE
190 	 * @return              Specifies a pointer to a BS_PackageManager::FileSearch object, or NULL if no file was found.
191 	 * @remark              Do not forget to delete the object after use.
192 	*/
193 	int doSearch(Common::ArchiveMemberList &list, const Common::String &filter, const Common::String &path, uint typeFilter = FT_DIRECTORY | FT_FILE);
194 
195 	/**
196 	 * Determines whether a file exists
197 	 * @param FileName      The filename
198 	 * @return              Returns true if the file exists, otherwise false.
199 	 */
200 	bool fileExists(const Common::String &FileName);
201 
202 private:
203 	bool registerScriptBindings();
204 };
205 
206 } // End of namespace Sword25
207 
208 #endif
209