Panda3D
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
30 typedef struct x509_st X509;
31 typedef struct evp_pkey_st EVP_PKEY;
32 #endif
33 
34 /**
35  * A file that contains a set of files.
36  */
37 class EXPCL_PANDA_EXPRESS Multifile : public ReferenceCount {
38 PUBLISHED:
39  Multifile();
40  Multifile(const Multifile &copy) = delete;
41  ~Multifile();
42 
43  Multifile &operator = (const Multifile &copy) = delete;
44 
45 PUBLISHED:
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 
145 public:
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 
165 private:
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:39
This class provides a locking wrapper around an arbitrary istream pointer.
Definition: streamWrapper.h:59
A file that contains a set of files.
Definition: multifile.h:37
A base class for all things that want to be reference-counted.
This class provides a locking wrapper around a combination ostream/istream pointer.
A specialization of ordered_vector that emulates a standard STL set: one copy of each element is allo...
This is our own Panda specialization on the default STL vector.
Definition: pvector.h:42
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.