diff --git a/panda/src/express/virtualFile.cxx b/panda/src/express/virtualFile.cxx index 1342fc61e9..715ac61e1f 100644 --- a/panda/src/express/virtualFile.cxx +++ b/panda/src/express/virtualFile.cxx @@ -163,6 +163,20 @@ open_read_file() const { return NULL; } +//////////////////////////////////////////////////////////////////// +// Function: VirtualFile::get_file_size +// Access: Published, Virtual +// Description: Returns the current size on disk (or wherever it is) +// of the already-open file. Pass in the stream that +// was returned by open_read_file(); some +// implementations may require this stream to determine +// the size. +//////////////////////////////////////////////////////////////////// +streampos VirtualFile:: +get_file_size(istream *stream) const { + return 0; +} + //////////////////////////////////////////////////////////////////// // Function: VirtualFile::close_read_file // Access: Public @@ -206,6 +220,27 @@ read_file(string &result) const { return false; } + bool okflag = read_file(in, result); + + close_read_file(in); + + if (!okflag) { + express_cat.info() + << "Error while reading " << get_filename() << "\n"; + } + return okflag; +} + +//////////////////////////////////////////////////////////////////// +// Function: VirtualFile::read_file +// Access: Public, Static +// Description: Fills up the indicated string with the contents of +// the just-opened file. Returns true on success, false +// otherwise. If the string was not empty on entry, the +// data read from the file will be concatenated onto it. +//////////////////////////////////////////////////////////////////// +bool VirtualFile:: +read_file(istream *in, string &result) { // Repeatedly appending into a string seems to be prohibitively // expensive on MSVC7's implementation of string, but the vector // implementation works much better. Even still, it seems to be @@ -213,7 +248,7 @@ read_file(string &result) const { // time. pvector result_vec; - static const int buffer_size = 1024; + static const size_t buffer_size = 1024; char buffer[buffer_size]; in->read(buffer, buffer_size); @@ -223,16 +258,36 @@ read_file(string &result) const { in->read(buffer, buffer_size); count = in->gcount(); } - result.assign(&result_vec[0], result_vec.size()); + result.append(&result_vec[0], result_vec.size()); - bool failed = in->fail() && !in->eof(); - close_read_file(in); + return (!in->fail() || in->eof()); +} - if (failed) { - express_cat.info() - << "Error while reading " << get_filename() << "\n"; +//////////////////////////////////////////////////////////////////// +// Function: VirtualFile::read_file +// Access: Public, Static +// Description: As in read_file() with two parameters, above, but +// only reads up to max_bytes bytes from the file. +//////////////////////////////////////////////////////////////////// +bool VirtualFile:: +read_file(istream *in, string &result, size_t max_bytes) { + pvector result_vec; + + static const size_t buffer_size = 1024; + char buffer[buffer_size]; + + in->read(buffer, min(buffer_size, max_bytes)); + size_t count = in->gcount(); + while (count != 0) { + nassertr(count <= max_bytes, false); + result_vec.insert(result_vec.end(), buffer, buffer + count); + max_bytes -= count; + in->read(buffer, min(buffer_size, max_bytes)); + count = in->gcount(); } - return !failed; + result.append(&result_vec[0], result_vec.size()); + + return (!in->fail() || in->eof()); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/express/virtualFile.h b/panda/src/express/virtualFile.h index 42e615a7c5..972f399629 100644 --- a/panda/src/express/virtualFile.h +++ b/panda/src/express/virtualFile.h @@ -55,9 +55,12 @@ PUBLISHED: INLINE string read_file() const; virtual istream *open_read_file() const; void close_read_file(istream *stream) const; + virtual streampos get_file_size(istream *stream) const; public: bool read_file(string &result) const; + static bool read_file(istream *stream, string &result); + static bool read_file(istream *stream, string &result, size_t max_bytes); protected: diff --git a/panda/src/express/virtualFileMount.h b/panda/src/express/virtualFileMount.h index 67365d3f71..e670168b21 100644 --- a/panda/src/express/virtualFileMount.h +++ b/panda/src/express/virtualFileMount.h @@ -52,6 +52,8 @@ public: virtual istream *open_read_file(const Filename &file) const=0; void close_read_file(istream *stream) const; + virtual streampos get_file_size(const Filename &file, istream *stream) const=0; + virtual bool scan_directory(vector_string &contents, const Filename &dir) const=0; diff --git a/panda/src/express/virtualFileMountMultifile.cxx b/panda/src/express/virtualFileMountMultifile.cxx index 42e85d39e7..1bc0268686 100644 --- a/panda/src/express/virtualFileMountMultifile.cxx +++ b/panda/src/express/virtualFileMountMultifile.cxx @@ -84,6 +84,24 @@ open_read_file(const Filename &file) const { return _multifile->open_read_subfile(subfile_index); } +//////////////////////////////////////////////////////////////////// +// Function: VirtualFileMountMultifile::get_file_size +// Access: Published, Virtual +// Description: Returns the current size on disk (or wherever it is) +// of the already-open file. Pass in the stream that +// was returned by open_read_file(); some +// implementations may require this stream to determine +// the size. +//////////////////////////////////////////////////////////////////// +streampos VirtualFileMountMultifile:: +get_file_size(const Filename &file, istream *) const { + int subfile_index = _multifile->find_subfile(file); + if (subfile_index < 0) { + return 0; + } + return _multifile->get_subfile_length(subfile_index); +} + //////////////////////////////////////////////////////////////////// // Function: VirtualFileMountMultifile::scan_directory // Access: Public, Virtual diff --git a/panda/src/express/virtualFileMountMultifile.h b/panda/src/express/virtualFileMountMultifile.h index 54c3a802d2..2420fa402b 100644 --- a/panda/src/express/virtualFileMountMultifile.h +++ b/panda/src/express/virtualFileMountMultifile.h @@ -45,6 +45,8 @@ public: virtual bool is_regular_file(const Filename &file) const; virtual istream *open_read_file(const Filename &file) const; + virtual streampos get_file_size(const Filename &file, istream *stream) const; + virtual bool scan_directory(vector_string &contents, const Filename &dir) const; diff --git a/panda/src/express/virtualFileMountSystem.cxx b/panda/src/express/virtualFileMountSystem.cxx index 405b685311..b1c34e6b8f 100644 --- a/panda/src/express/virtualFileMountSystem.cxx +++ b/panda/src/express/virtualFileMountSystem.cxx @@ -79,6 +79,30 @@ open_read_file(const Filename &file) const { return stream; } +//////////////////////////////////////////////////////////////////// +// Function: VirtualFileMountSystem::get_file_size +// Access: Published, Virtual +// Description: Returns the current size on disk (or wherever it is) +// of the already-open file. Pass in the stream that +// was returned by open_read_file(); some +// implementations may require this stream to determine +// the size. +//////////////////////////////////////////////////////////////////// +streampos VirtualFileMountSystem:: +get_file_size(const Filename &, istream *stream) const { + // First, save the original stream position. + streampos orig = stream->tellg(); + + // Seek to the end and get the stream position there. + stream->seekg(0, ios::end); + streampos size = stream->tellg(); + + // Then return to the original point. + stream->seekg(orig, ios::beg); + + return size; +} + //////////////////////////////////////////////////////////////////// // Function: VirtualFileMountSystem::scan_directory // Access: Public, Virtual diff --git a/panda/src/express/virtualFileMountSystem.h b/panda/src/express/virtualFileMountSystem.h index e4f27fa8c5..94258917e2 100644 --- a/panda/src/express/virtualFileMountSystem.h +++ b/panda/src/express/virtualFileMountSystem.h @@ -41,10 +41,11 @@ public: virtual bool is_regular_file(const Filename &file) const; virtual istream *open_read_file(const Filename &file) const; + virtual streampos get_file_size(const Filename &file, istream *stream) const; + virtual bool scan_directory(vector_string &contents, const Filename &dir) const; - public: virtual TypeHandle get_type() const { return get_class_type(); diff --git a/panda/src/express/virtualFileSimple.cxx b/panda/src/express/virtualFileSimple.cxx index 542aa555a0..8a8b18277e 100644 --- a/panda/src/express/virtualFileSimple.cxx +++ b/panda/src/express/virtualFileSimple.cxx @@ -92,6 +92,20 @@ open_read_file() const { return _mount->open_read_file(_local_filename); } +//////////////////////////////////////////////////////////////////// +// Function: VirtualFileSimple::get_file_size +// Access: Published, Virtual +// Description: Returns the current size on disk (or wherever it is) +// of the already-open file. Pass in the stream that +// was returned by open_read_file(); some +// implementations may require this stream to determine +// the size. +//////////////////////////////////////////////////////////////////// +streampos VirtualFileSimple:: +get_file_size(istream *stream) const { + return _mount->get_file_size(_local_filename, stream); +} + //////////////////////////////////////////////////////////////////// // Function: VirtualFileSimple::scan_local_directory // Access: Protected, Virtual diff --git a/panda/src/express/virtualFileSimple.h b/panda/src/express/virtualFileSimple.h index fbef54c9e4..d694cb5d78 100644 --- a/panda/src/express/virtualFileSimple.h +++ b/panda/src/express/virtualFileSimple.h @@ -42,6 +42,7 @@ public: virtual bool is_regular_file() const; virtual istream *open_read_file() const; + virtual streampos get_file_size(istream *stream) const; protected: virtual bool scan_local_directory(VirtualFileList *file_list,