// FileDirectory.cxx #include "dataset_util/FileDirectory.h" #include #include #include #include using std::string; using std::ostream; typedef FileDirectory::Name Name; typedef FileDirectory::NameList NameList; typedef FileDirectory::FileList FileList; typedef FileDirectory::DirectoryList DirectoryList; //********************************************************************** // Constructor from string name. FileDirectory::FileDirectory(Name name) : m_name(name) { update(); } //********************************************************************** // Update. bool FileDirectory::update() { m_file_names.erase(m_file_names.begin(), m_file_names.end()); m_files.erase(m_files.begin(), m_files.end()); m_subdirs_filled = false; m_subdir_names.erase(m_subdir_names.begin(), m_subdir_names.end()); m_subdirs.erase(m_subdirs.begin(), m_subdirs.end()); m_status = FileStatus(m_name); if ( ! is_valid() ) return false; DIR* pdir = opendir(m_name.c_str()); if ( pdir == 0 ) { m_status = FileStatus(); return false; } // Read the contents of the directory. dirent* pdirent; while ( (pdirent = readdir(pdir)) != 0 ) { Name name(pdirent->d_name); if ( name == "." ) continue; if ( name == ".." ) continue; m_file_names.push_back(name); string fullname = m_name + FileName::string_delimiter() + name; FileStatus fstat(fullname); m_files.push_back(fstat); } closedir(pdir); return true; } //********************************************************************** // Validity. bool FileDirectory::is_valid() const { return m_status.is_directory(); } //********************************************************************** // Return the subdirectory names. // Created on request and cleared during update. const NameList& FileDirectory::subdir_names() const { if ( is_valid() && ! m_subdirs_filled ) { NameList::const_iterator iname = file_names().begin(); for ( FileList::const_iterator ifile=files().begin(); ifile!=files().end(); ++ifile ) { assert( iname != file_names().end() ); if ( ifile->is_directory() ) { m_subdir_names.push_back(*iname); m_subdirs.push_back(FileDirectory(ifile->name())); } ++iname; } m_subdirs_filled = true; } return m_subdir_names; } //********************************************************************** // Return the subdirectories. // Created on request and cleared during update. const DirectoryList& FileDirectory::subdirs() const { if ( is_valid() && ! m_subdirs_filled ) { // Force filling of subdirectory info. subdir_names(); } return m_subdirs; } //********************************************************************** // Prepend directory name. Name FileDirectory::prepend(Name fname) const { if ( fname.size() == 0 ) { return ""; } return name() + FileName::string_delimiter() + fname; } //********************************************************************** // Find a file. Name FileDirectory::find(Name fname) const { if ( fname.size() == 0 ) { return ""; } NameList::const_iterator ifile = std::find(file_names().begin(), file_names().end(), fname); if ( ifile == file_names().end() ) { return ""; } return prepend(fname); } //********************************************************************** // Output stream. ostream& operator<<(ostream& lhs, const FileDirectory& rhs) { if ( rhs.is_valid() ) { lhs << rhs.name(); for ( FileList::const_iterator ifile=rhs.files().begin(); ifile!=rhs.files().end(); ++ifile ) { lhs << "\n " << *ifile; } lhs.flush(); } else { lhs << "Invalid directory " << rhs.name(); } return lhs; } //**********************************************************************