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_DIRECTORY_H 10 #define MCLD_DIRECTORY_H 11 #ifdef ENABLE_UNITTEST 12 #include <gtest.h> 13 #endif 14 15 #include <cstddef> 16 17 #include "mcld/ADT/TypeTraits.h" 18 #include "mcld/Support/FileSystem.h" 19 #include "mcld/Support/Path.h" 20 #include "mcld/Support/PathCache.h" 21 #include <llvm/Support/Allocator.h> 22 23 24 namespace mcld { 25 namespace sys { 26 namespace fs { 27 28 class DirIterator; 29 30 /** \class Directory 31 * \brief A Directory object stores a Path object, a FileStatus object for 32 * non-symbolic link status, and a FileStatus object for symbolic link 33 * status. The FileStatus objects act as value caches. 34 */ 35 class Directory 36 { 37 friend mcld::sys::fs::PathCache::entry_type* detail::bring_one_into_cache(DirIterator& pIter); 38 friend void detail::open_dir(Directory& pDir); 39 friend void detail::close_dir(Directory& pDir); 40 private: 41 friend class DirIterator; 42 43 public: 44 typedef DirIterator iterator; 45 46 public: 47 /// default constructor 48 Directory(); 49 50 /// constructor - a directory whose path is pPath 51 explicit Directory(const Path& pPath, 52 FileStatus st = FileStatus(), 53 FileStatus symlink_st = FileStatus()); 54 55 /// copy constructor 56 /// when a copying construction happens, the cache is not copied. 57 Directory(const Directory& pCopy); 58 59 /// assignment 60 /// When an assignment occurs, the cache is clear. 61 Directory& operator=(const Directory& pCopy); 62 63 /// destructor, inheritable. 64 virtual ~Directory(); 65 66 /// Since we have default construtor, we must provide assign. 67 void assign(const Path& pPath, 68 FileStatus st = FileStatus(), 69 FileStatus symlink_st = FileStatus()); 70 71 /// clear - clear the cache and close the directory handler 72 void clear(); 73 74 bool isGood() const; 75 76 /// path - the path of the directory 77 const Path& path() const 78 { 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 { 111 friend mcld::sys::fs::PathCache::entry_type* detail::bring_one_into_cache(DirIterator& pIter); 112 friend class Directory; 113 public: 114 typedef mcld::sys::fs::PathCache DirCache; 115 116 public: 117 typedef Directory value_type; 118 typedef ConstTraits<Directory> const_traits; 119 typedef NonConstTraits<Directory> non_const_traits; 120 typedef std::input_iterator_tag iterator_category; 121 typedef size_t size_type; 122 typedef ptrdiff_t difference_type; 123 124 private: 125 explicit DirIterator(Directory* pParent, 126 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 of fs 152 } // namespace of sys 153 } // namespace of mcld 154 155 #endif 156