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