RecursiveDirectoryIterator.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. //
  2. // RecursiveDirectoryIterator.h
  3. //
  4. // $Id$
  5. //
  6. // Library: Foundation
  7. // Package: Filesystem
  8. // Module: RecursiveDirectoryIterator
  9. //
  10. // Definition of the RecursiveDirectoryIterator class.
  11. //
  12. // Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
  13. // and Contributors.
  14. //
  15. // SPDX-License-Identifier: BSL-1.0
  16. //
  17. #ifndef Foundation_RecursiveDirectoryIterator_INCLUDED
  18. #define Foundation_RecursiveDirectoryIterator_INCLUDED
  19. #include "Poco/Foundation.h"
  20. #include "Poco/File.h"
  21. #include "Poco/Path.h"
  22. #include "Poco/RecursiveDirectoryIteratorImpl.h"
  23. #include "Poco/DirectoryIteratorStrategy.h"
  24. namespace Poco {
  25. class DirectoryIterator;
  26. template<class TTravStr>
  27. class RecursiveDirectoryIteratorImpl;
  28. template<class TTravStr = ChildrenFirstTraverse>
  29. class RecursiveDirectoryIterator
  30. /// The RecursiveDirectoryIterator class is used to enumerate
  31. /// all files in a directory and its subdirectories.
  32. ///
  33. /// RecursiveDirectoryIterator has some limitations:
  34. /// * only forward iteration (++) is supported
  35. /// * an iterator copied from another one will always
  36. /// point to the same file as the original iterator,
  37. /// even is the original iterator has been advanced
  38. /// (all copies of an iterator share their state with
  39. /// the original iterator)
  40. ///
  41. /// The class can follow different traversal strategies:
  42. /// * depth-first strategy;
  43. /// * siblings-first strategy.
  44. /// The stategies are set by template parameter.
  45. /// There are two corresponding typedefs:
  46. /// * SimpleRecursiveDirectoryIterator;
  47. /// * SiblingsFirstRecursiveDirectoryIterator.
  48. ///
  49. /// The depth of traversal can be limited by constructor
  50. /// parameter maxDepth (which sets the infinite depth by default).
  51. {
  52. public:
  53. typedef RecursiveDirectoryIterator<TTravStr> MyType;
  54. enum
  55. {
  56. D_INFINITE = 0
  57. };
  58. /// Constant for infinite traverse depth.
  59. RecursiveDirectoryIterator()
  60. /// Creates the end iterator.
  61. : _pImpl(0)
  62. {
  63. }
  64. RecursiveDirectoryIterator(const std::string& path, UInt16 maxDepth = D_INFINITE);
  65. /// Creates a recursive directory iterator for the given path.
  66. RecursiveDirectoryIterator(const MyType& iterator)
  67. /// Creates a copy of another recursive directory iterator.
  68. : _pImpl(iterator._pImpl), _path(iterator._path), _file(iterator._file)
  69. {
  70. }
  71. RecursiveDirectoryIterator(const DirectoryIterator& iterator, UInt16 maxDepth = D_INFINITE)
  72. /// Creates a recursive directory iterator for the path of
  73. /// non-recursive directory iterator.
  74. : _pImpl(new ImplType(iterator->path(), maxDepth)), _path(Path(_pImpl->get())), _file(_path)
  75. {
  76. }
  77. RecursiveDirectoryIterator(const File& file, UInt16 maxDepth = D_INFINITE)
  78. /// Creates a recursive directory iterator for the given path.
  79. : _pImpl(new ImplType(file.path(), maxDepth)), _path(Path(_pImpl->get())), _file(_path)
  80. {
  81. }
  82. RecursiveDirectoryIterator(const Path& path, UInt16 maxDepth = D_INFINITE)
  83. /// Creates a recursive directory iterator for the given path.
  84. : _pImpl(new ImplType(path.toString(), maxDepth)), _path(Path(_pImpl->get())), _file(_path)
  85. {
  86. }
  87. ~RecursiveDirectoryIterator()
  88. /// Destroys the DirectoryIterator.
  89. {
  90. if (_pImpl)
  91. _pImpl->release();
  92. }
  93. const std::string& name() const
  94. /// Returns the current filename.
  95. {
  96. return _path.getFileName();
  97. }
  98. const Poco::Path& path() const
  99. /// Returns the current path.
  100. {
  101. return _path;
  102. }
  103. UInt16 depth() const
  104. /// Depth of recursion (counting from 1).
  105. {
  106. return _pImpl->depth();
  107. }
  108. UInt16 maxDepth() const
  109. /// Max depth of recursion (counting from 1).
  110. {
  111. return _pImpl->maxDepth();
  112. }
  113. MyType& operator = (const MyType& it)
  114. {
  115. if (_pImpl)
  116. _pImpl->release();
  117. _pImpl = it._pImpl;
  118. if (_pImpl)
  119. {
  120. _pImpl->duplicate();
  121. _path = it._path;
  122. _file = _path;
  123. }
  124. return *this;
  125. }
  126. MyType& operator = (const File& file)
  127. {
  128. if (_pImpl)
  129. _pImpl->release();
  130. _pImpl = new ImplType(file.path());
  131. _path = Path(_pImpl->get());
  132. _file = _path;
  133. return *this;
  134. }
  135. MyType& operator = (const Path& path)
  136. {
  137. if (_pImpl)
  138. _pImpl->release();
  139. _pImpl = new ImplType(path.toString());
  140. _path = Path(_pImpl->get());
  141. _file = _path;
  142. return *this;
  143. }
  144. MyType& operator = (const std::string& path)
  145. {
  146. if (_pImpl)
  147. _pImpl->release();
  148. _pImpl = new ImplType(path);
  149. _path = Path(_pImpl->get());
  150. _file = _path;
  151. return *this;
  152. }
  153. MyType& operator ++ ()
  154. {
  155. if (_pImpl)
  156. {
  157. _path = Path(_pImpl->next());
  158. _file = _path;
  159. }
  160. return *this;
  161. }
  162. const File& operator * () const
  163. {
  164. return _file;
  165. }
  166. File& operator *()
  167. {
  168. return _file;
  169. }
  170. const File* operator -> () const
  171. {
  172. return &_file;
  173. }
  174. File* operator -> ()
  175. {
  176. return &_file;
  177. }
  178. template<class T1, class T2>
  179. friend inline bool operator ==(const RecursiveDirectoryIterator<T1>& a, const RecursiveDirectoryIterator<T2>& b);
  180. template<class T1, class T2>
  181. friend inline bool operator !=(const RecursiveDirectoryIterator<T1>& a, const RecursiveDirectoryIterator<T2>& b);
  182. private:
  183. typedef RecursiveDirectoryIteratorImpl<TTravStr> ImplType;
  184. ImplType* _pImpl;
  185. Path _path;
  186. File _file;
  187. };
  188. //
  189. // friend comparsion operators
  190. //
  191. template<class T1, class T2>
  192. inline bool operator ==(const RecursiveDirectoryIterator<T1>& a, const RecursiveDirectoryIterator<T2>& b)
  193. {
  194. return a.path().toString() == b.path().toString();;
  195. }
  196. template<class T1, class T2>
  197. inline bool operator !=(const RecursiveDirectoryIterator<T1>& a, const RecursiveDirectoryIterator<T2>& b)
  198. {
  199. return a.path().toString() != b.path().toString();;
  200. }
  201. //
  202. // typedefs
  203. //
  204. typedef RecursiveDirectoryIterator<ChildrenFirstTraverse> SimpleRecursiveDirectoryIterator;
  205. typedef RecursiveDirectoryIterator<SiblingsFirstTraverse> SiblingsFirstRecursiveDirectoryIterator;
  206. } // namespace Poco
  207. #endif // Foundation_RecursiveDirectoryIterator_INCLUDED