15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- Directory.h --------------------------------------------------------===//
25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//                     The MCLinker Project
45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source
65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details.
75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//
85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===//
937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#ifndef MCLD_SUPPORT_DIRECTORY_H_
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define MCLD_SUPPORT_DIRECTORY_H_
1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/ADT/TypeTraits.h"
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/FileSystem.h"
1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/Path.h"
1537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/PathCache.h"
165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/Allocator.h>
18affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <cstddef>
195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld {
215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace sys {
225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace fs {
235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass DirIterator;
255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/** \class Directory
275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  \brief A Directory object stores a Path object, a FileStatus object for
285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *   non-symbolic link status, and a FileStatus object for symbolic link
295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *   status. The FileStatus objects act as value caches.
305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */
3137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass Directory {
3237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  friend mcld::sys::fs::PathCache::entry_type* detail::bring_one_into_cache(
3337b74a387bb3993387029859c2d9d051c41c724eStephen Hines      DirIterator& pIter);
3437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  friend void detail::open_dir(Directory& pDir);
3537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  friend void detail::close_dir(Directory& pDir);
3637b74a387bb3993387029859c2d9d051c41c724eStephen Hines
3737b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  friend class DirIterator;
395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4037b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  typedef DirIterator iterator;
425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
4337b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// default constructor
455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Directory();
465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// constructor - a directory whose path is pPath
485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  explicit Directory(const Path& pPath,
495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     FileStatus st = FileStatus(),
505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao                     FileStatus symlink_st = FileStatus());
515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
5237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  explicit Directory(const char* pPath,
5337b74a387bb3993387029859c2d9d051c41c724eStephen Hines                     FileStatus st = FileStatus(),
5437b74a387bb3993387029859c2d9d051c41c724eStephen Hines                     FileStatus symlink_st = FileStatus());
5537b74a387bb3993387029859c2d9d051c41c724eStephen Hines
565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// copy constructor
575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// when a copying construction happens, the cache is not copied.
585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Directory(const Directory& pCopy);
595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// assignment
615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// When an assignment occurs, the cache is clear.
625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Directory& operator=(const Directory& pCopy);
635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// destructor, inheritable.
655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  virtual ~Directory();
665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// Since we have default construtor, we must provide assign.
685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void assign(const Path& pPath,
695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              FileStatus st = FileStatus(),
705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao              FileStatus symlink_st = FileStatus());
715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// clear - clear the cache and close the directory handler
735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  void clear();
745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool isGood() const;
765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  /// path - the path of the directory
7837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  const Path& path() const { return m_Path; }
795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  FileStatus status() const;
815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  FileStatus symlinkStatus() const;
825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // -----  iterators  ----- //
845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // While the iterators move, the direcotry is modified.
855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Thus, we only provide non-constant iterator.
865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  iterator begin();
875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  iterator end();
885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
8937b74a387bb3993387029859c2d9d051c41c724eStephen Hines protected:
905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  mcld::sys::fs::Path m_Path;
915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  mutable FileStatus m_FileStatus;
925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  mutable FileStatus m_SymLinkStatus;
935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  intptr_t m_Handler;
945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // the cache of directory
955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  mcld::sys::fs::PathCache m_Cache;
965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool m_CacheFull;
975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/** \class DirIterator
1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  \brief A DirIterator object can traverse all entries in a Directory
1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *
1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  DirIterator will open the directory and add entry into Directory::m_Cache
1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  DirIterator() is the end of a directory.
1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  If the end of the directory elements is reached, the iterator becomes
1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  equal to the end iterator value - DirIterator().
1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *
1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao *  @see Directory
1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao */
10937b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass DirIterator {
11037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  friend mcld::sys::fs::PathCache::entry_type* detail::bring_one_into_cache(
11137b74a387bb3993387029859c2d9d051c41c724eStephen Hines      DirIterator& pIter);
11237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  friend class Directory;
11337b74a387bb3993387029859c2d9d051c41c724eStephen Hines
11437b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
11537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef mcld::sys::fs::PathCache DirCache;
11637b74a387bb3993387029859c2d9d051c41c724eStephen Hines
11737b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
11837b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef Directory value_type;
11937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef ConstTraits<Directory> const_traits;
12037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef NonConstTraits<Directory> non_const_traits;
12137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef std::input_iterator_tag iterator_category;
12237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef size_t size_type;
12337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef ptrdiff_t difference_type;
12437b74a387bb3993387029859c2d9d051c41c724eStephen Hines
12537b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
12637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  explicit DirIterator(Directory* pParent, const DirCache::iterator& pIter);
12737b74a387bb3993387029859c2d9d051c41c724eStephen Hines
12837b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  // Since StringMapIterator has no default constructor, we also have none.
13037b74a387bb3993387029859c2d9d051c41c724eStephen Hines  DirIterator(const DirIterator& X);
1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  ~DirIterator();
1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  DirIterator& operator=(const DirIterator& pCopy);
1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  DirIterator& operator++();
1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  DirIterator operator++(int);
1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Path* generic_path();
1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  Path* path();
1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  const Path* path() const;
1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool operator==(const DirIterator& y) const;
1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  bool operator!=(const DirIterator& y) const;
1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
14537b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
14637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  Directory* m_pParent;       // get handler
14737b74a387bb3993387029859c2d9d051c41c724eStephen Hines  DirCache::iterator m_Iter;  // for full situation
1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao  DirCache::entry_type* m_pEntry;
1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao};
1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
15137b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace fs
15237b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace sys
15337b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao
15537b74a387bb3993387029859c2d9d051c41c724eStephen Hines#endif  // MCLD_SUPPORT_DIRECTORY_H_
156