add vfs::mount_loop()

This commit is contained in:
David Rose 2010-04-27 21:45:00 +00:00
parent 15d98ead96
commit c3eace229e
4 changed files with 74 additions and 7 deletions

View File

@ -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 &copy) {
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();
}

View File

@ -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);

View File

@ -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

View File

@ -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);