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
28namespace Poco {
29
30
31class ChildrenFirstTraverse;
32class SiblingsFirstTraverse;
33
34
35template<class TTraverseStrategy = ChildrenFirstTraverse>
36class RecursiveDirectoryIteratorImpl
37{
38public:
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
97private:
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