File: IArchive.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 (141 lines) | stat: -rw-r--r-- 4,311 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
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */

#ifndef _ARCHIVE_BASE_H
#define _ARCHIVE_BASE_H

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

#include "ArchiveTypes.h"
#include "System/Sync/SHA512.hpp"
#include "System/UnorderedMap.hpp"

/**
 * @brief Abstraction of different archive types
 *
 * Loosely resembles STL container:
 * for (unsigned int fid = 0; fid < NumFiles(); ++fid) {
 * 	//stuff
 * }
 */
class IArchive
{
protected:
	IArchive(const std::string& archiveFile): archiveFile(archiveFile) {
	}

public:
	virtual ~IArchive() {}

	virtual int GetType() const = 0;

	virtual bool IsOpen() = 0;
	const std::string& GetArchiveFile() const { return archiveFile; }

	/**
	 * @return The amount of files in the archive, does not change during
	 * lifetime
	 */
	virtual unsigned int NumFiles() const = 0;
	/**
	 * Returns whether the supplied fileId is valid and available in this
	 * archive.
	 */
	inline bool IsFileId(unsigned int fileId) const {
		return (fileId < NumFiles());
	}
	/**
	 * Returns true if the file exists in this archive.
	 * @param normalizedFilePath VFS path to the file in lower-case,
	 *   using forward-slashes, for example "maps/mymap.smf"
	 * @return true if the file exists in this archive, false otherwise
	 */
	bool FileExists(const std::string& normalizedFilePath) const {
		return (lcNameIndex.find(normalizedFilePath) != lcNameIndex.end());
	}

	/**
	 * Returns the fileID of a file.
	 * @param filePath VFS path to the file, for example "maps/myMap.smf"
	 * @return fileID of the file, NumFiles() if not found
	 */
	unsigned int FindFile(const std::string& filePath) const;
	/**
	 * Fetches the content of a file by its ID.
	 * @param fid file ID in [0, NumFiles())
	 * @param buffer on success, this will be filled with the contents
	 *   of the file
	 * @return true if the file was found, and its contents have been
	 *   successfully read into buffer
	 * @see GetFile(unsigned int fid, std::vector<std::uint8_t>& buffer)
	 */
	virtual bool GetFile(unsigned int fid, std::vector<std::uint8_t>& buffer) = 0;
	/**
	 * Fetches the content of a file by its name.
	 * @param name VFS path to the file, for example "maps/myMap.smf"
	 * @param buffer on success, this will be filled with the contents
	 *   of the file
	 * @return true if the file was found, and its contents have been
	 *   successfully read into buffer
	 * @see GetFile(unsigned int fid, std::vector<std::uint8_t>& buffer)
	 */
	bool GetFile(const std::string& name, std::vector<std::uint8_t>& buffer);

	std::pair<std::string, int> FileInfo(unsigned int fid) const {
		std::pair<std::string, int> info;
		FileInfo(fid, info.first, info.second);
		return info;
	}

	unsigned int ExtractedSize() const {
		unsigned int size = 0;

		// no archive should be larger than 4GB when extracted
		for (unsigned int fid = 0; fid < NumFiles(); fid++) {
			size += (FileInfo(fid).second);
		}

		return size;
	}

	/**
	 * Fetches the name and size in bytes of a file by its ID.
	 */
	virtual void FileInfo(unsigned int fid, std::string& name, int& size) const = 0;

	/**
	 * Returns true if the cost of reading the file is qualitatively relative
	 * to its file-size.
	 * This is mainly usefull in the case of solid archives,
	 * which may make the reading of a single small file over proportionally
	 * expensive.
	 * The returned value is usually relative to certain arbitrary chosen
	 * constants.
	 * Most implementations may always return true.
	 * @return true if cost is ~ relative to its file-size
	 */
	virtual bool HasLowReadingCost(unsigned int fid) const { return true; }

	/**
	 * @return true if archive type can be packed solid (which is VERY slow when reading)
	 */
	virtual bool CheckForSolid() const { return false; }
	/**
	 * Fetches the (SHA512) hash of a file by its ID.
	 */
	virtual bool CalcHash(uint32_t fid, uint8_t hash[sha512::SHA_LEN], std::vector<std::uint8_t>& fb);


protected:
	// Spring expects the contents of archives to be case-independent
	// this map (which must be populated by subclass archives) is kept
	// to allow converting back from lowercase to original case
	spring::unordered_map<std::string, unsigned int> lcNameIndex;

protected:
	/// "ExampleArchive.sdd"
	const std::string archiveFile;
};

#endif // _ARCHIVE_BASE_H