15 #include "extractor.h" 16 #include "config_downloader.h" 17 #include "trueClock.h" 19 #include "error_utils.h" 53 _multifile_name = multifile_name;
54 return _multifile->
open_read(multifile_name);
67 _extract_dir = extract_dir;
80 if (_read != (istream *)NULL) {
82 _read = (istream *)NULL;
89 _requests_total_length = 0;
101 int index = _multifile->find_subfile(subfile_name);
105 _requests.push_back(index);
106 _requests_total_length += _multifile->get_subfile_length(index);
119 _requests_total_length = 0;
120 int num_subfiles = _multifile->get_num_subfiles();
121 for (
int i = 0; i < num_subfiles; i++) {
122 _requests.push_back(i);
123 _requests_total_length += _multifile->get_subfile_length(i);
149 _total_bytes_extracted = 0;
150 _read = (istream *)NULL;
155 double now = clock->get_short_time();
156 double finish = now + extractor_step_time;
159 if (_read == (istream *)NULL) {
161 if (_request_index >= (
int)_requests.size()) {
163 if (downloader_cat.is_debug()) {
164 downloader_cat.debug()
165 <<
"Finished extracting.\n";
171 _subfile_index = _requests[_request_index];
172 _subfile_filename =
Filename(_extract_dir,
173 _multifile->get_subfile_name(_subfile_index));
175 if (downloader_cat.is_debug()) {
176 downloader_cat.debug()
177 <<
"Extracting " << _subfile_filename <<
".\n";
182 if (!_subfile_filename.
open_write(_write,
true)) {
183 downloader_cat.error()
184 <<
"Unable to write to " << _subfile_filename <<
".\n";
186 return EU_error_abort;
189 _subfile_length = _multifile->get_subfile_length(_subfile_index);
191 _read = _multifile->open_read_subfile(_subfile_index);
192 if (_read == (istream *)NULL) {
193 downloader_cat.error()
194 <<
"Unable to read subfile " 195 << _multifile->get_subfile_name(_subfile_index) <<
".\n";
197 return EU_error_abort;
200 }
else if (_subfile_pos >= _subfile_length) {
203 if (downloader_cat.is_debug()) {
204 downloader_cat.debug()
205 <<
"Finished current subfile.\n";
208 _read = (istream *)NULL;
215 static const size_t buffer_size = 1024;
216 char buffer[buffer_size];
218 size_t max_bytes = min(buffer_size, _subfile_length - _subfile_pos);
219 _read->read(buffer, max_bytes);
220 size_t count = _read->gcount();
222 if (downloader_cat.is_spam()) {
223 downloader_cat.spam()
224 <<
" . . . read " << count <<
" bytes.\n";
226 _write.write(buffer, count);
228 downloader_cat.error()
229 <<
"Error writing to " << _subfile_filename <<
".\n";
231 return EU_error_abort;
234 _subfile_pos += count;
235 _total_bytes_extracted += count;
237 now = clock->get_short_time();
243 max_bytes = min(buffer_size, _subfile_length - _subfile_pos);
244 _read->read(buffer, max_bytes);
245 count = _read->gcount();
248 if (max_bytes != 0) {
249 downloader_cat.error()
250 <<
"Unexpected EOF on multifile " << _multifile_name <<
".\n";
252 return EU_error_abort;
256 now = clock->get_short_time();
257 }
while (now < finish);
274 if (_requests_total_length == 0) {
278 return (PN_stdfloat)_total_bytes_extracted / (PN_stdfloat)_requests_total_length;
298 if (ret == EU_success) {
static TrueClock * get_global_ptr()
Returns a pointer to the one TrueClock object in the world.
bool open_write(ofstream &stream, bool truncate=true) const
Opens the indicated ifstream for writing the file, if possible.
void set_binary()
Indicates that the filename represents a binary file.
static void close_read_subfile(istream *stream)
Closes a file opened by a previous call to open_read_subfile().
bool open_read(ifstream &stream) const
Opens the indicated ifstream for reading the file, if possible.
The name of a file, such as a texture file or an Egg file.
An interface to whatever real-time clock we might have available in the current environment.
A file that contains a set of files.
bool make_dir() const
Creates all the directories in the path to the file specified in the filename, except for the basenam...