use zStreamBuf to handle compression/decompression interface
This commit is contained in:
parent
5d56f13f1a
commit
74c8b349ff
|
|
@ -26,7 +26,7 @@
|
|||
socketStream.h socketStream.I \
|
||||
urlSpec.I urlSpec.h \
|
||||
$[if $[HAVE_NET], downloadDb.I downloadDb.h downloader.I downloader.h] \
|
||||
$[if $[HAVE_ZLIB], decompressor.h zcompressor.I zcompressor.h download_utils.h] \
|
||||
$[if $[HAVE_ZLIB], decompressor.h download_utils.h] \
|
||||
$[if $[HAVE_CRYPTO], patcher.cxx patcher.h patcher.I]
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
multiplexStream.cxx multiplexStreamBuf.cxx \
|
||||
urlSpec.cxx \
|
||||
$[if $[HAVE_NET], downloadDb.cxx downloader.cxx] \
|
||||
$[if $[HAVE_ZLIB], decompressor.cxx zcompressor.cxx download_utils.cxx]
|
||||
$[if $[HAVE_ZLIB], decompressor.cxx download_utils.cxx]
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
asyncUtility.h asyncUtility.I \
|
||||
|
|
@ -63,8 +63,7 @@
|
|||
multiplexStreamBuf.I multiplexStreamBuf.I \
|
||||
patcher.h patcher.I \
|
||||
socketStream.h socketStream.I \
|
||||
urlSpec.h urlSpec.I \
|
||||
zcompressor.I zcompressor.h
|
||||
urlSpec.h urlSpec.I
|
||||
|
||||
#define IGATESCAN all
|
||||
|
||||
|
|
|
|||
|
|
@ -15,22 +15,3 @@
|
|||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "config_downloader.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Decompressor::get_progress
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float Decompressor::
|
||||
get_progress(void) const {
|
||||
if (_initiated == false) {
|
||||
downloader_cat.warning()
|
||||
<< "Decompressor::get_progress() - Decompression has not been "
|
||||
<< "initiated" << endl;
|
||||
return 0.0;
|
||||
}
|
||||
nassertr(_source_file_length > 0, 0.0);
|
||||
return ((float)_total_bytes_read / (float)_source_file_length);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,69 +18,27 @@
|
|||
|
||||
// This file is compiled only if we have zlib installed.
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "config_downloader.h"
|
||||
|
||||
#include "error_utils.h"
|
||||
#include "filename.h"
|
||||
#include "zStream.h"
|
||||
|
||||
#include "decompressor.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <error_utils.h>
|
||||
#include <filename.h>
|
||||
|
||||
#include "decompressor.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Defines
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Decompressor::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Decompressor::
|
||||
Decompressor(void) {
|
||||
if (downloader_cat.is_debug())
|
||||
downloader_cat.debug()
|
||||
<< "Decompressor::constructor() - Creating buffer of size: "
|
||||
<< decompressor_buffer_size << endl;
|
||||
PT(Buffer) buffer = new Buffer(decompressor_buffer_size);
|
||||
init(buffer);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Decompressor::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Decompressor::
|
||||
Decompressor(PT(Buffer) buffer) {
|
||||
init(buffer);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Decompressor::Constructor
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Decompressor::
|
||||
init(PT(Buffer) buffer) {
|
||||
if (downloader_cat.is_debug())
|
||||
downloader_cat.debug()
|
||||
<< "Decompressor constructor called" << endl;
|
||||
_initiated = false;
|
||||
nassertv(!buffer.is_null());
|
||||
_half_buffer_length = buffer->get_length()/2;
|
||||
_buffer = buffer;
|
||||
char *temp_name = tempnam(NULL, "dc");
|
||||
_temp_file_name = temp_name;
|
||||
_temp_file_name.set_binary();
|
||||
delete temp_name;
|
||||
_decompressor = new ZDecompressor();
|
||||
Decompressor() {
|
||||
_source = NULL;
|
||||
_decompress = NULL;
|
||||
_dest = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -89,267 +47,208 @@ init(PT(Buffer) buffer) {
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Decompressor::
|
||||
~Decompressor(void) {
|
||||
if (downloader_cat.is_debug())
|
||||
downloader_cat.debug()
|
||||
<< "Decompressor destructor called" << endl;
|
||||
_temp_file_name.unlink();
|
||||
if (_initiated == true)
|
||||
cleanup();
|
||||
~Decompressor() {
|
||||
cleanup();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Decompressor::initiate
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description: Begins a background decompression of the named file
|
||||
// (whose filename must end in ".pz") to a new file
|
||||
// without the .pz extension. The source file is
|
||||
// removed after successful completion.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Decompressor::
|
||||
initiate(Filename &source_file) {
|
||||
Filename dest_file = source_file;
|
||||
initiate(const Filename &source_file) {
|
||||
string extension = source_file.get_extension();
|
||||
if (extension == "pz")
|
||||
if (extension == "pz") {
|
||||
Filename dest_file = source_file;
|
||||
dest_file = source_file.get_fullpath_wo_extension();
|
||||
else {
|
||||
if (downloader_cat.is_debug())
|
||||
downloader_cat.debug()
|
||||
<< "Decompressor::request_decompress() - Unknown file extension: ."
|
||||
<< extension << endl;
|
||||
return EU_error_abort;
|
||||
}
|
||||
return initiate(source_file, dest_file);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Decompressor::initiate
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Decompressor::
|
||||
initiate(Filename &source_file, Filename &dest_file) {
|
||||
|
||||
if (_initiated == true) {
|
||||
downloader_cat.error()
|
||||
<< "Decompressor::initiate() - Decompression has already been initiated"
|
||||
<< endl;
|
||||
return EU_error_abort;
|
||||
return initiate(source_file, dest_file);
|
||||
}
|
||||
|
||||
// Open source file
|
||||
_source_file = source_file;
|
||||
_source_file.set_binary();
|
||||
if (!_source_file.open_read(_read_stream)) {
|
||||
downloader_cat.error()
|
||||
<< "Decompressor::initiate() - Error opening source file: "
|
||||
<< _source_file << " : " << strerror(errno) << endl;
|
||||
return get_write_error();
|
||||
}
|
||||
|
||||
// Determine source file length
|
||||
_read_stream.seekg(0, ios::end);
|
||||
_source_file_length = _read_stream.tellg();
|
||||
if (_source_file_length == 0) {
|
||||
downloader_cat.warning()
|
||||
<< "Decompressor::initiate() - Zero length file: "
|
||||
<< source_file << " : " << strerror(errno) << endl;
|
||||
return get_write_error();
|
||||
}
|
||||
_read_stream.seekg(0, ios::beg);
|
||||
|
||||
// Open destination file
|
||||
dest_file.set_binary();
|
||||
if (!dest_file.open_write(_write_stream)) {
|
||||
downloader_cat.error()
|
||||
<< "Decompressor::initiate() - Error opening dest file: "
|
||||
<< source_file << " : " << strerror(errno) << endl;
|
||||
return get_write_error();
|
||||
}
|
||||
|
||||
// Read from the source file into the first half of the buffer,
|
||||
// decompress into the second half of the buffer, write the second
|
||||
// half of the buffer to disk, and repeat.
|
||||
_total_bytes_read = 0;
|
||||
_read_all_input = false;
|
||||
_source_buffer_length = 0;
|
||||
_initiated = true;
|
||||
_decompressor = new ZDecompressor();
|
||||
_decompress_to_ram = false;
|
||||
return EU_success;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Decompressor::initiate
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Decompressor::
|
||||
initiate(Ramfile &source_file) {
|
||||
|
||||
if (_initiated == true) {
|
||||
downloader_cat.error()
|
||||
<< "Decompressor::initiate() - Decompression has already been initiated"
|
||||
<< endl;
|
||||
return EU_error_abort;
|
||||
}
|
||||
|
||||
// Open source file
|
||||
_read_string_stream = new istringstream(source_file._data);
|
||||
|
||||
// Determine source file length
|
||||
_source_file_length = source_file._data.length();
|
||||
if (_source_file_length == 0) {
|
||||
downloader_cat.warning()
|
||||
<< "Decompressor::initiate() - Zero length file: "
|
||||
<< strerror(errno) << endl;
|
||||
return get_write_error();
|
||||
}
|
||||
|
||||
// Open destination file
|
||||
_write_string_stream = new ostringstream();
|
||||
|
||||
// Read from the source file into the first half of the buffer,
|
||||
// decompress into the second half of the buffer, write the second
|
||||
// half of the buffer to disk, and repeat.
|
||||
_total_bytes_read = 0;
|
||||
_read_all_input = false;
|
||||
_source_buffer_length = 0;
|
||||
_initiated = true;
|
||||
_decompressor = new ZDecompressor();
|
||||
_decompress_to_ram = true;
|
||||
return EU_success;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Decompressor::cleanup
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Decompressor::
|
||||
cleanup(void) {
|
||||
if (downloader_cat.is_debug())
|
||||
if (downloader_cat.is_debug()) {
|
||||
downloader_cat.debug()
|
||||
<< "Decompressor cleanup called" << endl;
|
||||
if (_initiated == false) {
|
||||
<< "Unknown file extension for decompressor: ."
|
||||
<< extension << endl;
|
||||
}
|
||||
return EU_error_abort;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Decompressor::initiate
|
||||
// Access: Public
|
||||
// Description: Begins a background decompression from the named
|
||||
// source file to the named destination file. The
|
||||
// source file is removed after successful completion.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Decompressor::
|
||||
initiate(const Filename &source_file, const Filename &dest_file) {
|
||||
cleanup();
|
||||
|
||||
// Open source file
|
||||
_source_filename = Filename(source_file);
|
||||
_source_filename.set_binary();
|
||||
|
||||
ifstream *source_fstream = new ifstream;
|
||||
_source = source_fstream;
|
||||
if (!_source_filename.open_read(*source_fstream)) {
|
||||
downloader_cat.error()
|
||||
<< "Decompressor::cleanup() - Decompression has not been "
|
||||
<< "initiated" << endl;
|
||||
return;
|
||||
<< "Unable to read " << _source_filename << "\n";
|
||||
return get_write_error();
|
||||
}
|
||||
|
||||
_initiated = false;
|
||||
delete _decompressor;
|
||||
_decompressor = NULL;
|
||||
_read_stream.close();
|
||||
_write_stream.close();
|
||||
if (_decompress_to_ram == false)
|
||||
_source_file.unlink();
|
||||
// Determine source file length
|
||||
source_fstream->seekg(0, ios::end);
|
||||
_source_length = source_fstream->tellg();
|
||||
if (_source_length == 0) {
|
||||
downloader_cat.warning()
|
||||
<< "Zero length file: " << source_file << "\n";
|
||||
return EU_error_file_empty;
|
||||
}
|
||||
source_fstream->seekg(0, ios::beg);
|
||||
|
||||
// Open destination file
|
||||
Filename dest_filename(dest_file);
|
||||
dest_filename.set_binary();
|
||||
|
||||
ofstream *dest_fstream = new ofstream;
|
||||
_dest = dest_fstream;
|
||||
if (!dest_filename.open_write(*dest_fstream)) {
|
||||
downloader_cat.error()
|
||||
<< "Unable to write to " << dest_filename << "\n";
|
||||
return get_write_error();
|
||||
}
|
||||
|
||||
// Now create the decompressor stream.
|
||||
_decompress = new IDecompressStream(_source, false);
|
||||
return EU_success;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Decompressor::run
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description: Called each frame to do the next bit of work in the
|
||||
// background task. Returns EU_ok if a chunk is
|
||||
// completed but there is more to go, or EU_success when
|
||||
// we're all done. Any other return value indicates an
|
||||
// error.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Decompressor::
|
||||
run(void) {
|
||||
if (_initiated == false) {
|
||||
downloader_cat.error()
|
||||
<< "Decompressor::run() - Decompression has not been initiated"
|
||||
<< endl;
|
||||
return EU_error_abort;
|
||||
run() {
|
||||
if (_decompress == (istream *)NULL) {
|
||||
// Hmm, we were already done.
|
||||
return EU_success;
|
||||
}
|
||||
|
||||
// See if there is anything left in the source file
|
||||
if (_read_all_input == false) {
|
||||
if (_decompress_to_ram == false) {
|
||||
_read_stream.read(_buffer->_buffer, _half_buffer_length);
|
||||
_source_buffer_length = _read_stream.gcount();
|
||||
_total_bytes_read += _source_buffer_length;
|
||||
if (_read_stream.eof()) {
|
||||
nassertr(_total_bytes_read == _source_file_length, false);
|
||||
_read_all_input = true;
|
||||
}
|
||||
} else {
|
||||
_read_string_stream->read(_buffer->_buffer, _half_buffer_length);
|
||||
_source_buffer_length = _read_string_stream->gcount();
|
||||
_total_bytes_read += _source_buffer_length;
|
||||
if (_read_string_stream->eof()) {
|
||||
nassertr(_total_bytes_read == _source_file_length, false);
|
||||
_read_all_input = true;
|
||||
}
|
||||
|
||||
// Read a bunch of characters from the decompress stream, but no
|
||||
// more than decompressor_buffer_size.
|
||||
int count = 0;
|
||||
int ch = _decompress->get();
|
||||
while (!_decompress->eof() && !_decompress->fail()) {
|
||||
_dest->put(ch);
|
||||
if (++count >= decompressor_buffer_size) {
|
||||
// That's enough for now.
|
||||
return EU_ok;
|
||||
}
|
||||
|
||||
ch = _decompress->get();
|
||||
}
|
||||
|
||||
char *next_in = _buffer->_buffer;
|
||||
int avail_in = _source_buffer_length;
|
||||
char *dest_buffer = _buffer->_buffer + _source_buffer_length;
|
||||
char *next_out = dest_buffer;
|
||||
int dest_buffer_length = _buffer->get_length() - _source_buffer_length;
|
||||
int avail_out = dest_buffer_length;
|
||||
nassertr(avail_out > 0 && avail_in > 0, false);
|
||||
|
||||
while (avail_in > 0) {
|
||||
int ret;
|
||||
if (_decompress_to_ram == false)
|
||||
ret = _decompressor->decompress_to_stream(next_in, avail_in,
|
||||
next_out, avail_out, dest_buffer,
|
||||
dest_buffer_length, _write_stream);
|
||||
else
|
||||
ret = _decompressor->decompress_to_stream(next_in, avail_in,
|
||||
next_out, avail_out, dest_buffer,
|
||||
dest_buffer_length, *_write_string_stream);
|
||||
if (ret == ZCompressorBase::S_error)
|
||||
return EU_error_zlib;
|
||||
if ((int)_decompressor->get_total_in() == _source_file_length &&
|
||||
avail_out == dest_buffer_length) {
|
||||
cleanup();
|
||||
return EU_success;
|
||||
}
|
||||
}
|
||||
|
||||
return EU_ok;
|
||||
// All done!
|
||||
cleanup();
|
||||
_source_filename.unlink();
|
||||
return EU_success;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Decompressor::decompress
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description: Performs a foreground decompression of the named
|
||||
// file; does not return until the decompression is
|
||||
// complete.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Decompressor::
|
||||
decompress(Filename &source_file) {
|
||||
decompress(const Filename &source_file) {
|
||||
int ret = initiate(source_file);
|
||||
if (ret < 0)
|
||||
return false;
|
||||
for (;;) {
|
||||
ret = run();
|
||||
if (ret == EU_success)
|
||||
return true;
|
||||
else if (ret < 0)
|
||||
return false;
|
||||
|
||||
int ch = _decompress->get();
|
||||
while (!_decompress->eof() && !_decompress->fail()) {
|
||||
_dest->put(ch);
|
||||
ch = _decompress->get();
|
||||
}
|
||||
return false;
|
||||
|
||||
cleanup();
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Decompressor::decompress
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Description: Does an in-memory decompression of the indicated
|
||||
// Ramfile. The decompressed contents are written back
|
||||
// into the same Ramfile on completion.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Decompressor::
|
||||
decompress(Ramfile &source_file) {
|
||||
int ret = initiate(source_file);
|
||||
if (ret < 0)
|
||||
return false;
|
||||
for (;;) {
|
||||
ret = run();
|
||||
if (ret == EU_success) {
|
||||
source_file._data = _write_string_stream->str();
|
||||
delete _read_string_stream;
|
||||
_read_string_stream = NULL;
|
||||
delete _write_string_stream;
|
||||
_write_string_stream = NULL;
|
||||
return true;
|
||||
} else if (ret < 0)
|
||||
return false;
|
||||
decompress(Ramfile &source_and_dest_file) {
|
||||
istringstream source(source_and_dest_file._data);
|
||||
ostringstream dest;
|
||||
|
||||
IDecompressStream decompress(&source, false);
|
||||
|
||||
int ch = decompress.get();
|
||||
while (!decompress.eof() && !decompress.fail()) {
|
||||
dest.put(ch);
|
||||
ch = decompress.get();
|
||||
}
|
||||
|
||||
source_and_dest_file._pos = 0;
|
||||
source_and_dest_file._data = dest.str();
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Decompressor::get_progress
|
||||
// Access: Public
|
||||
// Description: Returns the ratio through the decompression step
|
||||
// in the background.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
float Decompressor::
|
||||
get_progress() const {
|
||||
if (_decompress == (istream *)NULL) {
|
||||
// Hmm, we were already done.
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
nassertr(_source_length > 0, 0.0);
|
||||
size_t source_pos = _source->tellg();
|
||||
|
||||
// We stop the scale at 0.99 because there may be a little bit more
|
||||
// to do even after the decompressor has read all of the source.
|
||||
return (0.99f * (float)source_pos / (float)_source_length);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Decompressor::cleanup
|
||||
// Access: Private
|
||||
// Description: Called to reset a previous decompressor state and
|
||||
// clean up properly.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Decompressor::
|
||||
cleanup() {
|
||||
if (_source != (istream *)NULL) {
|
||||
delete _source;
|
||||
_source = NULL;
|
||||
}
|
||||
if (_dest != (ostream *)NULL) {
|
||||
delete _dest;
|
||||
_dest = NULL;
|
||||
}
|
||||
if (_decompress != (istream *)NULL) {
|
||||
delete _decompress;
|
||||
_decompress = NULL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,59 +15,45 @@
|
|||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef DECOMPRESSOR_H
|
||||
#define DECOMPRESSOR_H
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#include <pandabase.h>
|
||||
#include <filename.h>
|
||||
#include <buffer.h>
|
||||
#include <pointerTo.h>
|
||||
#include "zcompressor.h"
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "filename.h"
|
||||
|
||||
class Ramfile;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Decompressor
|
||||
// Description :
|
||||
// Description : This manages run-time decompression of a
|
||||
// zlib-compressed stream, as a background or foreground
|
||||
// task.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDAEXPRESS Decompressor {
|
||||
PUBLISHED:
|
||||
Decompressor(void);
|
||||
Decompressor(PT(Buffer) buffer);
|
||||
virtual ~Decompressor(void);
|
||||
Decompressor();
|
||||
~Decompressor();
|
||||
|
||||
int initiate(Filename &source_file);
|
||||
int initiate(Filename &source_file, Filename &dest_file);
|
||||
int initiate(Ramfile &source_file);
|
||||
int run(void);
|
||||
int initiate(const Filename &source_file);
|
||||
int initiate(const Filename &source_file, const Filename &dest_file);
|
||||
int run();
|
||||
|
||||
bool decompress(Filename &source_file);
|
||||
bool decompress(Ramfile &source_file);
|
||||
bool decompress(const Filename &source_file);
|
||||
bool decompress(Ramfile &source_and_dest_file);
|
||||
|
||||
INLINE float get_progress(void) const;
|
||||
float get_progress() const;
|
||||
|
||||
private:
|
||||
void init(PT(Buffer) buffer);
|
||||
void cleanup(void);
|
||||
|
||||
bool _initiated;
|
||||
PT(Buffer) _buffer;
|
||||
int _half_buffer_length;
|
||||
Filename _temp_file_name;
|
||||
Filename _source_filename;
|
||||
|
||||
istream *_source;
|
||||
istream *_decompress;
|
||||
ostream *_dest;
|
||||
|
||||
Filename _source_file;
|
||||
ifstream _read_stream;
|
||||
ofstream _write_stream;
|
||||
istringstream *_read_string_stream;
|
||||
ostringstream *_write_string_stream;
|
||||
int _source_file_length;
|
||||
int _total_bytes_read;
|
||||
bool _read_all_input;
|
||||
bool _handled_all_input;
|
||||
int _source_buffer_length;
|
||||
ZDecompressor *_decompressor;
|
||||
bool _decompress_to_ram;
|
||||
size_t _source_length;
|
||||
};
|
||||
|
||||
#include "decompressor.I"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#include "download_utils.cxx"
|
||||
#include "decompressor.cxx"
|
||||
#include "zcompressor.cxx"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,95 +0,0 @@
|
|||
// Filename: zcompressor.I
|
||||
// Created by: mike (09Jan97)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ZCompressorBase::get_total_in
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ulong ZCompressorBase::
|
||||
get_total_in(void) const {
|
||||
return (_stream->total_in);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ZCompressorBase::get_total_out
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE ulong ZCompressorBase::
|
||||
get_total_out(void) const {
|
||||
return (_stream->total_out);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ZCompressorBase::reset
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ZCompressorBase::
|
||||
reset(void) {
|
||||
reset_stream(_stream);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ZCompressorBase::reset_stream
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ZCompressorBase::
|
||||
reset_stream(z_stream *strm) const {
|
||||
strm->next_in = Z_NULL;
|
||||
strm->avail_in = 0;
|
||||
strm->total_in = 0;
|
||||
strm->next_out = Z_NULL;
|
||||
strm->avail_out = 0;
|
||||
strm->total_out = 0;
|
||||
strm->zalloc = Z_NULL;
|
||||
strm->zfree = Z_NULL;
|
||||
strm->opaque = Z_NULL;
|
||||
}
|
||||
|
||||
#ifndef CPPPARSER
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ZCompressorBase::put_stream
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ZCompressorBase::
|
||||
put_stream(z_stream *strm, char *next_in, int avail_in, char *next_out,
|
||||
int avail_out) const {
|
||||
strm->next_in = (uchar *)next_in;
|
||||
strm->avail_in = (ulong)avail_in;
|
||||
strm->next_out = (uchar *)next_out;
|
||||
strm->avail_out = (ulong)avail_out;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ZCompressorBase::get_stream
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ZCompressorBase::
|
||||
get_stream(z_stream *strm, char *&next_in, int &avail_in, char *&next_out,
|
||||
int &avail_out) const {
|
||||
next_in = (char *)strm->next_in;
|
||||
avail_in = (int)strm->avail_in;
|
||||
next_out = (char *)strm->next_out;
|
||||
avail_out = (int)strm->avail_out;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,242 +0,0 @@
|
|||
// Filename: zcompressor.cxx
|
||||
// Created by: mike (09Jan97)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is compiled only if we have zlib installed.
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "config_downloader.h"
|
||||
#include <zlib.h>
|
||||
#include "zcompressor.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Defines
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ZCompressor::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ZCompressor::
|
||||
ZCompressor(void) {
|
||||
if (downloader_cat.is_debug())
|
||||
downloader_cat.debug()
|
||||
<< "ZCompressor constructor called" << endl;
|
||||
_stream = new z_stream;
|
||||
reset_stream(_stream);
|
||||
int ret = deflateInit(_stream, 9);
|
||||
if (ret == Z_OK)
|
||||
downloader_cat.debug()
|
||||
<< "ZCompressor::ZCompressor() - Zlib deflate initialized" << endl;
|
||||
else
|
||||
handle_zerror(ret, _stream);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ZCompressor::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ZCompressor::
|
||||
~ZCompressor(void) {
|
||||
if (downloader_cat.is_debug())
|
||||
downloader_cat.debug()
|
||||
<< "ZCompressor destructor called" << endl;
|
||||
handle_zerror(deflateEnd(_stream), _stream);
|
||||
delete _stream;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ZCompressor::compress
|
||||
// Access: Public
|
||||
// Description: Compress from next_in into next_out until avail_in
|
||||
// is 0 or avail_out is 0 or an error occurs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int ZCompressor::
|
||||
compress(char *&next_in, int &avail_in, char *&next_out, int &avail_out,
|
||||
bool finish) {
|
||||
|
||||
int fin_flag = (finish == true) ? Z_FINISH : Z_NO_FLUSH;
|
||||
|
||||
put_stream(_stream, next_in, avail_in, next_out, avail_out);
|
||||
int ret = handle_zerror(deflate(_stream, fin_flag), _stream);
|
||||
get_stream(_stream, next_in, avail_in, next_out, avail_out);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ZCompressor::compress_to_stream
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int ZCompressor::
|
||||
compress_to_stream(char *&next_in, int &avail_in, char *&next_out,
|
||||
int &avail_out, char *out_buffer,
|
||||
int out_buffer_length, ofstream &write_stream,
|
||||
bool finish) {
|
||||
int ret = compress(next_in, avail_in, next_out, avail_out, finish);
|
||||
if (ret == S_error)
|
||||
return ret;
|
||||
|
||||
// See if there is any output to write
|
||||
int out_bytes = out_buffer_length - avail_out;
|
||||
if (out_bytes > 0) {
|
||||
write_stream.write(out_buffer, out_bytes);
|
||||
next_out = out_buffer;
|
||||
avail_out = out_buffer_length;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ZDecompressor::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ZDecompressor::
|
||||
ZDecompressor(void) {
|
||||
if (downloader_cat.is_debug())
|
||||
downloader_cat.debug()
|
||||
<< "ZDecompressor constructor called" << endl;
|
||||
_stream = new z_stream;
|
||||
reset_stream(_stream);
|
||||
int ret = inflateInit(_stream);
|
||||
if (ret == Z_OK)
|
||||
downloader_cat.debug()
|
||||
<< "ZDecompressor::ZDecompressor() - Zlib inflate initialized" << endl;
|
||||
else
|
||||
handle_zerror(ret, _stream);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ZDecompressor::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ZDecompressor::
|
||||
~ZDecompressor(void) {
|
||||
if (downloader_cat.is_debug())
|
||||
downloader_cat.debug()
|
||||
<< "ZDecompressor destructor called" << endl;
|
||||
handle_zerror(inflateEnd(_stream), _stream);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ZDecompressor::decompress
|
||||
// Access: Public
|
||||
// Description: Decompress from next_in into next_out until avail_in
|
||||
// is 0 or avail_out is 0 or an error occurs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int ZDecompressor::
|
||||
decompress(char *&next_in, int &avail_in, char *&next_out, int &avail_out,
|
||||
bool finish) {
|
||||
|
||||
int fin_flag = (finish == true) ? Z_FINISH : Z_NO_FLUSH;
|
||||
|
||||
put_stream(_stream, next_in, avail_in, next_out, avail_out);
|
||||
int ret = handle_zerror(inflate(_stream, fin_flag), _stream);
|
||||
get_stream(_stream, next_in, avail_in, next_out, avail_out);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ZDecompressor::decompress_to_stream
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int ZDecompressor::
|
||||
decompress_to_stream(char *&next_in, int &avail_in, char *&next_out,
|
||||
int &avail_out, char *out_buffer,
|
||||
int out_buffer_length, ostream &write_stream,
|
||||
bool finish) {
|
||||
int ret = decompress(next_in, avail_in, next_out, avail_out, finish);
|
||||
if (ret == S_error)
|
||||
return ret;
|
||||
|
||||
// See if there is any output to write
|
||||
int out_bytes = out_buffer_length - avail_out;
|
||||
if (out_bytes > 0) {
|
||||
write_stream.write(out_buffer, out_bytes);
|
||||
next_out = out_buffer;
|
||||
avail_out = out_buffer_length;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ZCompressorBase::handle_zerror
|
||||
// Access: Private
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int ZCompressorBase::
|
||||
handle_zerror(int code, const z_stream *strm) const {
|
||||
if (code == Z_OK)
|
||||
return S_ok;
|
||||
else if (code == Z_STREAM_END)
|
||||
return S_finished;
|
||||
else {
|
||||
downloader_cat.error()
|
||||
<< "ZCompressorBase::handle_zerror() - ";
|
||||
switch (code) {
|
||||
case Z_DATA_ERROR:
|
||||
downloader_cat.error()
|
||||
<< "corrupt data";
|
||||
break;
|
||||
case Z_NEED_DICT:
|
||||
downloader_cat.error()
|
||||
<< "need a dictionary";
|
||||
break;
|
||||
case Z_STREAM_ERROR:
|
||||
downloader_cat.error()
|
||||
<< "next_in or next_out = NULL";
|
||||
break;
|
||||
case Z_MEM_ERROR:
|
||||
downloader_cat.error()
|
||||
<< "not enough memory";
|
||||
break;
|
||||
case Z_BUF_ERROR:
|
||||
downloader_cat.error()
|
||||
<< "no progress is possible";
|
||||
break;
|
||||
case Z_VERSION_ERROR:
|
||||
downloader_cat.error()
|
||||
<< "zlib version conflict";
|
||||
break;
|
||||
default:
|
||||
downloader_cat.error()
|
||||
<< "unknown error: " << code;
|
||||
break;
|
||||
}
|
||||
if (strm != NULL) {
|
||||
if (strm->msg != NULL) {
|
||||
downloader_cat.error()
|
||||
<< " - zlib message: " << strm->msg;
|
||||
}
|
||||
}
|
||||
downloader_cat.error()
|
||||
<< endl;
|
||||
}
|
||||
return S_error;
|
||||
}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
// Filename: zcompressor.h
|
||||
// Created by: mike (09Jan97)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://www.panda3d.org/license.txt .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d@yahoogroups.com .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#ifndef ZCOMPRESSOR_H
|
||||
#define ZCOMPRESSOR_H
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Includes
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#include <pandabase.h>
|
||||
#include <zlib.h>
|
||||
#include "typedef.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ZCompressorBase
|
||||
// Description :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDAEXPRESS ZCompressorBase {
|
||||
public:
|
||||
enum status {
|
||||
S_ok,
|
||||
S_finished,
|
||||
S_error,
|
||||
};
|
||||
|
||||
INLINE ulong get_total_in(void) const;
|
||||
INLINE ulong get_total_out(void) const;
|
||||
INLINE void reset(void);
|
||||
INLINE void reset_stream(z_stream *strm) const;
|
||||
#ifndef CPPPARSER
|
||||
INLINE void put_stream(z_stream *strm, char *next_in, int avail_in,
|
||||
char *next_out, int avail_out) const;
|
||||
INLINE void get_stream(z_stream *strm, char *&next_in, int &avail_in,
|
||||
char *&next_out, int &avail_out) const;
|
||||
#endif
|
||||
int handle_zerror(int code, const z_stream *strm = NULL) const;
|
||||
|
||||
protected:
|
||||
z_stream *_stream;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ZCompressor
|
||||
// Description :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDAEXPRESS ZCompressor : public ZCompressorBase {
|
||||
public:
|
||||
ZCompressor(void);
|
||||
~ZCompressor(void);
|
||||
|
||||
int compress(char *&next_in, int &avail_in, char *&next_out,
|
||||
int &avail_out, bool finish = false);
|
||||
int compress_to_stream(char *&next_in, int &avail_in, char *&next_out,
|
||||
int &avail_out, char *out_buffer, int out_buffer_length,
|
||||
ofstream &write_stream, bool finish = false);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ZDecompressor
|
||||
// Description :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDAEXPRESS ZDecompressor : public ZCompressorBase {
|
||||
public:
|
||||
ZDecompressor(void);
|
||||
~ZDecompressor(void);
|
||||
|
||||
int decompress(char *&next_in, int &avail_in, char *&next_out,
|
||||
int &avail_out, bool finish = false);
|
||||
int decompress_to_stream(char *&next_in, int &avail_in, char *&next_out,
|
||||
int &avail_out, char *out_buffer, int out_buffer_length,
|
||||
ostream &write_stream, bool finish = false);
|
||||
};
|
||||
|
||||
#include "zcompressor.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -16,15 +16,15 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <filename.h>
|
||||
#include <zcompressor.h>
|
||||
#include <notify.h>
|
||||
#include "filename.h"
|
||||
#include "zStream.h"
|
||||
#include "notify.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
if (argc < 2) {
|
||||
cerr << "Usage: pcompress <file>" << endl;
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Filename source_file = argv[1];
|
||||
|
|
@ -37,7 +37,7 @@ main(int argc, char *argv[]) {
|
|||
source_file.set_binary();
|
||||
if (!source_file.open_read(read_stream)) {
|
||||
cerr << "failed to open: " << source_file << endl;
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Determine source file length
|
||||
|
|
@ -55,64 +55,16 @@ main(int argc, char *argv[]) {
|
|||
dest_file.set_binary();
|
||||
if (!dest_file.open_write(write_stream)) {
|
||||
cerr << "failed to open: " << dest_file << endl;
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
ZCompressor compressor;
|
||||
int buffer_length = 1000000;
|
||||
int half_buffer_length = buffer_length/2;
|
||||
char *buffer = new char[buffer_length];
|
||||
|
||||
// Read from the source file into the first half of the buffer,
|
||||
// decompress into the second half of the buffer, write the second
|
||||
// half of the buffer to disk, and repeat.
|
||||
int total_bytes_read = 0;
|
||||
bool read_all_input = false;
|
||||
bool handled_all_input = false;
|
||||
int source_buffer_length;
|
||||
int ret;
|
||||
while (handled_all_input == false) {
|
||||
|
||||
// See if there is anything left in the source file
|
||||
if (read_all_input == false) {
|
||||
read_stream.read(buffer, half_buffer_length);
|
||||
source_buffer_length = read_stream.gcount();
|
||||
total_bytes_read += source_buffer_length;
|
||||
if (read_stream.eof()) {
|
||||
nassertr(total_bytes_read == source_file_length, false);
|
||||
read_all_input = true;
|
||||
}
|
||||
}
|
||||
|
||||
char *next_in = buffer;
|
||||
int avail_in = source_buffer_length;
|
||||
char *dest_buffer = buffer + source_buffer_length;
|
||||
char *next_out = dest_buffer;
|
||||
int dest_buffer_length = buffer_length - source_buffer_length;
|
||||
int avail_out = dest_buffer_length;
|
||||
nassertr(avail_out > 0 && avail_in > 0, false);
|
||||
|
||||
// Consume all the input from the input buffer, writing to disk
|
||||
// as we go to free output buffer space
|
||||
while (avail_in > 0) {
|
||||
ret = compressor.compress_to_stream(next_in, avail_in,
|
||||
next_out, avail_out, dest_buffer,
|
||||
dest_buffer_length, write_stream);
|
||||
if (ret == ZCompressorBase::S_error)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If all the input has been consumed, we need to keep processing
|
||||
// output until it says it's finished
|
||||
if (compressor.get_total_in() == source_file_length) {
|
||||
while (ret != ZCompressorBase::S_finished) {
|
||||
ret = compressor.compress_to_stream(next_in, avail_in,
|
||||
next_out, avail_out, dest_buffer,
|
||||
dest_buffer_length, write_stream, true);
|
||||
if (ret == ZCompressorBase::S_error)
|
||||
return 0;
|
||||
}
|
||||
handled_all_input = true;
|
||||
{
|
||||
OCompressStream compress(&write_stream, false);
|
||||
|
||||
int ch = read_stream.get();
|
||||
while (!read_stream.eof() && !read_stream.fail()) {
|
||||
compress.put(ch);
|
||||
ch = read_stream.get();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -120,5 +72,5 @@ main(int argc, char *argv[]) {
|
|||
write_stream.close();
|
||||
source_file.unlink();
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,27 +16,22 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <filename.h>
|
||||
#include <decompressor.h>
|
||||
#include <buffer.h>
|
||||
#include "filename.h"
|
||||
#include "decompressor.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
if (argc < 2) {
|
||||
cerr << "Usage: pdecompress <file>" << endl;
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Filename source_file = argv[1];
|
||||
|
||||
#ifdef TESTING_CODE
|
||||
Decompressor decompressor;
|
||||
#else
|
||||
PT(Buffer) buffer = new Buffer(1000000);
|
||||
Decompressor decompressor(buffer);
|
||||
#endif
|
||||
if (decompressor.decompress(source_file) == false)
|
||||
if (decompressor.decompress(source_file) == false) {
|
||||
cerr << "Decompress failed" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue