Home | History | Annotate | Download | only in Support
      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
     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