Panda3D
|
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 ©_pos, PN_uint16 ©_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