#include <FileSystemStorage.h>
Classes | |
class | Iterator |
Public Types | |
typedef RcHandle< Directory > | Ptr |
typedef Iterator< File > | FileIterator |
typedef Iterator< Directory > | DirectoryIterator |
Public Member Functions | |
FileIterator | begin_files () |
FileIterator | end_files () |
RcHandle< File > | get_file (const char *name) |
RcHandle< File > | create_next_file () |
assumes all files in this dir are created with this API | |
DirectoryIterator | begin_dirs () |
DirectoryIterator | end_dirs () |
Directory::Ptr | get_dir (const OPENDDS_VECTOR(OPENDDS_STRING)&path) |
Directory::Ptr | get_subdir (const char *name) |
Directory::Ptr | create_next_dir () |
assumes all subdirectories in this dir are created with this API | |
void | remove () |
OPENDDS_STRING | name () const |
Directory::Ptr | parent () const |
Static Public Member Functions | |
static Ptr | create (const char *root_path) |
Private Member Functions | |
ACE_TString | full_path (const ACE_TString &relative) const |
typedef | OPENDDS_MAP (ACE_TString, ACE_TString) Map |
Directory (const ACE_TString &root_path, const ACE_TString &logical, const Directory::Ptr &parent) | |
void | scan_dir (const ACE_TString &relative, DDS_Dirent &dir, unsigned int overflow_index) |
RcHandle< File > | make_new_file (const ACE_TString &t_name) |
void | removing (const ACE_TString &logical_child, bool file) |
Directory::Ptr | make_new_subdir (const ACE_TString &logical) |
ACE_TString | add_entry () |
OPENDDS_MAP (unsigned int, unsigned int) overflow_ | |
OPENDDS_MAP (ACE_TString, unsigned int) long_names_ | |
Private Attributes | |
Directory::Ptr | parent_ |
ACE_TString | physical_dirname_ |
ACE_TString | logical_dirname_ |
Map | files_ |
Map | dirs_ |
Friends | |
class | File |
template<typename T , typename U0 , typename U1 , typename U2 > | |
RcHandle< T > | OpenDDS::DCPS::make_rch (const U0 &, const U1 &, const U2 &) |
Definition at line 101 of file FileSystemStorage.h.
Definition at line 171 of file FileSystemStorage.h.
Definition at line 170 of file FileSystemStorage.h.
Definition at line 103 of file FileSystemStorage.h.
OpenDDS::FileSystemStorage::Directory::Directory | ( | const ACE_TString & | root_path, | |
const ACE_TString & | logical, | |||
const Directory::Ptr & | parent | |||
) | [private] |
Definition at line 758 of file FileSystemStorage.cpp.
References ACE_TEXT(), ACE_String_Base< ACE_CHAR_T >::c_str(), DDS_Dirent, physical_dirname_, and scan_dir().
00760 : parent_(parent) 00761 , physical_dirname_(dirname) 00762 , logical_dirname_(logical) 00763 { 00764 add_slash(physical_dirname_); 00765 00766 bool ok(true); 00767 DDS_Dirent dir; 00768 00769 if (dir.open(physical_dirname_.c_str()) == -1) { 00770 ok = false; 00771 00772 if (errno == ENOENT && dds_mkdir(physical_dirname_.c_str()) != -1 00773 && dir.open(physical_dirname_.c_str()) != -1) { 00774 ok = true; 00775 } 00776 } 00777 00778 if (!ok) throw std::runtime_error("Can't open or create directory"); 00779 00780 scan_dir(ACE_TEXT(""), dir, 0); 00781 }
ACE_TString OpenDDS::FileSystemStorage::Directory::add_entry | ( | ) | [private] |
Definition at line 692 of file FileSystemStorage.cpp.
References ACE_TEXT(), ACE_String_Base< ACE_CHAR_T >::c_str(), OPENDDS_FILESYSTEMSTORAGE_MAX_FILES_PER_DIR, OPENDDS_MAP(), and physical_dirname_.
Referenced by make_new_file(), and make_new_subdir().
00693 { 00694 if (overflow_.empty()) { 00695 overflow_[0] = 1; 00696 return ACE_TEXT(""); 00697 } 00698 00699 typedef OPENDDS_MAP(unsigned int, unsigned int)::iterator iterator; 00700 // find existing overflow bucket with capacity 00701 bool found_gap(false); 00702 unsigned int last_seen(0), unused_bucket(0); 00703 00704 for (iterator iter = overflow_.begin(), end = overflow_.end(); 00705 iter != end; ++iter) { 00706 if (iter->second < OPENDDS_FILESYSTEMSTORAGE_MAX_FILES_PER_DIR) { 00707 ++iter->second; 00708 00709 if (iter->first == 0) return ACE_TEXT(""); 00710 00711 return overflow_dir_name(iter->first); 00712 } 00713 00714 if (!found_gap && iter->first > last_seen + 1) { 00715 found_gap = true; 00716 unused_bucket = last_seen + 1; 00717 } 00718 00719 last_seen = iter->first; 00720 } 00721 00722 if (!found_gap) { 00723 if (last_seen == FSS_MAX_OVERFLOW_DIR) { 00724 throw std::runtime_error("Overflow serial # out of range."); 00725 } 00726 00727 unused_bucket = last_seen + 1; 00728 } 00729 00730 overflow_[unused_bucket] = 1; 00731 ACE_TString dir_name = overflow_dir_name(unused_bucket); 00732 CwdGuard cg(physical_dirname_); 00733 00734 if (dds_mkdir(dir_name.c_str()) == -1) { 00735 throw std::runtime_error("Can't create overflow directory"); 00736 } 00737 00738 return dir_name; 00739 }
Directory::DirectoryIterator OpenDDS::FileSystemStorage::Directory::begin_dirs | ( | ) |
Definition at line 592 of file FileSystemStorage.cpp.
References dirs_, and OpenDDS::DCPS::rchandle_from().
00593 { 00594 return DirectoryIterator(dirs_.begin(), rchandle_from(this)); 00595 }
Directory::FileIterator OpenDDS::FileSystemStorage::Directory::begin_files | ( | ) |
Definition at line 526 of file FileSystemStorage.cpp.
References files_, and OpenDDS::DCPS::rchandle_from().
00527 { 00528 return FileIterator(files_.begin(), rchandle_from(this)); 00529 }
Directory::Ptr OpenDDS::FileSystemStorage::Directory::create | ( | const char * | root_path | ) | [static] |
If root_path is relative it is up to the application to make sure the current directory is not changed while this object or any of its "child" objects are still alive.
Definition at line 516 of file FileSystemStorage.cpp.
References ACE_TEXT(), and ACE_TEXT_CHAR_TO_TCHAR.
00517 { 00518 return DCPS::make_rch<Directory>(ACE_TEXT_CHAR_TO_TCHAR(dirname), ACE_TEXT(""), Directory::Ptr ()); 00519 }
Directory::Ptr OpenDDS::FileSystemStorage::Directory::create_next_dir | ( | ) |
assumes all subdirectories in this dir are created with this API
Definition at line 627 of file FileSystemStorage.cpp.
References dirs_, and make_new_subdir().
00628 { 00629 ACE_TString logical; 00630 00631 if (dirs_.empty()) { 00632 logical = FSS_DEFAULT_DIR_NAME; 00633 00634 } else { 00635 Map::iterator last = --dirs_.end(); 00636 logical = last->first; 00637 00638 if (!increment(logical)) { 00639 throw std::runtime_error("out of range for create_next_dir"); 00640 } 00641 } 00642 00643 return make_new_subdir(logical); 00644 }
File::Ptr OpenDDS::FileSystemStorage::Directory::create_next_file | ( | ) |
assumes all files in this dir are created with this API
Definition at line 573 of file FileSystemStorage.cpp.
References files_, and make_new_file().
00574 { 00575 ACE_TString logical; 00576 00577 if (files_.empty()) { 00578 logical = FSS_DEFAULT_FILE_NAME; 00579 00580 } else { 00581 Map::iterator last = --files_.end(); 00582 logical = last->first; 00583 00584 if (!increment(logical)) { 00585 throw std::runtime_error("out of range for create_next_file"); 00586 } 00587 } 00588 00589 return make_new_file(logical); 00590 }
Directory::DirectoryIterator OpenDDS::FileSystemStorage::Directory::end_dirs | ( | ) |
Definition at line 597 of file FileSystemStorage.cpp.
References dirs_, and OpenDDS::DCPS::rchandle_from().
00598 { 00599 return DirectoryIterator(dirs_.end(), rchandle_from(this)); 00600 }
Directory::FileIterator OpenDDS::FileSystemStorage::Directory::end_files | ( | ) |
Definition at line 531 of file FileSystemStorage.cpp.
References files_, and OpenDDS::DCPS::rchandle_from().
00532 { 00533 return FileIterator(files_.end(), rchandle_from(this)); 00534 }
ACE_TString OpenDDS::FileSystemStorage::Directory::full_path | ( | const ACE_TString & | relative | ) | const [private] |
Definition at line 521 of file FileSystemStorage.cpp.
References physical_dirname_.
Referenced by get_file(), and get_subdir().
00522 { 00523 return physical_dirname_ + relative; 00524 }
Directory::Ptr OpenDDS::FileSystemStorage::Directory::get_dir | ( | const OPENDDS_VECTOR(OPENDDS_STRING)& | path | ) |
Definition at line 602 of file FileSystemStorage.cpp.
References OPENDDS_STRING, OPENDDS_VECTOR, and OpenDDS::DCPS::rchandle_from().
00603 { 00604 Directory::Ptr dir = rchandle_from(this); 00605 typedef OPENDDS_VECTOR(OPENDDS_STRING)::const_iterator iterator; 00606 00607 for (iterator iter = path.begin(), end = path.end(); iter != end; ++iter) { 00608 dir = dir->get_subdir(iter->c_str()); 00609 } 00610 00611 return dir; 00612 }
File::Ptr OpenDDS::FileSystemStorage::Directory::get_file | ( | const char * | name | ) |
Definition at line 536 of file FileSystemStorage.cpp.
References ACE_TEXT_CHAR_TO_TCHAR, files_, full_path(), make_new_file(), and OpenDDS::DCPS::rchandle_from().
00537 { 00538 if (std::strlen(name) >= FSS_MAX_FILE_NAME) { 00539 throw std::runtime_error("file name too long"); 00540 } 00541 00542 ACE_TString t_name(ACE_TEXT_CHAR_TO_TCHAR(name)); 00543 Map::iterator it = files_.find(t_name); 00544 00545 if (it == files_.end()) { 00546 return make_new_file(t_name); 00547 00548 } else { 00549 return DCPS::make_rch<File>(full_path(it->second), it->first, rchandle_from(this)); 00550 } 00551 }
Directory::Ptr OpenDDS::FileSystemStorage::Directory::get_subdir | ( | const char * | name | ) |
Definition at line 614 of file FileSystemStorage.cpp.
References ACE_TEXT_CHAR_TO_TCHAR, dirs_, full_path(), make_new_subdir(), and OpenDDS::DCPS::rchandle_from().
00615 { 00616 ACE_TString t_name = ACE_TEXT_CHAR_TO_TCHAR(name); 00617 Map::iterator it = dirs_.find(t_name); 00618 00619 if (it == dirs_.end()) { 00620 return make_new_subdir(t_name); 00621 00622 } else { 00623 return DCPS::make_rch<Directory>(full_path(it->second), it->first, rchandle_from(this)); 00624 } 00625 }
File::Ptr OpenDDS::FileSystemStorage::Directory::make_new_file | ( | const ACE_TString & | t_name | ) | [private] |
Definition at line 553 of file FileSystemStorage.cpp.
References ACE_TEXT_ALWAYS_CHAR, add_entry(), OpenDDS::FileSystemStorage::b32h_encode(), ACE_String_Base< ACE_CHAR_T >::c_str(), dirs_, files_, physical_dirname_, and OpenDDS::DCPS::rchandle_from().
Referenced by create_next_file(), and get_file().
00554 { 00555 if (dirs_.find(t_name) != dirs_.end()) { 00556 throw std::runtime_error("Can't create a file with the same name as " 00557 "an existing directory."); 00558 } 00559 00560 ACE_TString phys = add_entry() + b32h_encode(t_name.c_str()); 00561 files_[t_name] = phys; 00562 00563 CwdGuard cg(physical_dirname_); 00564 // touch the file since the user has asked to create it 00565 std::FILE* fh = std::fopen(ACE_TEXT_ALWAYS_CHAR(phys.c_str()), "w"); 00566 00567 if (!fh) throw std::runtime_error("Can't create the file"); 00568 00569 std::fclose(fh); 00570 return DCPS::make_rch<File>(physical_dirname_ + phys, t_name, rchandle_from(this)); 00571 }
Directory::Ptr OpenDDS::FileSystemStorage::Directory::make_new_subdir | ( | const ACE_TString & | logical | ) | [private] |
Definition at line 646 of file FileSystemStorage.cpp.
References ACE_TEXT(), add_entry(), OpenDDS::FileSystemStorage::b32h_encode(), ACE_String_Base< ACE_CHAR_T >::c_str(), dirs_, files_, ACE_String_Base< ACE_CHAR_T >::length(), physical_dirname_, OpenDDS::DCPS::rchandle_from(), ACE_OS::snprintf(), and ACE_String_Base< ACE_CHAR_T >::substr().
Referenced by create_next_dir(), and get_subdir().
00647 { 00648 if (files_.find(t_name) != files_.end()) { 00649 throw std::runtime_error("Can't create a directory with the same " 00650 "name as an existing file."); 00651 } 00652 00653 ACE_TString logical(t_name.c_str(), 00654 (std::min)(FSS_MAX_FILE_NAME, t_name.length())); 00655 ACE_TString phys_prefix = add_entry(); 00656 ACE_TString phys_base = b32h_encode(logical.c_str()); 00657 00658 if (t_name.length() >= FSS_MAX_FILE_NAME) { 00659 unsigned int& counter = long_names_[phys_prefix + phys_base]; 00660 00661 if (counter == 99999) { 00662 throw std::runtime_error("Long directory name out of range"); 00663 } 00664 00665 phys_base += ACE_TEXT(". X"); // snprintf will clobber the X with a 0 00666 ACE_TCHAR* buf = &phys_base[0] + phys_base.length() - 6; 00667 ACE_OS::snprintf(buf, 6, ACE_TEXT("%05u"), counter++); 00668 phys_base = phys_base.substr(0, phys_base.length() - 1); // trim the 0 00669 } 00670 00671 ACE_TString phys = phys_prefix + phys_base; 00672 dirs_[t_name] = phys; 00673 { 00674 CwdGuard cg(physical_dirname_); 00675 00676 if (dds_mkdir(phys.c_str()) == -1) { 00677 throw std::runtime_error("Can't create directory"); 00678 } 00679 00680 if ((phys_prefix.length() > 0 && dds_chdir(phys_prefix.c_str()) == -1) 00681 || dds_chdir(phys_base.c_str()) == -1) { 00682 dds_rmdir(phys.c_str()); 00683 throw std::runtime_error("Can't change to newly created directory"); 00684 } 00685 00686 std::ofstream fn("_fullname"); 00687 fn << t_name << '\n'; 00688 } 00689 return DCPS::make_rch<Directory>(physical_dirname_ + phys, t_name, rchandle_from(this)); 00690 }
OPENDDS_STRING OpenDDS::FileSystemStorage::Directory::name | ( | void | ) | const |
Definition at line 753 of file FileSystemStorage.cpp.
References ACE_TEXT_ALWAYS_CHAR, ACE_String_Base< ACE_CHAR_T >::c_str(), and logical_dirname_.
00754 { 00755 return ACE_TEXT_ALWAYS_CHAR(logical_dirname_.c_str()); 00756 }
OpenDDS::FileSystemStorage::Directory::OPENDDS_MAP | ( | ACE_TString | , | |
unsigned | int | |||
) | [private] |
OpenDDS::FileSystemStorage::Directory::OPENDDS_MAP | ( | unsigned | int, | |
unsigned | int | |||
) | [private] |
typedef OpenDDS::FileSystemStorage::Directory::OPENDDS_MAP | ( | ACE_TString | , | |
ACE_TString | ||||
) | [private] |
Directory::Ptr OpenDDS::FileSystemStorage::Directory::parent | ( | void | ) | const [inline] |
Definition at line 193 of file FileSystemStorage.h.
00193 { 00194 return parent_; 00195 }
void OpenDDS::FileSystemStorage::Directory::remove | ( | void | ) |
Definition at line 741 of file FileSystemStorage.cpp.
References dirs_, files_, OpenDDS::DCPS::RcHandle< T >::is_nil(), logical_dirname_, parent_, physical_dirname_, and OpenDDS::DCPS::RcHandle< T >::reset().
00742 { 00743 if (!parent_.is_nil()) parent_->removing(logical_dirname_, false); 00744 00745 parent_.reset(); 00746 recursive_remove(physical_dirname_); 00747 overflow_.clear(); 00748 files_.clear(); 00749 dirs_.clear(); 00750 long_names_.clear(); 00751 }
void OpenDDS::FileSystemStorage::Directory::removing | ( | const ACE_TString & | logical_child, | |
bool | file | |||
) | [private] |
Definition at line 846 of file FileSystemStorage.cpp.
References ACE_TEXT(), ACE_OS::atoi(), ACE_String_Base< ACE_CHAR_T >::c_str(), dirs_, files_, ACE_String_Base< ACE_CHAR_T >::find(), and physical_dirname_.
00847 { 00848 Map& m = file ? files_ : dirs_; 00849 Map::iterator iter = m.find(child); 00850 00851 if (iter == m.end()) return; 00852 00853 const ACE_TString& phys = iter->second; 00854 String_Index_t idx = phys.find(ACE_TEXT("_overflow.")); 00855 unsigned int bucket = (idx == 0 ? ACE_OS::atoi(&phys[idx + 10]) : 0); 00856 00857 if (--overflow_[bucket] == 0 && bucket > 0) { 00858 overflow_.erase(bucket); 00859 idx = phys.find(ACE_TEXT('/')); 00860 ACE_TString ov_dir = physical_dirname_ + ACE_TString(phys.c_str(), idx); 00861 dds_rmdir(ov_dir.c_str()); 00862 } 00863 00864 m.erase(iter); 00865 }
void OpenDDS::FileSystemStorage::Directory::scan_dir | ( | const ACE_TString & | relative, | |
DDS_Dirent & | dir, | |||
unsigned int | overflow_index | |||
) | [private] |
Definition at line 783 of file FileSystemStorage.cpp.
References ACE_TEXT(), ACE_TEXT_CHAR_TO_TCHAR, ACE_OS::atoi(), OpenDDS::FileSystemStorage::b32h_decode(), ACE_String_Base< ACE_CHAR_T >::c_str(), DDS_Dirent, DDS_DIRENT, dirs_, file, files_, ACE_String_Base_Const::npos, OPENDDS_STRING, physical_dirname_, ACE_String_Base< ACE_CHAR_T >::rfind(), ACE_OS::strlen(), and ACE_OS::strncmp().
Referenced by Directory().
00785 { 00786 ACE_TString path = physical_dirname_ + relative; 00787 add_slash(path); 00788 00789 while (DDS_DIRENT* ent = dir.read()) { 00790 if (ent->d_name[0] == ACE_TEXT('.') && (!ent->d_name[1] || 00791 (ent->d_name[1] == ACE_TEXT('.') && !ent->d_name[2]))) { 00792 continue; // skip '.' and '..' 00793 } 00794 00795 ACE_TString file = path + ent->d_name; 00796 00797 if (is_dir(file.c_str())) { 00798 ACE_TString phys(relative); 00799 add_slash(phys); 00800 phys += ent->d_name; 00801 00802 if (ACE_OS::strncmp(ent->d_name, ACE_TEXT("_overflow."), 10) == 0) { 00803 unsigned int n = ACE_OS::atoi(ent->d_name + 10); 00804 DDS_Dirent overflow(file.c_str()); 00805 scan_dir(ent->d_name, overflow, n); 00806 00807 } else if (ACE_OS::strlen(ent->d_name) <= FSS_MAX_FILE_NAME_ENCODED) { 00808 dirs_[b32h_decode(ent->d_name)] = phys; 00809 ++overflow_[overflow_index]; 00810 00811 } else { 00812 CwdGuard cg(file); 00813 std::ifstream fn("_fullname"); 00814 OPENDDS_STRING fullname; 00815 00816 if (!std::getline(fn, fullname)) { 00817 throw std::runtime_error("Can't read .../_fullname"); 00818 } 00819 00820 ACE_TString full_t(ACE_TEXT_CHAR_TO_TCHAR(fullname.c_str())); 00821 dirs_[full_t] = phys; 00822 ++overflow_[overflow_index]; 00823 00824 String_Index_t idx = phys.rfind(ACE_TEXT('.')); 00825 00826 if (idx == ACE_TString::npos) { 00827 throw std::runtime_error("Badly formatted long dir name"); 00828 } 00829 00830 ACE_TString prefix(phys.c_str(), idx); 00831 unsigned int serial = ACE_OS::atoi(&phys[idx + 1]); 00832 unsigned int& counter = long_names_[prefix]; 00833 00834 if (serial >= counter) counter = serial + 1; 00835 } 00836 00837 } else { // regular file 00838 if (ent->d_name[0] != ACE_TEXT('_')) { 00839 files_[b32h_decode(ent->d_name)] = ent->d_name; 00840 ++overflow_[overflow_index]; 00841 } 00842 } 00843 } 00844 }
friend class File [friend] |
Definition at line 198 of file FileSystemStorage.h.
RcHandle<T> OpenDDS::DCPS::make_rch | ( | const U0 & | , | |
const U1 & | , | |||
const U2 & | ||||
) | [friend] |
Map OpenDDS::FileSystemStorage::Directory::dirs_ [private] |
Definition at line 217 of file FileSystemStorage.h.
Referenced by begin_dirs(), create_next_dir(), end_dirs(), get_subdir(), make_new_file(), make_new_subdir(), remove(), removing(), and scan_dir().
Map OpenDDS::FileSystemStorage::Directory::files_ [private] |
Definition at line 217 of file FileSystemStorage.h.
Referenced by begin_files(), create_next_file(), end_files(), get_file(), make_new_file(), make_new_subdir(), remove(), removing(), and scan_dir().
Definition at line 212 of file FileSystemStorage.h.
Definition at line 211 of file FileSystemStorage.h.
Referenced by remove().
Definition at line 212 of file FileSystemStorage.h.
Referenced by add_entry(), Directory(), full_path(), make_new_file(), make_new_subdir(), remove(), removing(), and scan_dir().