Panda3D
 All Classes Functions Variables Enumerations
virtualFileMountRamdisk.cxx
1 // Filename: virtualFileMountRamdisk.cxx
2 // Created by: drose (19Sep11)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "virtualFileMountRamdisk.h"
16 #include "subStream.h"
17 #include "dcast.h"
18 
19 TypeHandle VirtualFileMountRamdisk::_type_handle;
20 TypeHandle VirtualFileMountRamdisk::FileBase::_type_handle;
21 TypeHandle VirtualFileMountRamdisk::File::_type_handle;
22 TypeHandle VirtualFileMountRamdisk::Directory::_type_handle;
23 
24 ////////////////////////////////////////////////////////////////////
25 // Function: VirtualFileMountRamdisk::Constructor
26 // Access: Public
27 // Description:
28 ////////////////////////////////////////////////////////////////////
29 VirtualFileMountRamdisk::
30 VirtualFileMountRamdisk() : _root("") {
31 }
32 
33 ////////////////////////////////////////////////////////////////////
34 // Function: VirtualFileMountRamdisk::has_file
35 // Access: Public, Virtual
36 // Description: Returns true if the indicated file exists within the
37 // mount system.
38 ////////////////////////////////////////////////////////////////////
40 has_file(const Filename &file) const {
41  _lock.acquire();
42  PT(FileBase) f = _root.do_find_file(file);
43  _lock.release();
44  return (f != NULL);
45 }
46 
47 ////////////////////////////////////////////////////////////////////
48 // Function: VirtualFileMountRamdisk::create_file
49 // Access: Public, Virtual
50 // Description: Attempts to create the indicated file within the
51 // mount, if it does not already exist. Returns true on
52 // success (or if the file already exists), or false if
53 // it cannot be created.
54 ////////////////////////////////////////////////////////////////////
56 create_file(const Filename &file) {
57  _lock.acquire();
58  PT(File) f = _root.do_create_file(file);
59  _lock.release();
60  return (f != NULL);
61 }
62 
63 ////////////////////////////////////////////////////////////////////
64 // Function: VirtualFileMountRamdisk::delete_file
65 // Access: Public, Virtual
66 // Description: Attempts to delete the indicated file or directory
67 // within the mount. This can remove a single file or
68 // an empty directory. It will not remove a nonempty
69 // directory. Returns true on success, false on
70 // failure.
71 ////////////////////////////////////////////////////////////////////
73 delete_file(const Filename &file) {
74  _lock.acquire();
75  PT(FileBase) f = _root.do_delete_file(file);
76  _lock.release();
77  return (f != NULL);
78 }
79 
80 ////////////////////////////////////////////////////////////////////
81 // Function: VirtualFileMountRamdisk::rename_file
82 // Access: Public
83 // Description: Attempts to rename the contents of the indicated file
84 // to the indicated file. Both filenames will be within
85 // the mount. Returns true on success, false on
86 // failure. If this returns false, this will be
87 // attempted again with a copy-and-delete operation.
88 ////////////////////////////////////////////////////////////////////
90 rename_file(const Filename &orig_filename, const Filename &new_filename) {
91  _lock.acquire();
92  PT(FileBase) orig_fb = _root.do_find_file(orig_filename);
93  if (orig_fb == NULL) {
94  _lock.release();
95  return false;
96  }
97 
98  if (orig_fb->is_directory()) {
99  // Rename the 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()) {
103  _lock.release();
104  return false;
105  }
106 
107  if (express_cat.is_debug()) {
108  express_cat.debug()
109  << "Renaming ramdisk directory " << orig_filename << " to " << new_filename << "\n";
110  }
111 
112  new_d->_files.swap(orig_d->_files);
113  _root.do_delete_file(orig_filename);
114  _lock.release();
115  return true;
116  }
117 
118  // Rename the file.
119  File *orig_f = DCAST(File, orig_fb);
120  PT(File) new_f = _root.do_create_file(new_filename);
121  if (new_f == NULL) {
122  _lock.release();
123  return false;
124  }
125 
126  if (express_cat.is_debug()) {
127  express_cat.debug()
128  << "Renaming ramdisk file " << orig_filename << " to " << new_filename << "\n";
129  }
130 
131  new_f->_data.str(orig_f->_data.str());
132  _root.do_delete_file(orig_filename);
133 
134  _lock.release();
135  return true;
136 }
137 
138 ////////////////////////////////////////////////////////////////////
139 // Function: VirtualFileMountRamdisk::copy_file
140 // Access: Public
141 // Description: Attempts to copy the contents of the indicated file
142 // to the indicated file. Both filenames will be within
143 // the mount. Returns true on success, false on
144 // failure. If this returns false, the copy will be
145 // performed by explicit read-and-write operations.
146 ////////////////////////////////////////////////////////////////////
148 copy_file(const Filename &orig_filename, const Filename &new_filename) {
149  _lock.acquire();
150  PT(FileBase) orig_fb = _root.do_find_file(orig_filename);
151  if (orig_fb == NULL || orig_fb->is_directory()) {
152  _lock.release();
153  return false;
154  }
155 
156  // Copy the file.
157  File *orig_f = DCAST(File, orig_fb);
158  PT(File) new_f = _root.do_create_file(new_filename);
159  if (new_f == NULL) {
160  _lock.release();
161  return false;
162  }
163 
164  if (express_cat.is_debug()) {
165  express_cat.debug()
166  << "Copying ramdisk file " << orig_filename << " to " << new_filename << "\n";
167  }
168 
169  new_f->_data.str(orig_f->_data.str());
170 
171  _lock.release();
172  return true;
173 }
174 
175 ////////////////////////////////////////////////////////////////////
176 // Function: VirtualFileMountRamdisk::make_directory
177 // Access: Public, Virtual
178 // Description: Attempts to create the indicated file within the
179 // mount, if it does not already exist. Returns true on
180 // success, or false if it cannot be created. If the
181 // directory already existed prior to this call, may
182 // return either true or false.
183 ////////////////////////////////////////////////////////////////////
185 make_directory(const Filename &file) {
186  _lock.acquire();
187  PT(Directory) f = _root.do_make_directory(file);
188  _lock.release();
189  return (f != NULL);
190 }
191 
192 ////////////////////////////////////////////////////////////////////
193 // Function: VirtualFileMountRamdisk::is_directory
194 // Access: Public, Virtual
195 // Description: Returns true if the indicated file exists within the
196 // mount system and is a directory.
197 ////////////////////////////////////////////////////////////////////
199 is_directory(const Filename &file) const {
200  _lock.acquire();
201  PT(FileBase) f = _root.do_find_file(file);
202  _lock.release();
203  return (f != NULL && f->is_directory());
204 }
205 
206 ////////////////////////////////////////////////////////////////////
207 // Function: VirtualFileMountRamdisk::is_regular_file
208 // Access: Public, Virtual
209 // Description: Returns true if the indicated file exists within the
210 // mount system and is a regular file.
211 ////////////////////////////////////////////////////////////////////
213 is_regular_file(const Filename &file) const {
214  _lock.acquire();
215  PT(FileBase) f = _root.do_find_file(file);
216  _lock.release();
217  return (f != NULL && !f->is_directory());
218 }
219 
220 ////////////////////////////////////////////////////////////////////
221 // Function: VirtualFileMountRamdisk::is_writable
222 // Access: Public, Virtual
223 // Description: Returns true if the named file or directory may be
224 // written to, false otherwise.
225 ////////////////////////////////////////////////////////////////////
227 is_writable(const Filename &file) const {
228  return has_file(file);
229 }
230 
231 ////////////////////////////////////////////////////////////////////
232 // Function: VirtualFileMountRamdisk::open_read_file
233 // Access: Public, Virtual
234 // Description: Opens the file for reading, if it exists. Returns a
235 // newly allocated istream on success (which you should
236 // eventually delete when you are done reading).
237 // Returns NULL on failure.
238 ////////////////////////////////////////////////////////////////////
240 open_read_file(const Filename &file) const {
241  _lock.acquire();
242  PT(FileBase) f = _root.do_find_file(file);
243  _lock.release();
244  if (f == (FileBase *)NULL || f->is_directory()) {
245  return NULL;
246  }
247 
248  File *f2 = DCAST(File, f);
249  return new ISubStream(&f2->_wrapper, 0, 0);
250 }
251 
252 ////////////////////////////////////////////////////////////////////
253 // Function: VirtualFileMountRamdisk::open_write_file
254 // Access: Published, Virtual
255 // Description: Opens the file for writing. Returns a newly
256 // allocated ostream on success (which you should
257 // eventually delete when you are done writing).
258 // Returns NULL on failure.
259 ////////////////////////////////////////////////////////////////////
261 open_write_file(const Filename &file, bool truncate) {
262  _lock.acquire();
263  PT(File) f = _root.do_create_file(file);
264  _lock.release();
265  if (f == (File *)NULL) {
266  return NULL;
267  }
268 
269  if (truncate) {
270  // Reset to an empty string.
271  f->_data.str(string());
272  f->_timestamp = time(NULL);
273  }
274 
275  return new OSubStream(&f->_wrapper, 0, 0);
276 }
277 
278 ////////////////////////////////////////////////////////////////////
279 // Function: VirtualFileMountRamdisk::open_append_file
280 // Access: Published
281 // Description: Works like open_write_file(), but the file is opened
282 // in append mode. Like open_write_file, the returned
283 // pointer should eventually be passed to
284 // close_write_file().
285 ////////////////////////////////////////////////////////////////////
288  _lock.acquire();
289  PT(File) f = _root.do_create_file(file);
290  _lock.release();
291  if (f == (File *)NULL) {
292  return NULL;
293  }
294 
295  return new OSubStream(&f->_wrapper, 0, 0, true);
296 }
297 
298 ////////////////////////////////////////////////////////////////////
299 // Function: VirtualFileMountRamdisk::open_read_write_file
300 // Access: Published, Virtual
301 // Description: Opens the file for writing. Returns a newly
302 // allocated iostream on success (which you should
303 // eventually delete when you are done writing).
304 // Returns NULL on failure.
305 ////////////////////////////////////////////////////////////////////
307 open_read_write_file(const Filename &file, bool truncate) {
308  _lock.acquire();
309  PT(File) f = _root.do_create_file(file);
310  _lock.release();
311  if (f == (File *)NULL) {
312  return NULL;
313  }
314 
315  if (truncate) {
316  // Reset to an empty string.
317  f->_data.str(string());
318  f->_timestamp = time(NULL);
319  }
320 
321  return new SubStream(&f->_wrapper, 0, 0);
322 }
323 
324 ////////////////////////////////////////////////////////////////////
325 // Function: VirtualFileMountRamdisk::open_read_append_file
326 // Access: Published, Virtual
327 // Description: Works like open_read_write_file(), but the file is opened
328 // in append mode. Like open_read_write_file, the returned
329 // pointer should eventually be passed to
330 // close_read_write_file().
331 ////////////////////////////////////////////////////////////////////
334  _lock.acquire();
335  PT(FileBase) f = _root.do_find_file(file);
336  _lock.release();
337  if (f == (FileBase *)NULL || f->is_directory()) {
338  return NULL;
339  }
340 
341  File *f2 = DCAST(File, f);
342  return new SubStream(&f2->_wrapper, 0, 0, true);
343 }
344 
345 ////////////////////////////////////////////////////////////////////
346 // Function: VirtualFileMountRamdisk::get_file_size
347 // Access: Published, Virtual
348 // Description: Returns the current size on disk (or wherever it is)
349 // of the already-open file. Pass in the stream that
350 // was returned by open_read_file(); some
351 // implementations may require this stream to determine
352 // the size.
353 ////////////////////////////////////////////////////////////////////
354 streamsize VirtualFileMountRamdisk::
355 get_file_size(const Filename &file, istream *stream) const {
356  _lock.acquire();
357  PT(FileBase) f = _root.do_find_file(file);
358  _lock.release();
359  if (f == (FileBase *)NULL || f->is_directory()) {
360  return 0;
361  }
362 
363  File *f2 = DCAST(File, f);
364  return f2->_data.str().length();
365 }
366 
367 ////////////////////////////////////////////////////////////////////
368 // Function: VirtualFileMountRamdisk::get_file_size
369 // Access: Published, Virtual
370 // Description: Returns the current size on disk (or wherever it is)
371 // of the file before it has been opened.
372 ////////////////////////////////////////////////////////////////////
373 streamsize VirtualFileMountRamdisk::
374 get_file_size(const Filename &file) const {
375  _lock.acquire();
376  PT(FileBase) f = _root.do_find_file(file);
377  _lock.release();
378  if (f == (FileBase *)NULL || f->is_directory()) {
379  return 0;
380  }
381 
382  File *f2 = DCAST(File, f);
383  return f2->_data.str().length();
384 }
385 
386 ////////////////////////////////////////////////////////////////////
387 // Function: VirtualFileMountRamdisk::get_timestamp
388 // Access: Published, Virtual
389 // Description: Returns a time_t value that represents the time the
390 // file was last modified, to within whatever precision
391 // the operating system records this information (on a
392 // Windows95 system, for instance, this may only be
393 // accurate to within 2 seconds).
394 //
395 // If the timestamp cannot be determined, either because
396 // it is not supported by the operating system or
397 // because there is some error (such as file not found),
398 // returns 0.
399 ////////////////////////////////////////////////////////////////////
401 get_timestamp(const Filename &file) const {
402  _lock.acquire();
403  PT(FileBase) f = _root.do_find_file(file);
404  if (f.is_null()) {
405  _lock.release();
406  return 0;
407  }
408  time_t timestamp = f->_timestamp;
409  _lock.release();
410  return timestamp;
411 }
412 
413 ////////////////////////////////////////////////////////////////////
414 // Function: VirtualFileMountRamdisk::scan_directory
415 // Access: Public, Virtual
416 // Description: Fills the given vector up with the list of filenames
417 // that are local to this directory, if the filename is
418 // a directory. Returns true if successful, or false if
419 // the file is not a directory or cannot be read.
420 ////////////////////////////////////////////////////////////////////
422 scan_directory(vector_string &contents, const Filename &dir) const {
423  _lock.acquire();
424  PT(FileBase) f = _root.do_find_file(dir);
425  if (f == (FileBase *)NULL || !f->is_directory()) {
426  _lock.release();
427  return false;
428  }
429 
430  Directory *f2 = DCAST(Directory, f);
431  bool result = f2->do_scan_directory(contents);
432 
433  _lock.release();
434  return result;
435 }
436 
437 ////////////////////////////////////////////////////////////////////
438 // Function: VirtualFileMountRamdisk::atomic_compare_and_exchange_contents
439 // Access: Public, Virtual
440 // Description: See Filename::atomic_compare_and_exchange_contents().
441 ////////////////////////////////////////////////////////////////////
443 atomic_compare_and_exchange_contents(const Filename &file, string &orig_contents,
444  const string &old_contents,
445  const string &new_contents) {
446  _lock.acquire();
447  PT(FileBase) f = _root.do_find_file(file);
448  if (f == (FileBase *)NULL || f->is_directory()) {
449  _lock.release();
450  return false;
451  }
452 
453  bool retval = false;
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);
459  retval = true;
460  }
461 
462  _lock.release();
463  return retval;
464 }
465 
466 ////////////////////////////////////////////////////////////////////
467 // Function: VirtualFileMountRamdisk::atomic_read_contents
468 // Access: Public, Virtual
469 // Description: See Filename::atomic_read_contents().
470 ////////////////////////////////////////////////////////////////////
472 atomic_read_contents(const Filename &file, string &contents) const {
473  _lock.acquire();
474  PT(FileBase) f = _root.do_find_file(file);
475  if (f == (FileBase *)NULL || f->is_directory()) {
476  _lock.release();
477  return false;
478  }
479 
480  File *f2 = DCAST(File, f);
481  contents = f2->_data.str();
482 
483  _lock.release();
484  return true;
485 }
486 
487 
488 ////////////////////////////////////////////////////////////////////
489 // Function: VirtualFileMountRamdisk::output
490 // Access: Public, Virtual
491 // Description:
492 ////////////////////////////////////////////////////////////////////
493 void VirtualFileMountRamdisk::
494 output(ostream &out) const {
495  out << "VirtualFileMountRamdisk";
496 }
497 
498 ////////////////////////////////////////////////////////////////////
499 // Function: VirtualFileMountRamdisk::FileBase::Destructor
500 // Access: Public, Virtual
501 // Description:
502 ////////////////////////////////////////////////////////////////////
503 VirtualFileMountRamdisk::FileBase::
504 ~FileBase() {
505 }
506 
507 ////////////////////////////////////////////////////////////////////
508 // Function: VirtualFileMountRamdisk::FileBase::is_directory
509 // Access: Public, Virtual
510 // Description:
511 ////////////////////////////////////////////////////////////////////
512 bool VirtualFileMountRamdisk::FileBase::
513 is_directory() const {
514  return false;
515 }
516 
517 ////////////////////////////////////////////////////////////////////
518 // Function: VirtualFileMountRamdisk::Directory::is_directory
519 // Access: Public, Virtual
520 // Description:
521 ////////////////////////////////////////////////////////////////////
522 bool VirtualFileMountRamdisk::Directory::
523 is_directory() const {
524  return true;
525 }
526 
527 ////////////////////////////////////////////////////////////////////
528 // Function: VirtualFileMountRamdisk::Directory::do_find_file
529 // Access: Public
530 // Description: Recursively search for the file with the indicated
531 // name in this directory hierarchy.
532 ////////////////////////////////////////////////////////////////////
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) {
537  // Search for a file within the local directory.
538  FileBase tfile(filename);
539  tfile.local_object();
540  Files::const_iterator fi = _files.find(&tfile);
541  if (fi != _files.end()) {
542  return (*fi);
543  }
544  return NULL;
545  }
546 
547  // A nested directory. Search for the directory name, then recurse.
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);
557  }
558  }
559 
560  return NULL;
561 }
562 
563 ////////////////////////////////////////////////////////////////////
564 // Function: VirtualFileMountRamdisk::Directory::do_create_file
565 // Access: Public
566 // Description: Recursively search for the file with the indicated
567 // name in this directory hierarchy. If not found,
568 // creates a new file.
569 ////////////////////////////////////////////////////////////////////
570 PT(VirtualFileMountRamdisk::File) VirtualFileMountRamdisk::Directory::
571 do_create_file(const string &filename) {
572  size_t slash = filename.find('/');
573  if (slash == string::npos) {
574  // Search for a file within the local directory.
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());
582  }
583  // Cannot create: a directory by the same name already exists.
584  return NULL;
585  }
586 
587  // Create a new file.
588  if (express_cat.is_debug()) {
589  express_cat.debug()
590  << "Making ramdisk file " << filename << "\n";
591  }
592  PT(File) file = new File(filename);
593  _files.insert(file.p());
594  _timestamp = time(NULL);
595  return file;
596  }
597 
598  // A nested directory. Search for the directory name, then recurse.
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);
608  }
609  }
610 
611  return NULL;
612 }
613 
614 ////////////////////////////////////////////////////////////////////
615 // Function: VirtualFileMountRamdisk::Directory::do_make_directory
616 // Access: Public
617 // Description: Recursively search for the file with the indicated
618 // name in this directory hierarchy. If not found,
619 // creates a new directory.
620 ////////////////////////////////////////////////////////////////////
621 PT(VirtualFileMountRamdisk::Directory) VirtualFileMountRamdisk::Directory::
622 do_make_directory(const string &filename) {
623  size_t slash = filename.find('/');
624  if (slash == string::npos) {
625  // Search for a file within the local directory.
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());
633  }
634  // Cannot create: a file by the same name already exists.
635  return NULL;
636  }
637 
638  // Create a new directory.
639  if (express_cat.is_debug()) {
640  express_cat.debug()
641  << "Making ramdisk directory " << filename << "\n";
642  }
643  PT(Directory) file = new Directory(filename);
644  _files.insert(file.p());
645  _timestamp = time(NULL);
646  return file;
647  }
648 
649  // A nested directory. Search for the directory name, then recurse.
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);
659  }
660  }
661 
662  return NULL;
663 }
664 
665 ////////////////////////////////////////////////////////////////////
666 // Function: VirtualFileMountRamdisk::Directory::do_delete_file
667 // Access: Public
668 // Description: Recursively search for the file with the indicated
669 // name in this directory hierarchy, and removes it.
670 // Returns the removed FileBase object.
671 ////////////////////////////////////////////////////////////////////
672 PT(VirtualFileMountRamdisk::FileBase) VirtualFileMountRamdisk::Directory::
673 do_delete_file(const string &filename) {
674  size_t slash = filename.find('/');
675  if (slash == string::npos) {
676  // Search for a file within the local directory.
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()) {
685  // Can't delete a nonempty directory.
686  return NULL;
687  }
688  }
689  _files.erase(fi);
690  _timestamp = time(NULL);
691  return file;
692  }
693  return NULL;
694  }
695 
696  // A nested directory. Search for the directory name, then recurse.
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);
706  }
707  }
708 
709  return NULL;
710 }
711 
712 ////////////////////////////////////////////////////////////////////
713 // Function: VirtualFileMountRamdisk::Directory::do_scan_directory
714 // Access: Public
715 // Description:
716 ////////////////////////////////////////////////////////////////////
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);
723  }
724 
725  return true;
726 }
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 iostream * open_read_write_file(const Filename &file, bool truncate)
Opens the file for writing.
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 bool atomic_read_contents(const Filename &file, string &contents) const
See Filename::atomic_read_contents().
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 ostream * open_write_file(const Filename &file, bool truncate)
Opens the file for writing.
Simulates an actual directory on disk with in-memory storage.
An istream object that presents a subwindow into another istream.
Definition: subStream.h:34
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 make_directory(const Filename &file)
Attempts to create the indicated file within the mount, if it does not already exist.
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...
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:44
virtual ostream * open_append_file(const Filename &file)
Works like open_write_file(), but the file is opened in append mode.
virtual bool has_file(const Filename &file) const
Returns true if the indicated file exists within the mount system.
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_writable(const Filename &file) const
Returns true if the named file or directory may be written to, false otherwise.
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.
virtual bool is_directory(const Filename &file) const
Returns true if the indicated file exists within the mount system and is a directory.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
virtual istream * open_read_file(const Filename &file) const
Opens the file for reading, if it exists.
An ostream object that presents a subwindow into another ostream.
Definition: subStream.h:58
Combined ISubStream and OSubStream for bidirectional I/O.
Definition: subStream.h:75