45 _multifile_name = multifile_name;
46 return _multifile->
open_read(multifile_name);
56 _extract_dir = extract_dir;
66 if (_read !=
nullptr) {
75 _requests_total_length = 0;
84 int index = _multifile->find_subfile(subfile_name);
88 _requests.push_back(index);
89 _requests_total_length += _multifile->get_subfile_length(index);
100 _requests_total_length = 0;
101 int num_subfiles = _multifile->get_num_subfiles();
102 for (
int i = 0; i < num_subfiles; i++) {
103 _requests.push_back(i);
104 _requests_total_length += _multifile->get_subfile_length(i);
127 _total_bytes_extracted = 0;
133 double now = clock->get_short_time();
134 double finish = now + extractor_step_time;
137 if (_read ==
nullptr) {
139 if (_request_index >= (
int)_requests.size()) {
141 if (downloader_cat.is_debug()) {
142 downloader_cat.debug()
143 <<
"Finished extracting.\n";
149 _subfile_index = _requests[_request_index];
150 _subfile_filename =
Filename(_extract_dir,
151 _multifile->get_subfile_name(_subfile_index));
153 if (downloader_cat.is_debug()) {
154 downloader_cat.debug()
155 <<
"Extracting " << _subfile_filename <<
".\n";
160 if (!_subfile_filename.
open_write(_write,
true)) {
161 downloader_cat.error()
162 <<
"Unable to write to " << _subfile_filename <<
".\n";
164 return EU_error_abort;
167 _subfile_length = _multifile->get_subfile_length(_subfile_index);
169 _read = _multifile->open_read_subfile(_subfile_index);
170 if (_read ==
nullptr) {
171 downloader_cat.error()
172 <<
"Unable to read subfile "
173 << _multifile->get_subfile_name(_subfile_index) <<
".\n";
175 return EU_error_abort;
178 }
else if (_subfile_pos >= _subfile_length) {
181 if (downloader_cat.is_debug()) {
182 downloader_cat.debug()
183 <<
"Finished current subfile.\n";
192 static const size_t buffer_size = 1024;
193 char buffer[buffer_size];
195 size_t max_bytes = std::min(buffer_size, _subfile_length - _subfile_pos);
196 _read->read(buffer, max_bytes);
197 size_t count = _read->gcount();
199 if (downloader_cat.is_spam()) {
200 downloader_cat.spam()
201 <<
" . . . read " << count <<
" bytes.\n";
203 _write.write(buffer, count);
205 downloader_cat.error()
206 <<
"Error writing to " << _subfile_filename <<
".\n";
208 return EU_error_abort;
211 _subfile_pos += count;
212 _total_bytes_extracted += count;
214 now = clock->get_short_time();
220 max_bytes = std::min(buffer_size, _subfile_length - _subfile_pos);
221 _read->read(buffer, max_bytes);
222 count = _read->gcount();
225 if (max_bytes != 0) {
226 downloader_cat.error()
227 <<
"Unexpected EOF on multifile " << _multifile_name <<
".\n";
229 return EU_error_abort;
233 now = clock->get_short_time();
234 }
while (now < finish);
248 if (_requests_total_length == 0) {
252 return (PN_stdfloat)_total_bytes_extracted / (PN_stdfloat)_requests_total_length;
268 if (ret == EU_success) {
The name of a file, such as a texture file or an Egg file.
bool open_read(std::ifstream &stream) const
Opens the indicated ifstream for reading the file, if possible.
void set_binary()
Indicates that the filename represents a binary file.
bool make_dir() const
Creates all the directories in the path to the file specified in the filename, except for the basenam...
bool open_write(std::ofstream &stream, bool truncate=true) const
Opens the indicated ifstream for writing the file, if possible.
A file that contains a set of files.
static void close_read_subfile(std::istream *stream)
Closes a file opened by a previous call to open_read_subfile().
An interface to whatever real-time clock we might have available in the current environment.
static TrueClock * get_global_ptr()
Returns a pointer to the one TrueClock object in the world.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.