Browse Source

add vfs::mount_loop()

David Rose 15 years ago
parent
commit
c3eace229e

+ 16 - 6
panda/src/express/multifile.cxx

@@ -110,7 +110,7 @@ Multifile() :
      PRC_DESC("This is a special value of encryption-iteration-count used to encrypt "
      PRC_DESC("This is a special value of encryption-iteration-count used to encrypt "
               "subfiles within a multifile.  It has a default value of 0 (just one "
               "subfiles within a multifile.  It has a default value of 0 (just one "
               "application), on the assumption that the files from a multifile must "
               "application), on the assumption that the files from a multifile must "
-          "be loaded quickly, without paying the cost of an expensive hash on "
+              "be loaded quickly, without paying the cost of an expensive hash on "
               "each subfile in order to decrypt it."));
               "each subfile in order to decrypt it."));
   
   
   _read = (IStreamWrapper *)NULL;
   _read = (IStreamWrapper *)NULL;
@@ -187,15 +187,23 @@ operator = (const Multifile &copy) {
 bool Multifile::
 bool Multifile::
 open_read(const Filename &multifile_name, const streampos &offset) {
 open_read(const Filename &multifile_name, const streampos &offset) {
   close();
   close();
-  _offset = offset;
   Filename fname = multifile_name;
   Filename fname = multifile_name;
   fname.set_binary();
   fname.set_binary();
-  if (!fname.open_read(_read_file)) {
+
+  VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
+  PT(VirtualFile) vfile = vfs->get_file(fname);
+  if (vfile == NULL) {
     return false;
     return false;
   }
   }
-  _timestamp = fname.get_timestamp();
+  istream *multifile_stream = vfile->open_read_file(false);
+  if (multifile_stream == NULL) {
+    return false;
+  }
+
+  _timestamp = vfile->get_timestamp();
   _timestamp_dirty = true;
   _timestamp_dirty = true;
-  _read = &_read_filew;
+  _read = new IStreamWrapper(multifile_stream, true);
+  _owns_stream = true;
   _multifile_name = multifile_name;
   _multifile_name = multifile_name;
   return read_index();
   return read_index();
 }
 }
@@ -213,12 +221,14 @@ open_read(const Filename &multifile_name, const streampos &offset) {
 //               function returns false.
 //               function returns false.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool Multifile::
 bool Multifile::
-open_read(IStreamWrapper *multifile_stream, bool owns_pointer) {
+open_read(IStreamWrapper *multifile_stream, bool owns_pointer,
+          const streampos &offset) {
   close();
   close();
   _timestamp = time(NULL);
   _timestamp = time(NULL);
   _timestamp_dirty = true;
   _timestamp_dirty = true;
   _read = multifile_stream;
   _read = multifile_stream;
   _owns_stream = owns_pointer;
   _owns_stream = owns_pointer;
+  _offset = offset;
   return read_index();
   return read_index();
 }
 }
 
 

+ 1 - 1
panda/src/express/multifile.h

@@ -42,7 +42,7 @@ private:
 
 
 PUBLISHED:
 PUBLISHED:
   BLOCKING bool open_read(const Filename &multifile_name, const streampos &offset = 0);
   BLOCKING bool open_read(const Filename &multifile_name, const streampos &offset = 0);
-  BLOCKING bool open_read(IStreamWrapper *multifile_stream, bool owns_pointer = false);
+  BLOCKING bool open_read(IStreamWrapper *multifile_stream, bool owns_pointer = false, const streampos &offset = 0);
   BLOCKING bool open_write(const Filename &multifile_name);
   BLOCKING bool open_write(const Filename &multifile_name);
   BLOCKING bool open_write(ostream *multifile_stream, bool owns_pointer = false);
   BLOCKING bool open_write(ostream *multifile_stream, bool owns_pointer = false);
   BLOCKING bool open_read_write(const Filename &multifile_name);
   BLOCKING bool open_read_write(const Filename &multifile_name);

+ 55 - 0
panda/src/express/virtualFileSystem.cxx

@@ -109,6 +109,12 @@ mount(Multifile *multifile, const Filename &mount_point, int flags) {
 //               exactly the same full pathname), the most-recently
 //               exactly the same full pathname), the most-recently
 //               mounted system wins.
 //               mounted system wins.
 //
 //
+//               The filename specified as the first parameter must
+//               refer to a real, physical filename on disk; it cannot
+//               be a virtual file already appearing within the vfs
+//               filespace.  However, it is possible to mount such a
+//               file; see mount_loop() for this.
+////
 //               Note that a mounted VirtualFileSystem directory is
 //               Note that a mounted VirtualFileSystem directory is
 //               fully case-sensitive, unlike the native Windows file
 //               fully case-sensitive, unlike the native Windows file
 //               system, so you must refer to files within the virtual
 //               system, so you must refer to files within the virtual
@@ -143,6 +149,55 @@ mount(const Filename &physical_filename, const Filename &mount_point,
   }
   }
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: VirtualFileSystem::mount_loop
+//       Access: Published
+//  Description: This is similar to mount(), but it receives the name
+//               of a Multifile that already appears within the
+//               virtual file system.  It can be used to mount a
+//               Multifile that is itself hosted within a
+//               virtually-mounted Multifile.
+//
+//               This interface can also be used to mount physical
+//               files (that appear within the virtual filespace), but
+//               it cannot be used to mount directories.  Use mount()
+//               if you need to mount a directory.
+//
+//               Note that there is additional overhead, in the form
+//               of additional buffer copies of the data, for
+//               recursively mounting a multifile like this.
+////////////////////////////////////////////////////////////////////
+bool VirtualFileSystem::
+mount_loop(const Filename &virtual_filename, const Filename &mount_point, 
+           int flags, const string &password) {
+  PT(VirtualFile) file = get_file(virtual_filename, false);
+  if (file == NULL) {
+    express_cat->warning()
+      << "Attempt to mount " << virtual_filename << ", not found.\n";
+    return false;
+  }
+
+  if (file->is_directory()) {
+    PT(VirtualFileMountSystem) new_mount =
+      new VirtualFileMountSystem(virtual_filename);
+    return mount(new_mount, mount_point, flags);
+
+  } else {
+    // It's not a directory; it must be a Multifile.
+    PT(Multifile) multifile = new Multifile;
+    multifile->set_encryption_password(password);
+
+    // For now these are always opened read only.  Maybe later we'll
+    // support read-write on Multifiles.
+    flags |= MF_read_only;
+    if (!multifile->open_read(virtual_filename)) {
+      return false;
+    }
+
+    return mount(multifile, mount_point, flags);
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: VirtualFileSystem::mount
 //     Function: VirtualFileSystem::mount
 //       Access: Published
 //       Access: Published

+ 2 - 0
panda/src/express/virtualFileSystem.h

@@ -53,6 +53,8 @@ PUBLISHED:
   BLOCKING bool mount(Multifile *multifile, const Filename &mount_point, int flags);
   BLOCKING bool mount(Multifile *multifile, const Filename &mount_point, int flags);
   BLOCKING bool mount(const Filename &physical_filename, const Filename &mount_point, 
   BLOCKING bool mount(const Filename &physical_filename, const Filename &mount_point, 
                       int flags, const string &password = "");
                       int flags, const string &password = "");
+  BLOCKING bool mount_loop(const Filename &virtual_filename, const Filename &mount_point, 
+                      int flags, const string &password = "");
   bool mount(VirtualFileMount *mount, const Filename &mount_point, int flags);
   bool mount(VirtualFileMount *mount, const Filename &mount_point, int flags);
   BLOCKING int unmount(Multifile *multifile);
   BLOCKING int unmount(Multifile *multifile);
   BLOCKING int unmount(const Filename &physical_filename);
   BLOCKING int unmount(const Filename &physical_filename);