1 //===- Directory.h --------------------------------------------------------===// 2 // 3 // The MCLinker Project 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 #ifndef MCLD_SUPPORT_DIRECTORY_H_ 10 #define MCLD_SUPPORT_DIRECTORY_H_ 11 12 #include "mcld/ADT/TypeTraits.h" 13 #include "mcld/Support/FileSystem.h" 14 #include "mcld/Support/Path.h" 15 #include "mcld/Support/PathCache.h" 16 17 #include <llvm/Support/Allocator.h> 18 #include <cstddef> 19 20 namespace mcld { 21 namespace sys { 22 namespace fs { 23 24 class DirIterator; 25 26 /** \class Directory 27 * \brief A Directory object stores a Path object, a FileStatus object for 28 * non-symbolic link status, and a FileStatus object for symbolic link 29 * status. The FileStatus objects act as value caches. 30 */ 31 class Directory { 32 friend mcld::sys::fs::PathCache::entry_type* detail::bring_one_into_cache( 33 DirIterator& pIter); 34 friend void detail::open_dir(Directory& pDir); 35 friend void detail::close_dir(Directory& pDir); 36 37 private: 38 friend class DirIterator; 39 40 public: 41 typedef DirIterator iterator; 42 43 public: 44 /// default constructor 45 Directory(); 46 47 /// constructor - a directory whose path is pPath 48 explicit Directory(const Path& pPath, 49 FileStatus st = FileStatus(), 50 FileStatus symlink_st = FileStatus()); 51 52 explicit Directory(const char* pPath, 53 FileStatus st = FileStatus(), 54 FileStatus symlink_st = FileStatus()); 55 56 /// copy constructor 57 /// when a copying construction happens, the cache is not copied. 58 Directory(const Directory& pCopy); 59 60 /// assignment 61 /// When an assignment occurs, the cache is clear. 62 Directory& operator=(const Directory& pCopy); 63 64 /// destructor, inheritable. 65 virtual ~Directory(); 66 67 /// Since we have default construtor, we must provide assign. 68 void assign(const Path& pPath, 69 FileStatus st = FileStatus(), 70 FileStatus symlink_st = FileStatus()); 71 72 /// clear - clear the cache and close the directory handler 73 void clear(); 74 75 bool isGood() const; 76 77 /// path - the path of the directory path()78 const Path& path() const { return m_Path; } 79 80 FileStatus status() const; 81 FileStatus symlinkStatus() const; 82 83 // ----- iterators ----- // 84 // While the iterators move, the direcotry is modified. 85 // Thus, we only provide non-constant iterator. 86 iterator begin(); 87 iterator end(); 88 89 protected: 90 mcld::sys::fs::Path m_Path; 91 mutable FileStatus m_FileStatus; 92 mutable FileStatus m_SymLinkStatus; 93 intptr_t m_Handler; 94 // the cache of directory 95 mcld::sys::fs::PathCache m_Cache; 96 bool m_CacheFull; 97 }; 98 99 /** \class DirIterator 100 * \brief A DirIterator object can traverse all entries in a Directory 101 * 102 * DirIterator will open the directory and add entry into Directory::m_Cache 103 * DirIterator() is the end of a directory. 104 * If the end of the directory elements is reached, the iterator becomes 105 * equal to the end iterator value - DirIterator(). 106 * 107 * @see Directory 108 */ 109 class DirIterator { 110 friend mcld::sys::fs::PathCache::entry_type* detail::bring_one_into_cache( 111 DirIterator& pIter); 112 friend class Directory; 113 114 public: 115 typedef mcld::sys::fs::PathCache DirCache; 116 117 public: 118 typedef Directory value_type; 119 typedef ConstTraits<Directory> const_traits; 120 typedef NonConstTraits<Directory> non_const_traits; 121 typedef std::input_iterator_tag iterator_category; 122 typedef size_t size_type; 123 typedef ptrdiff_t difference_type; 124 125 private: 126 explicit DirIterator(Directory* pParent, const DirCache::iterator& pIter); 127 128 public: 129 // Since StringMapIterator has no default constructor, we also have none. 130 DirIterator(const DirIterator& X); 131 ~DirIterator(); 132 DirIterator& operator=(const DirIterator& pCopy); 133 134 DirIterator& operator++(); 135 DirIterator operator++(int); 136 137 Path* generic_path(); 138 139 Path* path(); 140 const Path* path() const; 141 142 bool operator==(const DirIterator& y) const; 143 bool operator!=(const DirIterator& y) const; 144 145 private: 146 Directory* m_pParent; // get handler 147 DirCache::iterator m_Iter; // for full situation 148 DirCache::entry_type* m_pEntry; 149 }; 150 151 } // namespace fs 152 } // namespace sys 153 } // namespace mcld 154 155 #endif // MCLD_SUPPORT_DIRECTORY_H_ 156