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.

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, Directory *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

Classes

class  Iterator

Detailed Description

Definition at line 99 of file FileSystemStorage.h.


Member Typedef Documentation

typedef Iterator<Directory> OpenDDS::FileSystemStorage::Directory::DirectoryIterator

Definition at line 169 of file FileSystemStorage.h.

typedef Iterator<File> OpenDDS::FileSystemStorage::Directory::FileIterator

Definition at line 168 of file FileSystemStorage.h.

typedef RcHandle<Directory> OpenDDS::FileSystemStorage::Directory::Ptr

Definition at line 101 of file FileSystemStorage.h.


Constructor & Destructor Documentation

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 }


Member Function Documentation

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]

Definition at line 191 of file FileSystemStorage.h.

00191                               {
00192     return parent_;
00193   }

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 }


Friends And Related Function Documentation

friend class File [friend]

Definition at line 196 of file FileSystemStorage.h.

Referenced by get_file(), and make_new_file().


Member Data Documentation

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]

Definition at line 207 of file FileSystemStorage.h.

Referenced by name(), and remove().

Directory::Ptr OpenDDS::FileSystemStorage::Directory::parent_ [private]

Definition at line 206 of file FileSystemStorage.h.

Referenced by remove().

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


The documentation for this class was generated from the following files:
Generated on Fri Feb 12 20:06:47 2016 for OpenDDS by  doxygen 1.4.7