Panda3D
|
00001 // Filename: multifile.h 00002 // Created by: mike (09Jan97) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #ifndef MULTIFILE_H 00016 #define MULTIFILE_H 00017 00018 #include "pandabase.h" 00019 00020 #include "config_express.h" 00021 #include "streamWrapper.h" 00022 #include "subStream.h" 00023 #include "filename.h" 00024 #include "ordered_vector.h" 00025 #include "indirectLess.h" 00026 #include "referenceCount.h" 00027 #include "pvector.h" 00028 #include "openSSLWrapper.h" 00029 00030 //////////////////////////////////////////////////////////////////// 00031 // Class : Multifile 00032 // Description : A file that contains a set of files. 00033 //////////////////////////////////////////////////////////////////// 00034 class EXPCL_PANDAEXPRESS Multifile : public ReferenceCount { 00035 PUBLISHED: 00036 Multifile(); 00037 ~Multifile(); 00038 00039 private: 00040 Multifile(const Multifile ©); 00041 void operator = (const Multifile ©); 00042 00043 PUBLISHED: 00044 BLOCKING bool open_read(const Filename &multifile_name, const streampos &offset = 0); 00045 BLOCKING bool open_read(IStreamWrapper *multifile_stream, bool owns_pointer = false, const streampos &offset = 0); 00046 BLOCKING bool open_write(const Filename &multifile_name); 00047 BLOCKING bool open_write(ostream *multifile_stream, bool owns_pointer = false); 00048 BLOCKING bool open_read_write(const Filename &multifile_name); 00049 BLOCKING bool open_read_write(iostream *multifile_stream, bool owns_pointer = false); 00050 BLOCKING void close(); 00051 00052 INLINE const Filename &get_multifile_name() const; 00053 INLINE void set_multifile_name(const Filename &multifile_name); 00054 00055 INLINE bool is_read_valid() const; 00056 INLINE bool is_write_valid() const; 00057 INLINE bool needs_repack() const; 00058 00059 INLINE time_t get_timestamp() const; 00060 00061 INLINE void set_record_timestamp(bool record_timestamp); 00062 INLINE bool get_record_timestamp() const; 00063 00064 void set_scale_factor(size_t scale_factor); 00065 INLINE size_t get_scale_factor() const; 00066 00067 INLINE void set_encryption_flag(bool flag); 00068 INLINE bool get_encryption_flag() const; 00069 INLINE void set_encryption_password(const string &encryption_password); 00070 INLINE const string &get_encryption_password() const; 00071 00072 INLINE void set_encryption_algorithm(const string &encryption_algorithm); 00073 INLINE const string &get_encryption_algorithm() const; 00074 INLINE void set_encryption_key_length(int encryption_key_length); 00075 INLINE int get_encryption_key_length() const; 00076 INLINE void set_encryption_iteration_count(int encryption_iteration_count); 00077 INLINE int get_encryption_iteration_count() const; 00078 00079 string add_subfile(const string &subfile_name, const Filename &filename, 00080 int compression_level); 00081 string add_subfile(const string &subfile_name, istream *subfile_data, 00082 int compression_level); 00083 string update_subfile(const string &subfile_name, const Filename &filename, 00084 int compression_level); 00085 00086 #ifdef HAVE_OPENSSL 00087 class CertRecord { 00088 public: 00089 INLINE CertRecord(X509 *cert); 00090 INLINE CertRecord(const CertRecord ©); 00091 INLINE ~CertRecord(); 00092 INLINE void operator = (const CertRecord &other); 00093 X509 *_cert; 00094 }; 00095 typedef pvector<CertRecord> CertChain; 00096 00097 bool add_signature(const Filename &certificate, 00098 const Filename &chain, 00099 const Filename &pkey, 00100 const string &password = ""); 00101 bool add_signature(const Filename &composite, 00102 const string &password = ""); 00103 bool add_signature(X509 *certificate, STACK_OF(X509) *chain, EVP_PKEY *pkey); 00104 bool add_signature(const CertChain &chain, EVP_PKEY *pkey); 00105 00106 int get_num_signatures() const; 00107 const CertChain &get_signature(int n) const; 00108 string get_signature_subject_name(int n) const; 00109 string get_signature_friendly_name(int n) const; 00110 string get_signature_public_key(int n) const; 00111 void write_signature_certificate(int n, ostream &out) const; 00112 00113 int validate_signature_certificate(int n) const; 00114 #endif // HAVE_OPENSSL 00115 00116 BLOCKING bool flush(); 00117 BLOCKING bool repack(); 00118 00119 int get_num_subfiles() const; 00120 int find_subfile(const string &subfile_name) const; 00121 bool has_directory(const string &subfile_name) const; 00122 bool scan_directory(vector_string &contents, 00123 const string &subfile_name) const; 00124 void remove_subfile(int index); 00125 INLINE bool remove_subfile(const string &subfile_name); 00126 const string &get_subfile_name(int index) const; 00127 MAKE_SEQ(get_subfile_names, get_num_subfiles, get_subfile_name); 00128 size_t get_subfile_length(int index) const; 00129 time_t get_subfile_timestamp(int index) const; 00130 bool is_subfile_compressed(int index) const; 00131 bool is_subfile_encrypted(int index) const; 00132 00133 streampos get_index_end() const; 00134 streampos get_subfile_internal_start(int index) const; 00135 size_t get_subfile_internal_length(int index) const; 00136 00137 BLOCKING INLINE string read_subfile(int index); 00138 BLOCKING istream *open_read_subfile(int index); 00139 BLOCKING static void close_read_subfile(istream *stream); 00140 BLOCKING bool extract_subfile(int index, const Filename &filename); 00141 BLOCKING bool extract_subfile_to(int index, ostream &out); 00142 BLOCKING bool compare_subfile(int index, const Filename &filename); 00143 00144 void output(ostream &out) const; 00145 void ls(ostream &out = cout) const; 00146 00147 static INLINE string get_magic_number(); 00148 00149 void set_header_prefix(const string &header_prefix); 00150 INLINE const string &get_header_prefix() const; 00151 00152 public: 00153 bool read_subfile(int index, string &result); 00154 bool read_subfile(int index, pvector<unsigned char> &result); 00155 00156 private: 00157 enum SubfileFlags { 00158 SF_deleted = 0x0001, 00159 SF_index_invalid = 0x0002, 00160 SF_data_invalid = 0x0004, 00161 SF_compressed = 0x0008, 00162 SF_encrypted = 0x0010, 00163 SF_signature = 0x0020, 00164 }; 00165 00166 class Subfile { 00167 public: 00168 INLINE Subfile(); 00169 INLINE bool operator < (const Subfile &other) const; 00170 streampos read_index(istream &read, streampos fpos, 00171 Multifile *multfile); 00172 streampos write_index(ostream &write, streampos fpos, 00173 Multifile *multifile); 00174 streampos write_data(ostream &write, istream *read, streampos fpos, 00175 Multifile *multifile); 00176 void rewrite_index_data_start(ostream &write, Multifile *multifile); 00177 void rewrite_index_flags(ostream &write); 00178 INLINE bool is_deleted() const; 00179 INLINE bool is_index_invalid() const; 00180 INLINE bool is_data_invalid() const; 00181 INLINE bool is_cert_special() const; 00182 INLINE streampos get_last_byte_pos() const; 00183 00184 string _name; 00185 streampos _index_start; 00186 size_t _index_length; 00187 streampos _data_start; 00188 size_t _data_length; 00189 size_t _uncompressed_length; 00190 time_t _timestamp; 00191 istream *_source; 00192 Filename _source_filename; 00193 int _flags; 00194 int _compression_level; // Not preserved on disk. 00195 #ifdef HAVE_OPENSSL 00196 EVP_PKEY *_pkey; // Not preserved on disk. 00197 #endif 00198 }; 00199 00200 INLINE streampos word_to_streampos(size_t word) const; 00201 INLINE size_t streampos_to_word(streampos fpos) const; 00202 INLINE streampos normalize_streampos(streampos fpos) const; 00203 streampos pad_to_streampos(streampos fpos); 00204 00205 void add_new_subfile(Subfile *subfile, int compression_level); 00206 istream *open_read_subfile(Subfile *subfile); 00207 string standardize_subfile_name(const string &subfile_name) const; 00208 00209 void clear_subfiles(); 00210 bool read_index(); 00211 bool write_header(); 00212 00213 void check_signatures(); 00214 00215 static INLINE char tohex(unsigned int nibble); 00216 00217 typedef ov_set<Subfile *, IndirectLess<Subfile> > Subfiles; 00218 Subfiles _subfiles; 00219 typedef pvector<Subfile *> PendingSubfiles; 00220 PendingSubfiles _new_subfiles; 00221 PendingSubfiles _removed_subfiles; 00222 PendingSubfiles _cert_special; 00223 00224 #ifdef HAVE_OPENSSL 00225 typedef pvector<CertChain> Certificates; 00226 Certificates _signatures; 00227 #endif 00228 00229 streampos _offset; 00230 IStreamWrapper *_read; 00231 ostream *_write; 00232 bool _owns_stream; 00233 streampos _next_index; 00234 streampos _last_index; 00235 streampos _last_data_byte; 00236 00237 bool _needs_repack; 00238 time_t _timestamp; 00239 bool _timestamp_dirty; 00240 bool _record_timestamp; 00241 size_t _scale_factor; 00242 size_t _new_scale_factor; 00243 00244 bool _encryption_flag; 00245 string _encryption_password; 00246 string _encryption_algorithm; 00247 int _encryption_key_length; 00248 int _encryption_iteration_count; 00249 00250 pifstream _read_file; 00251 IStreamWrapper _read_filew; 00252 pofstream _write_file; 00253 pfstream _read_write_file; 00254 StreamWrapper _read_write_filew; 00255 Filename _multifile_name; 00256 string _header_prefix; 00257 00258 int _file_major_ver; 00259 int _file_minor_ver; 00260 00261 static const char _header[]; 00262 static const size_t _header_size; 00263 static const int _current_major_ver; 00264 static const int _current_minor_ver; 00265 00266 static const char _encrypt_header[]; 00267 static const size_t _encrypt_header_size; 00268 00269 friend class Subfile; 00270 }; 00271 00272 #include "multifile.I" 00273 00274 #endif