mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
*** empty log message ***
This commit is contained in:
parent
9f2c083966
commit
45fe04bff1
332
panda/src/downloader/asyncDecompressor.cxx
Normal file
332
panda/src/downloader/asyncDecompressor.cxx
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
// Filename: decompressor.cxx
|
||||||
|
// Created by: mike (09Jan97)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// This file is compiled only if we have zlib installed.
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Includes
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
#include "asyncDecompressor.h"
|
||||||
|
#include "config_downloader.h"
|
||||||
|
|
||||||
|
#include <event.h>
|
||||||
|
#include <pt_Event.h>
|
||||||
|
#include <throw_event.h>
|
||||||
|
#include <eventParameter.h>
|
||||||
|
#include <filename.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Defines
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : DecompressorToken
|
||||||
|
// Description : Holds a request for the decompressor.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class DecompressorToken : public ReferenceCount {
|
||||||
|
public:
|
||||||
|
INLINE DecompressorToken(uint id, const Filename &source_file,
|
||||||
|
const Filename &dest_file, const string &event_name) {
|
||||||
|
_id = id;
|
||||||
|
_source_file = source_file;
|
||||||
|
_dest_file = dest_file;
|
||||||
|
_event_name = event_name;
|
||||||
|
}
|
||||||
|
int _id;
|
||||||
|
Filename _source_file;
|
||||||
|
Filename _dest_file;
|
||||||
|
string _event_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Decompressor::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
Decompressor::
|
||||||
|
Decompressor(void) : AsyncUtility() {
|
||||||
|
PT(Buffer) buffer = new Buffer(decompressor_buffer_size);
|
||||||
|
init(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Decompressor::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
Decompressor::
|
||||||
|
Decompressor(PT(Buffer) buffer) : AsyncUtility() {
|
||||||
|
init(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Decompressor::Constructor
|
||||||
|
// Access: Private
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void Decompressor::
|
||||||
|
init(PT(Buffer) buffer) {
|
||||||
|
nassertv(!buffer.is_null());
|
||||||
|
_frequency = decompressor_frequency;
|
||||||
|
_token_board = new DecompressorTokenBoard;
|
||||||
|
_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Decompressor::Destructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
Decompressor::
|
||||||
|
~Decompressor(void) {
|
||||||
|
destroy_thread();
|
||||||
|
|
||||||
|
delete _token_board;
|
||||||
|
_temp_file_name.unlink();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Decompressor::request_decompress
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int Decompressor::
|
||||||
|
request_decompress(const Filename &source_file, const string &event_name) {
|
||||||
|
Filename dest_file = source_file;
|
||||||
|
string extension = source_file.get_extension();
|
||||||
|
if (extension == "pz")
|
||||||
|
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 request_decompress(source_file, dest_file, event_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Decompressor::request_decompress
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int Decompressor::
|
||||||
|
request_decompress(const Filename &source_file, const Filename &dest_file,
|
||||||
|
const string &event_name) {
|
||||||
|
|
||||||
|
PT(DecompressorToken) tok;
|
||||||
|
if (_threads_enabled) {
|
||||||
|
|
||||||
|
// Make sure we actually are threaded
|
||||||
|
if (!_threaded) {
|
||||||
|
downloader_cat.info()
|
||||||
|
<< "Decompressor::request_decompress() - create_thread() was "
|
||||||
|
<< "never called! Calling it now..." << endl;
|
||||||
|
create_thread();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to grab the lock in order to signal the condition variable
|
||||||
|
#ifdef HAVE_IPC
|
||||||
|
_lock.lock();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (_token_board->_waiting.is_full()) {
|
||||||
|
downloader_cat.error()
|
||||||
|
<< "Downloader::request_download() - Too many pending requests\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (downloader_cat.is_debug()) {
|
||||||
|
downloader_cat.debug()
|
||||||
|
<< "Decompress requested for file: " << source_file << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
tok = new DecompressorToken(_next_token++, source_file, dest_file,
|
||||||
|
event_name);
|
||||||
|
_token_board->_waiting.insert(tok);
|
||||||
|
|
||||||
|
#ifdef HAVE_IPC
|
||||||
|
_request_cond->signal();
|
||||||
|
_lock.unlock();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// If we're not running asynchronously, process the load request
|
||||||
|
// directly now.
|
||||||
|
if (_token_board->_waiting.is_full()) {
|
||||||
|
downloader_cat.error()
|
||||||
|
<< "Downloader::request_download() - Too many pending requests\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (downloader_cat.is_debug()) {
|
||||||
|
downloader_cat.debug()
|
||||||
|
<< "Decompress requested for file: " << source_file << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
tok = new DecompressorToken(_next_token++, source_file, dest_file,
|
||||||
|
event_name);
|
||||||
|
_token_board->_waiting.insert(tok);
|
||||||
|
process_request();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tok->_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Decompressor::process_request
|
||||||
|
// Access: Private
|
||||||
|
// Description: Serves any requests on the token board, moving them
|
||||||
|
// to the done queue.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool Decompressor::
|
||||||
|
process_request() {
|
||||||
|
if (_shutdown) {
|
||||||
|
if (downloader_cat.is_debug())
|
||||||
|
downloader_cat.debug()
|
||||||
|
<< "Decompressor shutting down...\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is actually a request token - process it
|
||||||
|
while (!_token_board->_waiting.is_empty()) {
|
||||||
|
PT(DecompressorToken) tok = _token_board->_waiting.extract();
|
||||||
|
if (decompress(tok->_source_file, tok->_dest_file)) {
|
||||||
|
_token_board->_done.insert(tok);
|
||||||
|
|
||||||
|
// Throw a "done" event now.
|
||||||
|
if (!tok->_event_name.empty()) {
|
||||||
|
PT_Event done = new Event(tok->_event_name);
|
||||||
|
done->add_parameter(EventParameter((int)tok->_id));
|
||||||
|
throw_event(done);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (downloader_cat.is_debug()) {
|
||||||
|
downloader_cat.debug()
|
||||||
|
<< "Decompressor::process_request() - decompress complete for "
|
||||||
|
<< tok->_source_file << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Decompressor::decompress
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool Decompressor::
|
||||||
|
decompress(Filename &source_file) {
|
||||||
|
Filename dest_file = source_file;
|
||||||
|
string extension = source_file.get_extension();
|
||||||
|
if (extension == "pz")
|
||||||
|
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 false;
|
||||||
|
}
|
||||||
|
return decompress(source_file, dest_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Decompressor::decompress
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool Decompressor::
|
||||||
|
decompress(Filename &source_file, Filename &dest_file) {
|
||||||
|
|
||||||
|
// Open source file
|
||||||
|
ifstream read_stream;
|
||||||
|
source_file.set_binary();
|
||||||
|
if (!source_file.open_read(read_stream)) {
|
||||||
|
downloader_cat.error()
|
||||||
|
<< "Decompressor::decompress() - Error opening source file: "
|
||||||
|
<< source_file << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine source file length
|
||||||
|
read_stream.seekg(0, ios::end);
|
||||||
|
int source_file_length = read_stream.tellg();
|
||||||
|
if (source_file_length == 0) {
|
||||||
|
downloader_cat.warning()
|
||||||
|
<< "Decompressor::decompress() - Zero length file: "
|
||||||
|
<< source_file << endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
read_stream.seekg(0, ios::beg);
|
||||||
|
|
||||||
|
// Open destination file
|
||||||
|
ofstream write_stream;
|
||||||
|
dest_file.set_binary();
|
||||||
|
if (!dest_file.open_write(write_stream)) {
|
||||||
|
downloader_cat.error()
|
||||||
|
<< "Decompressor::decompress() - Error opening dest file: "
|
||||||
|
<< source_file << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
ZDecompressor decompressor;
|
||||||
|
while (handled_all_input == false) {
|
||||||
|
|
||||||
|
// See if there is anything left in the source file
|
||||||
|
if (read_all_input == 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = decompressor.decompress_to_stream(next_in, avail_in,
|
||||||
|
next_out, avail_out, dest_buffer,
|
||||||
|
dest_buffer_length, write_stream);
|
||||||
|
if (ret == ZCompressorBase::S_error)
|
||||||
|
return false;
|
||||||
|
if ((int)decompressor.get_total_in() == source_file_length &&
|
||||||
|
avail_out == dest_buffer_length)
|
||||||
|
handled_all_input = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nap();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
read_stream.close();
|
||||||
|
write_stream.close();
|
||||||
|
|
||||||
|
source_file.unlink();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
52
panda/src/downloader/asyncDecompressor.h
Normal file
52
panda/src/downloader/asyncDecompressor.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// Filename: decompressor.h
|
||||||
|
// Created by: mike (09Jan97)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
#ifndef ASYNCDECOMPRESSOR_H
|
||||||
|
#define ASYNCDECOMPRESSOR_H
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Includes
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
#include <pandabase.h>
|
||||||
|
#include <filename.h>
|
||||||
|
#include <tokenBoard.h>
|
||||||
|
#include <buffer.h>
|
||||||
|
#include "zcompressor.h"
|
||||||
|
#include "asyncUtility.h"
|
||||||
|
|
||||||
|
class DecompressorToken;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : Decompressor
|
||||||
|
// Description :
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDAEXPRESS Decompressor : public AsyncUtility {
|
||||||
|
PUBLISHED:
|
||||||
|
Decompressor(void);
|
||||||
|
Decompressor(PT(Buffer) buffer);
|
||||||
|
virtual ~Decompressor(void);
|
||||||
|
|
||||||
|
int request_decompress(const Filename &source_file,
|
||||||
|
const string &event_name);
|
||||||
|
int request_decompress(const Filename &source_file,
|
||||||
|
const Filename &dest_file,
|
||||||
|
const string &event_name);
|
||||||
|
|
||||||
|
bool decompress(Filename &source_file);
|
||||||
|
bool decompress(Filename &source_file, Filename &dest_file);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void init(PT(Buffer) buffer);
|
||||||
|
virtual bool process_request(void);
|
||||||
|
|
||||||
|
typedef TokenBoard<DecompressorToken> DecompressorTokenBoard;
|
||||||
|
DecompressorTokenBoard *_token_board;
|
||||||
|
|
||||||
|
PT(Buffer) _buffer;
|
||||||
|
int _half_buffer_length;
|
||||||
|
Filename _temp_file_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
251
panda/src/downloader/asyncExtractor.cxx
Normal file
251
panda/src/downloader/asyncExtractor.cxx
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
// Filename: extractor.cxx
|
||||||
|
// Created by: mike (09Jan97)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Includes
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
#include "asyncExtractor.h"
|
||||||
|
#include "config_downloader.h"
|
||||||
|
|
||||||
|
#include <event.h>
|
||||||
|
#include <pt_Event.h>
|
||||||
|
#include <throw_event.h>
|
||||||
|
#include <eventParameter.h>
|
||||||
|
#include <filename.h>
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Defines
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : ExtractorToken
|
||||||
|
// Description : Holds a request for the extractor.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class ExtractorToken : public ReferenceCount {
|
||||||
|
public:
|
||||||
|
INLINE ExtractorToken(uint id, const Filename &source_file,
|
||||||
|
const string &event_name,
|
||||||
|
const Filename &rel_path) {
|
||||||
|
_id = id;
|
||||||
|
_source_file = source_file;
|
||||||
|
_event_name = event_name;
|
||||||
|
_rel_path = rel_path;
|
||||||
|
}
|
||||||
|
int _id;
|
||||||
|
Filename _source_file;
|
||||||
|
string _event_name;
|
||||||
|
Filename _rel_path;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Extractor::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
Extractor::
|
||||||
|
Extractor(void) : AsyncUtility() {
|
||||||
|
PT(Buffer) buffer = new Buffer(extractor_buffer_size);
|
||||||
|
init(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Extractor::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
Extractor::
|
||||||
|
Extractor(PT(Buffer) buffer) : AsyncUtility() {
|
||||||
|
init(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Extractor::Constructor
|
||||||
|
// Access: Private
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void Extractor::
|
||||||
|
init(PT(Buffer) buffer) {
|
||||||
|
nassertv(!buffer.is_null());
|
||||||
|
_frequency = extractor_frequency;
|
||||||
|
_token_board = new ExtractorTokenBoard;
|
||||||
|
_buffer = buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Extractor::Destructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
Extractor::
|
||||||
|
~Extractor(void) {
|
||||||
|
destroy_thread();
|
||||||
|
|
||||||
|
delete _token_board;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Extractor::request_extract
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int Extractor::
|
||||||
|
request_extract(const Filename &source_file, const string &event_name,
|
||||||
|
const Filename &rel_path) {
|
||||||
|
|
||||||
|
PT(ExtractorToken) tok;
|
||||||
|
if (_threads_enabled) {
|
||||||
|
|
||||||
|
// Make sure we actually are threaded
|
||||||
|
if (!_threaded) {
|
||||||
|
downloader_cat.info()
|
||||||
|
<< "Extractor::request_extract() - create_thread() was "
|
||||||
|
<< "never called! Calling it now..." << endl;
|
||||||
|
create_thread();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to grab the lock in order to signal the condition variable
|
||||||
|
#ifdef HAVE_IPC
|
||||||
|
_lock.lock();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (_token_board->_waiting.is_full()) {
|
||||||
|
downloader_cat.error()
|
||||||
|
<< "Extractor::request_extract() - Too many pending requests\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (downloader_cat.is_debug()) {
|
||||||
|
downloader_cat.debug()
|
||||||
|
<< "Extract requested for file: " << source_file << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
tok = new ExtractorToken(_next_token++, source_file, event_name,
|
||||||
|
rel_path);
|
||||||
|
_token_board->_waiting.insert(tok);
|
||||||
|
|
||||||
|
#ifdef HAVE_IPC
|
||||||
|
_request_cond->signal();
|
||||||
|
_lock.unlock();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// If we're not running asynchronously, process the load request
|
||||||
|
// directly now.
|
||||||
|
if (_token_board->_waiting.is_full()) {
|
||||||
|
downloader_cat.error()
|
||||||
|
<< "Extractor::request_extract() - Too many pending requests\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (downloader_cat.is_debug()) {
|
||||||
|
downloader_cat.debug()
|
||||||
|
<< "Extract requested for file: " << source_file << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
tok = new ExtractorToken(_next_token++, source_file, event_name,
|
||||||
|
rel_path);
|
||||||
|
_token_board->_waiting.insert(tok);
|
||||||
|
process_request();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tok->_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Extractor::process_request
|
||||||
|
// Access: Private
|
||||||
|
// Description: Serves any requests on the token board, moving them
|
||||||
|
// to the done queue.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool Extractor::
|
||||||
|
process_request() {
|
||||||
|
if (_shutdown) {
|
||||||
|
if (downloader_cat.is_debug())
|
||||||
|
downloader_cat.debug()
|
||||||
|
<< "Extractor shutting down...\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is actually a request token - process it
|
||||||
|
while (!_token_board->_waiting.is_empty()) {
|
||||||
|
PT(ExtractorToken) tok = _token_board->_waiting.extract();
|
||||||
|
if (extract(tok->_source_file, tok->_rel_path)) {
|
||||||
|
_token_board->_done.insert(tok);
|
||||||
|
|
||||||
|
// Throw a "done" event now.
|
||||||
|
if (!tok->_event_name.empty()) {
|
||||||
|
PT_Event done = new Event(tok->_event_name);
|
||||||
|
done->add_parameter(EventParameter((int)tok->_id));
|
||||||
|
throw_event(done);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (downloader_cat.is_debug()) {
|
||||||
|
downloader_cat.debug()
|
||||||
|
<< "Extractor::process_request() - extract complete for "
|
||||||
|
<< tok->_source_file << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Extractor::extract
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool Extractor::
|
||||||
|
extract(Filename &source_file, const Filename &rel_path) {
|
||||||
|
|
||||||
|
// Open source file
|
||||||
|
ifstream read_stream;
|
||||||
|
source_file.set_binary();
|
||||||
|
if (!source_file.open_read(read_stream)) {
|
||||||
|
downloader_cat.error()
|
||||||
|
<< "Extractor::extract() - Error opening source file: "
|
||||||
|
<< source_file << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine source file length
|
||||||
|
read_stream.seekg(0, ios::end);
|
||||||
|
int source_file_length = read_stream.tellg();
|
||||||
|
read_stream.seekg(0, ios::beg);
|
||||||
|
|
||||||
|
// Read the multifile header
|
||||||
|
Multifile mfile;
|
||||||
|
|
||||||
|
// Read from the source file and write to the appropriate extracted file
|
||||||
|
int total_bytes_read = 0;
|
||||||
|
bool read_all_input = false;
|
||||||
|
bool handled_all_input = false;
|
||||||
|
int source_buffer_length;
|
||||||
|
while (handled_all_input == false) {
|
||||||
|
|
||||||
|
// See if there is anything left in the source file
|
||||||
|
if (read_all_input == false) {
|
||||||
|
read_stream.read(_buffer->_buffer, _buffer->get_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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write to the out file
|
||||||
|
char *start = _buffer->_buffer;
|
||||||
|
int size = source_buffer_length;
|
||||||
|
if (mfile.write_extract(start, size, rel_path) == true)
|
||||||
|
handled_all_input = true;
|
||||||
|
|
||||||
|
nap();
|
||||||
|
}
|
||||||
|
|
||||||
|
read_stream.close();
|
||||||
|
source_file.unlink();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
46
panda/src/downloader/asyncExtractor.h
Normal file
46
panda/src/downloader/asyncExtractor.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// Filename: extractor.h
|
||||||
|
// Created by: mike (09Jan97)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
#ifndef ASYNCEXTRACTOR_H
|
||||||
|
#define ASYNCEXTRACTOR_H
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Includes
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
#include <pandabase.h>
|
||||||
|
#include <filename.h>
|
||||||
|
#include <tokenBoard.h>
|
||||||
|
#include <buffer.h>
|
||||||
|
#include <multifile.h>
|
||||||
|
#include "asyncUtility.h"
|
||||||
|
|
||||||
|
class ExtractorToken;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : Extractor
|
||||||
|
// Description :
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EXPCL_PANDAEXPRESS Extractor : public AsyncUtility {
|
||||||
|
PUBLISHED:
|
||||||
|
Extractor(void);
|
||||||
|
Extractor(PT(Buffer) buffer);
|
||||||
|
virtual ~Extractor(void);
|
||||||
|
|
||||||
|
int request_extract(const Filename &source_file,
|
||||||
|
const string &event_name, const Filename &rel_path = "");
|
||||||
|
|
||||||
|
bool extract(Filename &source_file, const Filename &rel_path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void init(PT(Buffer) buffer);
|
||||||
|
virtual bool process_request(void);
|
||||||
|
|
||||||
|
typedef TokenBoard<ExtractorToken> ExtractorTokenBoard;
|
||||||
|
ExtractorTokenBoard *_token_board;
|
||||||
|
|
||||||
|
PT(Buffer) _buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -11,10 +11,6 @@
|
|||||||
#include "decompressor.h"
|
#include "decompressor.h"
|
||||||
#include "config_downloader.h"
|
#include "config_downloader.h"
|
||||||
|
|
||||||
#include <event.h>
|
|
||||||
#include <pt_Event.h>
|
|
||||||
#include <throw_event.h>
|
|
||||||
#include <eventParameter.h>
|
|
||||||
#include <filename.h>
|
#include <filename.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@ -22,32 +18,13 @@
|
|||||||
// Defines
|
// Defines
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Class : DecompressorToken
|
|
||||||
// Description : Holds a request for the decompressor.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
class DecompressorToken : public ReferenceCount {
|
|
||||||
public:
|
|
||||||
INLINE DecompressorToken(uint id, const Filename &source_file,
|
|
||||||
const Filename &dest_file, const string &event_name) {
|
|
||||||
_id = id;
|
|
||||||
_source_file = source_file;
|
|
||||||
_dest_file = dest_file;
|
|
||||||
_event_name = event_name;
|
|
||||||
}
|
|
||||||
int _id;
|
|
||||||
Filename _source_file;
|
|
||||||
Filename _dest_file;
|
|
||||||
string _event_name;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Decompressor::Constructor
|
// Function: Decompressor::Constructor
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
Decompressor::
|
Decompressor::
|
||||||
Decompressor(void) : AsyncUtility() {
|
Decompressor(void) {
|
||||||
PT(Buffer) buffer = new Buffer(decompressor_buffer_size);
|
PT(Buffer) buffer = new Buffer(decompressor_buffer_size);
|
||||||
init(buffer);
|
init(buffer);
|
||||||
}
|
}
|
||||||
@ -58,7 +35,7 @@ Decompressor(void) : AsyncUtility() {
|
|||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
Decompressor::
|
Decompressor::
|
||||||
Decompressor(PT(Buffer) buffer) : AsyncUtility() {
|
Decompressor(PT(Buffer) buffer) {
|
||||||
init(buffer);
|
init(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,8 +47,6 @@ Decompressor(PT(Buffer) buffer) : AsyncUtility() {
|
|||||||
void Decompressor::
|
void Decompressor::
|
||||||
init(PT(Buffer) buffer) {
|
init(PT(Buffer) buffer) {
|
||||||
nassertv(!buffer.is_null());
|
nassertv(!buffer.is_null());
|
||||||
_frequency = decompressor_frequency;
|
|
||||||
_token_board = new DecompressorTokenBoard;
|
|
||||||
_half_buffer_length = buffer->get_length()/2;
|
_half_buffer_length = buffer->get_length()/2;
|
||||||
_buffer = buffer;
|
_buffer = buffer;
|
||||||
char *temp_name = tempnam(NULL, "dc");
|
char *temp_name = tempnam(NULL, "dc");
|
||||||
@ -87,19 +62,16 @@ init(PT(Buffer) buffer) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
Decompressor::
|
Decompressor::
|
||||||
~Decompressor(void) {
|
~Decompressor(void) {
|
||||||
destroy_thread();
|
|
||||||
|
|
||||||
delete _token_board;
|
|
||||||
_temp_file_name.unlink();
|
_temp_file_name.unlink();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Decompressor::request_decompress
|
// Function: Decompressor::initiate
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
int Decompressor::
|
int Decompressor::
|
||||||
request_decompress(const Filename &source_file, const string &event_name) {
|
initiate(Filename &source_file) {
|
||||||
Filename dest_file = source_file;
|
Filename dest_file = source_file;
|
||||||
string extension = source_file.get_extension();
|
string extension = source_file.get_extension();
|
||||||
if (extension == "pz")
|
if (extension == "pz")
|
||||||
@ -110,169 +82,41 @@ request_decompress(const Filename &source_file, const string &event_name) {
|
|||||||
<< "Decompressor::request_decompress() - Unknown file extension: ."
|
<< "Decompressor::request_decompress() - Unknown file extension: ."
|
||||||
<< extension << endl;
|
<< extension << endl;
|
||||||
}
|
}
|
||||||
return request_decompress(source_file, dest_file, event_name);
|
return initiate(source_file, dest_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: Decompressor::request_decompress
|
// Function: Decompressor::initiate
|
||||||
// Access: Public
|
// Access: Public
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
int Decompressor::
|
int Decompressor::
|
||||||
request_decompress(const Filename &source_file, const Filename &dest_file,
|
initiate(Filename &source_file, Filename &dest_file) {
|
||||||
const string &event_name) {
|
|
||||||
|
|
||||||
PT(DecompressorToken) tok;
|
|
||||||
if (_threads_enabled) {
|
|
||||||
|
|
||||||
// Make sure we actually are threaded
|
|
||||||
if (!_threaded) {
|
|
||||||
downloader_cat.info()
|
|
||||||
<< "Decompressor::request_decompress() - create_thread() was "
|
|
||||||
<< "never called! Calling it now..." << endl;
|
|
||||||
create_thread();
|
|
||||||
}
|
|
||||||
|
|
||||||
// We need to grab the lock in order to signal the condition variable
|
|
||||||
#ifdef HAVE_IPC
|
|
||||||
_lock.lock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (_token_board->_waiting.is_full()) {
|
|
||||||
downloader_cat.error()
|
|
||||||
<< "Downloader::request_download() - Too many pending requests\n";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (downloader_cat.is_debug()) {
|
|
||||||
downloader_cat.debug()
|
|
||||||
<< "Decompress requested for file: " << source_file << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
tok = new DecompressorToken(_next_token++, source_file, dest_file,
|
|
||||||
event_name);
|
|
||||||
_token_board->_waiting.insert(tok);
|
|
||||||
|
|
||||||
#ifdef HAVE_IPC
|
|
||||||
_request_cond->signal();
|
|
||||||
_lock.unlock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// If we're not running asynchronously, process the load request
|
|
||||||
// directly now.
|
|
||||||
if (_token_board->_waiting.is_full()) {
|
|
||||||
downloader_cat.error()
|
|
||||||
<< "Downloader::request_download() - Too many pending requests\n";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (downloader_cat.is_debug()) {
|
|
||||||
downloader_cat.debug()
|
|
||||||
<< "Decompress requested for file: " << source_file << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
tok = new DecompressorToken(_next_token++, source_file, dest_file,
|
|
||||||
event_name);
|
|
||||||
_token_board->_waiting.insert(tok);
|
|
||||||
process_request();
|
|
||||||
}
|
|
||||||
|
|
||||||
return tok->_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: Decompressor::process_request
|
|
||||||
// Access: Private
|
|
||||||
// Description: Serves any requests on the token board, moving them
|
|
||||||
// to the done queue.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
bool Decompressor::
|
|
||||||
process_request() {
|
|
||||||
if (_shutdown) {
|
|
||||||
if (downloader_cat.is_debug())
|
|
||||||
downloader_cat.debug()
|
|
||||||
<< "Decompressor shutting down...\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there is actually a request token - process it
|
|
||||||
while (!_token_board->_waiting.is_empty()) {
|
|
||||||
PT(DecompressorToken) tok = _token_board->_waiting.extract();
|
|
||||||
if (decompress(tok->_source_file, tok->_dest_file)) {
|
|
||||||
_token_board->_done.insert(tok);
|
|
||||||
|
|
||||||
// Throw a "done" event now.
|
|
||||||
if (!tok->_event_name.empty()) {
|
|
||||||
PT_Event done = new Event(tok->_event_name);
|
|
||||||
done->add_parameter(EventParameter((int)tok->_id));
|
|
||||||
throw_event(done);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (downloader_cat.is_debug()) {
|
|
||||||
downloader_cat.debug()
|
|
||||||
<< "Decompressor::process_request() - decompress complete for "
|
|
||||||
<< tok->_source_file << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: Decompressor::decompress
|
|
||||||
// Access: Public
|
|
||||||
// Description:
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
bool Decompressor::
|
|
||||||
decompress(Filename &source_file) {
|
|
||||||
Filename dest_file = source_file;
|
|
||||||
string extension = source_file.get_extension();
|
|
||||||
if (extension == "pz")
|
|
||||||
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 false;
|
|
||||||
}
|
|
||||||
return decompress(source_file, dest_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: Decompressor::decompress
|
|
||||||
// Access: Public
|
|
||||||
// Description:
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
bool Decompressor::
|
|
||||||
decompress(Filename &source_file, Filename &dest_file) {
|
|
||||||
|
|
||||||
// Open source file
|
// Open source file
|
||||||
ifstream read_stream;
|
_source_file = source_file;
|
||||||
source_file.set_binary();
|
_source_file.set_binary();
|
||||||
if (!source_file.open_read(read_stream)) {
|
if (!_source_file.open_read(_read_stream)) {
|
||||||
downloader_cat.error()
|
downloader_cat.error()
|
||||||
<< "Decompressor::decompress() - Error opening source file: "
|
<< "Decompressor::decompress() - Error opening source file: "
|
||||||
<< source_file << endl;
|
<< _source_file << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine source file length
|
// Determine source file length
|
||||||
read_stream.seekg(0, ios::end);
|
_read_stream.seekg(0, ios::end);
|
||||||
int source_file_length = read_stream.tellg();
|
_source_file_length = _read_stream.tellg();
|
||||||
if (source_file_length == 0) {
|
if (_source_file_length == 0) {
|
||||||
downloader_cat.warning()
|
downloader_cat.warning()
|
||||||
<< "Decompressor::decompress() - Zero length file: "
|
<< "Decompressor::decompress() - Zero length file: "
|
||||||
<< source_file << endl;
|
<< source_file << endl;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
read_stream.seekg(0, ios::beg);
|
_read_stream.seekg(0, ios::beg);
|
||||||
|
|
||||||
// Open destination file
|
// Open destination file
|
||||||
ofstream write_stream;
|
|
||||||
dest_file.set_binary();
|
dest_file.set_binary();
|
||||||
if (!dest_file.open_write(write_stream)) {
|
if (!dest_file.open_write(_write_stream)) {
|
||||||
downloader_cat.error()
|
downloader_cat.error()
|
||||||
<< "Decompressor::decompress() - Error opening dest file: "
|
<< "Decompressor::decompress() - Error opening dest file: "
|
||||||
<< source_file << endl;
|
<< source_file << endl;
|
||||||
@ -282,51 +126,52 @@ decompress(Filename &source_file, Filename &dest_file) {
|
|||||||
// Read from the source file into the first half of the buffer,
|
// Read from the source file into the first half of the buffer,
|
||||||
// decompress into the second half of the buffer, write the second
|
// decompress into the second half of the buffer, write the second
|
||||||
// half of the buffer to disk, and repeat.
|
// half of the buffer to disk, and repeat.
|
||||||
int total_bytes_read = 0;
|
_total_bytes_read = 0;
|
||||||
bool read_all_input = false;
|
_read_all_input = false;
|
||||||
bool handled_all_input = false;
|
_source_buffer_length;
|
||||||
int source_buffer_length;
|
return 1;
|
||||||
ZDecompressor decompressor;
|
}
|
||||||
while (handled_all_input == false) {
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Decompressor::run
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
int Decompressor::
|
||||||
|
run(void) {
|
||||||
|
|
||||||
// See if there is anything left in the source file
|
// See if there is anything left in the source file
|
||||||
if (read_all_input == false) {
|
if (_read_all_input == false) {
|
||||||
read_stream.read(_buffer->_buffer, _half_buffer_length);
|
_read_stream.read(_buffer->_buffer, _half_buffer_length);
|
||||||
source_buffer_length = read_stream.gcount();
|
_source_buffer_length = _read_stream.gcount();
|
||||||
total_bytes_read += source_buffer_length;
|
_total_bytes_read += _source_buffer_length;
|
||||||
if (read_stream.eof()) {
|
if (_read_stream.eof()) {
|
||||||
nassertr(total_bytes_read == source_file_length, false);
|
nassertr(_total_bytes_read == _source_file_length, false);
|
||||||
read_all_input = true;
|
_read_all_input = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *next_in = _buffer->_buffer;
|
char *next_in = _buffer->_buffer;
|
||||||
int avail_in = source_buffer_length;
|
int avail_in = _source_buffer_length;
|
||||||
char *dest_buffer = _buffer->_buffer + source_buffer_length;
|
char *dest_buffer = _buffer->_buffer + _source_buffer_length;
|
||||||
char *next_out = dest_buffer;
|
char *next_out = dest_buffer;
|
||||||
int dest_buffer_length = _buffer->get_length() - source_buffer_length;
|
int dest_buffer_length = _buffer->get_length() - _source_buffer_length;
|
||||||
int avail_out = dest_buffer_length;
|
int avail_out = dest_buffer_length;
|
||||||
nassertr(avail_out > 0 && avail_in > 0, false);
|
nassertr(avail_out > 0 && avail_in > 0, false);
|
||||||
|
|
||||||
while (avail_in > 0) {
|
while (avail_in > 0) {
|
||||||
int ret = decompressor.decompress_to_stream(next_in, avail_in,
|
int ret = _decompressor.decompress_to_stream(next_in, avail_in,
|
||||||
next_out, avail_out, dest_buffer,
|
next_out, avail_out, dest_buffer,
|
||||||
dest_buffer_length, write_stream);
|
dest_buffer_length, _write_stream);
|
||||||
if (ret == ZCompressorBase::S_error)
|
if (ret == ZCompressorBase::S_error)
|
||||||
return false;
|
return DS_error_zlib;
|
||||||
if ((int)decompressor.get_total_in() == source_file_length &&
|
if ((int)_decompressor.get_total_in() == _source_file_length &&
|
||||||
avail_out == dest_buffer_length)
|
avail_out == dest_buffer_length)
|
||||||
handled_all_input = true;
|
_read_stream.close();
|
||||||
|
_write_stream.close();
|
||||||
|
_source_file.unlink();
|
||||||
|
return DS_success;
|
||||||
}
|
}
|
||||||
|
|
||||||
nap();
|
return DS_ok;
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
read_stream.close();
|
|
||||||
write_stream.close();
|
|
||||||
|
|
||||||
source_file.unlink();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
@ -11,42 +11,49 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
#include <pandabase.h>
|
#include <pandabase.h>
|
||||||
#include <filename.h>
|
#include <filename.h>
|
||||||
#include <tokenBoard.h>
|
|
||||||
#include <buffer.h>
|
#include <buffer.h>
|
||||||
|
#include <pointerTo.h>
|
||||||
#include "zcompressor.h"
|
#include "zcompressor.h"
|
||||||
#include "asyncUtility.h"
|
|
||||||
|
|
||||||
class DecompressorToken;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Class : Decompressor
|
// Class : Decompressor
|
||||||
// Description :
|
// Description :
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
class EXPCL_PANDAEXPRESS Decompressor : public AsyncUtility {
|
class EXPCL_PANDAEXPRESS Decompressor {
|
||||||
PUBLISHED:
|
PUBLISHED:
|
||||||
|
enum DecompressStatus {
|
||||||
|
DS_ok = 2,
|
||||||
|
DS_success = 1,
|
||||||
|
DS_error = -1,
|
||||||
|
DS_error_write = -2,
|
||||||
|
DS_error_zlib = -3,
|
||||||
|
};
|
||||||
|
|
||||||
Decompressor(void);
|
Decompressor(void);
|
||||||
Decompressor(PT(Buffer) buffer);
|
Decompressor(PT(Buffer) buffer);
|
||||||
virtual ~Decompressor(void);
|
virtual ~Decompressor(void);
|
||||||
|
|
||||||
int request_decompress(const Filename &source_file,
|
int initiate(Filename &source_file);
|
||||||
const string &event_name);
|
int initiate(Filename &source_file, Filename &dest_file);
|
||||||
int request_decompress(const Filename &source_file,
|
|
||||||
const Filename &dest_file,
|
|
||||||
const string &event_name);
|
|
||||||
|
|
||||||
bool decompress(Filename &source_file);
|
int run(void);
|
||||||
bool decompress(Filename &source_file, Filename &dest_file);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init(PT(Buffer) buffer);
|
void init(PT(Buffer) buffer);
|
||||||
virtual bool process_request(void);
|
|
||||||
|
|
||||||
typedef TokenBoard<DecompressorToken> DecompressorTokenBoard;
|
|
||||||
DecompressorTokenBoard *_token_board;
|
|
||||||
|
|
||||||
PT(Buffer) _buffer;
|
PT(Buffer) _buffer;
|
||||||
int _half_buffer_length;
|
int _half_buffer_length;
|
||||||
Filename _temp_file_name;
|
Filename _temp_file_name;
|
||||||
|
|
||||||
|
Filename _source_file;
|
||||||
|
ifstream _read_stream;
|
||||||
|
ofstream _write_stream;
|
||||||
|
int _source_file_length;
|
||||||
|
int _total_bytes_read;
|
||||||
|
bool _read_all_input;
|
||||||
|
bool _handled_all_input;
|
||||||
|
int _source_buffer_length;
|
||||||
|
ZDecompressor _decompressor;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user