Browse Source

add get_file_size()

David Rose 21 years ago
parent
commit
00990fb767

+ 63 - 8
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<char> 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<char> 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());
 }
 
 ////////////////////////////////////////////////////////////////////

+ 3 - 0
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:

+ 2 - 0
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;
 

+ 18 - 0
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

+ 2 - 0
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;
 

+ 24 - 0
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

+ 2 - 1
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();

+ 14 - 0
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

+ 1 - 0
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,