mirror of
https://github.com/pocoproject/poco.git
synced 2025-04-01 09:24:55 +02:00
parent
ef1c594fb1
commit
8ddba0bcd1
@ -52,7 +52,6 @@ set( BASE_SRCS
|
|||||||
src/DigestEngine.cpp
|
src/DigestEngine.cpp
|
||||||
src/DigestStream.cpp
|
src/DigestStream.cpp
|
||||||
src/DirectoryIterator.cpp
|
src/DirectoryIterator.cpp
|
||||||
src/RecursiveDirectoryIterator.cpp
|
|
||||||
src/RecursiveDirectoryIteratorStrategies.cpp
|
src/RecursiveDirectoryIteratorStrategies.cpp
|
||||||
src/DirectoryWatcher.cpp
|
src/DirectoryWatcher.cpp
|
||||||
src/Environment.cpp
|
src/Environment.cpp
|
||||||
@ -116,8 +115,6 @@ set( BASE_SRCS
|
|||||||
src/RWLock.cpp
|
src/RWLock.cpp
|
||||||
src/Random.cpp
|
src/Random.cpp
|
||||||
src/RandomStream.cpp
|
src/RandomStream.cpp
|
||||||
src/RecursiveDirectoryIterator.cpp
|
|
||||||
src/RecursiveDirectoryIteratorStrategies.cpp
|
|
||||||
src/RefCountedObject.cpp
|
src/RefCountedObject.cpp
|
||||||
src/RegularExpression.cpp
|
src/RegularExpression.cpp
|
||||||
src/RotateStrategy.cpp
|
src/RotateStrategy.cpp
|
||||||
|
@ -21,7 +21,7 @@ objects = ArchiveStrategy Ascii ASCIIEncoding AsyncChannel \
|
|||||||
NestedDiagnosticContext Notification NotificationCenter \
|
NestedDiagnosticContext Notification NotificationCenter \
|
||||||
NotificationQueue PriorityNotificationQueue TimedNotificationQueue \
|
NotificationQueue PriorityNotificationQueue TimedNotificationQueue \
|
||||||
NullStream NumberFormatter NumberParser NumericString AbstractObserver \
|
NullStream NumberFormatter NumberParser NumericString AbstractObserver \
|
||||||
Path PatternFormatter Process PurgeStrategy RWLock Random RandomStream RecursiveDirectoryIterator \
|
Path PatternFormatter Process PurgeStrategy RWLock Random RandomStream \
|
||||||
RecursiveDirectoryIteratorStrategies RegularExpression RefCountedObject Runnable RotateStrategy Condition \
|
RecursiveDirectoryIteratorStrategies RegularExpression RefCountedObject Runnable RotateStrategy Condition \
|
||||||
SHA1Engine Semaphore SharedLibrary SimpleFileChannel \
|
SHA1Engine Semaphore SharedLibrary SimpleFileChannel \
|
||||||
SignalHandler SplitterChannel SortedDirectoryIterator Stopwatch StreamChannel \
|
SignalHandler SplitterChannel SortedDirectoryIterator Stopwatch StreamChannel \
|
||||||
|
@ -109,7 +109,7 @@ public:
|
|||||||
bool operator == (const DirectoryIterator& iterator) const;
|
bool operator == (const DirectoryIterator& iterator) const;
|
||||||
bool operator != (const DirectoryIterator& iterator) const;
|
bool operator != (const DirectoryIterator& iterator) const;
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
Path _path;
|
Path _path;
|
||||||
File _file;
|
File _file;
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
#ifndef Foundation_RecursiveDirectoryIterator_INCLUDE
|
#ifndef Foundation_RecursiveDirectoryIterator_INCLUDE
|
||||||
#define Foundation_RecursiveDirectoryIterator_INCLUDE
|
#define Foundation_RecursiveDirectoryIterator_INCLUDE
|
||||||
|
|
||||||
@ -44,6 +45,7 @@
|
|||||||
#include "Poco/RecursiveDirectoryIteratorImpl.h"
|
#include "Poco/RecursiveDirectoryIteratorImpl.h"
|
||||||
#include "Poco/RecursiveDirectoryIteratorStrategies.h"
|
#include "Poco/RecursiveDirectoryIteratorStrategies.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco
|
namespace Poco
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -54,27 +56,27 @@ class RecursiveDirectoryIteratorImpl;
|
|||||||
|
|
||||||
template<class TTravStr = ChildrenFirstTraverse>
|
template<class TTravStr = ChildrenFirstTraverse>
|
||||||
class RecursiveDirectoryIterator
|
class RecursiveDirectoryIterator
|
||||||
/// The RecursiveDirectoryIterator class is used to enumerate
|
/// The RecursiveDirectoryIterator class is used to enumerate
|
||||||
/// all files in a directory and its subdirectories.
|
/// all files in a directory and its subdirectories.
|
||||||
///
|
///
|
||||||
/// RecursiveDirectoryIterator has some limitations:
|
/// RecursiveDirectoryIterator has some limitations:
|
||||||
/// * only forward iteration (++) is supported
|
/// * only forward iteration (++) is supported
|
||||||
/// * an iterator copied from another one will always
|
/// * an iterator copied from another one will always
|
||||||
/// point to the same file as the original iterator,
|
/// point to the same file as the original iterator,
|
||||||
/// even is the original iterator has been advanced
|
/// even is the original iterator has been advanced
|
||||||
/// (all copies of an iterator share their state with
|
/// (all copies of an iterator share their state with
|
||||||
/// the original iterator)
|
/// the original iterator)
|
||||||
///
|
///
|
||||||
/// The class can follow different traversal strategies:
|
/// The class can follow different traversal strategies:
|
||||||
/// * depth-first strategy;
|
/// * depth-first strategy;
|
||||||
/// * siblings-first strategy.
|
/// * siblings-first strategy.
|
||||||
/// The stategies are set by template parameter.
|
/// The stategies are set by template parameter.
|
||||||
/// There are two corresponding typedefs:
|
/// There are two corresponding typedefs:
|
||||||
/// * SimpleRecursiveDirectoryIterator;
|
/// * SimpleRecursiveDirectoryIterator;
|
||||||
/// * SiblingsFirstRecursiveDirectoryIterator.
|
/// * SiblingsFirstRecursiveDirectoryIterator.
|
||||||
///
|
///
|
||||||
/// The depth of traversal can be limited by constructor
|
/// The depth of traversal can be limited by constructor
|
||||||
/// parameter maxDepth (which sets the infinite depth by default).
|
/// parameter maxDepth (which sets the infinite depth by default).
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef RecursiveDirectoryIterator<TTravStr> MyType;
|
typedef RecursiveDirectoryIterator<TTravStr> MyType;
|
||||||
@ -83,53 +85,150 @@ public:
|
|||||||
{
|
{
|
||||||
D_INFINITE = 0
|
D_INFINITE = 0
|
||||||
};
|
};
|
||||||
/// Constant for infinite traverse depth.
|
/// Constant for infinite traverse depth.
|
||||||
|
|
||||||
RecursiveDirectoryIterator();
|
RecursiveDirectoryIterator()
|
||||||
/// Creates the end iterator.
|
/// Creates the end iterator.
|
||||||
|
: _pImpl(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
RecursiveDirectoryIterator(const std::string& path, UInt16 maxDepth = D_INFINITE);
|
RecursiveDirectoryIterator(const std::string& path, UInt16 maxDepth = D_INFINITE);
|
||||||
/// Creates a recursive directory iterator for the given path.
|
/// Creates a recursive directory iterator for the given path.
|
||||||
|
|
||||||
RecursiveDirectoryIterator(const MyType& iterator);
|
RecursiveDirectoryIterator(const MyType& iterator)
|
||||||
/// Creates a copy of another recursive directory iterator.
|
/// Creates a copy of another recursive directory iterator.
|
||||||
|
: _pImpl(iterator._pImpl), _path(iterator._path), _file(iterator._file)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
RecursiveDirectoryIterator(const DirectoryIterator& iterator, UInt16 maxDepth = D_INFINITE);
|
RecursiveDirectoryIterator(const DirectoryIterator& iterator, UInt16 maxDepth = D_INFINITE)
|
||||||
/// Creates a recursive directory iterator for the path of
|
/// Creates a recursive directory iterator for the path of
|
||||||
/// non-recursive directory iterator.
|
/// non-recursive directory iterator.
|
||||||
|
: _pImpl(new ImplType(iterator->path(), maxDepth)), _path(Path(_pImpl->get())), _file(_path)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
RecursiveDirectoryIterator(const File& file, UInt16 maxDepth = D_INFINITE);
|
RecursiveDirectoryIterator(const File& file, UInt16 maxDepth = D_INFINITE)
|
||||||
/// Creates a recursive directory iterator for the given path.
|
/// Creates a recursive directory iterator for the given path.
|
||||||
|
: _pImpl(new ImplType(file.path(), maxDepth)), _path(Path(_pImpl->get())), _file(_path)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
RecursiveDirectoryIterator(const Path& path, UInt16 maxDepth = D_INFINITE);
|
RecursiveDirectoryIterator(const Path& path, UInt16 maxDepth = D_INFINITE)
|
||||||
/// Creates a recursive directory iterator for the given path.
|
/// Creates a recursive directory iterator for the given path.
|
||||||
|
: _pImpl(new ImplType(path.toString(), maxDepth)), _path(Path(_pImpl->get())), _file(_path)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
~RecursiveDirectoryIterator();
|
|
||||||
/// Destroys the DirectoryIterator.
|
|
||||||
|
|
||||||
const std::string& name() const;
|
~RecursiveDirectoryIterator()
|
||||||
/// Returns the current filename.
|
/// Destroys the DirectoryIterator.
|
||||||
|
{
|
||||||
|
if (_pImpl)
|
||||||
|
_pImpl->release();
|
||||||
|
}
|
||||||
|
|
||||||
const Poco::Path& path() const;
|
const std::string& name() const
|
||||||
/// Returns the current path.
|
/// Returns the current filename.
|
||||||
|
{
|
||||||
|
return _path.getFileName();
|
||||||
|
}
|
||||||
|
|
||||||
UInt16 depth() const;
|
const Poco::Path& path() const
|
||||||
/// Depth of recursion (counting from 1).
|
/// Returns the current path.
|
||||||
|
{
|
||||||
|
return _path;
|
||||||
|
}
|
||||||
|
|
||||||
UInt16 maxDepth() const;
|
UInt16 depth() const
|
||||||
/// Max depth of recursion (counting from 1).
|
/// Depth of recursion (counting from 1).
|
||||||
|
{
|
||||||
|
return _pImpl->depth();
|
||||||
|
}
|
||||||
|
|
||||||
MyType& operator =(const MyType& it);
|
UInt16 maxDepth() const
|
||||||
MyType& operator =(const File& file);
|
/// Max depth of recursion (counting from 1).
|
||||||
MyType& operator =(const Path& path);
|
{
|
||||||
MyType& operator =(const std::string& path);
|
return _pImpl->maxDepth();
|
||||||
|
}
|
||||||
|
|
||||||
MyType& operator ++();
|
|
||||||
|
|
||||||
const File& operator *() const;
|
MyType& operator =(const MyType& it)
|
||||||
File& operator *();
|
{
|
||||||
const File* operator ->() const;
|
if (_pImpl)
|
||||||
File* operator ->();
|
_pImpl->release();
|
||||||
|
_pImpl = it._pImpl;
|
||||||
|
if (_pImpl)
|
||||||
|
{
|
||||||
|
_pImpl->duplicate();
|
||||||
|
_path = it._path;
|
||||||
|
_file = _path;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
MyType& operator =(const File& file)
|
||||||
|
{
|
||||||
|
if (_pImpl)
|
||||||
|
_pImpl->release();
|
||||||
|
_pImpl = new ImplType(file.path());
|
||||||
|
_path = Path(_pImpl->get());
|
||||||
|
_file = _path;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
MyType& operator =(const Path& path)
|
||||||
|
{
|
||||||
|
if (_pImpl)
|
||||||
|
_pImpl->release();
|
||||||
|
_pImpl = new ImplType(path.toString());
|
||||||
|
_path = Path(_pImpl->get());
|
||||||
|
_file = _path;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
MyType& operator =(const std::string& path)
|
||||||
|
{
|
||||||
|
if (_pImpl)
|
||||||
|
_pImpl->release();
|
||||||
|
_pImpl = new ImplType(path);
|
||||||
|
_path = Path(_pImpl->get());
|
||||||
|
_file = _path;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
MyType& operator ++()
|
||||||
|
{
|
||||||
|
if (_pImpl)
|
||||||
|
{
|
||||||
|
_path = Path(_pImpl->next());
|
||||||
|
_file = _path;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const File& operator *() const
|
||||||
|
{
|
||||||
|
return _file;
|
||||||
|
}
|
||||||
|
|
||||||
|
File& operator *()
|
||||||
|
{
|
||||||
|
return _file;
|
||||||
|
}
|
||||||
|
|
||||||
|
const File* operator ->() const
|
||||||
|
{
|
||||||
|
return &_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
File* operator ->()
|
||||||
|
{
|
||||||
|
return &_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T1, class T2>
|
template<class T1, class T2>
|
||||||
friend inline bool operator ==(const RecursiveDirectoryIterator<T1>& a, const RecursiveDirectoryIterator<T2>& b);
|
friend inline bool operator ==(const RecursiveDirectoryIterator<T1>& a, const RecursiveDirectoryIterator<T2>& b);
|
||||||
@ -144,6 +243,7 @@ private:
|
|||||||
File _file;
|
File _file;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// friend comparsion operators
|
// friend comparsion operators
|
||||||
//
|
//
|
||||||
@ -159,172 +259,6 @@ inline bool operator !=(const RecursiveDirectoryIterator<T1>& a, const Recursive
|
|||||||
return a.path().toString() != b.path().toString();;
|
return a.path().toString() != b.path().toString();;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
template<class TTravStr>
|
|
||||||
inline const std::string&
|
|
||||||
RecursiveDirectoryIterator<TTravStr>::name() const
|
|
||||||
{
|
|
||||||
return _path.getFileName();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTravStr>
|
|
||||||
inline const Path&
|
|
||||||
RecursiveDirectoryIterator<TTravStr>::path() const
|
|
||||||
{
|
|
||||||
return _path;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTravStr>
|
|
||||||
inline UInt16 RecursiveDirectoryIterator<TTravStr>::depth() const
|
|
||||||
{
|
|
||||||
return _pImpl->depth();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTravStr>
|
|
||||||
inline UInt16 RecursiveDirectoryIterator<TTravStr>::maxDepth() const
|
|
||||||
{
|
|
||||||
return _pImpl->maxDepth();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTravStr>
|
|
||||||
inline const File&
|
|
||||||
RecursiveDirectoryIterator<TTravStr>::operator *() const
|
|
||||||
{
|
|
||||||
return _file;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTravStr>
|
|
||||||
inline File&
|
|
||||||
RecursiveDirectoryIterator<TTravStr>::operator *()
|
|
||||||
{
|
|
||||||
return _file;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTravStr>
|
|
||||||
inline const File*
|
|
||||||
RecursiveDirectoryIterator<TTravStr>::operator ->() const
|
|
||||||
{
|
|
||||||
return &_file;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTravStr>
|
|
||||||
inline File*
|
|
||||||
RecursiveDirectoryIterator<TTravStr>::operator ->()
|
|
||||||
{
|
|
||||||
return &_file;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// not inlines
|
|
||||||
//
|
|
||||||
template<class TTravStr>
|
|
||||||
RecursiveDirectoryIterator<TTravStr>::RecursiveDirectoryIterator()
|
|
||||||
: _pImpl(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTravStr>
|
|
||||||
RecursiveDirectoryIterator<TTravStr>::RecursiveDirectoryIterator(const std::string& path, UInt16 maxDepth)
|
|
||||||
: _pImpl(new ImplType(path, maxDepth)), _path(Path(_pImpl->get())), _file(_path)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTravStr>
|
|
||||||
RecursiveDirectoryIterator<TTravStr>::RecursiveDirectoryIterator(const MyType& iterator)
|
|
||||||
: _pImpl(iterator._pImpl), _path(iterator._path), _file(iterator._file)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTravStr>
|
|
||||||
RecursiveDirectoryIterator<TTravStr>::RecursiveDirectoryIterator(const DirectoryIterator& iterator, UInt16 maxDepth)
|
|
||||||
: _pImpl(new ImplType(iterator->path(), maxDepth)), _path(Path(_pImpl->get())), _file(_path)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTravStr>
|
|
||||||
RecursiveDirectoryIterator<TTravStr>::RecursiveDirectoryIterator(const File& file, UInt16 maxDepth)
|
|
||||||
: _pImpl(new ImplType(file.path(), maxDepth)), _path(Path(_pImpl->get())), _file(_path)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTravStr>
|
|
||||||
RecursiveDirectoryIterator<TTravStr>::RecursiveDirectoryIterator(const Path& path, UInt16 maxDepth)
|
|
||||||
: _pImpl(new ImplType(path.toString(), maxDepth)), _path(Path(_pImpl->get())), _file(_path)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTravStr>
|
|
||||||
RecursiveDirectoryIterator<TTravStr>::~RecursiveDirectoryIterator()
|
|
||||||
{
|
|
||||||
if (_pImpl)
|
|
||||||
_pImpl->release();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTravStr>
|
|
||||||
RecursiveDirectoryIterator<TTravStr>&
|
|
||||||
RecursiveDirectoryIterator<TTravStr>::operator =(const MyType& it)
|
|
||||||
{
|
|
||||||
if (_pImpl)
|
|
||||||
_pImpl->release();
|
|
||||||
_pImpl = it._pImpl;
|
|
||||||
if (_pImpl)
|
|
||||||
{
|
|
||||||
_pImpl->duplicate();
|
|
||||||
_path = it._path;
|
|
||||||
_file = _path;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTravStr>
|
|
||||||
RecursiveDirectoryIterator<TTravStr>&
|
|
||||||
RecursiveDirectoryIterator<TTravStr>::operator =(const File& file)
|
|
||||||
{
|
|
||||||
if (_pImpl)
|
|
||||||
_pImpl->release();
|
|
||||||
_pImpl = new ImplType(file.path());
|
|
||||||
_path = Path(_pImpl->get());
|
|
||||||
_file = _path;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTravStr>
|
|
||||||
RecursiveDirectoryIterator<TTravStr>&
|
|
||||||
RecursiveDirectoryIterator<TTravStr>::operator =(const Path& path)
|
|
||||||
{
|
|
||||||
if (_pImpl)
|
|
||||||
_pImpl->release();
|
|
||||||
_pImpl = new ImplType(path.toString());
|
|
||||||
_path = Path(_pImpl->get());
|
|
||||||
_file = _path;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTravStr>
|
|
||||||
RecursiveDirectoryIterator<TTravStr>&
|
|
||||||
RecursiveDirectoryIterator<TTravStr>::operator =(const std::string& path)
|
|
||||||
{
|
|
||||||
if (_pImpl)
|
|
||||||
_pImpl->release();
|
|
||||||
_pImpl = new ImplType(path);
|
|
||||||
_path = Path(_pImpl->get());
|
|
||||||
_file = _path;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTravStr>
|
|
||||||
RecursiveDirectoryIterator<TTravStr>&
|
|
||||||
RecursiveDirectoryIterator<TTravStr>::operator ++()
|
|
||||||
{
|
|
||||||
if (_pImpl)
|
|
||||||
{
|
|
||||||
_path = Path(_pImpl->next());
|
|
||||||
_file = _path;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// exported instances
|
// exported instances
|
||||||
@ -334,12 +268,14 @@ RecursiveDirectoryIterator<ChildrenFirstTraverse> ;
|
|||||||
template class Foundation_API
|
template class Foundation_API
|
||||||
RecursiveDirectoryIterator<SiblingsFirstTraverse> ;
|
RecursiveDirectoryIterator<SiblingsFirstTraverse> ;
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// typedefs
|
// typedefs
|
||||||
//
|
//
|
||||||
typedef RecursiveDirectoryIterator<ChildrenFirstTraverse> SimpleRecursiveDirectoryIterator;
|
typedef RecursiveDirectoryIterator<ChildrenFirstTraverse> SimpleRecursiveDirectoryIterator;
|
||||||
typedef RecursiveDirectoryIterator<SiblingsFirstTraverse> SiblingsFirstRecursiveDirectoryIterator;
|
typedef RecursiveDirectoryIterator<SiblingsFirstTraverse> SiblingsFirstRecursiveDirectoryIterator;
|
||||||
|
|
||||||
|
|
||||||
} // namespace Poco
|
} // namespace Poco
|
||||||
|
|
||||||
#endif // Foundation_RecursiveDirectoryIterator_INCLUDE
|
#endif // Foundation_RecursiveDirectoryIterator_INCLUDE
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
#ifndef Foundation_RecursiveDirectoryIteratorImpl_INCLUDE
|
#ifndef Foundation_RecursiveDirectoryIteratorImpl_INCLUDE
|
||||||
#define Foundation_RecursiveDirectoryIteratorImpl_INCLUDE
|
#define Foundation_RecursiveDirectoryIteratorImpl_INCLUDE
|
||||||
|
|
||||||
@ -43,6 +44,7 @@
|
|||||||
#include <stack>
|
#include <stack>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
|
||||||
namespace Poco
|
namespace Poco
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -57,105 +59,72 @@ public:
|
|||||||
{
|
{
|
||||||
D_INFINITE = 0
|
D_INFINITE = 0
|
||||||
};
|
};
|
||||||
/// Constant for infinite traverse depth.
|
/// Constant for infinite traverse depth.
|
||||||
|
|
||||||
RecursiveDirectoryIteratorImpl(const std::string& path, UInt16 maxDepth = D_INFINITE);
|
RecursiveDirectoryIteratorImpl(const std::string& path, UInt16 maxDepth = D_INFINITE)
|
||||||
~RecursiveDirectoryIteratorImpl();
|
: _maxDepth(maxDepth), _traverseStrategy(std::ptr_fun(depthFun), _maxDepth), _isFinished(false), _rc(1)
|
||||||
|
{
|
||||||
|
_itStack.push(DirectoryIterator(path));
|
||||||
|
_current = _itStack.top()->path();
|
||||||
|
}
|
||||||
|
|
||||||
void duplicate();
|
~RecursiveDirectoryIteratorImpl()
|
||||||
void release();
|
{
|
||||||
UInt16 depth() const;
|
}
|
||||||
UInt16 maxDepth() const;
|
|
||||||
|
|
||||||
const std::string& get() const;
|
inline void duplicate()
|
||||||
const std::string& next();
|
{
|
||||||
|
++_rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void release()
|
||||||
|
{
|
||||||
|
if (--_rc == 0)
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline UInt16 depth() const
|
||||||
|
{
|
||||||
|
return depthFun(_itStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline UInt16 maxDepth() const
|
||||||
|
{
|
||||||
|
return _maxDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const std::string& get() const
|
||||||
|
{
|
||||||
|
return _current;
|
||||||
|
}
|
||||||
|
const std::string& next()
|
||||||
|
{
|
||||||
|
if (_isFinished)
|
||||||
|
return _current;
|
||||||
|
|
||||||
|
_current = _traverseStrategy.next(&_itStack, &_isFinished);
|
||||||
|
|
||||||
|
return _current;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::stack<DirectoryIterator> Stack;
|
typedef std::stack<DirectoryIterator> Stack;
|
||||||
|
|
||||||
static UInt16 depthFun(const Stack& stack);
|
static UInt16 depthFun(const Stack& stack)
|
||||||
/// Function which implements the logic of determining
|
/// Function which implements the logic of determining
|
||||||
/// recursion depth.
|
/// recursion depth.
|
||||||
|
{
|
||||||
|
return stack.size();
|
||||||
|
}
|
||||||
|
|
||||||
UInt16 _maxDepth;
|
UInt16 _maxDepth;
|
||||||
TTraverseStrategy _traverseStrategy;
|
TTraverseStrategy _traverseStrategy;
|
||||||
|
|
||||||
bool _isFinished;
|
bool _isFinished;
|
||||||
|
|
||||||
Stack _itStack;
|
Stack _itStack;
|
||||||
std::string _current;
|
std::string _current;
|
||||||
int _rc;
|
int _rc;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
|
||||||
// inlines
|
|
||||||
//
|
|
||||||
template<class TTraverseStrategy>
|
|
||||||
inline void RecursiveDirectoryIteratorImpl<TTraverseStrategy>::duplicate()
|
|
||||||
{
|
|
||||||
++_rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTraverseStrategy>
|
|
||||||
inline void RecursiveDirectoryIteratorImpl<TTraverseStrategy>::release()
|
|
||||||
{
|
|
||||||
if (--_rc == 0)
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTraverseStrategy>
|
|
||||||
inline UInt16 RecursiveDirectoryIteratorImpl<TTraverseStrategy>::depth() const
|
|
||||||
{
|
|
||||||
return depthFun(_itStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTraverseStrategy>
|
|
||||||
inline UInt16 RecursiveDirectoryIteratorImpl<TTraverseStrategy>::maxDepth() const
|
|
||||||
{
|
|
||||||
return _maxDepth;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTraverseStrategy>
|
|
||||||
inline const std::string&
|
|
||||||
RecursiveDirectoryIteratorImpl<TTraverseStrategy>::get() const
|
|
||||||
{
|
|
||||||
return _current;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTraverseStrategy>
|
|
||||||
inline UInt16 RecursiveDirectoryIteratorImpl<TTraverseStrategy>::depthFun(const Stack& stack)
|
|
||||||
{
|
|
||||||
return stack.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// not inlines
|
|
||||||
//
|
|
||||||
template<class TTraverseStrategy>
|
|
||||||
RecursiveDirectoryIteratorImpl<TTraverseStrategy>::RecursiveDirectoryIteratorImpl(const std::string& path, UInt16 maxDepth)
|
|
||||||
: _maxDepth(maxDepth), _traverseStrategy(std::ptr_fun(depthFun), _maxDepth), _isFinished(false)
|
|
||||||
{
|
|
||||||
_itStack.push(DirectoryIterator(path));
|
|
||||||
_current = _itStack.top()->path();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTraverseStrategy>
|
|
||||||
RecursiveDirectoryIteratorImpl<TTraverseStrategy>::~RecursiveDirectoryIteratorImpl()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class TTraverseStrategy>
|
|
||||||
const std::string&
|
|
||||||
RecursiveDirectoryIteratorImpl<TTraverseStrategy>::next()
|
|
||||||
{
|
|
||||||
if (_isFinished)
|
|
||||||
return _current;
|
|
||||||
|
|
||||||
_current = _traverseStrategy.next(&_itStack, &_isFinished);
|
|
||||||
|
|
||||||
return _current;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Poco
|
} // namespace Poco
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
#ifndef Foundation_RecursiveDirectoryIteratorStategies_INCLUDE
|
#ifndef Foundation_RecursiveDirectoryIteratorStategies_INCLUDE
|
||||||
#define Foundation_RecursiveDirectoryIteratorStategies_INCLUDE
|
#define Foundation_RecursiveDirectoryIteratorStategies_INCLUDE
|
||||||
|
|
||||||
@ -44,6 +45,7 @@
|
|||||||
#include <queue>
|
#include <queue>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
|
||||||
namespace Poco
|
namespace Poco
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -57,7 +59,7 @@ public:
|
|||||||
{
|
{
|
||||||
D_INFINITE = 0
|
D_INFINITE = 0
|
||||||
};
|
};
|
||||||
/// Constant for infinite traverse depth.
|
/// Constant for infinite traverse depth.
|
||||||
|
|
||||||
TraverseBase(DepthFunPtr depthDeterminer, UInt16 maxDepth = D_INFINITE);
|
TraverseBase(DepthFunPtr depthDeterminer, UInt16 maxDepth = D_INFINITE);
|
||||||
|
|
||||||
@ -66,7 +68,6 @@ protected:
|
|||||||
|
|
||||||
DepthFunPtr _depthDeterminer;
|
DepthFunPtr _depthDeterminer;
|
||||||
UInt16 _maxDepth;
|
UInt16 _maxDepth;
|
||||||
|
|
||||||
DirectoryIterator _itEnd;
|
DirectoryIterator _itEnd;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -75,6 +76,7 @@ private:
|
|||||||
TraverseBase& operator=(const TraverseBase&);
|
TraverseBase& operator=(const TraverseBase&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class ChildrenFirstTraverse: public TraverseBase
|
class ChildrenFirstTraverse: public TraverseBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -88,6 +90,7 @@ private:
|
|||||||
ChildrenFirstTraverse& operator=(const ChildrenFirstTraverse&);
|
ChildrenFirstTraverse& operator=(const ChildrenFirstTraverse&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class SiblingsFirstTraverse: public TraverseBase
|
class SiblingsFirstTraverse: public TraverseBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -103,6 +106,7 @@ private:
|
|||||||
std::stack<std::queue<std::string> > _dirsStack;
|
std::stack<std::queue<std::string> > _dirsStack;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace Poco
|
} // namespace Poco
|
||||||
|
|
||||||
#endif // Foundation_RecursiveDirectoryIteratorStategies_INCLUDE
|
#endif // Foundation_RecursiveDirectoryIteratorStategies_INCLUDE
|
||||||
|
@ -39,7 +39,6 @@
|
|||||||
#ifndef Foundation_SortedDirectoryIterator_INCLUDED
|
#ifndef Foundation_SortedDirectoryIterator_INCLUDED
|
||||||
#define Foundation_SortedDirectoryIterator_INCLUDED
|
#define Foundation_SortedDirectoryIterator_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/Foundation.h"
|
#include "Poco/Foundation.h"
|
||||||
#include "Poco/File.h"
|
#include "Poco/File.h"
|
||||||
#include "Poco/Path.h"
|
#include "Poco/Path.h"
|
||||||
@ -47,49 +46,47 @@
|
|||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
|
{
|
||||||
|
|
||||||
|
class Foundation_API SortedDirectoryIterator: public DirectoryIterator
|
||||||
class Foundation_API SortedDirectoryIterator : public DirectoryIterator
|
/// The SortedDirectoryIterator class is similar to
|
||||||
/// The SortedDirectoryIterator class is similar to
|
/// DirectoryIterator class, but places directories before files
|
||||||
/// DirectoryIterator class, but places directories before files
|
/// and sorts content alphabetically.
|
||||||
/// and sorts content alphabetically.
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SortedDirectoryIterator();
|
SortedDirectoryIterator();
|
||||||
/// Creates the end iterator.
|
/// Creates the end iterator.
|
||||||
|
|
||||||
SortedDirectoryIterator(const std::string& path);
|
SortedDirectoryIterator(const std::string& path);
|
||||||
/// Creates a directory iterator for the given path.
|
/// Creates a directory iterator for the given path.
|
||||||
|
|
||||||
SortedDirectoryIterator(const DirectoryIterator& iterator);
|
SortedDirectoryIterator(const DirectoryIterator& iterator);
|
||||||
/// Creates a directory iterator for the given path.
|
/// Creates a directory iterator for the given path.
|
||||||
|
|
||||||
SortedDirectoryIterator(const File& file);
|
SortedDirectoryIterator(const File& file);
|
||||||
/// Creates a directory iterator for the given file.
|
/// Creates a directory iterator for the given file.
|
||||||
|
|
||||||
SortedDirectoryIterator(const Path& path);
|
SortedDirectoryIterator(const Path& path);
|
||||||
/// Creates a directory iterator for the given path.
|
/// Creates a directory iterator for the given path.
|
||||||
|
|
||||||
virtual ~SortedDirectoryIterator();
|
virtual ~SortedDirectoryIterator();
|
||||||
/// Destroys the DirsFirstDirectoryIterator.
|
/// Destroys the DirsFirstDirectoryIterator.
|
||||||
|
|
||||||
virtual SortedDirectoryIterator& operator ++ (); // prefix
|
virtual SortedDirectoryIterator& operator ++(); // prefix
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _is_finished;
|
bool _is_finished;
|
||||||
std::deque<std::string> _directories;
|
std::deque<std::string> _directories;
|
||||||
std::deque<std::string> _files;
|
std::deque<std::string> _files;
|
||||||
|
|
||||||
void next();
|
void next();
|
||||||
/// Take next item
|
/// Take next item
|
||||||
void scan();
|
void scan();
|
||||||
/// Scan directory to collect its children directories and files
|
/// Scan directory to collect its children directories and files
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace Poco
|
} // namespace Poco
|
||||||
|
|
||||||
|
|
||||||
#endif //Foundation_SortedDirectoryIterator_INCLUDED
|
#endif //Foundation_SortedDirectoryIterator_INCLUDED
|
||||||
|
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
#include "Poco/RecursiveDirectoryIterator.h"
|
|
||||||
|
|
||||||
namespace Poco {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -33,8 +33,10 @@
|
|||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/RecursiveDirectoryIteratorStrategies.h"
|
#include "Poco/RecursiveDirectoryIteratorStrategies.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Poco
|
namespace Poco
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -44,23 +46,26 @@ using namespace std;
|
|||||||
// TraverseBase
|
// TraverseBase
|
||||||
//
|
//
|
||||||
TraverseBase::TraverseBase(DepthFunPtr depthDeterminer, UInt16 maxDepth)
|
TraverseBase::TraverseBase(DepthFunPtr depthDeterminer, UInt16 maxDepth)
|
||||||
: _depthDeterminer(depthDeterminer), _maxDepth(maxDepth)
|
: _depthDeterminer(depthDeterminer), _maxDepth(maxDepth)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool TraverseBase::isFiniteDepth()
|
inline bool TraverseBase::isFiniteDepth()
|
||||||
{
|
{
|
||||||
return _maxDepth != D_INFINITE;
|
return _maxDepth != D_INFINITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// ChildrenFirstTraverse
|
// ChildrenFirstTraverse
|
||||||
//
|
//
|
||||||
ChildrenFirstTraverse::ChildrenFirstTraverse(DepthFunPtr depthDeterminer, UInt16 maxDepth)
|
ChildrenFirstTraverse::ChildrenFirstTraverse(DepthFunPtr depthDeterminer, UInt16 maxDepth)
|
||||||
: TraverseBase(depthDeterminer, maxDepth)
|
: TraverseBase(depthDeterminer, maxDepth)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string ChildrenFirstTraverse::next(Stack* itStack, bool* isFinished)
|
const string ChildrenFirstTraverse::next(Stack* itStack, bool* isFinished)
|
||||||
{
|
{
|
||||||
// pointer mustn't point to NULL and iteration mustn't be finished
|
// pointer mustn't point to NULL and iteration mustn't be finished
|
||||||
@ -108,15 +113,17 @@ const string ChildrenFirstTraverse::next(Stack* itStack, bool* isFinished)
|
|||||||
return itStack->top()->path();
|
return itStack->top()->path();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// SiblingsFirstTraverse
|
// SiblingsFirstTraverse
|
||||||
//
|
//
|
||||||
SiblingsFirstTraverse::SiblingsFirstTraverse(DepthFunPtr depthDeterminer, UInt16 maxDepth)
|
SiblingsFirstTraverse::SiblingsFirstTraverse(DepthFunPtr depthDeterminer, UInt16 maxDepth)
|
||||||
: TraverseBase(depthDeterminer, maxDepth)
|
: TraverseBase(depthDeterminer, maxDepth)
|
||||||
{
|
{
|
||||||
_dirsStack.push(queue<string>());
|
_dirsStack.push(queue<string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string SiblingsFirstTraverse::next(Stack* itStack, bool* isFinished)
|
const string SiblingsFirstTraverse::next(Stack* itStack, bool* isFinished)
|
||||||
{
|
{
|
||||||
// pointer mustn't point to NULL and iteration mustn't be finished
|
// pointer mustn't point to NULL and iteration mustn't be finished
|
||||||
@ -168,4 +175,5 @@ const string SiblingsFirstTraverse::next(Stack* itStack, bool* isFinished)
|
|||||||
return itStack->top()->path();
|
return itStack->top()->path();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace Poco
|
} // namespace Poco
|
||||||
|
@ -33,49 +33,48 @@
|
|||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
#include "Poco/SortedDirectoryIterator.h"
|
#include "Poco/SortedDirectoryIterator.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco
|
||||||
|
{
|
||||||
|
|
||||||
SortedDirectoryIterator::SortedDirectoryIterator()
|
SortedDirectoryIterator::SortedDirectoryIterator()
|
||||||
: DirectoryIterator(), _is_finished(true)
|
: DirectoryIterator(), _is_finished(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SortedDirectoryIterator::SortedDirectoryIterator(const std::string& path)
|
SortedDirectoryIterator::SortedDirectoryIterator(const std::string& path)
|
||||||
: DirectoryIterator(path), _is_finished(false)
|
: DirectoryIterator(path), _is_finished(false)
|
||||||
{
|
{
|
||||||
scan();
|
scan();
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SortedDirectoryIterator::SortedDirectoryIterator(const DirectoryIterator& iterator)
|
SortedDirectoryIterator::SortedDirectoryIterator(const DirectoryIterator& iterator)
|
||||||
: DirectoryIterator(iterator), _is_finished(false)
|
: DirectoryIterator(iterator), _is_finished(false)
|
||||||
{
|
{
|
||||||
scan();
|
scan();
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SortedDirectoryIterator::SortedDirectoryIterator(const File& file)
|
SortedDirectoryIterator::SortedDirectoryIterator(const File& file)
|
||||||
: DirectoryIterator(file), _is_finished(false)
|
: DirectoryIterator(file), _is_finished(false)
|
||||||
{
|
{
|
||||||
scan();
|
scan();
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SortedDirectoryIterator::SortedDirectoryIterator(const Path& path)
|
SortedDirectoryIterator::SortedDirectoryIterator(const Path& path)
|
||||||
: DirectoryIterator(path), _is_finished(false)
|
: DirectoryIterator(path), _is_finished(false)
|
||||||
{
|
{
|
||||||
scan();
|
scan();
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -83,56 +82,56 @@ SortedDirectoryIterator::~SortedDirectoryIterator()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SortedDirectoryIterator& SortedDirectoryIterator::operator ++()
|
||||||
SortedDirectoryIterator& SortedDirectoryIterator::operator ++ ()
|
|
||||||
{
|
{
|
||||||
if (!_is_finished)
|
if (!_is_finished)
|
||||||
{
|
{
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SortedDirectoryIterator::scan()
|
void SortedDirectoryIterator::scan()
|
||||||
{
|
{
|
||||||
DirectoryIterator end_it;
|
DirectoryIterator end_it;
|
||||||
while (*this != end_it)
|
while (*this != end_it)
|
||||||
{
|
{
|
||||||
if ((*this)->isDirectory())
|
if ((*this)->isDirectory())
|
||||||
_directories.push_back(_path.toString());
|
_directories.push_back(_path.toString());
|
||||||
else
|
else
|
||||||
_files.push_back(_path.toString());
|
_files.push_back(_path.toString());
|
||||||
|
|
||||||
DirectoryIterator::operator++();
|
DirectoryIterator::operator++();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(_directories.begin(), _directories.end());
|
std::sort(_directories.begin(), _directories.end());
|
||||||
std::sort(_files.begin(), _files.end());
|
std::sort(_files.begin(), _files.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SortedDirectoryIterator::next()
|
void SortedDirectoryIterator::next()
|
||||||
{
|
{
|
||||||
DirectoryIterator end_it;
|
DirectoryIterator end_it;
|
||||||
if (!_directories.empty())
|
if (!_directories.empty())
|
||||||
{
|
{
|
||||||
_path.assign(_directories.front());
|
_path.assign(_directories.front());
|
||||||
_directories.pop_front();
|
_directories.pop_front();
|
||||||
_file = _path;
|
_file = _path;
|
||||||
}
|
}
|
||||||
else if (!_files.empty())
|
else if (!_files.empty())
|
||||||
{
|
{
|
||||||
_path.assign(_files.front());
|
_path.assign(_files.front());
|
||||||
_files.pop_front();
|
_files.pop_front();
|
||||||
_file = _path;
|
_file = _path;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_is_finished = true;
|
_is_finished = true;
|
||||||
_path = end_it.path();
|
_path = end_it.path();
|
||||||
_file = _path;
|
_file = _path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace Poco
|
} // namespace Poco
|
||||||
|
Loading…
x
Reference in New Issue
Block a user