Panda3D
 All Classes Functions Variables Enumerations
multifile.h
1 // Filename: multifile.h
2 // Created by: mike (09Jan97)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #ifndef MULTIFILE_H
16 #define MULTIFILE_H
17 
18 #include "pandabase.h"
19 
20 #include "config_express.h"
21 #include "streamWrapper.h"
22 #include "subStream.h"
23 #include "filename.h"
24 #include "ordered_vector.h"
25 #include "indirectLess.h"
26 #include "referenceCount.h"
27 #include "pvector.h"
28 #include "openSSLWrapper.h"
29 
30 ////////////////////////////////////////////////////////////////////
31 // Class : Multifile
32 // Description : A file that contains a set of files.
33 ////////////////////////////////////////////////////////////////////
34 class EXPCL_PANDAEXPRESS Multifile : public ReferenceCount {
35 PUBLISHED:
36  Multifile();
37  ~Multifile();
38 
39 private:
40  Multifile(const Multifile &copy);
41  void operator = (const Multifile &copy);
42 
43 PUBLISHED:
44  BLOCKING bool open_read(const Filename &multifile_name, const streampos &offset = 0);
45  BLOCKING bool open_read(IStreamWrapper *multifile_stream, bool owns_pointer = false, const streampos &offset = 0);
46  BLOCKING bool open_write(const Filename &multifile_name);
47  BLOCKING bool open_write(ostream *multifile_stream, bool owns_pointer = false);
48  BLOCKING bool open_read_write(const Filename &multifile_name);
49  BLOCKING bool open_read_write(iostream *multifile_stream, bool owns_pointer = false);
50  BLOCKING void close();
51 
52  INLINE const Filename &get_multifile_name() const;
53  INLINE void set_multifile_name(const Filename &multifile_name);
54 
55  INLINE bool is_read_valid() const;
56  INLINE bool is_write_valid() const;
57  INLINE bool needs_repack() const;
58 
59  INLINE time_t get_timestamp() const;
60 
61  INLINE void set_record_timestamp(bool record_timestamp);
62  INLINE bool get_record_timestamp() const;
63 
64  void set_scale_factor(size_t scale_factor);
65  INLINE size_t get_scale_factor() const;
66 
67  INLINE void set_encryption_flag(bool flag);
68  INLINE bool get_encryption_flag() const;
69  INLINE void set_encryption_password(const string &encryption_password);
70  INLINE const string &get_encryption_password() const;
71 
72  INLINE void set_encryption_algorithm(const string &encryption_algorithm);
73  INLINE const string &get_encryption_algorithm() const;
74  INLINE void set_encryption_key_length(int encryption_key_length);
75  INLINE int get_encryption_key_length() const;
76  INLINE void set_encryption_iteration_count(int encryption_iteration_count);
77  INLINE int get_encryption_iteration_count() const;
78 
79  string add_subfile(const string &subfile_name, const Filename &filename,
80  int compression_level);
81  string add_subfile(const string &subfile_name, istream *subfile_data,
82  int compression_level);
83  string update_subfile(const string &subfile_name, const Filename &filename,
84  int compression_level);
85 
86 #ifdef HAVE_OPENSSL
87  bool add_signature(const Filename &certificate,
88  const Filename &chain,
89  const Filename &pkey,
90  const string &password = "");
91  bool add_signature(const Filename &composite,
92  const string &password = "");
93 
94  int get_num_signatures() const;
95  string get_signature_subject_name(int n) const;
96  string get_signature_friendly_name(int n) const;
97  string get_signature_public_key(int n) const;
98  void print_signature_certificate(int n, ostream &out) const;
99  void write_signature_certificate(int n, ostream &out) const;
100 
101  int validate_signature_certificate(int n) const;
102 #endif // HAVE_OPENSSL
103 
104  BLOCKING bool flush();
105  BLOCKING bool repack();
106 
107  int get_num_subfiles() const;
108  int find_subfile(const string &subfile_name) const;
109  bool has_directory(const string &subfile_name) const;
110  bool scan_directory(vector_string &contents,
111  const string &subfile_name) const;
112  void remove_subfile(int index);
113  INLINE bool remove_subfile(const string &subfile_name);
114  const string &get_subfile_name(int index) const;
115  MAKE_SEQ(get_subfile_names, get_num_subfiles, get_subfile_name);
116  size_t get_subfile_length(int index) const;
117  time_t get_subfile_timestamp(int index) const;
118  bool is_subfile_compressed(int index) const;
119  bool is_subfile_encrypted(int index) const;
120  bool is_subfile_text(int index) const;
121 
122  streampos get_index_end() const;
123  streampos get_subfile_internal_start(int index) const;
124  size_t get_subfile_internal_length(int index) const;
125 
126  BLOCKING INLINE string read_subfile(int index);
127  BLOCKING istream *open_read_subfile(int index);
128  BLOCKING static void close_read_subfile(istream *stream);
129  BLOCKING bool extract_subfile(int index, const Filename &filename);
130  BLOCKING bool extract_subfile_to(int index, ostream &out);
131  BLOCKING bool compare_subfile(int index, const Filename &filename);
132 
133  void output(ostream &out) const;
134  void ls(ostream &out = cout) const;
135 
136  static INLINE string get_magic_number();
137 
138  void set_header_prefix(const string &header_prefix);
139  INLINE const string &get_header_prefix() const;
140 
141 public:
142 #ifdef HAVE_OPENSSL
143  class CertRecord {
144  public:
145  INLINE CertRecord(X509 *cert);
146  INLINE CertRecord(const CertRecord &copy);
147  INLINE ~CertRecord();
148  INLINE void operator = (const CertRecord &other);
149  X509 *_cert;
150  };
151  typedef pvector<CertRecord> CertChain;
152 
153  bool add_signature(X509 *certificate, STACK_OF(X509) *chain, EVP_PKEY *pkey);
154  bool add_signature(const CertChain &chain, EVP_PKEY *pkey);
155 
156  const CertChain &get_signature(int n) const;
157 #endif // HAVE_OPENSSL
158 
159  bool read_subfile(int index, string &result);
160  bool read_subfile(int index, pvector<unsigned char> &result);
161 
162 private:
163  enum SubfileFlags {
164  SF_deleted = 0x0001,
165  SF_index_invalid = 0x0002,
166  SF_data_invalid = 0x0004,
167  SF_compressed = 0x0008,
168  SF_encrypted = 0x0010,
169  SF_signature = 0x0020,
170  SF_text = 0x0040,
171  };
172 
173  class Subfile {
174  public:
175  INLINE Subfile();
176  INLINE bool operator < (const Subfile &other) const;
177  streampos read_index(istream &read, streampos fpos,
178  Multifile *multfile);
179  streampos write_index(ostream &write, streampos fpos,
180  Multifile *multifile);
181  streampos write_data(ostream &write, istream *read, streampos fpos,
182  Multifile *multifile);
183  void rewrite_index_data_start(ostream &write, Multifile *multifile);
184  void rewrite_index_flags(ostream &write);
185  INLINE bool is_deleted() const;
186  INLINE bool is_index_invalid() const;
187  INLINE bool is_data_invalid() const;
188  INLINE bool is_cert_special() const;
189  INLINE streampos get_last_byte_pos() const;
190 
191  string _name;
192  streampos _index_start;
193  size_t _index_length;
194  streampos _data_start;
195  size_t _data_length;
196  size_t _uncompressed_length;
197  time_t _timestamp;
198  istream *_source;
199  Filename _source_filename;
200  int _flags;
201  int _compression_level; // Not preserved on disk.
202 #ifdef HAVE_OPENSSL
203  EVP_PKEY *_pkey; // Not preserved on disk.
204 #endif
205  };
206 
207  INLINE streampos word_to_streampos(size_t word) const;
208  INLINE size_t streampos_to_word(streampos fpos) const;
209  INLINE streampos normalize_streampos(streampos fpos) const;
210  streampos pad_to_streampos(streampos fpos);
211 
212  void add_new_subfile(Subfile *subfile, int compression_level);
213  istream *open_read_subfile(Subfile *subfile);
214  string standardize_subfile_name(const string &subfile_name) const;
215 
216  void clear_subfiles();
217  bool read_index();
218  bool write_header();
219 
220  void check_signatures();
221 
222  static INLINE char tohex(unsigned int nibble);
223 
225  Subfiles _subfiles;
227  PendingSubfiles _new_subfiles;
228  PendingSubfiles _removed_subfiles;
229  PendingSubfiles _cert_special;
230 
231 #ifdef HAVE_OPENSSL
232  typedef pvector<CertChain> Certificates;
233  Certificates _signatures;
234 #endif
235 
236  streampos _offset;
237  IStreamWrapper *_read;
238  ostream *_write;
239  bool _owns_stream;
240  streampos _next_index;
241  streampos _last_index;
242  streampos _last_data_byte;
243 
244  bool _needs_repack;
245  time_t _timestamp;
246  bool _timestamp_dirty;
247  bool _record_timestamp;
248  size_t _scale_factor;
249  size_t _new_scale_factor;
250 
251  bool _encryption_flag;
252  string _encryption_password;
253  string _encryption_algorithm;
254  int _encryption_key_length;
255  int _encryption_iteration_count;
256 
257  pifstream _read_file;
258  IStreamWrapper _read_filew;
259  pofstream _write_file;
260  pfstream _read_write_file;
261  StreamWrapper _read_write_filew;
262  Filename _multifile_name;
263  string _header_prefix;
264 
265  int _file_major_ver;
266  int _file_minor_ver;
267 
268  static const char _header[];
269  static const size_t _header_size;
270  static const int _current_major_ver;
271  static const int _current_minor_ver;
272 
273  static const char _encrypt_header[];
274  static const size_t _encrypt_header_size;
275 
276  friend class Subfile;
277 };
278 
279 #include "multifile.I"
280 
281 #endif
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:39
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.
Definition: streamWrapper.h:53
A base class for all things that want to be reference-counted.
A file that contains a set of files.
Definition: multifile.h:34