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