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);
243 PN_stdfloat Extractor::
244 get_progress()
const {
248 if (_requests_total_length == 0) {
252 return (PN_stdfloat)_total_bytes_extracted / (PN_stdfloat)_requests_total_length;
268 if (ret == EU_success) {
bool open_write(std::ofstream &stream, bool truncate=true) const
Opens the indicated ifstream for writing the file, if possible.
static TrueClock * get_global_ptr()
Returns a pointer to the one TrueClock object in the world.
void set_binary()
Indicates that the filename represents a binary file.
bool open_read(std::ifstream &stream) const
Opens the indicated ifstream for reading the file, if possible.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static void close_read_subfile(std::istream *stream)
Closes a file opened by a previous call to open_read_subfile().
The name of a file, such as a texture file or an Egg file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An interface to whatever real-time clock we might have available in the current environment.
A file that contains a set of files.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool make_dir() const
Creates all the directories in the path to the file specified in the filename, except for the basenam...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.