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
20namespace mcld {
21namespace sys {
22namespace fs {
23
24class 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 */
31class Directory
32{
33friend mcld::sys::fs::PathCache::entry_type* detail::bring_one_into_cache(DirIterator& pIter);
34friend void detail::open_dir(Directory& pDir);
35friend void detail::close_dir(Directory& pDir);
36private:
37  friend class DirIterator;
38
39public:
40  typedef DirIterator iterator;
41
42public:
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
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
85protected:
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 */
105class DirIterator
106{
107friend mcld::sys::fs::PathCache::entry_type* detail::bring_one_into_cache(DirIterator& pIter);
108friend class Directory;
109public:
110  typedef mcld::sys::fs::PathCache            DirCache;
111
112public:
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
120private:
121  explicit DirIterator(Directory* pParent,
122                       const DirCache::iterator& pIter);
123
124public:
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
141private:
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