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 
63  INLINE void set_record_timestamp(bool record_timestamp);
64  INLINE bool get_record_timestamp() const;
65 
66  void set_scale_factor(size_t scale_factor);
67  INLINE size_t get_scale_factor() const;
68 
69  INLINE void set_encryption_flag(bool flag);
70  INLINE bool get_encryption_flag() const;
71  INLINE void set_encryption_password(const std::string &encryption_password);
72  INLINE const std::string &get_encryption_password() const;
73 
74  INLINE void set_encryption_algorithm(const std::string &encryption_algorithm);
75  INLINE const std::string &get_encryption_algorithm() const;
76  INLINE void set_encryption_key_length(int encryption_key_length);
77  INLINE int get_encryption_key_length() const;
78  INLINE void set_encryption_iteration_count(int encryption_iteration_count);
79  INLINE int get_encryption_iteration_count() const;
80 
81  std::string add_subfile(const std::string &subfile_name, const Filename &filename,
82  int compression_level);
83  std::string add_subfile(const std::string &subfile_name, std::istream *subfile_data,
84  int compression_level);
85  std::string update_subfile(const std::string &subfile_name, const Filename &filename,
86  int compression_level);
87 
88 #ifdef HAVE_OPENSSL
89  bool add_signature(const Filename &certificate,
90  const Filename &chain,
91  const Filename &pkey,
92  const std::string &password = "");
93  bool add_signature(const Filename &composite,
94  const std::string &password = "");
95 
96  int get_num_signatures() const;
97  std::string get_signature_subject_name(int n) const;
98  std::string get_signature_friendly_name(int n) const;
99  std::string get_signature_public_key(int n) const;
100  void print_signature_certificate(int n, std::ostream &out) const;
101  void write_signature_certificate(int n, std::ostream &out) const;
102 
103  int validate_signature_certificate(int n) const;
104 #endif // HAVE_OPENSSL
105 
106  BLOCKING bool flush();
107  BLOCKING bool repack();
108 
109  int get_num_subfiles() const;
110  int find_subfile(const std::string &subfile_name) const;
111  bool has_directory(const std::string &subfile_name) const;
112  bool scan_directory(vector_string &contents,
113  const std::string &subfile_name) const;
114  void remove_subfile(int index);
115  INLINE bool remove_subfile(const std::string &subfile_name);
116  const std::string &get_subfile_name(int index) const;
117  MAKE_SEQ(get_subfile_names, get_num_subfiles, get_subfile_name);
118  size_t get_subfile_length(int index) const;
119  time_t get_subfile_timestamp(int index) const;
120  bool is_subfile_compressed(int index) const;
121  bool is_subfile_encrypted(int index) const;
122  bool is_subfile_text(int index) const;
123 
124  std::streampos get_index_end() const;
125  std::streampos get_subfile_internal_start(int index) const;
126  size_t get_subfile_internal_length(int index) const;
127 
128  BLOCKING INLINE vector_uchar read_subfile(int index);
129  BLOCKING std::istream *open_read_subfile(int index);
130  BLOCKING static void close_read_subfile(std::istream *stream);
131  BLOCKING bool extract_subfile(int index, const Filename &filename);
132  BLOCKING bool extract_subfile_to(int index, std::ostream &out);
133  BLOCKING bool compare_subfile(int index, const Filename &filename);
134 
135  void output(std::ostream &out) const;
136  void ls(std::ostream &out = std::cout) const;
137 
138  static INLINE std::string get_magic_number();
139  MAKE_PROPERTY(magic_number, get_magic_number);
140 
141  void set_header_prefix(const std::string &header_prefix);
142  INLINE const std::string &get_header_prefix() const;
143 
144 public:
145 #ifdef HAVE_OPENSSL
146  class CertRecord {
147  public:
148  INLINE CertRecord(X509 *cert);
149  INLINE CertRecord(const CertRecord &copy);
150  INLINE ~CertRecord();
151  INLINE void operator = (const CertRecord &other);
152  X509 *_cert;
153  };
154  typedef pvector<CertRecord> CertChain;
155 
156  bool add_signature(const CertChain &chain, EVP_PKEY *pkey);
157 
158  const CertChain &get_signature(int n) const;
159 #endif // HAVE_OPENSSL
160 
161  bool read_subfile(int index, std::string &result);
162  bool read_subfile(int index, vector_uchar &result);
163 
164 private:
165  enum SubfileFlags {
166  SF_deleted = 0x0001,
167  SF_index_invalid = 0x0002,
168  SF_data_invalid = 0x0004,
169  SF_compressed = 0x0008,
170  SF_encrypted = 0x0010,
171  SF_signature = 0x0020,
172  SF_text = 0x0040,
173  };
174 
175  class Subfile {
176  public:
177  INLINE Subfile();
178  INLINE bool operator < (const Subfile &other) const;
179  std::streampos read_index(std::istream &read, std::streampos fpos,
180  Multifile *multfile);
181  std::streampos write_index(std::ostream &write, std::streampos fpos,
182  Multifile *multifile);
183  std::streampos write_data(std::ostream &write, std::istream *read, std::streampos fpos,
184  Multifile *multifile);
185  void rewrite_index_data_start(std::ostream &write, Multifile *multifile);
186  void rewrite_index_flags(std::ostream &write);
187  INLINE bool is_deleted() const;
188  INLINE bool is_index_invalid() const;
189  INLINE bool is_data_invalid() const;
190  INLINE bool is_cert_special() const;
191  INLINE std::streampos get_last_byte_pos() const;
192 
193  std::string _name;
194  std::streampos _index_start;
195  size_t _index_length;
196  std::streampos _data_start;
197  size_t _data_length;
198  size_t _uncompressed_length;
199  time_t _timestamp;
200  std::istream *_source;
201  Filename _source_filename;
202  int _flags;
203  int _compression_level; // Not preserved on disk.
204 #ifdef HAVE_OPENSSL
205  EVP_PKEY *_pkey; // Not preserved on disk.
206 #endif
207  };
208 
209  INLINE std::streampos word_to_streampos(size_t word) const;
210  INLINE size_t streampos_to_word(std::streampos fpos) const;
211  INLINE std::streampos normalize_streampos(std::streampos fpos) const;
212  std::streampos pad_to_streampos(std::streampos fpos);
213 
214  void add_new_subfile(Subfile *subfile, int compression_level);
215  std::istream *open_read_subfile(Subfile *subfile);
216  std::string standardize_subfile_name(const std::string &subfile_name) const;
217 
218  void clear_subfiles();
219  bool read_index();
220  bool write_header();
221 
222  void check_signatures();
223 
224  static INLINE char tohex(unsigned int nibble);
225 
226  typedef ov_set<Subfile *, IndirectLess<Subfile> > Subfiles;
227  Subfiles _subfiles;
228  typedef pvector<Subfile *> PendingSubfiles;
229  PendingSubfiles _new_subfiles;
230  PendingSubfiles _removed_subfiles;
231  PendingSubfiles _cert_special;
232 
233 #ifdef HAVE_OPENSSL
234  typedef pvector<CertChain> Certificates;
235  Certificates _signatures;
236 #endif
237 
238  std::streampos _offset;
239  IStreamWrapper *_read;
240  std::ostream *_write;
241  bool _owns_stream;
242  std::streampos _next_index;
243  std::streampos _last_index;
244  std::streampos _last_data_byte;
245 
246  bool _needs_repack;
247  time_t _timestamp;
248  bool _timestamp_dirty;
249  bool _record_timestamp;
250  size_t _scale_factor;
251  size_t _new_scale_factor;
252 
253  bool _encryption_flag;
254  std::string _encryption_password;
255  std::string _encryption_algorithm;
256  int _encryption_key_length;
257  int _encryption_iteration_count;
258 
259  pifstream _read_file;
260  IStreamWrapper _read_filew;
261  pofstream _write_file;
262  pfstream _read_write_file;
263  StreamWrapper _read_write_filew;
264  Filename _multifile_name;
265  std::string _header_prefix;
266 
267  int _file_major_ver;
268  int _file_minor_ver;
269 
270  static const char _header[];
271  static const size_t _header_size;
272  static const int _current_major_ver;
273  static const int _current_minor_ver;
274 
275  static const char _encrypt_header[];
276  static const size_t _encrypt_header_size;
277 
278  friend class Subfile;
279 };
280 
281 #include "multifile.I"
282 
283 #endif
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.
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.
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 base class for all things that want to be reference-counted.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A file that contains a set of files.
Definition: multifile.h:37
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.