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