fixed GH# 236: Bug in RecursiveDirectoryIterator

This commit is contained in:
Guenter Obiltschnig 2013-07-18 17:28:16 +02:00
parent f7bc7272ad
commit 996ddf1b43
6 changed files with 44 additions and 27 deletions

View File

@ -97,6 +97,7 @@ Release 1.5.2 (2013-07-19)
- fixed GH #224: building 1.5.1 on Windows for x64 - fixed GH #224: building 1.5.1 on Windows for x64
- fixed GH# 233: ServerSocket::bind6(Poco::UInt16 port, bool reuseAddress, bool ipV6Only) does not work - fixed GH# 233: ServerSocket::bind6(Poco::UInt16 port, bool reuseAddress, bool ipV6Only) does not work
- fixed GH# 231: Compatibility issue with Poco::Net::NetworkInterface - fixed GH# 231: Compatibility issue with Poco::Net::NetworkInterface
- fixed GH# 236: Bug in RecursiveDirectoryIterator
Release 1.5.1 (2013-01-11) Release 1.5.1 (2013-01-11)

View File

@ -36,8 +36,9 @@
// //
#ifndef Foundation_RecursiveDirectoryIteratorStrategy_INCLUDE #ifndef Foundation_RecursiveDirectoryIteratorStrategy_INCLUDED
#define Foundation_RecursiveDirectoryIteratorStrategy_INCLUDE #define Foundation_RecursiveDirectoryIteratorStrategy_INCLUDED
#include "Poco/Foundation.h" #include "Poco/Foundation.h"
#include "Poco/DirectoryIterator.h" #include "Poco/DirectoryIterator.h"
@ -46,8 +47,8 @@
#include <functional> #include <functional>
namespace Poco namespace Poco {
{
class Foundation_API TraverseBase class Foundation_API TraverseBase
{ {
@ -57,14 +58,14 @@ public:
enum enum
{ {
D_INFINITE = 0 D_INFINITE = 0 /// Special value for infinite traverse depth.
}; };
/// Constant for infinite traverse depth.
TraverseBase(DepthFunPtr depthDeterminer, UInt16 maxDepth = D_INFINITE); TraverseBase(DepthFunPtr depthDeterminer, UInt16 maxDepth = D_INFINITE);
protected: protected:
bool isFiniteDepth(); bool isFiniteDepth();
bool isDirectory(Poco::File& file);
DepthFunPtr _depthDeterminer; DepthFunPtr _depthDeterminer;
UInt16 _maxDepth; UInt16 _maxDepth;
@ -109,4 +110,5 @@ private:
} // namespace Poco } // namespace Poco
#endif // Foundation_RecursiveDirectoryIteratorStrategy_INCLUDE
#endif // Foundation_RecursiveDirectoryIteratorStrategy_INCLUDED

View File

@ -36,8 +36,9 @@
// //
#ifndef Foundation_RecursiveDirectoryIterator_INCLUDE #ifndef Foundation_RecursiveDirectoryIterator_INCLUDED
#define Foundation_RecursiveDirectoryIterator_INCLUDE #define Foundation_RecursiveDirectoryIterator_INCLUDED
#include "Poco/Foundation.h" #include "Poco/Foundation.h"
#include "Poco/File.h" #include "Poco/File.h"
@ -123,7 +124,6 @@ public:
{ {
} }
~RecursiveDirectoryIterator() ~RecursiveDirectoryIterator()
/// Destroys the DirectoryIterator. /// Destroys the DirectoryIterator.
{ {
@ -156,7 +156,7 @@ public:
} }
MyType& operator =(const MyType& it) MyType& operator = (const MyType& it)
{ {
if (_pImpl) if (_pImpl)
_pImpl->release(); _pImpl->release();
@ -170,7 +170,7 @@ public:
return *this; return *this;
} }
MyType& operator =(const File& file) MyType& operator = (const File& file)
{ {
if (_pImpl) if (_pImpl)
_pImpl->release(); _pImpl->release();
@ -181,7 +181,7 @@ public:
} }
MyType& operator =(const Path& path) MyType& operator = (const Path& path)
{ {
if (_pImpl) if (_pImpl)
_pImpl->release(); _pImpl->release();
@ -191,7 +191,7 @@ public:
return *this; return *this;
} }
MyType& operator =(const std::string& path) MyType& operator = (const std::string& path)
{ {
if (_pImpl) if (_pImpl)
_pImpl->release(); _pImpl->release();
@ -201,7 +201,7 @@ public:
return *this; return *this;
} }
MyType& operator ++() MyType& operator ++ ()
{ {
if (_pImpl) if (_pImpl)
{ {
@ -211,7 +211,7 @@ public:
return *this; return *this;
} }
const File& operator *() const const File& operator * () const
{ {
return _file; return _file;
} }
@ -221,17 +221,16 @@ public:
return _file; return _file;
} }
const File* operator ->() const const File* operator -> () const
{ {
return &_file; return &_file;
} }
File* operator ->() File* operator -> ()
{ {
return &_file; 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);
template<class T1, class T2> template<class T1, class T2>
@ -271,4 +270,5 @@ typedef RecursiveDirectoryIterator<SiblingsFirstTraverse> SiblingsFirstRecursive
} // namespace Poco } // namespace Poco
#endif // Foundation_RecursiveDirectoryIterator_INCLUDE
#endif // Foundation_RecursiveDirectoryIterator_INCLUDED

View File

@ -36,8 +36,8 @@
// //
#ifndef Foundation_RecursiveDirectoryIteratorImpl_INCLUDE #ifndef Foundation_RecursiveDirectoryIteratorImpl_INCLUDED
#define Foundation_RecursiveDirectoryIteratorImpl_INCLUDE #define Foundation_RecursiveDirectoryIteratorImpl_INCLUDED
#include "Poco/Foundation.h" #include "Poco/Foundation.h"
@ -59,9 +59,8 @@ class RecursiveDirectoryIteratorImpl
public: public:
enum enum
{ {
D_INFINITE = 0 D_INFINITE = 0 /// Special value 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)
: _maxDepth(maxDepth), _traverseStrategy(std::ptr_fun(depthFun), _maxDepth), _isFinished(false), _rc(1) : _maxDepth(maxDepth), _traverseStrategy(std::ptr_fun(depthFun), _maxDepth), _isFinished(false), _rc(1)
@ -130,4 +129,5 @@ private:
} // namespace Poco } // namespace Poco
#endif // Foundation_RecursiveDirectoryIteratorImpl_INCLUDE
#endif // Foundation_RecursiveDirectoryIteratorImpl_INCLUDED

View File

@ -55,6 +55,19 @@ inline bool TraverseBase::isFiniteDepth()
} }
bool TraverseBase::isDirectory(Poco::File& file)
{
try
{
return file.isDirectory();
}
catch (...)
{
return false;
}
}
// //
// ChildrenFirstTraverse // ChildrenFirstTraverse
// //
@ -77,7 +90,7 @@ const std::string ChildrenFirstTraverse::next(Stack* itStack, bool* isFinished)
// go deeper into not empty directory // go deeper into not empty directory
// (if depth limit allows) // (if depth limit allows)
bool isDepthLimitReached = isFiniteDepth() && _depthDeterminer(*itStack) >= _maxDepth; bool isDepthLimitReached = isFiniteDepth() && _depthDeterminer(*itStack) >= _maxDepth;
if (!isDepthLimitReached && itStack->top()->isDirectory()) if (!isDepthLimitReached && isDirectory(*itStack->top()))
{ {
DirectoryIterator child_it(itStack->top().path()); DirectoryIterator child_it(itStack->top().path());
// check if directory is empty // check if directory is empty
@ -130,7 +143,7 @@ const std::string SiblingsFirstTraverse::next(Stack* itStack, bool* isFinished)
// add dirs to queue (if depth limit allows) // add dirs to queue (if depth limit allows)
bool isDepthLimitReached = isFiniteDepth() && _depthDeterminer(*itStack) >= _maxDepth; bool isDepthLimitReached = isFiniteDepth() && _depthDeterminer(*itStack) >= _maxDepth;
if (!isDepthLimitReached && itStack->top()->isDirectory()) if (!isDepthLimitReached && isDirectory(*itStack->top()))
{ {
const std::string& p = itStack->top()->path(); const std::string& p = itStack->top()->path();
_dirsStack.top().push(p); _dirsStack.top().push(p);

View File

@ -100,6 +100,7 @@ AAAIntroduction
- fixed GH #224: building 1.5.1 on Windows for x64 - fixed GH #224: building 1.5.1 on Windows for x64
- fixed GH# 233: ServerSocket::bind6(Poco::UInt16 port, bool reuseAddress, bool ipV6Only) does not work - fixed GH# 233: ServerSocket::bind6(Poco::UInt16 port, bool reuseAddress, bool ipV6Only) does not work
- fixed GH# 231: Compatibility issue with Poco::Net::NetworkInterface - fixed GH# 231: Compatibility issue with Poco::Net::NetworkInterface
- fixed GH# 236: Bug in RecursiveDirectoryIterator
!!Incompatible Changes and Possible Transition Issues !!Incompatible Changes and Possible Transition Issues