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
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  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
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 */
109class 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