Directory.h revision f767be5432ccac097334be48698e48621d730190
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 <cstddef>
16
17#include "mcld/ADT/TypeTraits.h"
18#include "mcld/Support/FileSystem.h"
19#include "mcld/Support/Path.h"
20#include "mcld/Support/PathCache.h"
21#include <llvm/Support/Allocator.h>
22
23
24namespace mcld {
25namespace sys {
26namespace fs {
27
28class DirIterator;
29
30/** \class Directory
31 *  \brief A Directory object stores a Path object, a FileStatus object for
32 *   non-symbolic link status, and a FileStatus object for symbolic link
33 *   status. The FileStatus objects act as value caches.
34 */
35class Directory
36{
37friend mcld::sys::fs::PathCache::entry_type* detail::bring_one_into_cache(DirIterator& pIter);
38friend void detail::open_dir(Directory& pDir);
39friend void detail::close_dir(Directory& pDir);
40private:
41  friend class DirIterator;
42
43public:
44  typedef DirIterator iterator;
45
46public:
47  /// default constructor
48  Directory();
49
50  /// constructor - a directory whose path is pPath
51  explicit Directory(const Path& pPath,
52                     FileStatus st = FileStatus(),
53                     FileStatus symlink_st = FileStatus());
54
55  /// copy constructor
56  /// when a copying construction happens, the cache is not copied.
57  Directory(const Directory& pCopy);
58
59  /// assignment
60  /// When an assignment occurs, the cache is clear.
61  Directory& operator=(const Directory& pCopy);
62
63  /// destructor, inheritable.
64  virtual ~Directory();
65
66  /// Since we have default construtor, we must provide assign.
67  void assign(const Path& pPath,
68              FileStatus st = FileStatus(),
69              FileStatus symlink_st = FileStatus());
70
71  /// clear - clear the cache and close the directory handler
72  void clear();
73
74  bool isGood() const;
75
76  /// path - the path of the directory
77  const Path& path() const
78  { 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
89protected:
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{
111friend mcld::sys::fs::PathCache::entry_type* detail::bring_one_into_cache(DirIterator& pIter);
112friend class Directory;
113public:
114  typedef mcld::sys::fs::PathCache            DirCache;
115
116public:
117  typedef Directory                       value_type;
118  typedef ConstTraits<Directory>          const_traits;
119  typedef NonConstTraits<Directory>       non_const_traits;
120  typedef std::input_iterator_tag         iterator_category;
121  typedef size_t                          size_type;
122  typedef ptrdiff_t                       difference_type;
123
124private:
125  explicit DirIterator(Directory* pParent,
126                       const DirCache::iterator& pIter);
127
128public:
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
145private:
146  Directory* m_pParent; // get handler
147  DirCache::iterator m_Iter; // for full situation
148  DirCache::entry_type* m_pEntry;
149};
150
151} // namespace of fs
152} // namespace of sys
153} // namespace of mcld
154
155#endif
156