Panda3D
Loading...
Searching...
No Matches
multifile.h
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file multifile.h
10 * @author mike
11 * @date 1997-01-09
12 */
13
14#ifndef MULTIFILE_H
15#define MULTIFILE_H
16
17#include "pandabase.h"
18
19#include "config_express.h"
20#include "streamWrapper.h"
21#include "subStream.h"
22#include "filename.h"
23#include "ordered_vector.h"
24#include "indirectLess.h"
25#include "referenceCount.h"
26#include "pvector.h"
27#include "vector_uchar.h"
28
29#ifdef HAVE_OPENSSL
30typedef struct x509_st X509;
31typedef struct evp_pkey_st EVP_PKEY;
32#endif
33
34/**
35 * A file that contains a set of files.
36 */
37class EXPCL_PANDA_EXPRESS Multifile : public ReferenceCount {
38PUBLISHED:
39 Multifile();
40 Multifile(const Multifile &copy) = delete;
41 ~Multifile();
42
43 Multifile &operator = (const Multifile &copy) = delete;
44
45PUBLISHED:
46 BLOCKING bool open_read(const Filename &multifile_name, const std::streampos &offset = 0);
47 BLOCKING bool open_read(IStreamWrapper *multifile_stream, bool owns_pointer = false, const std::streampos &offset = 0);
48 BLOCKING bool open_write(const Filename &multifile_name);
49 BLOCKING bool open_write(std::ostream *multifile_stream, bool owns_pointer = false);
50 BLOCKING bool open_read_write(const Filename &multifile_name);
51 BLOCKING bool open_read_write(std::iostream *multifile_stream, bool owns_pointer = false);
52 BLOCKING void close();
53
54 INLINE const Filename &get_multifile_name() const;
55 INLINE void set_multifile_name(const Filename &multifile_name);
56
57 INLINE bool is_read_valid() const;
58 INLINE bool is_write_valid() const;
59 INLINE bool needs_repack() const;
60
61 INLINE time_t get_timestamp() const;
62 INLINE void set_timestamp(time_t timestamp);
63
64 INLINE void set_record_timestamp(bool record_timestamp);
65 INLINE bool get_record_timestamp() const;
66
67 void set_scale_factor(size_t scale_factor);
68 INLINE size_t get_scale_factor() const;
69
70 INLINE void set_encryption_flag(bool flag);
71 INLINE bool get_encryption_flag() const;
72 INLINE void set_encryption_password(const std::string &encryption_password);
73 INLINE const std::string &get_encryption_password() const;
74
75 INLINE void set_encryption_algorithm(const std::string &encryption_algorithm);
76 INLINE const std::string &get_encryption_algorithm() const;
77 INLINE void set_encryption_key_length(int encryption_key_length);
78 INLINE int get_encryption_key_length() const;
79 INLINE void set_encryption_iteration_count(int encryption_iteration_count);
80 INLINE int get_encryption_iteration_count() const;
81
82 std::string add_subfile(const std::string &subfile_name, const Filename &filename,
83 int compression_level);
84 std::string add_subfile(const std::string &subfile_name, std::istream *subfile_data,
85 int compression_level);
86 std::string update_subfile(const std::string &subfile_name, const Filename &filename,
87 int compression_level);
88
89#ifdef HAVE_OPENSSL
90 bool add_signature(const Filename &certificate,
91 const Filename &chain,
92 const Filename &pkey,
93 const std::string &password = "");
94 bool add_signature(const Filename &composite,
95 const std::string &password = "");
96
97 int get_num_signatures() const;
98 std::string get_signature_subject_name(int n) const;
99 std::string get_signature_friendly_name(int n) const;
100 std::string get_signature_public_key(int n) const;
101 void print_signature_certificate(int n, std::ostream &out) const;
102 void write_signature_certificate(int n, std::ostream &out) const;
103
104 int validate_signature_certificate(int n) const;
105#endif // HAVE_OPENSSL
106
107 BLOCKING bool flush();
108 BLOCKING bool repack();
109
110 int get_num_subfiles() const;
111 int find_subfile(const std::string &subfile_name) const;
112 bool has_directory(const std::string &subfile_name) const;
113 bool scan_directory(vector_string &contents,
114 const std::string &subfile_name) const;
115 void remove_subfile(int index);
116 INLINE bool remove_subfile(const std::string &subfile_name);
117 const std::string &get_subfile_name(int index) const;
118 MAKE_SEQ(get_subfile_names, get_num_subfiles, get_subfile_name);
119 size_t get_subfile_length(int index) const;
120 time_t get_subfile_timestamp(int index) const;
121 bool is_subfile_compressed(int index) const;
122 bool is_subfile_encrypted(int index) const;
123 bool is_subfile_text(int index) const;
124
125 std::streampos get_index_end() const;
126 std::streampos get_subfile_internal_start(int index) const;
127 size_t get_subfile_internal_length(int index) const;
128
129 BLOCKING INLINE vector_uchar read_subfile(int index);
130 BLOCKING std::istream *open_read_subfile(int index);
131 BLOCKING static void close_read_subfile(std::istream *stream);
132 BLOCKING bool extract_subfile(int index, const Filename &filename);
133 BLOCKING bool extract_subfile_to(int index, std::ostream &out);
134 BLOCKING bool compare_subfile(int index, const Filename &filename);
135
136 void output(std::ostream &out) const;
137 void ls(std::ostream &out = std::cout) const;
138
139 static INLINE std::string get_magic_number();
140 MAKE_PROPERTY(magic_number, get_magic_number);
141
142 void set_header_prefix(const std::string &header_prefix);
143 INLINE const std::string &get_header_prefix() const;
144
145public:
146#ifdef HAVE_OPENSSL
147 class CertRecord {
148 public:
149 INLINE CertRecord(X509 *cert);
150 INLINE CertRecord(const CertRecord &copy);
151 INLINE ~CertRecord();
152 INLINE void operator = (const CertRecord &other);
153 X509 *_cert;
154 };
155 typedef pvector<CertRecord> CertChain;
156
157 bool add_signature(const CertChain &chain, EVP_PKEY *pkey);
158
159 const CertChain &get_signature(int n) const;
160#endif // HAVE_OPENSSL
161
162 bool read_subfile(int index, std::string &result);
163 bool read_subfile(int index, vector_uchar &result);
164
165private:
166 enum SubfileFlags {
167 SF_deleted = 0x0001,
168 SF_index_invalid = 0x0002,
169 SF_data_invalid = 0x0004,
170 SF_compressed = 0x0008,
171 SF_encrypted = 0x0010,
172 SF_signature = 0x0020,
173 SF_text = 0x0040,
174 };
175
176 class Subfile {
177 public:
178 INLINE Subfile();
179 INLINE bool operator < (const Subfile &other) const;
180 std::streampos read_index(std::istream &read, std::streampos fpos,
181 Multifile *multfile);
182 std::streampos write_index(std::ostream &write, std::streampos fpos,
183 Multifile *multifile);
184 std::streampos write_data(std::ostream &write, std::istream *read, std::streampos fpos,
185 Multifile *multifile);
186 void rewrite_index_data_start(std::ostream &write, Multifile *multifile);
187 void rewrite_index_flags(std::ostream &write);
188 INLINE bool is_deleted() const;
189 INLINE bool is_index_invalid() const;
190 INLINE bool is_data_invalid() const;
191 INLINE bool is_cert_special() const;
192 INLINE std::streampos get_last_byte_pos() const;
193
194 std::string _name;
195 std::streampos _index_start;
196 size_t _index_length;
197 std::streampos _data_start;
198 size_t _data_length;
199 size_t _uncompressed_length;
200 time_t _timestamp;
201 std::istream *_source;
202 Filename _source_filename;
203 int _flags;
204 int _compression_level; // Not preserved on disk.
205#ifdef HAVE_OPENSSL
206 EVP_PKEY *_pkey; // Not preserved on disk.
207#endif
208 };
209
210 INLINE std::streampos word_to_streampos(size_t word) const;
211 INLINE size_t streampos_to_word(std::streampos fpos) const;
212 INLINE std::streampos normalize_streampos(std::streampos fpos) const;
213 std::streampos pad_to_streampos(std::streampos fpos);
214
215 void add_new_subfile(Subfile *subfile, int compression_level);
216 std::istream *open_read_subfile(Subfile *subfile);
217 std::string standardize_subfile_name(const std::string &subfile_name) const;
218
219 void clear_subfiles();
220 bool read_index();
221 bool write_header();
222
223 void check_signatures();
224
225 static INLINE char tohex(unsigned int nibble);
226
227 typedef ov_set<Subfile *, IndirectLess<Subfile> > Subfiles;
228 Subfiles _subfiles;
229 typedef pvector<Subfile *> PendingSubfiles;
230 PendingSubfiles _new_subfiles;
231 PendingSubfiles _removed_subfiles;
232 PendingSubfiles _cert_special;
233
234#ifdef HAVE_OPENSSL
235 typedef pvector<CertChain> Certificates;
236 Certificates _signatures;
237#endif
238
239 std::streampos _offset;
240 IStreamWrapper *_read;
241 std::ostream *_write;
242 bool _owns_stream;
243 std::streampos _next_index;
244 std::streampos _last_index;
245 std::streampos _last_data_byte;
246
247 bool _needs_repack;
248 time_t _timestamp;
249 bool _timestamp_dirty;
250 bool _record_timestamp;
251 size_t _scale_factor;
252 size_t _new_scale_factor;
253
254 bool _encryption_flag;
255 std::string _encryption_password;
256 std::string _encryption_algorithm;
257 int _encryption_key_length;
258 int _encryption_iteration_count;
259
260 pifstream _read_file;
261 IStreamWrapper _read_filew;
262 pofstream _write_file;
263 pfstream _read_write_file;
264 StreamWrapper _read_write_filew;
265 Filename _multifile_name;
266 std::string _header_prefix;
267
268 int _file_major_ver;
269 int _file_minor_ver;
270
271 static const char _header[];
272 static const size_t _header_size;
273 static const int _current_major_ver;
274 static const int _current_minor_ver;
275
276 static const char _encrypt_header[];
277 static const size_t _encrypt_header_size;
278
279 friend class Subfile;
280};
281
282#include "multifile.I"
283
284#endif
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
This class provides a locking wrapper around an arbitrary istream pointer.
void set_header_prefix(const std::string &header_prefix)
Sets the string which is written to the Multifile before the Multifile header.
bool get_encryption_flag() const
Returns the flag indicating whether subsequently-added subfiles should be encrypted before writing th...
Definition multifile.I:143
const Filename & get_multifile_name() const
Returns the filename of the Multifile, if it is available.
Definition multifile.I:18
size_t get_scale_factor() const
Returns the internal scale factor for this Multifile.
Definition multifile.I:113
bool compare_subfile(int index, const Filename &filename)
Performs a byte-for-byte comparison of the indicated file on disk with the nth subfile.
bool is_subfile_text(int index) const
Returns true if the indicated subfile represents text data, or false if it represents binary data.
bool open_read_write(const Filename &multifile_name)
Opens the named Multifile on disk for reading and writing.
std::string update_subfile(const std::string &subfile_name, const Filename &filename, int compression_level)
Adds a file on disk to the subfile.
bool has_directory(const std::string &subfile_name) const
Returns true if the indicated subfile name is the directory prefix to one or more files within the Mu...
bool extract_subfile_to(int index, std::ostream &out)
Extracts the nth subfile to the indicated ostream.
std::streampos get_index_end() const
Returns the first byte that is guaranteed to follow any index byte already written to disk in the Mul...
void close()
Closes the Multifile if it is open.
bool scan_directory(vector_string &contents, const std::string &subfile_name) const
Considers subfile_name to be the name of a subdirectory within the Multifile, but not a file itself; ...
get_num_subfiles
Returns the number of subfiles within the Multifile.
Definition multifile.h:118
int get_encryption_iteration_count() const
Returns the value that was specified by set_encryption_iteration_count().
Definition multifile.I:267
void set_record_timestamp(bool record_timestamp)
Sets the flag indicating whether timestamps should be recorded within the Multifile or not.
Definition multifile.I:94
bool flush()
Writes all contents of the Multifile to disk.
bool is_subfile_compressed(int index) const
Returns true if the indicated subfile has been compressed when stored within the archive,...
static void close_read_subfile(std::istream *stream)
Closes a file opened by a previous call to open_read_subfile().
int find_subfile(const std::string &subfile_name) const
Returns the index of the subfile with the indicated name, or -1 if the named subfile is not within th...
time_t get_subfile_timestamp(int index) const
Returns the modification time of the nth subfile.
void set_encryption_key_length(int encryption_key_length)
Specifies the length of the key, in bits, that should be used to encrypt the stream in future calls t...
Definition multifile.I:222
bool get_record_timestamp() const
Returns the flag indicating whether timestamps should be recorded within the Multifile or not.
Definition multifile.I:104
bool is_write_valid() const
Returns true if the Multifile has been opened for write mode and there have been no errors,...
Definition multifile.I:46
void set_scale_factor(size_t scale_factor)
Changes the internal scale factor for this Multifile.
void set_timestamp(time_t timestamp)
Changes the overall modification timestamp of the multifile.
Definition multifile.I:76
void set_encryption_algorithm(const std::string &encryption_algorithm)
Specifies the encryption algorithm that should be used for future calls to add_subfile().
Definition multifile.I:190
size_t get_subfile_length(int index) const
Returns the uncompressed data length of the nth subfile.
void set_encryption_flag(bool flag)
Sets the flag indicating whether subsequently-added subfiles should be encrypted before writing them ...
Definition multifile.I:127
bool is_subfile_encrypted(int index) const
Returns true if the indicated subfile has been encrypted when stored within the archive,...
time_t get_timestamp() const
Returns the modification timestamp of the overall Multifile.
Definition multifile.I:66
void set_encryption_iteration_count(int encryption_iteration_count)
Specifies the number of times to repeatedly hash the key before writing it to the stream in future ca...
Definition multifile.I:256
int get_encryption_key_length() const
Returns the encryption key length, in bits, that was specified by set_encryption_key_length().
Definition multifile.I:236
void set_encryption_password(const std::string &encryption_password)
Specifies the password that will be used to encrypt subfiles subsequently added to the multifile,...
Definition multifile.I:157
const std::string & get_header_prefix() const
Returns the string that preceded the Multifile header on the file, if any.
Definition multifile.I:316
bool needs_repack() const
Returns true if the Multifile index is suboptimal and should be repacked.
Definition multifile.I:55
bool repack()
Forces a complete rewrite of the Multifile and all of its contents, so that its index will appear at ...
std::streampos get_subfile_internal_start(int index) const
Returns the starting byte position within the Multifile at which the indicated subfile begins.
const std::string & get_encryption_algorithm() const
Returns the encryption algorithm that was specified by set_encryption_algorithm().
Definition multifile.I:204
std::istream * open_read_subfile(int index)
Returns an istream that may be used to read the indicated subfile.
bool open_write(const Filename &multifile_name)
Opens the named Multifile on disk for writing.
size_t get_subfile_internal_length(int index) const
Returns the number of bytes the indicated subfile consumes within the archive.
get_magic_number
Returns a string with the first n bytes written to a Multifile, to identify it as a Multifile.
Definition multifile.h:140
void set_multifile_name(const Filename &multifile_name)
Replaces the filename of the Multifile.
Definition multifile.I:28
bool is_read_valid() const
Returns true if the Multifile has been opened for read mode and there have been no errors,...
Definition multifile.I:37
void remove_subfile(int index)
Removes the nth subfile from the Multifile.
get_subfile_name
Returns the name of the nth subfile.
Definition multifile.h:118
vector_uchar read_subfile(int index)
Returns a vector_uchar that contains the entire contents of the indicated subfile.
Definition multifile.I:296
const std::string & get_encryption_password() const
Returns the password that will be used to encrypt subfiles subsequently added to the multifile.
Definition multifile.I:171
void ls(std::ostream &out=std::cout) const
Shows a list of all subfiles within the Multifile.
std::string add_subfile(const std::string &subfile_name, const Filename &filename, int compression_level)
Adds a file on disk as a subfile to the Multifile.
bool extract_subfile(int index, const Filename &filename)
Extracts the nth subfile into a file with the given name.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.