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 	bool _extractedFiles;
91 	Common::String _directoryName;
92 
93 	bool _useEnglishSpeech;
94 	Common::String ensureSpeechLang(const Common::String &fileName);
95 
96 	Common::ArchiveMemberPtr getArchiveMember(const Common::String &fileName);
97 
98 public:
99 	PackageManager(Kernel *pKernel);
100 	~PackageManager() override;
101 
102 	enum FILE_TYPES {
103 		FT_DIRECTORY    = (1 << 0),
104 		FT_FILE         = (1 << 1)
105 	};
106 
107 	/**
108 	 *
109 	 * Set the PackageManager to run on extracted game files.s
110 	 */
setRunWithExtractedFiles(const Common::String & directoryName)111 	void setRunWithExtractedFiles(const Common::String &directoryName) {
112 		_extractedFiles = true;
113 		_directoryName = directoryName;
114 	}
115 
116 	/**
117 	 * Mounts the contents of a package in the directory specified in the directory tree.
118 	 * @param FileName      The filename of the package to mount
119 	 * @param MountPosition The directory name under which the package should be mounted
120 	 * @return              Returns true if the mount was successful, otherwise false.
121 	 */
122 	bool loadPackage(const Common::String &fileName, const Common::String &mountPosition);
123 	/**
124 	 * Mounts the contents of a directory in the specified directory in the directory tree.
125 	 * @param               The name of the directory to mount
126 	 * @param MountPosition The directory name under which the package should be mounted
127 	 * @return              Returns true if the mount was successful, otherwise false.
128 	 */
129 	bool loadDirectoryAsPackage(const Common::String &directoryName, const Common::String &mountPosition);
130 	/**
131 	 * Downloads a file from the directory tree
132 	 * @param FileName      The filename of the file to load
133 	 * @param pFileSize     Pointer to the variable that will contain the size of the loaded file. The deafult is NULL.
134 	 * @return              Specifies a pointer to the loaded data of the file
135 	 * @remark              The client must not forget to release the data of the file using BE_DELETE_A.
136 	 */
137 	byte *getFile(const Common::String &fileName, uint *pFileSize = NULL);
138 
139 	/**
140 	 * Returns a stream from file file from the directory tree
141 	 * @param FileName      The filename of the file to load
142 	 * @return              Pointer to the stream object
143 	 */
144 	Common::SeekableReadStream *getStream(const Common::String &fileName);
145 	/**
146 	 * Downloads an XML file and prefixes it with an XML Version key, since the XML files don't contain it,
147 	 * and it is required for ScummVM to correctly parse the XML.
148 	 * @param FileName      The filename of the file to load
149 	 * @param pFileSize     Pointer to the variable that will contain the size of the loaded file. The deafult is NULL.
150 	 * @return              Specifies a pointer to the loaded data of the file
151 	 * @remark              The client must not forget to release the data of the file using BE_DELETE_A.
152 	 */
153 	char *getXmlFile(const Common::String &fileName, uint *pFileSize = NULL) {
154 		const char *versionStr = "<?xml version=\"1.0\"?>";
155 		uint fileSize;
156 		char *data = (char *)getFile(fileName, &fileSize);
157 		char *result = (char *)malloc(fileSize + strlen(versionStr) + 1);
158 		if (!result)
159 			error("[PackageManager::getXmlFile] Cannot allocate memory");
160 
161 		strcpy(result, versionStr);
162 		Common::copy(data, data + fileSize, result + strlen(versionStr));
163 		result[fileSize + strlen(versionStr)] = '\0';
164 
165 		delete[] data;
166 		if (pFileSize)
167 			*pFileSize = fileSize + strlen(versionStr);
168 
169 		return result;
170 	}
171 
172 	/**
173 	 * Returns the path to the current directory.
174 	 * @return              Returns a string containing the path to the current directory.
175 	 * If the path could not be determined, an empty string is returned.
176 	 * @remark              For cutting path elements '\' is used rather than '/' elements.
177 	 */
getCurrentDirectory()178 	Common::String getCurrentDirectory() { return _currentDirectory; }
179 	/**
180 	 * Changes the current directory.
181 	 * @param Directory     The path to the new directory. The path can be relative.
182 	 * @return              Returns true if the operation was successful, otherwise false.
183 	 * @remark              For cutting path elements '\' is used rather than '/' elements.
184 	 */
185 	bool changeDirectory(const Common::String &directory);
186 	/**
187 	 * Returns the absolute path to a file in the directory tree.
188 	 * @param FileName      The filename of the file whose absolute path is to be determined.
189 	 * These parameters may include both relative and absolute paths.
190 	 * @return              Returns an absolute path to the given file.
191 	 * @remark              For cutting path elements '\' is used rather than '/' elements.
192 	 */
193 	Common::String getAbsolutePath(const Common::String &fileName);
194 	/**
195 	 * Creates a BS_PackageManager::FileSearch object to search for files
196 	 * @param Filter        Specifies the search string. Wildcards of '*' and '?' are allowed
197 	 * @param Path          Specifies the directory that should be searched.
198 	 * @param TypeFilter    A combination of flags BS_PackageManager::FT_DIRECTORY and BS_PackageManager::FT_FILE.
199 	 * These flags indicate whether to search for files, directories, or both.
200 	 * The default is BS_PackageManager::FT_DIRECTORY | BS_PackageManager::FT_FILE
201 	 * @return              Specifies a pointer to a BS_PackageManager::FileSearch object, or NULL if no file was found.
202 	 * @remark              Do not forget to delete the object after use.
203 	*/
204 	int doSearch(Common::ArchiveMemberList &list, const Common::String &filter, const Common::String &path, uint typeFilter = FT_DIRECTORY | FT_FILE);
205 
206 	/**
207 	 * Determines whether a file exists
208 	 * @param FileName      The filename
209 	 * @return              Returns true if the file exists, otherwise false.
210 	 */
211 	bool fileExists(const Common::String &FileName);
212 
213 private:
214 	bool registerScriptBindings();
215 };
216 
217 } // End of namespace Sword25
218 
219 #endif
220