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 <llvm/Support/Allocator.h>
     16 #include <cstddef>
     17 
     18 #include "PathCache.h"
     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 {
     33 friend mcld::sys::fs::PathCache::entry_type* detail::bring_one_into_cache(DirIterator& pIter);
     34 friend void detail::open_dir(Directory& pDir);
     35 friend void detail::close_dir(Directory& pDir);
     36 private:
     37   friend class DirIterator;
     38 
     39 public:
     40   typedef DirIterator iterator;
     41 
     42 public:
     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 
     85 protected:
     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  */
    105 class DirIterator
    106 {
    107 friend mcld::sys::fs::PathCache::entry_type* detail::bring_one_into_cache(DirIterator& pIter);
    108 friend class Directory;
    109 public:
    110   typedef mcld::sys::fs::PathCache            DirCache;
    111 
    112 public:
    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 
    120 private:
    121   explicit DirIterator(Directory* pParent,
    122                        const DirCache::iterator& pIter);
    123 
    124 public:
    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 
    141 private:
    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