15 #include "virtualFileMountRamdisk.h" 16 #include "subStream.h" 19 TypeHandle VirtualFileMountRamdisk::_type_handle;
20 TypeHandle VirtualFileMountRamdisk::FileBase::_type_handle;
21 TypeHandle VirtualFileMountRamdisk::File::_type_handle;
22 TypeHandle VirtualFileMountRamdisk::Directory::_type_handle;
29 VirtualFileMountRamdisk::
30 VirtualFileMountRamdisk() : _root(
"") {
42 PT(FileBase) f = _root.do_find_file(file);
58 PT(File) f = _root.do_create_file(file);
75 PT(FileBase) f = _root.do_delete_file(file);
92 PT(FileBase) orig_fb = _root.do_find_file(orig_filename);
93 if (orig_fb == NULL) {
98 if (orig_fb->is_directory()) {
100 Directory *orig_d = DCAST(Directory, orig_fb);
101 PT(Directory) new_d = _root.do_make_directory(new_filename);
102 if (new_d == NULL || !new_d->_files.empty()) {
107 if (express_cat.is_debug()) {
109 <<
"Renaming ramdisk directory " << orig_filename <<
" to " << new_filename <<
"\n";
112 new_d->_files.swap(orig_d->_files);
113 _root.do_delete_file(orig_filename);
119 File *orig_f = DCAST(File, orig_fb);
120 PT(File) new_f = _root.do_create_file(new_filename);
126 if (express_cat.is_debug()) {
128 <<
"Renaming ramdisk file " << orig_filename <<
" to " << new_filename <<
"\n";
131 new_f->_data.str(orig_f->_data.str());
132 _root.do_delete_file(orig_filename);
150 PT(FileBase) orig_fb = _root.do_find_file(orig_filename);
151 if (orig_fb == NULL || orig_fb->is_directory()) {
157 File *orig_f = DCAST(File, orig_fb);
158 PT(File) new_f = _root.do_create_file(new_filename);
164 if (express_cat.is_debug()) {
166 <<
"Copying ramdisk file " << orig_filename <<
" to " << new_filename <<
"\n";
169 new_f->_data.str(orig_f->_data.str());
187 PT(Directory) f = _root.do_make_directory(file);
201 PT(FileBase) f = _root.do_find_file(file);
203 return (f != NULL && f->is_directory());
215 PT(FileBase) f = _root.do_find_file(file);
217 return (f != NULL && !f->is_directory());
242 PT(FileBase) f = _root.do_find_file(file);
244 if (f == (FileBase *)NULL || f->is_directory()) {
248 File *f2 = DCAST(File, f);
263 PT(File) f = _root.do_create_file(file);
265 if (f == (File *)NULL) {
271 f->_data.str(
string());
272 f->_timestamp = time(NULL);
289 PT(File) f = _root.do_create_file(file);
291 if (f == (File *)NULL) {
295 return new OSubStream(&f->_wrapper, 0, 0,
true);
309 PT(File) f = _root.do_create_file(file);
311 if (f == (File *)NULL) {
317 f->_data.str(
string());
318 f->_timestamp = time(NULL);
321 return new SubStream(&f->_wrapper, 0, 0);
335 PT(FileBase) f = _root.do_find_file(file);
337 if (f == (FileBase *)NULL || f->is_directory()) {
341 File *f2 = DCAST(File, f);
342 return new SubStream(&f2->_wrapper, 0, 0,
true);
357 PT(FileBase) f = _root.do_find_file(file);
359 if (f == (FileBase *)NULL || f->is_directory()) {
363 File *f2 = DCAST(File, f);
364 return f2->_data.str().length();
376 PT(FileBase) f = _root.do_find_file(file);
378 if (f == (FileBase *)NULL || f->is_directory()) {
382 File *f2 = DCAST(File, f);
383 return f2->_data.str().length();
403 PT(FileBase) f = _root.do_find_file(file);
408 time_t timestamp = f->_timestamp;
424 PT(FileBase) f = _root.do_find_file(dir);
425 if (f == (FileBase *)NULL || !f->is_directory()) {
430 Directory *f2 = DCAST(Directory, f);
431 bool result = f2->do_scan_directory(contents);
444 const string &old_contents,
445 const string &new_contents) {
447 PT(FileBase) f = _root.do_find_file(file);
448 if (f == (FileBase *)NULL || f->is_directory()) {
454 File *f2 = DCAST(File, f);
455 orig_contents = f2->_data.str();
456 if (orig_contents == old_contents) {
457 f2->_data.str(new_contents);
458 f2->_timestamp = time(NULL);
474 PT(FileBase) f = _root.do_find_file(file);
475 if (f == (FileBase *)NULL || f->is_directory()) {
480 File *f2 = DCAST(File, f);
481 contents = f2->_data.str();
493 void VirtualFileMountRamdisk::
494 output(ostream &out)
const {
495 out <<
"VirtualFileMountRamdisk";
503 VirtualFileMountRamdisk::FileBase::
512 bool VirtualFileMountRamdisk::FileBase::
513 is_directory()
const {
522 bool VirtualFileMountRamdisk::Directory::
523 is_directory()
const {
533 PT(VirtualFileMountRamdisk::FileBase) VirtualFileMountRamdisk::Directory::
534 do_find_file(
const string &filename)
const {
535 size_t slash = filename.find(
'/');
536 if (slash == string::npos) {
538 FileBase tfile(filename);
539 tfile.local_object();
540 Files::const_iterator fi = _files.find(&tfile);
541 if (fi != _files.end()) {
548 string dirname = filename.substr(0, slash);
549 string remainder = filename.substr(slash + 1);
550 FileBase tfile(dirname);
551 tfile.local_object();
552 Files::const_iterator fi = _files.find(&tfile);
553 if (fi != _files.end()) {
554 PT(FileBase) file = (*fi);
555 if (file->is_directory()) {
556 return DCAST(Directory, file.p())->do_find_file(remainder);
570 PT(VirtualFileMountRamdisk::File) VirtualFileMountRamdisk::Directory::
571 do_create_file(
const string &filename) {
572 size_t slash = filename.find(
'/');
573 if (slash == string::npos) {
575 FileBase tfile(filename);
576 tfile.local_object();
577 Files::iterator fi = _files.find(&tfile);
578 if (fi != _files.end()) {
579 PT(FileBase) file = (*fi);
580 if (!file->is_directory()) {
581 return DCAST(File, file.p());
588 if (express_cat.is_debug()) {
590 <<
"Making ramdisk file " << filename <<
"\n";
592 PT(File) file =
new File(filename);
593 _files.insert(file.p());
594 _timestamp = time(NULL);
599 string dirname = filename.substr(0, slash);
600 string remainder = filename.substr(slash + 1);
601 FileBase tfile(dirname);
602 tfile.local_object();
603 Files::iterator fi = _files.find(&tfile);
604 if (fi != _files.end()) {
605 PT(FileBase) file = (*fi);
606 if (file->is_directory()) {
607 return DCAST(Directory, file.p())->do_create_file(remainder);
621 PT(VirtualFileMountRamdisk::Directory) VirtualFileMountRamdisk::Directory::
622 do_make_directory(
const string &filename) {
623 size_t slash = filename.find(
'/');
624 if (slash == string::npos) {
626 FileBase tfile(filename);
627 tfile.local_object();
628 Files::iterator fi = _files.find(&tfile);
629 if (fi != _files.end()) {
630 PT(FileBase) file = (*fi);
631 if (file->is_directory()) {
632 return DCAST(Directory, file.p());
639 if (express_cat.is_debug()) {
641 <<
"Making ramdisk directory " << filename <<
"\n";
643 PT(Directory) file =
new Directory(filename);
644 _files.insert(file.p());
645 _timestamp = time(NULL);
650 string dirname = filename.substr(0, slash);
651 string remainder = filename.substr(slash + 1);
652 FileBase tfile(dirname);
653 tfile.local_object();
654 Files::iterator fi = _files.find(&tfile);
655 if (fi != _files.end()) {
656 PT(FileBase) file = (*fi);
657 if (file->is_directory()) {
658 return DCAST(Directory, file.p())->do_make_directory(remainder);
672 PT(VirtualFileMountRamdisk::FileBase) VirtualFileMountRamdisk::Directory::
673 do_delete_file(
const string &filename) {
674 size_t slash = filename.find(
'/');
675 if (slash == string::npos) {
677 FileBase tfile(filename);
678 tfile.local_object();
679 Files::iterator fi = _files.find(&tfile);
680 if (fi != _files.end()) {
681 PT(FileBase) file = (*fi);
682 if (file->is_directory()) {
683 Directory *dir = DCAST(Directory, file.p());
684 if (!dir->_files.empty()) {
690 _timestamp = time(NULL);
697 string dirname = filename.substr(0, slash);
698 string remainder = filename.substr(slash + 1);
699 FileBase tfile(dirname);
700 tfile.local_object();
701 Files::iterator fi = _files.find(&tfile);
702 if (fi != _files.end()) {
703 PT(FileBase) file = (*fi);
704 if (file->is_directory()) {
705 return DCAST(Directory, file.p())->do_delete_file(remainder);
717 bool VirtualFileMountRamdisk::Directory::
718 do_scan_directory(vector_string &contents)
const {
719 Files::const_iterator fi;
720 for (fi = _files.begin(); fi != _files.end(); ++fi) {
721 FileBase *file = (*fi);
722 contents.push_back(file->_basename);
virtual iostream * open_read_write_file(const Filename &file, bool truncate)
Opens the file for writing.
virtual istream * open_read_file(const Filename &file) const
Opens the file for reading, if it exists.
virtual bool atomic_compare_and_exchange_contents(const Filename &file, string &orig_contents, const string &old_contents, const string &new_contents)
See Filename::atomic_compare_and_exchange_contents().
virtual bool create_file(const Filename &file)
Attempts to create the indicated file within the mount, if it does not already exist.
virtual time_t get_timestamp(const Filename &file) const
Returns a time_t value that represents the time the file was last modified, to within whatever precis...
virtual bool copy_file(const Filename &orig_filename, const Filename &new_filename)
Attempts to copy the contents of the indicated file to the indicated file.
virtual bool atomic_read_contents(const Filename &file, string &contents) const
See Filename::atomic_read_contents().
virtual streamsize get_file_size(const Filename &file, istream *stream) const
Returns the current size on disk (or wherever it is) of the already-open file.
virtual ostream * open_write_file(const Filename &file, bool truncate)
Opens the file for writing.
virtual bool has_file(const Filename &file) const
Returns true if the indicated file exists within the mount system.
An istream object that presents a subwindow into another istream.
virtual bool make_directory(const Filename &file)
Attempts to create the indicated file within the mount, if it does not already exist.
The name of a file, such as a texture file or an Egg file.
virtual bool is_writable(const Filename &file) const
Returns true if the named file or directory may be written to, false otherwise.
virtual ostream * open_append_file(const Filename &file)
Works like open_write_file(), but the file is opened in append mode.
virtual iostream * open_read_append_file(const Filename &file)
Works like open_read_write_file(), but the file is opened in append mode.
virtual bool is_regular_file(const Filename &file) const
Returns true if the indicated file exists within the mount system and is a regular file...
virtual bool is_directory(const Filename &file) const
Returns true if the indicated file exists within the mount system and is a directory.
virtual bool rename_file(const Filename &orig_filename, const Filename &new_filename)
Attempts to rename the contents of the indicated file to the indicated file.
virtual bool delete_file(const Filename &file)
Attempts to delete the indicated file or directory within the mount.
virtual bool scan_directory(vector_string &contents, const Filename &dir) const
Fills the given vector up with the list of filenames that are local to this directory, if the filename is a directory.
TypeHandle is the identifier used to differentiate C++ class types.
An ostream object that presents a subwindow into another ostream.
Combined ISubStream and OSubStream for bidirectional I/O.