Panda3D
 All Classes Functions Variables Enumerations
multifile.h
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 &copy);
00041   void operator = (const Multifile &copy);
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 &copy);
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
 All Classes Functions Variables Enumerations