From c3eace229e4dc2cbd542eb168b87394cd84f2a5f Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 27 Apr 2010 21:45:00 +0000 Subject: [PATCH] add vfs::mount_loop() --- panda/src/express/multifile.cxx | 22 +++++++--- panda/src/express/multifile.h | 2 +- panda/src/express/virtualFileSystem.cxx | 55 +++++++++++++++++++++++++ panda/src/express/virtualFileSystem.h | 2 + 4 files changed, 74 insertions(+), 7 deletions(-) diff --git a/panda/src/express/multifile.cxx b/panda/src/express/multifile.cxx index a7b86d9298..38133af001 100644 --- a/panda/src/express/multifile.cxx +++ b/panda/src/express/multifile.cxx @@ -110,7 +110,7 @@ Multifile() : 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 " "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.")); _read = (IStreamWrapper *)NULL; @@ -187,15 +187,23 @@ operator = (const Multifile ©) { bool Multifile:: open_read(const Filename &multifile_name, const streampos &offset) { close(); - _offset = offset; Filename fname = multifile_name; 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; } - _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; - _read = &_read_filew; + _read = new IStreamWrapper(multifile_stream, true); + _owns_stream = true; _multifile_name = multifile_name; return read_index(); } @@ -213,12 +221,14 @@ open_read(const Filename &multifile_name, const streampos &offset) { // function returns false. //////////////////////////////////////////////////////////////////// bool Multifile:: -open_read(IStreamWrapper *multifile_stream, bool owns_pointer) { +open_read(IStreamWrapper *multifile_stream, bool owns_pointer, + const streampos &offset) { close(); _timestamp = time(NULL); _timestamp_dirty = true; _read = multifile_stream; _owns_stream = owns_pointer; + _offset = offset; return read_index(); } diff --git a/panda/src/express/multifile.h b/panda/src/express/multifile.h index a6317dd9e4..1623fd479d 100644 --- a/panda/src/express/multifile.h +++ b/panda/src/express/multifile.h @@ -42,7 +42,7 @@ private: PUBLISHED: 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(ostream *multifile_stream, bool owns_pointer = false); BLOCKING bool open_read_write(const Filename &multifile_name); diff --git a/panda/src/express/virtualFileSystem.cxx b/panda/src/express/virtualFileSystem.cxx index c5ad698078..ac962736bd 100644 --- a/panda/src/express/virtualFileSystem.cxx +++ b/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 // 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 // fully case-sensitive, unlike the native Windows file // 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 // Access: Published diff --git a/panda/src/express/virtualFileSystem.h b/panda/src/express/virtualFileSystem.h index df88841fa2..1070b1a7b0 100644 --- a/panda/src/express/virtualFileSystem.h +++ b/panda/src/express/virtualFileSystem.h @@ -53,6 +53,8 @@ PUBLISHED: BLOCKING bool mount(Multifile *multifile, const Filename &mount_point, int flags); BLOCKING bool mount(const Filename &physical_filename, const Filename &mount_point, 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); BLOCKING int unmount(Multifile *multifile); BLOCKING int unmount(const Filename &physical_filename);