00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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"
00031 #include "ordered_vector.h"
00032 #include "streamWrapper.h"
00033
00034 #include <algorithm>
00035
00036
00037
00038
00039
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
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
00129
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;
00170
00171
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