Panda3D
 All Classes Functions Variables Enumerations
patchfile.h
00001 // Filename: patchfile.h
00002 // Created by:  darren, 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 PATCHFILE_H
00016 #define PATCHFILE_H
00017 
00018 #include "pandabase.h"
00019 
00020 #ifdef HAVE_OPENSSL
00021 
00022 #include "typedef.h"
00023 #include "pnotify.h"
00024 #include "filename.h"
00025 #include "plist.h"
00026 #include "datagram.h"
00027 #include "datagramIterator.h"
00028 #include "buffer.h"
00029 #include "pointerTo.h"
00030 #include "hashVal.h" // MD5 stuff
00031 #include "ordered_vector.h"
00032 #include "streamWrapper.h"
00033 
00034 #include <algorithm>
00035 
00036 
00037 ////////////////////////////////////////////////////////////////////
00038 //       Class : Patchfile
00039 // Description :
00040 ////////////////////////////////////////////////////////////////////
00041 class EXPCL_PANDAEXPRESS Patchfile {
00042 PUBLISHED:
00043   Patchfile();
00044   Patchfile(PT(Buffer) buffer);
00045   ~Patchfile();
00046 
00047   bool build(Filename file_orig, Filename file_new, Filename patch_name);
00048   int read_header(const Filename &patch_file);
00049 
00050   int initiate(const Filename &patch_file, const Filename &file);
00051   int initiate(const Filename &patch_file, const Filename &orig_file,
00052                const Filename &target_file);
00053   int run();
00054 
00055   bool apply(Filename &patch_file, Filename &file);
00056   bool apply(Filename &patch_file, Filename &orig_file, 
00057              const Filename &target_file);
00058 
00059   INLINE PN_stdfloat get_progress() const;
00060 
00061   INLINE void set_allow_multifile(bool allow_multifile);
00062   INLINE bool get_allow_multifile();
00063 
00064   INLINE void set_footprint_length(int length);
00065   INLINE int get_footprint_length();
00066   INLINE void reset_footprint_length();
00067 
00068   INLINE bool has_source_hash() const;
00069   INLINE const HashVal &get_source_hash() const;
00070   INLINE const HashVal &get_result_hash() const;
00071 
00072 private:
00073   int internal_read_header(const Filename &patch_file);
00074   void init(PT(Buffer) buffer);
00075   void cleanup();
00076 
00077 private:
00078   // stuff for the build operation
00079   void build_hash_link_tables(const char *buffer_orig, PN_uint32 length_orig,
00080     PN_uint32 *hash_table, PN_uint32 *link_table);
00081   PN_uint32 calc_hash(const char *buffer);
00082   void find_longest_match(PN_uint32 new_pos, PN_uint32 &copy_pos, PN_uint16 &copy_length,
00083     PN_uint32 *hash_table, PN_uint32 *link_table, const char* buffer_orig,
00084     PN_uint32 length_orig, const char* buffer_new, PN_uint32 length_new);
00085   PN_uint32 calc_match_length(const char* buf1, const char* buf2, PN_uint32 max_length,
00086     PN_uint32 min_length);
00087 
00088   void emit_ADD(ostream &write_stream, PN_uint32 length, const char* buffer);
00089   void emit_COPY(ostream &write_stream, PN_uint32 length, PN_uint32 COPY_pos);
00090   void emit_add_and_copy(ostream &write_stream, 
00091                          PN_uint32 add_length, const char *add_buffer,
00092                          PN_uint32 copy_length, PN_uint32 copy_pos);
00093   void cache_add_and_copy(ostream &write_stream, 
00094                           PN_uint32 add_length, const char *add_buffer,
00095                           PN_uint32 copy_length, PN_uint32 copy_pos);
00096   void cache_flush(ostream &write_stream);
00097 
00098   void write_header(ostream &write_stream, 
00099                     istream &stream_orig, istream &stream_new);
00100   void write_terminator(ostream &write_stream);
00101 
00102   bool compute_file_patches(ostream &write_stream, 
00103                             PN_uint32 offset_orig, PN_uint32 offset_new,
00104                              istream &stream_orig, istream &stream_new);
00105   bool compute_mf_patches(ostream &write_stream, 
00106                           PN_uint32 offset_orig, PN_uint32 offset_new,
00107                           istream &stream_orig, istream &stream_new);
00108 #ifdef HAVE_TAR
00109   class TarSubfile {
00110   public:
00111     inline bool operator < (const TarSubfile &other) const {
00112       return _name < other._name;
00113     }
00114     string _name;
00115     streampos _header_start;
00116     streampos _data_start;
00117     streampos _data_end;
00118     streampos _end;
00119   };
00120   typedef ov_set<TarSubfile> TarDef;
00121 
00122   bool read_tar(TarDef &tar, istream &stream);
00123   bool compute_tar_patches(ostream &write_stream, 
00124                            PN_uint32 offset_orig, PN_uint32 offset_new,
00125                            istream &stream_orig, istream &stream_new,
00126                            TarDef &tar_orig, TarDef &tar_new);
00127 
00128   // Because this is static, we can only call read_tar() one at a
00129   // time--no threads, please.
00130   static istream *_tar_istream;
00131   
00132   static int tar_openfunc(const char *filename, int oflags, ...);
00133   static int tar_closefunc(int fd);
00134   static ssize_t tar_readfunc(int fd, void *buffer, size_t nbytes);
00135   static ssize_t tar_writefunc(int fd, const void *buffer, size_t nbytes);
00136 #endif  // HAVE_TAR
00137 
00138   bool do_compute_patches(const Filename &file_orig, const Filename &file_new,
00139                           ostream &write_stream, 
00140                           PN_uint32 offset_orig, PN_uint32 offset_new,
00141                           istream &stream_orig, istream &stream_new);
00142   
00143   bool patch_subfile(ostream &write_stream, 
00144                      PN_uint32 offset_orig, PN_uint32 offset_new,
00145                      const Filename &filename,
00146                      IStreamWrapper &stream_orig, streampos orig_start, streampos orig_end,
00147                      IStreamWrapper &stream_new, streampos new_start, streampos new_end);
00148 
00149   static const PN_uint32 _HASH_BITS;
00150   static const PN_uint32 _HASHTABLESIZE;
00151   static const PN_uint32 _DEFAULT_FOOTPRINT_LENGTH;
00152   static const PN_uint32 _NULL_VALUE;
00153   static const PN_uint32 _MAX_RUN_LENGTH;
00154   static const PN_uint32 _HASH_MASK;
00155 
00156   bool _allow_multifile;
00157   PN_uint32 _footprint_length;
00158 
00159   PN_uint32 *_hash_table;
00160 
00161   PN_uint32 _add_pos;
00162   PN_uint32 _last_copy_pos;
00163 
00164   string _cache_add_data;
00165   PN_uint32 _cache_copy_start;
00166   PN_uint32 _cache_copy_length;
00167 
00168 private:
00169   PT(Buffer) _buffer; // this is the work buffer for apply -- used to prevent virtual memory swapping
00170 
00171   // async patch apply state variables
00172   bool _initiated;
00173 
00174   PN_uint16 _version_number;
00175 
00176   HashVal _MD5_ofSource;  
00177 
00178   HashVal _MD5_ofResult;  
00179 
00180   PN_uint32 _total_bytes_to_process;
00181   PN_uint32 _total_bytes_processed;
00182 
00183   istream *_patch_stream;
00184   pofstream _write_stream;
00185   istream *_origfile_stream;
00186 
00187   Filename _patch_file;
00188   Filename _orig_file;
00189   Filename _output_file;
00190   bool _rename_output_to_orig;
00191   bool _delete_patchfile;
00192 
00193   static const PN_uint32 _v0_magic_number;
00194   static const PN_uint32 _magic_number;
00195   static const PN_uint16 _current_version;
00196 };
00197 
00198 #include "patchfile.I"
00199 
00200 #endif // HAVE_OPENSSL
00201 
00202 #endif
 All Classes Functions Variables Enumerations