00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "virtualFileMountRamdisk.h"
00016 #include "subStream.h"
00017 #include "dcast.h"
00018
00019 TypeHandle VirtualFileMountRamdisk::_type_handle;
00020 TypeHandle VirtualFileMountRamdisk::FileBase::_type_handle;
00021 TypeHandle VirtualFileMountRamdisk::File::_type_handle;
00022 TypeHandle VirtualFileMountRamdisk::Directory::_type_handle;
00023
00024
00025
00026
00027
00028
00029 VirtualFileMountRamdisk::
00030 VirtualFileMountRamdisk() : _root("") {
00031 }
00032
00033
00034
00035
00036
00037
00038
00039 bool VirtualFileMountRamdisk::
00040 has_file(const Filename &file) const {
00041 ((VirtualFileMountRamdisk *)this)->_lock.acquire();
00042 PT(FileBase) f = _root.do_find_file(file);
00043 ((VirtualFileMountRamdisk *)this)->_lock.release();
00044 return (f != NULL);
00045 }
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 bool VirtualFileMountRamdisk::
00056 create_file(const Filename &file) {
00057 _lock.acquire();
00058 PT(File) f = _root.do_create_file(file);
00059 _lock.release();
00060 return (f != NULL);
00061 }
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 bool VirtualFileMountRamdisk::
00073 delete_file(const Filename &file) {
00074 _lock.acquire();
00075 PT(FileBase) f = _root.do_delete_file(file);
00076 _lock.release();
00077 return (f != NULL);
00078 }
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 bool VirtualFileMountRamdisk::
00090 rename_file(const Filename &orig_filename, const Filename &new_filename) {
00091 _lock.acquire();
00092 PT(FileBase) orig_fb = _root.do_find_file(orig_filename);
00093 if (orig_fb == NULL) {
00094 _lock.release();
00095 return false;
00096 }
00097
00098 if (orig_fb->is_directory()) {
00099
00100 Directory *orig_d = DCAST(Directory, orig_fb);
00101 PT(Directory) new_d = _root.do_make_directory(new_filename);
00102 if (new_d == NULL || !new_d->_files.empty()) {
00103 _lock.release();
00104 return false;
00105 }
00106
00107 if (express_cat.is_debug()) {
00108 express_cat.debug()
00109 << "Renaming ramdisk directory " << orig_filename << " to " << new_filename << "\n";
00110 }
00111
00112 new_d->_files.swap(orig_d->_files);
00113 _root.do_delete_file(orig_filename);
00114 _lock.release();
00115 return true;
00116 }
00117
00118
00119 File *orig_f = DCAST(File, orig_fb);
00120 PT(File) new_f = _root.do_create_file(new_filename);
00121 if (new_f == NULL) {
00122 _lock.release();
00123 return false;
00124 }
00125
00126 if (express_cat.is_debug()) {
00127 express_cat.debug()
00128 << "Renaming ramdisk file " << orig_filename << " to " << new_filename << "\n";
00129 }
00130
00131 new_f->_data.str(orig_f->_data.str());
00132 _root.do_delete_file(orig_filename);
00133
00134 _lock.release();
00135 return true;
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 bool VirtualFileMountRamdisk::
00148 copy_file(const Filename &orig_filename, const Filename &new_filename) {
00149 _lock.acquire();
00150 PT(FileBase) orig_fb = _root.do_find_file(orig_filename);
00151 if (orig_fb == NULL || orig_fb->is_directory()) {
00152 _lock.release();
00153 return false;
00154 }
00155
00156
00157 File *orig_f = DCAST(File, orig_fb);
00158 PT(File) new_f = _root.do_create_file(new_filename);
00159 if (new_f == NULL) {
00160 _lock.release();
00161 return false;
00162 }
00163
00164 if (express_cat.is_debug()) {
00165 express_cat.debug()
00166 << "Copying ramdisk file " << orig_filename << " to " << new_filename << "\n";
00167 }
00168
00169 new_f->_data.str(orig_f->_data.str());
00170
00171 _lock.release();
00172 return true;
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 bool VirtualFileMountRamdisk::
00185 make_directory(const Filename &file) {
00186 _lock.acquire();
00187 PT(Directory) f = _root.do_make_directory(file);
00188 _lock.release();
00189 return (f != NULL);
00190 }
00191
00192
00193
00194
00195
00196
00197
00198 bool VirtualFileMountRamdisk::
00199 is_directory(const Filename &file) const {
00200 ((VirtualFileMountRamdisk *)this)->_lock.acquire();
00201 PT(FileBase) f = _root.do_find_file(file);
00202 ((VirtualFileMountRamdisk *)this)->_lock.release();
00203 return (f != NULL && f->is_directory());
00204 }
00205
00206
00207
00208
00209
00210
00211
00212 bool VirtualFileMountRamdisk::
00213 is_regular_file(const Filename &file) const {
00214 ((VirtualFileMountRamdisk *)this)->_lock.acquire();
00215 PT(FileBase) f = _root.do_find_file(file);
00216 ((VirtualFileMountRamdisk *)this)->_lock.release();
00217 return (f != NULL && !f->is_directory());
00218 }
00219
00220
00221
00222
00223
00224
00225
00226 bool VirtualFileMountRamdisk::
00227 is_writable(const Filename &file) const {
00228 return has_file(file);
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 istream *VirtualFileMountRamdisk::
00240 open_read_file(const Filename &file) const {
00241 ((VirtualFileMountRamdisk *)this)->_lock.acquire();
00242 PT(FileBase) f = _root.do_find_file(file);
00243 ((VirtualFileMountRamdisk *)this)->_lock.release();
00244 if (f == (FileBase *)NULL || f->is_directory()) {
00245 return false;
00246 }
00247
00248 File *f2 = DCAST(File, f);
00249 return new ISubStream(&f2->_wrapper, 0, 0);
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 ostream *VirtualFileMountRamdisk::
00261 open_write_file(const Filename &file, bool truncate) {
00262 _lock.acquire();
00263 PT(File) f = _root.do_create_file(file);
00264 _lock.release();
00265 if (f == (File *)NULL) {
00266 return false;
00267 }
00268
00269 if (truncate) {
00270
00271 f->_data.str(string());
00272 }
00273
00274 return new OSubStream(&f->_wrapper, 0, 0);
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 ostream *VirtualFileMountRamdisk::
00286 open_append_file(const Filename &file) {
00287 _lock.acquire();
00288 PT(File) f = _root.do_create_file(file);
00289 _lock.release();
00290 if (f == (File *)NULL) {
00291 return false;
00292 }
00293
00294 return new OSubStream(&f->_wrapper, 0, 0, true);
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 iostream *VirtualFileMountRamdisk::
00306 open_read_write_file(const Filename &file, bool truncate) {
00307 _lock.acquire();
00308 PT(File) f = _root.do_create_file(file);
00309 _lock.release();
00310 if (f == (File *)NULL) {
00311 return false;
00312 }
00313
00314 return new SubStream(&f->_wrapper, 0, 0);
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325 iostream *VirtualFileMountRamdisk::
00326 open_read_append_file(const Filename &file) {
00327 _lock.acquire();
00328 PT(FileBase) f = _root.do_find_file(file);
00329 _lock.release();
00330 if (f == (FileBase *)NULL || f->is_directory()) {
00331 return false;
00332 }
00333
00334 File *f2 = DCAST(File, f);
00335 return new SubStream(&f2->_wrapper, 0, 0, true);
00336 }
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 off_t VirtualFileMountRamdisk::
00348 get_file_size(const Filename &file, istream *stream) const {
00349 ((VirtualFileMountRamdisk *)this)->_lock.acquire();
00350 PT(FileBase) f = _root.do_find_file(file);
00351 ((VirtualFileMountRamdisk *)this)->_lock.release();
00352 if (f == (FileBase *)NULL || f->is_directory()) {
00353 return false;
00354 }
00355
00356 File *f2 = DCAST(File, f);
00357 return f2->_data.str().length();
00358 }
00359
00360
00361
00362
00363
00364
00365
00366 off_t VirtualFileMountRamdisk::
00367 get_file_size(const Filename &file) const {
00368 ((VirtualFileMountRamdisk *)this)->_lock.acquire();
00369 PT(FileBase) f = _root.do_find_file(file);
00370 ((VirtualFileMountRamdisk *)this)->_lock.release();
00371 if (f == (FileBase *)NULL || f->is_directory()) {
00372 return false;
00373 }
00374
00375 File *f2 = DCAST(File, f);
00376 return f2->_data.str().length();
00377 }
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 time_t VirtualFileMountRamdisk::
00394 get_timestamp(const Filename &file) const {
00395 return 0;
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406 bool VirtualFileMountRamdisk::
00407 scan_directory(vector_string &contents, const Filename &dir) const {
00408 ((VirtualFileMountRamdisk *)this)->_lock.acquire();
00409 PT(FileBase) f = _root.do_find_file(dir);
00410 if (f == (FileBase *)NULL || !f->is_directory()) {
00411 ((VirtualFileMountRamdisk *)this)->_lock.release();
00412 return false;
00413 }
00414
00415 Directory *f2 = DCAST(Directory, f);
00416 bool result = f2->do_scan_directory(contents);
00417
00418 ((VirtualFileMountRamdisk *)this)->_lock.release();
00419 return result;
00420 }
00421
00422
00423
00424
00425
00426
00427 bool VirtualFileMountRamdisk::
00428 atomic_compare_and_exchange_contents(const Filename &file, string &orig_contents,
00429 const string &old_contents,
00430 const string &new_contents) {
00431 _lock.acquire();
00432 PT(FileBase) f = _root.do_find_file(file);
00433 if (f == (FileBase *)NULL || f->is_directory()) {
00434 _lock.release();
00435 return false;
00436 }
00437
00438 bool retval = false;
00439 File *f2 = DCAST(File, f);
00440 orig_contents = f2->_data.str();
00441 if (orig_contents == old_contents) {
00442 f2->_data.str(new_contents);
00443 retval = true;
00444 }
00445
00446 _lock.release();
00447 return retval;
00448 }
00449
00450
00451
00452
00453
00454
00455 bool VirtualFileMountRamdisk::
00456 atomic_read_contents(const Filename &file, string &contents) const {
00457 ((VirtualFileMountRamdisk *)this)->_lock.acquire();
00458 PT(FileBase) f = _root.do_find_file(file);
00459 if (f == (FileBase *)NULL || f->is_directory()) {
00460 ((VirtualFileMountRamdisk *)this)->_lock.release();
00461 return false;
00462 }
00463
00464 File *f2 = DCAST(File, f);
00465 contents = f2->_data.str();
00466
00467 ((VirtualFileMountRamdisk *)this)->_lock.release();
00468 return true;
00469 }
00470
00471
00472
00473
00474
00475
00476
00477 void VirtualFileMountRamdisk::
00478 output(ostream &out) const {
00479 out << "VirtualFileMountRamdisk";
00480 }
00481
00482
00483
00484
00485
00486
00487 VirtualFileMountRamdisk::FileBase::
00488 ~FileBase() {
00489 }
00490
00491
00492
00493
00494
00495
00496 bool VirtualFileMountRamdisk::FileBase::
00497 is_directory() const {
00498 return false;
00499 }
00500
00501
00502
00503
00504
00505
00506 bool VirtualFileMountRamdisk::Directory::
00507 is_directory() const {
00508 return true;
00509 }
00510
00511
00512
00513
00514
00515
00516
00517 PT(VirtualFileMountRamdisk::FileBase) VirtualFileMountRamdisk::Directory::
00518 do_find_file(const string &filename) const {
00519 size_t slash = filename.find('/');
00520 if (slash == string::npos) {
00521
00522 FileBase tfile(filename);
00523 tfile.local_object();
00524 Files::const_iterator fi = _files.find(&tfile);
00525 if (fi != _files.end()) {
00526 return (*fi);
00527 }
00528 return NULL;
00529 }
00530
00531
00532 string dirname = filename.substr(0, slash);
00533 string remainder = filename.substr(slash + 1);
00534 FileBase tfile(dirname);
00535 tfile.local_object();
00536 Files::const_iterator fi = _files.find(&tfile);
00537 if (fi != _files.end()) {
00538 PT(FileBase) file = (*fi);
00539 if (file->is_directory()) {
00540 return DCAST(Directory, file.p())->do_find_file(remainder);
00541 }
00542 }
00543
00544 return NULL;
00545 }
00546
00547
00548
00549
00550
00551
00552
00553
00554 PT(VirtualFileMountRamdisk::File) VirtualFileMountRamdisk::Directory::
00555 do_create_file(const string &filename) {
00556 size_t slash = filename.find('/');
00557 if (slash == string::npos) {
00558
00559 FileBase tfile(filename);
00560 tfile.local_object();
00561 Files::iterator fi = _files.find(&tfile);
00562 if (fi != _files.end()) {
00563 PT(FileBase) file = (*fi);
00564 if (!file->is_directory()) {
00565 return DCAST(File, file.p());
00566 }
00567
00568 return NULL;
00569 }
00570
00571
00572 if (express_cat.is_debug()) {
00573 express_cat.debug()
00574 << "Making ramdisk file " << filename << "\n";
00575 }
00576 PT(File) file = new File(filename);
00577 _files.insert(file.p());
00578 return file;
00579 }
00580
00581
00582 string dirname = filename.substr(0, slash);
00583 string remainder = filename.substr(slash + 1);
00584 FileBase tfile(dirname);
00585 tfile.local_object();
00586 Files::iterator fi = _files.find(&tfile);
00587 if (fi != _files.end()) {
00588 PT(FileBase) file = (*fi);
00589 if (file->is_directory()) {
00590 return DCAST(Directory, file.p())->do_create_file(remainder);
00591 }
00592 }
00593
00594 return NULL;
00595 }
00596
00597
00598
00599
00600
00601
00602
00603
00604 PT(VirtualFileMountRamdisk::Directory) VirtualFileMountRamdisk::Directory::
00605 do_make_directory(const string &filename) {
00606 size_t slash = filename.find('/');
00607 if (slash == string::npos) {
00608
00609 FileBase tfile(filename);
00610 tfile.local_object();
00611 Files::iterator fi = _files.find(&tfile);
00612 if (fi != _files.end()) {
00613 PT(FileBase) file = (*fi);
00614 if (file->is_directory()) {
00615 return DCAST(Directory, file.p());
00616 }
00617
00618 return NULL;
00619 }
00620
00621
00622 if (express_cat.is_debug()) {
00623 express_cat.debug()
00624 << "Making ramdisk directory " << filename << "\n";
00625 }
00626 PT(Directory) file = new Directory(filename);
00627 _files.insert(file.p());
00628 return file;
00629 }
00630
00631
00632 string dirname = filename.substr(0, slash);
00633 string remainder = filename.substr(slash + 1);
00634 FileBase tfile(dirname);
00635 tfile.local_object();
00636 Files::iterator fi = _files.find(&tfile);
00637 if (fi != _files.end()) {
00638 PT(FileBase) file = (*fi);
00639 if (file->is_directory()) {
00640 return DCAST(Directory, file.p())->do_make_directory(remainder);
00641 }
00642 }
00643
00644 return NULL;
00645 }
00646
00647
00648
00649
00650
00651
00652
00653
00654 PT(VirtualFileMountRamdisk::FileBase) VirtualFileMountRamdisk::Directory::
00655 do_delete_file(const string &filename) {
00656 size_t slash = filename.find('/');
00657 if (slash == string::npos) {
00658
00659 FileBase tfile(filename);
00660 tfile.local_object();
00661 Files::iterator fi = _files.find(&tfile);
00662 if (fi != _files.end()) {
00663 PT(FileBase) file = (*fi);
00664 if (file->is_directory()) {
00665 Directory *dir = DCAST(Directory, file.p());
00666 if (!dir->_files.empty()) {
00667
00668 return NULL;
00669 }
00670 }
00671 _files.erase(fi);
00672 return file;
00673 }
00674 return NULL;
00675 }
00676
00677
00678 string dirname = filename.substr(0, slash);
00679 string remainder = filename.substr(slash + 1);
00680 FileBase tfile(dirname);
00681 tfile.local_object();
00682 Files::iterator fi = _files.find(&tfile);
00683 if (fi != _files.end()) {
00684 PT(FileBase) file = (*fi);
00685 if (file->is_directory()) {
00686 return DCAST(Directory, file.p())->do_delete_file(remainder);
00687 }
00688 }
00689
00690 return NULL;
00691 }
00692
00693
00694
00695
00696
00697
00698 bool VirtualFileMountRamdisk::Directory::
00699 do_scan_directory(vector_string &contents) const {
00700 Files::const_iterator fi;
00701 for (fi = _files.begin(); fi != _files.end(); ++fi) {
00702 FileBase *file = (*fi);
00703 contents.push_back(file->_basename);
00704 }
00705
00706 return true;
00707 }