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