Directory.h revision f33f6de54db174aa679a4b6d1e040d37e95541c0
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#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 <llvm/Support/Allocator.h>
19#include <cstddef>
20
21#include "PathCache.h"
22
23namespace mcld {
24namespace sys {
25namespace fs {
26
27class 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 */
34class Directory
35{
36friend mcld::sys::fs::PathCache::entry_type* detail::bring_one_into_cache(DirIterator& pIter);
37friend void detail::open_dir(Directory& pDir);
38friend void detail::close_dir(Directory& pDir);
39private:
40  friend class DirIterator;
41
42public:
43  typedef DirIterator iterator;
44
45public:
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
88protected:
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 */
108class DirIterator
109{
110friend mcld::sys::fs::PathCache::entry_type* detail::bring_one_into_cache(DirIterator& pIter);
111friend class Directory;
112public:
113  typedef mcld::sys::fs::PathCache            DirCache;
114
115public:
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
123private:
124  explicit DirIterator(Directory* pParent,
125                       const DirCache::iterator& pIter);
126
127public:
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
144private:
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