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