File: VFSHandler.h

package info (click to toggle)
spring 106.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 55,260 kB
  • sloc: cpp: 543,946; ansic: 44,800; python: 12,575; java: 12,201; awk: 5,889; sh: 1,796; asm: 1,546; xml: 655; perl: 405; php: 211; objc: 194; makefile: 76; sed: 2
file content (183 lines) | stat: -rw-r--r-- 5,697 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */

#ifndef _VFS_HANDLER_H
#define _VFS_HANDLER_H

#include <array>
#include <string>
#include <vector>
#include <cinttypes>

#include "System/UnorderedMap.hpp"

class IArchive;

/**
 * Main API for accessing the Virtual File System (VFS).
 * This only allows accessing the VFS (files in archives
 * registered with the VFS), NOT the real file system.
 */
class CVFSHandler
{
public:
	CVFSHandler(const char* s) { SetName(s); ReserveArchives(); }
	~CVFSHandler() { DeleteArchives(); }

	const char* GetName() const { return vfsName; }

	void SetName(const char* s) { vfsName = s; }

	void BlockInsertArchive() { insertAllowed = false; }
	void AllowInsertArchive() { insertAllowed =  true; }
	void BlockRemoveArchive() { removeAllowed = false; }
	void AllowRemoveArchive() { removeAllowed =  true; }


	enum Section: int {
		Mod,
		Map,
		Base,
		Menu,
		Temp,
		TempMod,
		TempMap,
		TempBase,
		TempMenu,
		Count,
		Error
	};

	static Section GetModeSection(char mode);
	static Section GetModTypeSection(int modtype);
	static Section GetArchiveSection(const std::string& archiveName);
	static Section GetTempArchiveSection(const std::string& archiveName) {
		return Section(GetArchiveSection(archiveName) + (Section::TempMod - Section::Mod));
	}


	static void GrabLock();
	static void FreeLock();
	static void FreeInstance(CVFSHandler* handler);
	static void FreeGlobalInstance();
	static void SetGlobalInstance(CVFSHandler* handler);
	static void SetGlobalInstanceRaw(CVFSHandler* handler);

	static CVFSHandler* GetGlobalInstance();


	/**
	 * Checks whether a file exists in the VFS (does not work for dirs).
	 * This is cheaper then calling LoadFile, if you do not require the contents
	 * of the file.
	 * @param filePath raw file path, for example "maps/myMap.smf",
	 *   case-insensitive
	 * @return 1 (or 0 if empty) if the file exists in the VFS, -1 otherwise
	 */
	int FileExists(const std::string& filePath, Section section);

	/**
	 * Returns the absolute path of a VFS file (does not work for dirs).
	 * @param filePath VFS relative file path, for example "maps/myMap.smf",
	 *   case-insensitive
	 * @return absoluteFilePath if the file exists in the VFS, "" otherwise
	 */
	std::string GetFileAbsolutePath(const std::string& filePath, Section section);

	/**
	 * Returns the archive name containing a VFS file (does not work for dirs).
	 * @param filePath VFS relative file path, for example "maps/myMap.smf",
	 *   case-insensitive
	 * @return archiveName if the file exists in the VFS, "" otherwise
	 */
	std::string GetFileArchiveName(const std::string& filePath, Section section);

	/**
	 * Returns a collection of all loaded archives.
	 */
	std::vector<std::string> GetAllArchiveNames() const;

	/**
	 * Reads the contents of a file from within the VFS.
	 * @param filePath raw file path, for example "maps/myMap.smf",
	 *   case-insensitive
	 * @return 1 if the file exists in the VFS and was successfully read
	 */
	int LoadFile(const std::string& filePath, std::vector<std::uint8_t>& buffer, Section section);


	/**
	 * Returns all the files in the given (virtual) directory without the
	 * preceeding pathname.
	 * @param dir raw directory path, for example "maps/" or "maps",
	 *   case-insensitive
	 */
	std::vector<std::string> GetFilesInDir(const std::string& dir, Section section);

	/**
	 * Returns all the sub-directories in the given (virtual) directory without
	 * the preceeding pathname.
	 * @param dir raw directory path, for example "maps/" or "maps",
	 *   case-insensitive
	 */
	std::vector<std::string> GetDirsInDir(const std::string& dir, Section section);


	bool HasTempArchive(const std::string& archiveName) const { return (HasArchive(archiveName, GetTempArchiveSection(archiveName))); }

	bool HasArchive(const std::string& archiveName) const { return (HasArchive(archiveName, GetArchiveSection(archiveName))); }
	bool HasArchive(const std::string& archiveName, Section archiveSection) const;

	/**
	 * Adds an archive to the VFS.
	 * @param override determines whether in case of a conflict, the existing
	 *   entry in the VFS is overwritten or not.
	 */
	bool AddArchive(const std::string& archiveName, bool overwrite);
	bool AddArchiveIf(const std::string& archiveName, bool overwrite) {
		return (!archiveName.empty() && !HasArchive(archiveName) && AddArchive(archiveName, overwrite));
	}

	/**
	 * Adds an archive and all of its dependencies to the VFS.
	 * @param override determines whether an existing entry in the VFS is overwritten or not.
	 */
	bool AddArchiveWithDeps(const std::string& archiveName, bool overwrite);

	/**
	 * Removes an archive from the VFS.
	 * @return true if the archive is not loaded anymore; it was not loaded
	 *   in the first place, or was unloaded successfully.
	 */
	bool RemoveArchive(const std::string& archiveName);

	void DeleteArchives();
	void DeleteArchives(Section section);
	void ReserveArchives();

	void UnMapArchives(bool reload = false);
	void ReMapArchives(bool reload = false);
	void SwapArchiveSections(Section src, Section dst);

private:
	struct FileData {
		IArchive* ar;
		int size;
	};
	typedef std::pair<std::string, FileData> FileEntry;

	std::string GetNormalizedPath(const std::string& rawPath);
	FileData GetFileData(const std::string& normalizedFilePath, Section section) const;

private:
	std::array<std::vector<FileEntry>, Section::Count> files;
	std::array<spring::unordered_map<std::string, IArchive*>, Section::Count> archives;

	const char* vfsName = "";

	bool insertAllowed = true;
	bool removeAllowed = true;
};

#define vfsHandler (CVFSHandler::GetGlobalInstance())

#endif // _VFS_HANDLER_H