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 print_signature_certificate(int n, ostream &out) const; 00112 void write_signature_certificate(int n, ostream &out) const; 00113 00114 int validate_signature_certificate(int n) const; 00115 #endif // HAVE_OPENSSL 00116 00117 BLOCKING bool flush(); 00118 BLOCKING bool repack(); 00119 00120 int get_num_subfiles() const; 00121 int find_subfile(const string &subfile_name) const; 00122 bool has_directory(const string &subfile_name) const; 00123 bool scan_directory(vector_string &contents, 00124 const string &subfile_name) const; 00125 void remove_subfile(int index); 00126 INLINE bool remove_subfile(const string &subfile_name); 00127 const string &get_subfile_name(int index) const; 00128 MAKE_SEQ(get_subfile_names, get_num_subfiles, get_subfile_name); 00129 size_t get_subfile_length(int index) const; 00130 time_t get_subfile_timestamp(int index) const; 00131 bool is_subfile_compressed(int index) const; 00132 bool is_subfile_encrypted(int index) const; 00133 bool is_subfile_text(int index) const; 00134 00135 streampos get_index_end() const; 00136 streampos get_subfile_internal_start(int index) const; 00137 size_t get_subfile_internal_length(int index) const; 00138 00139 BLOCKING INLINE string read_subfile(int index); 00140 BLOCKING istream *open_read_subfile(int index); 00141 BLOCKING static void close_read_subfile(istream *stream); 00142 BLOCKING bool extract_subfile(int index, const Filename &filename); 00143 BLOCKING bool extract_subfile_to(int index, ostream &out); 00144 BLOCKING bool compare_subfile(int index, const Filename &filename); 00145 00146 void output(ostream &out) const; 00147 void ls(ostream &out = cout) const; 00148 00149 static INLINE string get_magic_number(); 00150 00151 void set_header_prefix(const string &header_prefix); 00152 INLINE const string &get_header_prefix() const; 00153 00154 public: 00155 bool read_subfile(int index, string &result); 00156 bool read_subfile(int index, pvector<unsigned char> &result); 00157 00158 private: 00159 enum SubfileFlags { 00160 SF_deleted = 0x0001, 00161 SF_index_invalid = 0x0002, 00162 SF_data_invalid = 0x0004, 00163 SF_compressed = 0x0008, 00164 SF_encrypted = 0x0010, 00165 SF_signature = 0x0020, 00166 SF_text = 0x0040, 00167 }; 00168 00169 class Subfile { 00170 public: 00171 INLINE Subfile(); 00172 INLINE bool operator < (const Subfile &other) const; 00173 streampos read_index(istream &read, streampos fpos, 00174 Multifile *multfile); 00175 streampos write_index(ostream &write, streampos fpos, 00176 Multifile *multifile); 00177 streampos write_data(ostream &write, istream *read, streampos fpos, 00178 Multifile *multifile); 00179 void rewrite_index_data_start(ostream &write, Multifile *multifile); 00180 void rewrite_index_flags(ostream &write); 00181 INLINE bool is_deleted() const; 00182 INLINE bool is_index_invalid() const; 00183 INLINE bool is_data_invalid() const; 00184 INLINE bool is_cert_special() const; 00185 INLINE streampos get_last_byte_pos() const; 00186 00187 string _name; 00188 streampos _index_start; 00189 size_t _index_length; 00190 streampos _data_start; 00191 size_t _data_length; 00192 size_t _uncompressed_length; 00193 time_t _timestamp; 00194 istream *_source; 00195 Filename _source_filename; 00196 int _flags; 00197 int _compression_level; // Not preserved on disk. 00198 #ifdef HAVE_OPENSSL 00199 EVP_PKEY *_pkey; // Not preserved on disk. 00200 #endif 00201 }; 00202 00203 INLINE streampos word_to_streampos(size_t word) const; 00204 INLINE size_t streampos_to_word(streampos fpos) const; 00205 INLINE streampos normalize_streampos(streampos fpos) const; 00206 streampos pad_to_streampos(streampos fpos); 00207 00208 void add_new_subfile(Subfile *subfile, int compression_level); 00209 istream *open_read_subfile(Subfile *subfile); 00210 string standardize_subfile_name(const string &subfile_name) const; 00211 00212 void clear_subfiles(); 00213 bool read_index(); 00214 bool write_header(); 00215 00216 void check_signatures(); 00217 00218 static INLINE char tohex(unsigned int nibble); 00219 00220 typedef ov_set<Subfile *, IndirectLess<Subfile> > Subfiles; 00221 Subfiles _subfiles; 00222 typedef pvector<Subfile *> PendingSubfiles; 00223 PendingSubfiles _new_subfiles; 00224 PendingSubfiles _removed_subfiles; 00225 PendingSubfiles _cert_special; 00226 00227 #ifdef HAVE_OPENSSL 00228 typedef pvector<CertChain> Certificates; 00229 Certificates _signatures; 00230 #endif 00231 00232 streampos _offset; 00233 IStreamWrapper *_read; 00234 ostream *_write; 00235 bool _owns_stream; 00236 streampos _next_index; 00237 streampos _last_index; 00238 streampos _last_data_byte; 00239 00240 bool _needs_repack; 00241 time_t _timestamp; 00242 bool _timestamp_dirty; 00243 bool _record_timestamp; 00244 size_t _scale_factor; 00245 size_t _new_scale_factor; 00246 00247 bool _encryption_flag; 00248 string _encryption_password; 00249 string _encryption_algorithm; 00250 int _encryption_key_length; 00251 int _encryption_iteration_count; 00252 00253 pifstream _read_file; 00254 IStreamWrapper _read_filew; 00255 pofstream _write_file; 00256 pfstream _read_write_file; 00257 StreamWrapper _read_write_filew; 00258 Filename _multifile_name; 00259 string _header_prefix; 00260 00261 int _file_major_ver; 00262 int _file_minor_ver; 00263 00264 static const char _header[]; 00265 static const size_t _header_size; 00266 static const int _current_major_ver; 00267 static const int _current_minor_ver; 00268 00269 static const char _encrypt_header[]; 00270 static const size_t _encrypt_header_size; 00271 00272 friend class Subfile; 00273 }; 00274 00275 #include "multifile.I" 00276 00277 #endif