00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config_downloader.h"
00022
00023 #include "error_utils.h"
00024 #include "filename.h"
00025 #include "buffer.h"
00026 #include "zStream.h"
00027 #include "config_express.h"
00028
00029 #include "decompressor.h"
00030
00031 #include <stdio.h>
00032 #include <errno.h>
00033
00034
00035
00036
00037
00038
00039 Decompressor::
00040 Decompressor() {
00041 _source = NULL;
00042 _decompress = NULL;
00043 _dest = NULL;
00044 }
00045
00046
00047
00048
00049
00050
00051 Decompressor::
00052 ~Decompressor() {
00053 cleanup();
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 int Decompressor::
00065 initiate(const Filename &source_file) {
00066 string extension = source_file.get_extension();
00067 if (extension == "pz") {
00068 Filename dest_file = source_file;
00069 dest_file = source_file.get_fullpath_wo_extension();
00070 return initiate(source_file, dest_file);
00071 }
00072
00073 if (downloader_cat.is_debug()) {
00074 downloader_cat.debug()
00075 << "Unknown file extension for decompressor: ."
00076 << extension << endl;
00077 }
00078 return EU_error_abort;
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088 int Decompressor::
00089 initiate(const Filename &source_file, const Filename &dest_file) {
00090 cleanup();
00091
00092
00093 _source_filename = Filename(source_file);
00094 _source_filename.set_binary();
00095
00096 ifstream *source_fstream = new ifstream;
00097 _source = source_fstream;
00098 if (!_source_filename.open_read(*source_fstream)) {
00099 downloader_cat.error()
00100 << "Unable to read " << _source_filename << "\n";
00101 return get_write_error();
00102 }
00103
00104
00105 source_fstream->seekg(0, ios::end);
00106 _source_length = source_fstream->tellg();
00107 if (_source_length == 0) {
00108 downloader_cat.warning()
00109 << "Zero length file: " << source_file << "\n";
00110 return EU_error_file_empty;
00111 }
00112 source_fstream->seekg(0, ios::beg);
00113
00114
00115 Filename dest_filename(dest_file);
00116 dest_filename.set_binary();
00117
00118 ofstream *dest_fstream = new ofstream;
00119 _dest = dest_fstream;
00120 if (dest_filename.exists()) {
00121 downloader_cat.info()
00122 << dest_filename << " already exists, removing.\n";
00123 if (!dest_filename.unlink()) {
00124 downloader_cat.error()
00125 << "Unable to remove old " << dest_filename << "\n";
00126 return get_write_error();
00127 }
00128 } else {
00129 if (downloader_cat.is_debug()) {
00130 downloader_cat.debug()
00131 << dest_filename << " does not already exist.\n";
00132 }
00133 }
00134 if (!dest_filename.open_write(*dest_fstream, true)) {
00135 downloader_cat.error()
00136 << "Unable to write to " << dest_filename << "\n";
00137 return get_write_error();
00138 }
00139
00140
00141 _decompress = new IDecompressStream(_source, false);
00142 return EU_success;
00143 }
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 int Decompressor::
00155 run() {
00156 if (_decompress == (istream *)NULL) {
00157
00158 return EU_success;
00159 }
00160
00161
00162
00163 int count = 0;
00164 int ch = _decompress->get();
00165 while (!_decompress->eof() && !_decompress->fail()) {
00166 _dest->put(ch);
00167 if (++count >= decompressor_buffer_size) {
00168
00169 return EU_ok;
00170 }
00171
00172 ch = _decompress->get();
00173 }
00174
00175
00176 cleanup();
00177 if (!keep_temporary_files) {
00178 _source_filename.unlink();
00179 }
00180 return EU_success;
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190 bool Decompressor::
00191 decompress(const Filename &source_file) {
00192 int ret = initiate(source_file);
00193 if (ret < 0)
00194 return false;
00195
00196 int ch = _decompress->get();
00197 while (!_decompress->eof() && !_decompress->fail()) {
00198 _dest->put(ch);
00199 ch = _decompress->get();
00200 }
00201
00202 cleanup();
00203 if (!keep_temporary_files) {
00204 _source_filename.unlink();
00205 }
00206 return true;
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216 bool Decompressor::
00217 decompress(Ramfile &source_and_dest_file) {
00218 istringstream source(source_and_dest_file._data);
00219 ostringstream dest;
00220
00221 IDecompressStream decompress(&source, false);
00222
00223 int ch = decompress.get();
00224 while (!decompress.eof() && !decompress.fail()) {
00225 dest.put(ch);
00226 ch = decompress.get();
00227 }
00228
00229 source_and_dest_file._pos = 0;
00230 source_and_dest_file._data = dest.str();
00231 return true;
00232 }
00233
00234
00235
00236
00237
00238
00239
00240 float Decompressor::
00241 get_progress() const {
00242 if (_decompress == (istream *)NULL) {
00243
00244 return 1.0f;
00245 }
00246
00247 nassertr(_source_length > 0, 0.0);
00248 size_t source_pos = _source->tellg();
00249
00250
00251
00252 return (0.99f * (float)source_pos / (float)_source_length);
00253 }
00254
00255
00256
00257
00258
00259
00260
00261 void Decompressor::
00262 cleanup() {
00263 if (_source != (istream *)NULL) {
00264 delete _source;
00265 _source = NULL;
00266 }
00267 if (_dest != (ostream *)NULL) {
00268 delete _dest;
00269 _dest = NULL;
00270 }
00271 if (_decompress != (istream *)NULL) {
00272 delete _decompress;
00273 _decompress = NULL;
00274 }
00275 }