RecursiveDirectoryIterator.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  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. // Permission is hereby granted, free of charge, to any person or organization
  16. // obtaining a copy of the software and accompanying documentation covered by
  17. // this license (the "Software") to use, reproduce, display, distribute,
  18. // execute, and transmit the Software, and to prepare derivative works of the
  19. // Software, and to permit third-parties to whom the Software is furnished to
  20. // do so, all subject to the following:
  21. //
  22. // The copyright notices in the Software and this entire statement, including
  23. // the above license grant, this restriction and the following disclaimer,
  24. // must be included in all copies of the Software, in whole or in part, and
  25. // all derivative works of the Software, unless such copies or derivative
  26. // works are solely in the form of machine-executable object code generated by
  27. // a source language processor.
  28. //
  29. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  30. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  31. // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
  32. // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
  33. // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
  34. // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  35. // DEALINGS IN THE SOFTWARE.
  36. //
  37. #ifndef Foundation_RecursiveDirectoryIterator_INCLUDE
  38. #define Foundation_RecursiveDirectoryIterator_INCLUDE
  39. #include "Poco/Foundation.h"
  40. #include "Poco/File.h"
  41. #include "Poco/Path.h"
  42. #include "Poco/RecursiveDirectoryIteratorImpl.h"
  43. #include "Poco/RecursiveDirectoryIteratorStrategies.h"
  44. namespace Poco
  45. {
  46. class DirectoryIterator;
  47. template<class TTravStr>
  48. class RecursiveDirectoryIteratorImpl;
  49. template<class TTravStr = ChildrenFirstTraverse>
  50. class RecursiveDirectoryIterator
  51. /// The RecursiveDirectoryIterator class is used to enumerate
  52. /// all files in a directory and its subdirectories.
  53. ///
  54. /// RecursiveDirectoryIterator has some limitations:
  55. /// * only forward iteration (++) is supported
  56. /// * an iterator copied from another one will always
  57. /// point to the same file as the original iterator,
  58. /// even is the original iterator has been advanced
  59. /// (all copies of an iterator share their state with
  60. /// the original iterator)
  61. ///
  62. /// The class can follow different traversal strategies:
  63. /// * depth-first strategy;
  64. /// * siblings-first strategy.
  65. /// The stategies are set by template parameter.
  66. /// There are two corresponding typedefs:
  67. /// * SimpleRecursiveDirectoryIterator;
  68. /// * SiblingsFirstRecursiveDirectoryIterator.
  69. ///
  70. /// The depth of traversal can be limited by constructor
  71. /// parameter maxDepth (which sets the infinite depth by default).
  72. {
  73. public:
  74. typedef RecursiveDirectoryIterator<TTravStr> MyType;
  75. enum
  76. {
  77. D_INFINITE = 0
  78. };
  79. /// Constant for infinite traverse depth.
  80. RecursiveDirectoryIterator()
  81. /// Creates the end iterator.
  82. : _pImpl(0)
  83. {
  84. }
  85. RecursiveDirectoryIterator(const std::string& path, UInt16 maxDepth = D_INFINITE);
  86. /// Creates a recursive directory iterator for the given path.
  87. RecursiveDirectoryIterator(const MyType& iterator)
  88. /// Creates a copy of another recursive directory iterator.
  89. : _pImpl(iterator._pImpl), _path(iterator._path), _file(iterator._file)
  90. {
  91. }
  92. RecursiveDirectoryIterator(const DirectoryIterator& iterator, UInt16 maxDepth = D_INFINITE)
  93. /// Creates a recursive directory iterator for the path of
  94. /// non-recursive directory iterator.
  95. : _pImpl(new ImplType(iterator->path(), maxDepth)), _path(Path(_pImpl->get())), _file(_path)
  96. {
  97. }
  98. RecursiveDirectoryIterator(const File& file, UInt16 maxDepth = D_INFINITE)
  99. /// Creates a recursive directory iterator for the given path.
  100. : _pImpl(new ImplType(file.path(), maxDepth)), _path(Path(_pImpl->get())), _file(_path)
  101. {
  102. }
  103. RecursiveDirectoryIterator(const Path& path, UInt16 maxDepth = D_INFINITE)
  104. /// Creates a recursive directory iterator for the given path.
  105. : _pImpl(new ImplType(path.toString(), maxDepth)), _path(Path(_pImpl->get())), _file(_path)
  106. {
  107. }
  108. ~RecursiveDirectoryIterator()
  109. /// Destroys the DirectoryIterator.
  110. {
  111. if (_pImpl)
  112. _pImpl->release();
  113. }
  114. const std::string& name() const
  115. /// Returns the current filename.
  116. {
  117. return _path.getFileName();
  118. }
  119. const Poco::Path& path() const
  120. /// Returns the current path.
  121. {
  122. return _path;
  123. }
  124. UInt16 depth() const
  125. /// Depth of recursion (counting from 1).
  126. {
  127. return _pImpl->depth();
  128. }
  129. UInt16 maxDepth() const
  130. /// Max depth of recursion (counting from 1).
  131. {
  132. return _pImpl->maxDepth();
  133. }
  134. MyType& operator =(const MyType& it)
  135. {
  136. if (_pImpl)
  137. _pImpl->release();
  138. _pImpl = it._pImpl;
  139. if (_pImpl)
  140. {
  141. _pImpl->duplicate();
  142. _path = it._path;
  143. _file = _path;
  144. }
  145. return *this;
  146. }
  147. MyType& operator =(const File& file)
  148. {
  149. if (_pImpl)
  150. _pImpl->release();
  151. _pImpl = new ImplType(file.path());
  152. _path = Path(_pImpl->get());
  153. _file = _path;
  154. return *this;
  155. }
  156. MyType& operator =(const Path& path)
  157. {
  158. if (_pImpl)
  159. _pImpl->release();
  160. _pImpl = new ImplType(path.toString());
  161. _path = Path(_pImpl->get());
  162. _file = _path;
  163. return *this;
  164. }
  165. MyType& operator =(const std::string& path)
  166. {
  167. if (_pImpl)
  168. _pImpl->release();
  169. _pImpl = new ImplType(path);
  170. _path = Path(_pImpl->get());
  171. _file = _path;
  172. return *this;
  173. }
  174. MyType& operator ++()
  175. {
  176. if (_pImpl)
  177. {
  178. _path = Path(_pImpl->next());
  179. _file = _path;
  180. }
  181. return *this;
  182. }
  183. const File& operator *() const
  184. {
  185. return _file;
  186. }
  187. File& operator *()
  188. {
  189. return _file;
  190. }
  191. const File* operator ->() const
  192. {
  193. return &_file;
  194. }
  195. File* operator ->()
  196. {
  197. return &_file;
  198. }
  199. template<class T1, class T2>
  200. friend inline bool operator ==(const RecursiveDirectoryIterator<T1>& a, const RecursiveDirectoryIterator<T2>& b);
  201. template<class T1, class T2>
  202. friend inline bool operator !=(const RecursiveDirectoryIterator<T1>& a, const RecursiveDirectoryIterator<T2>& b);
  203. private:
  204. typedef RecursiveDirectoryIteratorImpl<TTravStr> ImplType;
  205. ImplType* _pImpl;
  206. Path _path;
  207. File _file;
  208. };
  209. //
  210. // friend comparsion operators
  211. //
  212. template<class T1, class T2>
  213. inline bool operator ==(const RecursiveDirectoryIterator<T1>& a, const RecursiveDirectoryIterator<T2>& b)
  214. {
  215. return a.path().toString() == b.path().toString();;
  216. }
  217. template<class T1, class T2>
  218. inline bool operator !=(const RecursiveDirectoryIterator<T1>& a, const RecursiveDirectoryIterator<T2>& b)
  219. {
  220. return a.path().toString() != b.path().toString();;
  221. }
  222. //
  223. // exported instances
  224. //
  225. template class Foundation_API
  226. RecursiveDirectoryIterator<ChildrenFirstTraverse> ;
  227. template class Foundation_API
  228. RecursiveDirectoryIterator<SiblingsFirstTraverse> ;
  229. //
  230. // typedefs
  231. //
  232. typedef RecursiveDirectoryIterator<ChildrenFirstTraverse> SimpleRecursiveDirectoryIterator;
  233. typedef RecursiveDirectoryIterator<SiblingsFirstTraverse> SiblingsFirstRecursiveDirectoryIterator;
  234. } // namespace Poco
  235. #endif // Foundation_RecursiveDirectoryIterator_INCLUDE