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 <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 
     24 namespace mcld {
     25 namespace sys {
     26 namespace fs {
     27 
     28 class 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  */
     35 class Directory
     36 {
     37 friend mcld::sys::fs::PathCache::entry_type* detail::bring_one_into_cache(DirIterator& pIter);
     38 friend void detail::open_dir(Directory& pDir);
     39 friend void detail::close_dir(Directory& pDir);
     40 private:
     41   friend class DirIterator;
     42 
     43 public:
     44   typedef DirIterator iterator;
     45 
     46 public:
     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 
     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 {
    111 friend mcld::sys::fs::PathCache::entry_type* detail::bring_one_into_cache(DirIterator& pIter);
    112 friend class Directory;
    113 public:
    114   typedef mcld::sys::fs::PathCache            DirCache;
    115 
    116 public:
    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 
    124 private:
    125   explicit DirIterator(Directory* pParent,
    126                        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 of fs
    152 } // namespace of sys
    153 } // namespace of mcld
    154 
    155 #endif
    156