OpenDDS::FileSystemStorage::Directory Class Reference

#include <FileSystemStorage.h>

Inheritance diagram for OpenDDS::FileSystemStorage::Directory:
Inheritance graph
[legend]
Collaboration diagram for OpenDDS::FileSystemStorage::Directory:
Collaboration graph
[legend]

List of all members.

Classes

class  Iterator

Public Types

typedef RcHandle< DirectoryPtr
typedef Iterator< FileFileIterator
typedef Iterator< DirectoryDirectoryIterator

Public Member Functions

FileIterator begin_files ()
FileIterator end_files ()
RcHandle< Fileget_file (const char *name)
RcHandle< Filecreate_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< Filemake_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 &)

Detailed Description

Definition at line 101 of file FileSystemStorage.h.


Member Typedef Documentation

Definition at line 171 of file FileSystemStorage.h.

Definition at line 170 of file FileSystemStorage.h.

Definition at line 103 of file FileSystemStorage.h.


Constructor & Destructor Documentation

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 }

Here is the call graph for this function:


Member Function Documentation

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

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().

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:


Friends And Related Function Documentation

friend class File [friend]

Definition at line 198 of file FileSystemStorage.h.

template<typename T , typename U0 , typename U1 , typename U2 >
RcHandle<T> OpenDDS::DCPS::make_rch ( const U0 &  ,
const U1 &  ,
const U2 &   
) [friend]

Member Data Documentation

Definition at line 212 of file FileSystemStorage.h.

Referenced by name(), and remove().

Definition at line 211 of file FileSystemStorage.h.

Referenced by remove().


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 10 Aug 2018 for OpenDDS by  doxygen 1.6.1