historical/toontown-classic.git/panda/include/patchfile.h
2024-01-16 11:20:27 -06:00

205 lines
6.6 KiB
C++

/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file patchfile.h
* @author darren, mike
* @date 1997-01-09
*/
#ifndef PATCHFILE_H
#define PATCHFILE_H
#include "pandabase.h"
#ifdef HAVE_OPENSSL
#include "typedef.h"
#include "pnotify.h"
#include "filename.h"
#include "plist.h"
#include "datagram.h"
#include "datagramIterator.h"
#include "buffer.h"
#include "pointerTo.h"
#include "hashVal.h" // MD5 stuff
#include "ordered_vector.h"
#include "streamWrapper.h"
#include <algorithm>
/**
*
*/
class EXPCL_PANDA_EXPRESS Patchfile {
PUBLISHED:
Patchfile();
explicit Patchfile(PT(Buffer) buffer);
~Patchfile();
bool build(Filename file_orig, Filename file_new, Filename patch_name);
int read_header(const Filename &patch_file);
int initiate(const Filename &patch_file, const Filename &file);
int initiate(const Filename &patch_file, const Filename &orig_file,
const Filename &target_file);
int run();
bool apply(Filename &patch_file, Filename &file);
bool apply(Filename &patch_file, Filename &orig_file,
const Filename &target_file);
INLINE PN_stdfloat get_progress() const;
MAKE_PROPERTY(progress, get_progress);
INLINE void set_allow_multifile(bool allow_multifile);
INLINE bool get_allow_multifile();
MAKE_PROPERTY(allow_multifile, get_allow_multifile, set_allow_multifile);
INLINE void set_footprint_length(int length);
INLINE int get_footprint_length();
INLINE void reset_footprint_length();
MAKE_PROPERTY(footprint_length, get_footprint_length, set_footprint_length);
INLINE bool has_source_hash() const;
INLINE const HashVal &get_source_hash() const;
INLINE const HashVal &get_result_hash() const;
MAKE_PROPERTY2(source_hash, has_source_hash, get_source_hash);
MAKE_PROPERTY(result_hash, get_result_hash);
private:
int internal_read_header(const Filename &patch_file);
void init(PT(Buffer) buffer);
void cleanup();
private:
// stuff for the build operation
void build_hash_link_tables(const char *buffer_orig, uint32_t length_orig,
uint32_t *hash_table, uint32_t *link_table);
uint32_t calc_hash(const char *buffer);
void find_longest_match(uint32_t new_pos, uint32_t &copy_pos, uint16_t &copy_length,
uint32_t *hash_table, uint32_t *link_table, const char* buffer_orig,
uint32_t length_orig, const char* buffer_new, uint32_t length_new);
uint32_t calc_match_length(const char* buf1, const char* buf2, uint32_t max_length,
uint32_t min_length);
void emit_ADD(std::ostream &write_stream, uint32_t length, const char* buffer);
void emit_COPY(std::ostream &write_stream, uint32_t length, uint32_t COPY_pos);
void emit_add_and_copy(std::ostream &write_stream,
uint32_t add_length, const char *add_buffer,
uint32_t copy_length, uint32_t copy_pos);
void cache_add_and_copy(std::ostream &write_stream,
uint32_t add_length, const char *add_buffer,
uint32_t copy_length, uint32_t copy_pos);
void cache_flush(std::ostream &write_stream);
void write_header(std::ostream &write_stream,
std::istream &stream_orig, std::istream &stream_new);
void write_terminator(std::ostream &write_stream);
bool compute_file_patches(std::ostream &write_stream,
uint32_t offset_orig, uint32_t offset_new,
std::istream &stream_orig, std::istream &stream_new);
bool compute_mf_patches(std::ostream &write_stream,
uint32_t offset_orig, uint32_t offset_new,
std::istream &stream_orig, std::istream &stream_new);
#ifdef HAVE_TAR
class TarSubfile {
public:
inline bool operator < (const TarSubfile &other) const {
return _name < other._name;
}
std::string _name;
std::streampos _header_start;
std::streampos _data_start;
std::streampos _data_end;
std::streampos _end;
};
typedef ov_set<TarSubfile> TarDef;
bool read_tar(TarDef &tar, std::istream &stream);
bool compute_tar_patches(std::ostream &write_stream,
uint32_t offset_orig, uint32_t offset_new,
std::istream &stream_orig, std::istream &stream_new,
TarDef &tar_orig, TarDef &tar_new);
// Because this is static, we can only call read_tar() one at a time--no
// threads, please.
static std::istream *_tar_istream;
static int tar_openfunc(const char *filename, int oflags, ...);
static int tar_closefunc(int fd);
static ssize_t tar_readfunc(int fd, void *buffer, size_t nbytes);
static ssize_t tar_writefunc(int fd, const void *buffer, size_t nbytes);
#endif // HAVE_TAR
bool do_compute_patches(const Filename &file_orig, const Filename &file_new,
std::ostream &write_stream,
uint32_t offset_orig, uint32_t offset_new,
std::istream &stream_orig, std::istream &stream_new);
bool patch_subfile(std::ostream &write_stream,
uint32_t offset_orig, uint32_t offset_new,
const Filename &filename,
IStreamWrapper &stream_orig, std::streampos orig_start, std::streampos orig_end,
IStreamWrapper &stream_new, std::streampos new_start, std::streampos new_end);
static const uint32_t _HASH_BITS;
static const uint32_t _HASHTABLESIZE;
static const uint32_t _DEFAULT_FOOTPRINT_LENGTH;
static const uint32_t _NULL_VALUE;
static const uint32_t _MAX_RUN_LENGTH;
static const uint32_t _HASH_MASK;
bool _allow_multifile;
uint32_t _footprint_length;
uint32_t *_hash_table;
uint32_t _add_pos;
uint32_t _last_copy_pos;
std::string _cache_add_data;
uint32_t _cache_copy_start;
uint32_t _cache_copy_length;
private:
PT(Buffer) _buffer; // this is the work buffer for apply -- used to prevent virtual memory swapping
// async patch apply state variables
bool _initiated;
uint16_t _version_number;
HashVal _MD5_ofSource;
HashVal _MD5_ofResult;
uint32_t _total_bytes_to_process;
uint32_t _total_bytes_processed;
std::istream *_patch_stream;
pofstream _write_stream;
std::istream *_origfile_stream;
Filename _patch_file;
Filename _orig_file;
Filename _output_file;
bool _rename_output_to_orig;
bool _delete_patchfile;
static const uint32_t _v0_magic_number;
static const uint32_t _magic_number;
static const uint16_t _current_version;
};
#include "patchfile.I"
#endif // HAVE_OPENSSL
#endif