1 | // |
2 | // RecursiveDirectoryIteratorImpl.h |
3 | // |
4 | // Library: Foundation |
5 | // Package: Filesystem |
6 | // Module: RecursiveDirectoryIterator |
7 | // |
8 | // Definition of the RecursiveDirectoryIteratorImpl class. |
9 | // |
10 | // Copyright (c) 2012, Applied Informatics Software Engineering GmbH. |
11 | // and Contributors. |
12 | // |
13 | // SPDX-License-Identifier: BSL-1.0 |
14 | // |
15 | |
16 | |
17 | #ifndef Foundation_RecursiveDirectoryIteratorImpl_INCLUDED |
18 | #define Foundation_RecursiveDirectoryIteratorImpl_INCLUDED |
19 | |
20 | |
21 | #include "Poco/Foundation.h" |
22 | #include "Poco/DirectoryIteratorStrategy.h" |
23 | #include "Poco/Delegate.h" |
24 | #include <stack> |
25 | #include <functional> |
26 | |
27 | |
28 | namespace Poco { |
29 | |
30 | |
31 | class ChildrenFirstTraverse; |
32 | class SiblingsFirstTraverse; |
33 | |
34 | |
35 | template<class TTraverseStrategy = ChildrenFirstTraverse> |
36 | class RecursiveDirectoryIteratorImpl |
37 | { |
38 | public: |
39 | enum |
40 | { |
41 | D_INFINITE = 0 /// Special value for infinite traverse depth. |
42 | }; |
43 | |
44 | RecursiveDirectoryIteratorImpl(const std::string& path, UInt16 maxDepth = D_INFINITE) |
45 | : _maxDepth(maxDepth), _traverseStrategy(std::ptr_fun(depthFun), _maxDepth), _isFinished(false), _rc(1) |
46 | { |
47 | _itStack.push(DirectoryIterator(path)); |
48 | _current = _itStack.top()->path(); |
49 | } |
50 | |
51 | ~RecursiveDirectoryIteratorImpl() |
52 | { |
53 | } |
54 | |
55 | inline void duplicate() |
56 | { |
57 | ++_rc; |
58 | } |
59 | |
60 | inline void release() |
61 | { |
62 | if (--_rc == 0) |
63 | delete this; |
64 | } |
65 | |
66 | inline UInt16 depth() const |
67 | { |
68 | return depthFun(_itStack); |
69 | } |
70 | |
71 | inline UInt16 maxDepth() const |
72 | { |
73 | return _maxDepth; |
74 | } |
75 | |
76 | inline const std::string& get() const |
77 | { |
78 | return _current; |
79 | } |
80 | |
81 | template <typename T> |
82 | void onError(T& obj, void (T::*pCB)(const void*, const std::string&)) |
83 | { |
84 | _traverseStrategy.traverseError += delegate(&obj, pCB); |
85 | } |
86 | |
87 | const std::string& next() |
88 | { |
89 | if (_isFinished) |
90 | return _current; |
91 | |
92 | _current = _traverseStrategy.next(&_itStack, &_isFinished); |
93 | |
94 | return _current; |
95 | } |
96 | |
97 | private: |
98 | typedef std::stack<DirectoryIterator> Stack; |
99 | |
100 | static UInt16 depthFun(const Stack& stack) |
101 | /// Function which implements the logic of determining |
102 | /// recursion depth. |
103 | { |
104 | return static_cast<Poco::UInt16>(stack.size()); |
105 | } |
106 | |
107 | UInt16 _maxDepth; |
108 | TTraverseStrategy _traverseStrategy; |
109 | bool _isFinished; |
110 | Stack _itStack; |
111 | std::string _current; |
112 | int _rc; |
113 | }; |
114 | |
115 | |
116 | } // namespace Poco |
117 | |
118 | |
119 | #endif // Foundation_RecursiveDirectoryIteratorImpl_INCLUDED |
120 | |