mirror of
https://github.com/pocoproject/poco.git
synced 2025-04-01 09:24:55 +02:00
porting 1.4.4 rev. 1989 (except for File_WIN32(U)/FileImpl::isDeviceImpl() where GENERIC_ACCESS was left due to breaking testFileAtributes3() test case)
This commit is contained in:
parent
eb20f339e1
commit
d384a499d5
38
CHANGELOG
38
CHANGELOG
@ -28,7 +28,6 @@ Release 1.5.0 (2012-08-??)
|
||||
- added IPAddress RFC 4291 compatible site-local prefix support
|
||||
- fixed SF#3012166: IPv6 patch
|
||||
- added SF#3558085: Add formatter to MACAddress object
|
||||
- fixed SF#3535990: POCO_HAVE_IPv6 without POCO_WIN32_UTF8 conflict
|
||||
- fixed SF#3552774: Don't hide default target in subordinate makefile
|
||||
- fixed SF#3534307: Building IPv6 for Linux by default
|
||||
- fixed SF#3516844: poco missing symbols with external >=lipcre-8.13
|
||||
@ -70,6 +69,43 @@ Release 1.4.4 (2012-08-??)
|
||||
response status.
|
||||
- fixed a DOM parser performance bug (patch by Peter Klotz)
|
||||
- fixed SF# 3559325: Util Windows broken in non-Unicode
|
||||
- updated iOS build configuration to use xcode-select for finding toolchain
|
||||
- Poco::Net::SecureSocketImpl::shutdown() now also shuts down the underlying socket.
|
||||
- fixed SF# 3552597: Crypto des-ecb error
|
||||
- fixed SF# 3550553: SecureSocketImpl::connect hangs
|
||||
- fixed SF# 3543047: Poco::Timer bug for long startInterval/periodic interval
|
||||
- fixed SF# 3539695: Thread attributes should be destroyed using the pthread_attr_destroy()
|
||||
- fixed SF# 3532311: Not able to set socket option on ServerSocket before bind
|
||||
Added Poco::Net::Socket::init(int af) which can be used to explicitely
|
||||
initialize the underlying socket before calling bind(), connect(), etc.
|
||||
- fixed SF# 3521347: Typo in UnWindows.h undef
|
||||
- fixed SF# 3519474: WinRegistryConfiguration bug
|
||||
Also added tests and fixed another potential issue with an empty root path passed to the constructor.
|
||||
- fixed SF# 3516827: wrong return value of WinRegistryKey::exists()
|
||||
- fixed SF# 3515284: RSA publickey format(X.509 SubjectPublicKeyInfo)
|
||||
- fixed SF# 3503267: VxWorks OS prio is not set in standard constructor
|
||||
- fixed SF# 3500438: HTTPResponse failure when reason is empty
|
||||
- fixed SF# 3495656: numberformater, numberparser error in mingw
|
||||
- fixed SF# 3496493: Reference counting broken in TaskManager postNotification
|
||||
- fixed SF# 3483174: LogFile flushing behavior on Windows
|
||||
Flushing is now configurable for FileChannel and SimpleFileChannel
|
||||
using the "flush" property (true or false).
|
||||
- fixed SF# 3479561: Subsequent IPs on a NIC is not enumerated
|
||||
- fixed SF# 3478665: Permission checks in Poco::File not correct for root
|
||||
- fixed SF# 3475050: Threading bug in initializeNetwork() on Windows
|
||||
- fixed SF# 3552680: websocket small frames bug and proposed fix
|
||||
- fixed a WebSocket interop issue with Firefox
|
||||
- added Poco::Net::MessageHeader::hasToken()
|
||||
- Poco::AtomicCounter now uses GCC 4.3 builtin atomics on more platforms
|
||||
- fixed SF# 3555938: NetSSL: socket closed twice
|
||||
- socket exceptions now include OS error code
|
||||
- fixed SF# 3556975: Need to fix Shared Memory for memory map
|
||||
- Poco::Net::SecureSocketImpl::close() now catches exceptions thrown by its call to shutdown().
|
||||
- fixed SF# 3535990: POCO_HAVE_IPv6 without POCO_WIN32_UTF8 conflict
|
||||
- fixed SF# 3559665: Poco::InflatingInputStream may not always inflate completely
|
||||
- added Poco::DirectoryWatcher class
|
||||
- fixed SF# 3561464: Poco::File::isDevice() can throw due to sharing violation
|
||||
|
||||
|
||||
Release 1.4.3p1 (2012-01-23)
|
||||
============================
|
||||
|
@ -33,6 +33,7 @@ SOURCES="
|
||||
DigestEngine.cpp
|
||||
DigestStream.cpp
|
||||
DirectoryIterator.cpp
|
||||
DirectoryWatcher.cpp
|
||||
DynamicAny.cpp
|
||||
DynamicAnyHolder.cpp
|
||||
Environment.cpp
|
||||
|
@ -3229,6 +3229,10 @@
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\DirectoryWatcher.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\File.cpp"
|
||||
>
|
||||
@ -3789,6 +3793,10 @@
|
||||
RelativePath=".\include\Poco\DirectoryIterator_WIN32U.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\DirectoryWatcher.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\File.h"
|
||||
>
|
||||
|
@ -290,6 +290,7 @@
|
||||
<ClCompile Include="src\ByteOrder.cpp" />
|
||||
<ClCompile Include="src\Checksum.cpp" />
|
||||
<ClCompile Include="src\Debugger.cpp" />
|
||||
<ClCompile Include="src\DirectoryWatcher.cpp" />
|
||||
<ClCompile Include="src\Environment.cpp" />
|
||||
<ClCompile Include="src\Environment_UNIX.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'">true</ExcludedFromBuild>
|
||||
@ -976,6 +977,7 @@
|
||||
<ClInclude Include="include\Poco\ByteOrder.h" />
|
||||
<ClInclude Include="include\Poco\Checksum.h" />
|
||||
<ClInclude Include="include\Poco\Config.h" />
|
||||
<ClInclude Include="include\Poco\DirectoryWatcher.h" />
|
||||
<ClInclude Include="include\Poco\Debugger.h" />
|
||||
<ClInclude Include="include\Poco\DynamicAny.h" />
|
||||
<ClInclude Include="include\Poco\DynamicAnyHolder.h" />
|
||||
|
@ -861,6 +861,9 @@
|
||||
<ClCompile Include="src\HashStatistic.cpp">
|
||||
<Filter>Hashing\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\DirectoryWatcher.cpp">
|
||||
<Filter>Filesystem\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Var.cpp">
|
||||
<Filter>Dynamic\Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -1784,6 +1787,12 @@
|
||||
<ClInclude Include="include\Poco\PriorityStrategy.h">
|
||||
<Filter>Events\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\ObjectPool.h">
|
||||
<Filter>Core\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\DirectoryWatcher.h">
|
||||
<Filter>Filesystem\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\Dynamic\Pair.h">
|
||||
<Filter>Dynamic\Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
@ -2903,6 +2903,9 @@
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\DirectoryWatcher.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\File.cpp">
|
||||
</File>
|
||||
@ -3246,6 +3249,9 @@
|
||||
<File
|
||||
RelativePath=".\include\Poco\DirectoryIterator_WIN32U.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\DirectoryWatcher.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\File.h">
|
||||
</File>
|
||||
|
@ -3737,6 +3737,10 @@
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\DirectoryWatcher.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\File.cpp"
|
||||
>
|
||||
@ -4193,6 +4197,10 @@
|
||||
RelativePath=".\include\Poco\DirectoryIterator_WIN32U.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\DirectoryWatcher.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\File.h"
|
||||
>
|
||||
|
@ -3730,6 +3730,10 @@
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\DirectoryWatcher.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\File.cpp"
|
||||
>
|
||||
@ -4186,6 +4190,10 @@
|
||||
RelativePath=".\include\Poco\DirectoryIterator_WIN32U.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\DirectoryWatcher.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\File.h"
|
||||
>
|
||||
|
@ -300,6 +300,7 @@
|
||||
<ClCompile Include="src\ByteOrder.cpp" />
|
||||
<ClCompile Include="src\Checksum.cpp" />
|
||||
<ClCompile Include="src\Debugger.cpp" />
|
||||
<ClCompile Include="src\DirectoryWatcher.cpp" />
|
||||
<ClCompile Include="src\Environment.cpp" />
|
||||
<ClCompile Include="src\Environment_UNIX.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'">true</ExcludedFromBuild>
|
||||
@ -985,6 +986,7 @@
|
||||
<ClInclude Include="include\Poco\Checksum.h" />
|
||||
<ClInclude Include="include\Poco\Config.h" />
|
||||
<ClInclude Include="include\Poco\Debugger.h" />
|
||||
<ClInclude Include="include\Poco\DirectoryWatcher.h" />
|
||||
<ClInclude Include="include\Poco\DynamicAny.h" />
|
||||
<ClInclude Include="include\Poco\DynamicAnyHolder.h" />
|
||||
<ClInclude Include="include\Poco\DynamicFactory.h" />
|
||||
|
@ -861,6 +861,9 @@
|
||||
<ClCompile Include="src\HashStatistic.cpp">
|
||||
<Filter>Hashing\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\DirectoryWatcher.cpp">
|
||||
<Filter>Filesystem\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\FIFOBufferStream.cpp">
|
||||
<Filter>Streams\Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -1805,6 +1808,12 @@
|
||||
<ClInclude Include="include\Poco\Windows1250Encoding.h">
|
||||
<Filter>Text\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\ObjectPool.h">
|
||||
<Filter>Core\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\Poco\DirectoryWatcher.h">
|
||||
<Filter>Filesystem\Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="src\pocomsg.rc">
|
||||
|
@ -3728,6 +3728,10 @@
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\DirectoryWatcher.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\File.cpp"
|
||||
>
|
||||
@ -4184,6 +4188,10 @@
|
||||
RelativePath=".\include\Poco\DirectoryIterator_WIN32U.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\DirectoryWatcher.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\include\Poco\File.h"
|
||||
>
|
||||
|
@ -11,7 +11,7 @@ include $(POCO_BASE)/build/rules/global
|
||||
objects = ArchiveStrategy Ascii ASCIIEncoding AsyncChannel Base64Decoder Base64Encoder \
|
||||
BinaryReader BinaryWriter Bugcheck ByteOrder Channel Checksum Configurable ConsoleChannel \
|
||||
CountingStream DateTime LocalDateTime DateTimeFormat DateTimeFormatter DateTimeParser \
|
||||
Debugger DeflatingStream DigestEngine DigestStream DirectoryIterator \
|
||||
Debugger DeflatingStream DigestEngine DigestStream DirectoryIterator DirectoryWatcher \
|
||||
Environment Event EventArgs ErrorHandler Exception FIFOBufferStream FPEnvironment File \
|
||||
FileChannel Formatter FormattingChannel Glob HexBinaryDecoder LineEndingConverter \
|
||||
HexBinaryEncoder InflatingStream Latin1Encoding Latin2Encoding Latin9Encoding LogFile \
|
||||
|
243
Foundation/include/Poco/DirectoryWatcher.h
Normal file
243
Foundation/include/Poco/DirectoryWatcher.h
Normal file
@ -0,0 +1,243 @@
|
||||
//
|
||||
// DirectoryWatcher.h
|
||||
//
|
||||
// $Id: //poco/1.4/Foundation/include/Poco/DirectoryWatcher.h#2 $
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Filesystem
|
||||
// Module: DirectoryWatcher
|
||||
//
|
||||
// Definition of the DirectoryWatcher class.
|
||||
//
|
||||
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#ifndef Foundation_DirectoryWatcher_INCLUDED
|
||||
#define Foundation_DirectoryWatcher_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Foundation.h"
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/BasicEvent.h"
|
||||
#include "Poco/Runnable.h"
|
||||
#include "Poco/Thread.h"
|
||||
#include "Poco/AtomicCounter.h"
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
class DirectoryWatcherStrategy;
|
||||
|
||||
|
||||
class Foundation_API DirectoryWatcher: protected Runnable
|
||||
/// This class is used to get notifications about changes
|
||||
/// to the filesystem, more specifically, to a specific
|
||||
/// directory. Changes to a directory are reported via
|
||||
/// events.
|
||||
///
|
||||
/// A thread will be created that watches the specified
|
||||
/// directory for changes. Events are reported in the context
|
||||
/// of this thread.
|
||||
///
|
||||
/// Note that changes to files in subdirectories of the watched
|
||||
/// directory are not reported. Separate DirectoryWatcher objects
|
||||
/// must be created for these directories if they should be watched.
|
||||
///
|
||||
/// Changes to file attributes are not reported.
|
||||
///
|
||||
/// On Windows, this class is implemented using FindFirstChangeNotification()/FindNextChangeNotification().
|
||||
/// On Linux, this class is implemented using inotify.
|
||||
/// On all other platforms, the watched directory is periodically scanned
|
||||
/// for changes. This can negatively affect performance if done too often.
|
||||
/// Therefore, the interval in which scans are done can be specified in
|
||||
/// the constructor.
|
||||
///
|
||||
/// DW_ITEM_MOVED_FROM and DW_ITEM_MOVED_TO events will only be reported
|
||||
/// on Linux. On other platforms, a file rename or move operation
|
||||
/// will be reported via a DW_ITEM_REMOVED and a DW_ITEM_ADDED event.
|
||||
/// The order of these two events is not defined.
|
||||
///
|
||||
/// An event mask can be specified to enable only certain events.
|
||||
{
|
||||
public:
|
||||
enum DirectoryEventType
|
||||
{
|
||||
DW_ITEM_ADDED = 1,
|
||||
/// A new item has been created and added to the directory.
|
||||
|
||||
DW_ITEM_REMOVED = 2,
|
||||
/// An item has been removed from the directory.
|
||||
|
||||
DW_ITEM_MODIFIED = 4,
|
||||
/// An item has been modified.
|
||||
|
||||
DW_ITEM_MOVED_FROM = 8,
|
||||
/// An item has been renamed or moved. This event delivers the old name.
|
||||
|
||||
DW_ITEM_MOVED_TO = 16,
|
||||
/// An item has been renamed or moved. This event delivers the new name.
|
||||
};
|
||||
|
||||
enum DirectoryEventMask
|
||||
{
|
||||
DW_FILTER_ENABLE_ALL = 31,
|
||||
/// Enables all event types.
|
||||
|
||||
DW_FILTER_DISABLE_ALL = 0
|
||||
/// Disables all event types.
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
DW_DEFAULT_SCAN_INTERVAL = 5 /// Default scan interval for platforms that don't provide a native notification mechanism.
|
||||
};
|
||||
|
||||
struct DirectoryEvent
|
||||
{
|
||||
DirectoryEvent(const File& f, DirectoryEventType ev):
|
||||
item(f),
|
||||
event(ev)
|
||||
{
|
||||
}
|
||||
|
||||
const File& item; /// The directory or file that has been changed.
|
||||
DirectoryEventType event; /// The kind of event.
|
||||
};
|
||||
|
||||
BasicEvent<const DirectoryEvent> itemAdded;
|
||||
/// Fired when a file or directory has been created or added to the directory.
|
||||
|
||||
BasicEvent<const DirectoryEvent> itemRemoved;
|
||||
/// Fired when a file or directory has been removed from the directory.
|
||||
|
||||
BasicEvent<const DirectoryEvent> itemModified;
|
||||
/// Fired when a file or directory has been modified.
|
||||
|
||||
BasicEvent<const DirectoryEvent> itemMovedFrom;
|
||||
/// Fired when a file or directory has been renamed. This event delivers the old name.
|
||||
|
||||
BasicEvent<const DirectoryEvent> itemMovedTo;
|
||||
/// Fired when a file or directory has been moved. This event delivers the new name.
|
||||
|
||||
BasicEvent<const Exception> scanError;
|
||||
/// Fired when an error occurs while scanning for changes.
|
||||
|
||||
DirectoryWatcher(const std::string& path, int eventMask = DW_FILTER_ENABLE_ALL, int scanInterval = DW_DEFAULT_SCAN_INTERVAL);
|
||||
/// Creates a DirectoryWatcher for the directory given in path.
|
||||
/// To enable only specific events, an eventMask can be specified by
|
||||
/// OR-ing the desired event IDs (e.g., DW_FILE_ADDED | DW_FILE_MODIFIED).
|
||||
/// On platforms where no native filesystem notifications are available,
|
||||
/// scanInterval specifies the interval in seconds between scans
|
||||
/// of the directory.
|
||||
|
||||
DirectoryWatcher(const File& directory, int eventMask = DW_FILTER_ENABLE_ALL, int scanInterval = DW_DEFAULT_SCAN_INTERVAL);
|
||||
/// Creates a DirectoryWatcher for the specified directory
|
||||
/// To enable only specific events, an eventMask can be specified by
|
||||
/// OR-ing the desired event IDs (e.g., DW_FILE_ADDED | DW_FILE_MODIFIED).
|
||||
/// On platforms where no native filesystem notifications are available,
|
||||
/// scanInterval specifies the interval in seconds between scans
|
||||
/// of the directory.
|
||||
|
||||
~DirectoryWatcher();
|
||||
/// Destroys the DirectoryWatcher.
|
||||
|
||||
void suspendEvents();
|
||||
/// Suspends sending of events. Can be called multiple times, but every
|
||||
/// call to suspendEvent() must be matched by a call to resumeEvents().
|
||||
|
||||
void resumeEvents();
|
||||
/// Resumes events, after they have been suspended with a call to suspendEvents().
|
||||
|
||||
bool eventsSuspended() const;
|
||||
/// Returns true iff events are suspended.
|
||||
|
||||
int eventMask() const;
|
||||
/// Returns the value of the eventMask passed to the constructor.
|
||||
|
||||
int scanInterval() const;
|
||||
/// Returns the scan interval in seconds.
|
||||
|
||||
const File& directory() const;
|
||||
/// Returns the directory being watched.
|
||||
|
||||
bool supportsMoveEvents() const;
|
||||
/// Returns true iff the platform supports DW_ITEM_MOVED_FROM/itemMovedFrom and
|
||||
/// DW_ITEM_MOVED_TO/itemMovedTo events.
|
||||
|
||||
protected:
|
||||
void init();
|
||||
void stop();
|
||||
void run();
|
||||
|
||||
private:
|
||||
DirectoryWatcher();
|
||||
DirectoryWatcher(const DirectoryWatcher&);
|
||||
DirectoryWatcher& operator = (const DirectoryWatcher&);
|
||||
|
||||
Thread _thread;
|
||||
File _directory;
|
||||
int _eventMask;
|
||||
AtomicCounter _eventsSuspended;
|
||||
int _scanInterval;
|
||||
DirectoryWatcherStrategy* _pStrategy;
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// inlines
|
||||
//
|
||||
|
||||
|
||||
inline bool DirectoryWatcher::eventsSuspended() const
|
||||
{
|
||||
return _eventsSuspended.value() > 0;
|
||||
}
|
||||
|
||||
|
||||
inline int DirectoryWatcher::eventMask() const
|
||||
{
|
||||
return _eventMask;
|
||||
}
|
||||
|
||||
|
||||
inline int DirectoryWatcher::scanInterval() const
|
||||
{
|
||||
return _scanInterval;
|
||||
}
|
||||
|
||||
|
||||
inline const File& DirectoryWatcher::directory() const
|
||||
{
|
||||
return _directory;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
||||
|
||||
|
||||
#endif // Foundation_DirectoryWatcher_INCLUDED
|
@ -84,6 +84,7 @@ private:
|
||||
std::string _path;
|
||||
|
||||
friend class DirectoryIteratorImpl;
|
||||
friend class LinuxDirectoryWatcherStrategy;
|
||||
};
|
||||
|
||||
|
||||
|
@ -86,6 +86,7 @@ private:
|
||||
|
||||
friend class FileHandle;
|
||||
friend class DirectoryIteratorImpl;
|
||||
friend class WindowsDirectoryWatcherStrategy;
|
||||
};
|
||||
|
||||
|
||||
|
@ -87,6 +87,7 @@ private:
|
||||
|
||||
friend class FileHandle;
|
||||
friend class DirectoryIteratorImpl;
|
||||
friend class WindowsDirectoryWatcherStrategy;
|
||||
};
|
||||
|
||||
|
||||
|
@ -109,6 +109,8 @@
|
||||
#pragma warning(disable:4351) // new behavior: elements of array '...' will be default initialized
|
||||
#pragma warning(disable:4675) // resolved overload was found by argument-dependent lookup
|
||||
#pragma warning(disable:4275) // non dll-interface class 'std::exception' used as base for dll-interface class 'Poco::Exception'
|
||||
#pragma warning(disable:4250) // VC++ 11.0: inheriting from std stream classes produces C4250 warning;
|
||||
// see <http://connect.microsoft.com/VisualStudio/feedback/details/733720/inheriting-from-std-fstream-produces-c4250-warning>
|
||||
#endif
|
||||
|
||||
|
||||
|
524
Foundation/src/DirectoryWatcher.cpp
Normal file
524
Foundation/src/DirectoryWatcher.cpp
Normal file
@ -0,0 +1,524 @@
|
||||
//
|
||||
// DirectoryWatcher.cpp
|
||||
//
|
||||
// $Id: //poco/1.4/Foundation/src/DirectoryWatcher.cpp#4 $
|
||||
//
|
||||
// Library: Foundation
|
||||
// Package: Filesystem
|
||||
// Module: DirectoryWatcher
|
||||
//
|
||||
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/DirectoryWatcher.h"
|
||||
#include "Poco/Path.h"
|
||||
#include "Poco/Glob.h"
|
||||
#include "Poco/DirectoryIterator.h"
|
||||
#include "Poco/Event.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/Buffer.h"
|
||||
#if defined(POCO_WIN32_UTF8)
|
||||
#include "Poco/UnicodeConverter.h"
|
||||
#endif
|
||||
#if POCO_OS == POCO_OS_LINUX
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/select.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace Poco {
|
||||
|
||||
|
||||
class DirectoryWatcherStrategy
|
||||
{
|
||||
public:
|
||||
DirectoryWatcherStrategy(DirectoryWatcher& owner):
|
||||
_owner(owner)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~DirectoryWatcherStrategy()
|
||||
{
|
||||
}
|
||||
|
||||
DirectoryWatcher& owner()
|
||||
{
|
||||
return _owner;
|
||||
}
|
||||
|
||||
virtual void run() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual bool supportsMoveEvents() const = 0;
|
||||
|
||||
protected:
|
||||
struct ItemInfo
|
||||
{
|
||||
ItemInfo():
|
||||
size(0)
|
||||
{
|
||||
}
|
||||
|
||||
ItemInfo(const ItemInfo& other):
|
||||
path(other.path),
|
||||
size(other.size),
|
||||
lastModified(other.lastModified)
|
||||
{
|
||||
}
|
||||
|
||||
explicit ItemInfo(const File& f):
|
||||
path(f.path()),
|
||||
size(f.isFile() ? f.getSize() : 0),
|
||||
lastModified(f.getLastModified())
|
||||
{
|
||||
}
|
||||
|
||||
std::string path;
|
||||
File::FileSize size;
|
||||
Timestamp lastModified;
|
||||
};
|
||||
typedef std::map<std::string, ItemInfo> ItemInfoMap;
|
||||
|
||||
void scan(ItemInfoMap& entries)
|
||||
{
|
||||
DirectoryIterator it(owner().directory());
|
||||
DirectoryIterator end;
|
||||
while (it != end)
|
||||
{
|
||||
entries[it.path().getFileName()] = ItemInfo(*it);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
void compare(ItemInfoMap& oldEntries, ItemInfoMap& newEntries)
|
||||
{
|
||||
for (ItemInfoMap::iterator itn = newEntries.begin(); itn != newEntries.end(); ++itn)
|
||||
{
|
||||
ItemInfoMap::iterator ito = oldEntries.find(itn->first);
|
||||
if (ito != oldEntries.end())
|
||||
{
|
||||
if ((owner().eventMask() & DirectoryWatcher::DW_ITEM_MODIFIED) && !owner().eventsSuspended())
|
||||
{
|
||||
if (itn->second.size != ito->second.size || itn->second.lastModified != ito->second.lastModified)
|
||||
{
|
||||
Poco::File f(itn->second.path);
|
||||
DirectoryWatcher::DirectoryEvent ev(f, DirectoryWatcher::DW_ITEM_MODIFIED);
|
||||
owner().itemModified(&owner(), ev);
|
||||
}
|
||||
}
|
||||
oldEntries.erase(ito);
|
||||
}
|
||||
else if ((owner().eventMask() & DirectoryWatcher::DW_ITEM_ADDED) && !owner().eventsSuspended())
|
||||
{
|
||||
Poco::File f(itn->second.path);
|
||||
DirectoryWatcher::DirectoryEvent ev(f, DirectoryWatcher::DW_ITEM_ADDED);
|
||||
owner().itemAdded(&owner(), ev);
|
||||
}
|
||||
}
|
||||
if ((owner().eventMask() & DirectoryWatcher::DW_ITEM_REMOVED) && !owner().eventsSuspended())
|
||||
{
|
||||
for (ItemInfoMap::iterator it = oldEntries.begin(); it != oldEntries.end(); ++it)
|
||||
{
|
||||
Poco::File f(it->second.path);
|
||||
DirectoryWatcher::DirectoryEvent ev(f, DirectoryWatcher::DW_ITEM_REMOVED);
|
||||
owner().itemRemoved(&owner(), ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
DirectoryWatcherStrategy();
|
||||
DirectoryWatcherStrategy(const DirectoryWatcherStrategy&);
|
||||
DirectoryWatcherStrategy& operator = (const DirectoryWatcherStrategy&);
|
||||
|
||||
DirectoryWatcher& _owner;
|
||||
};
|
||||
|
||||
|
||||
#if POCO_OS == POCO_OS_WINDOWS_NT
|
||||
|
||||
|
||||
class WindowsDirectoryWatcherStrategy: public DirectoryWatcherStrategy
|
||||
{
|
||||
public:
|
||||
WindowsDirectoryWatcherStrategy(DirectoryWatcher& owner):
|
||||
DirectoryWatcherStrategy(owner)
|
||||
{
|
||||
_hStopped = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
if (!_hStopped)
|
||||
throw SystemException("cannot create event");
|
||||
}
|
||||
|
||||
~WindowsDirectoryWatcherStrategy()
|
||||
{
|
||||
CloseHandle(_hStopped);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
ItemInfoMap entries;
|
||||
scan(entries);
|
||||
|
||||
DWORD filter = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME;
|
||||
if (owner().eventMask() & DirectoryWatcher::DW_ITEM_MODIFIED)
|
||||
filter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
|
||||
|
||||
std::string path(owner().directory().path());
|
||||
#if defined(POCO_WIN32_UTF8)
|
||||
std::wstring upath;
|
||||
Poco::UnicodeConverter::toUTF16(path.c_str(), upath);
|
||||
HANDLE hChange = FindFirstChangeNotificationW(upath.c_str(), FALSE, filter);
|
||||
#else
|
||||
HANDLE hChange = FindFirstChangeNotificationA(path.c_str(), FALSE, filter);
|
||||
#endif
|
||||
|
||||
if (hChange == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
try
|
||||
{
|
||||
FileImpl::handleLastErrorImpl(path);
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
owner().scanError(&owner(), exc);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool stopped = false;
|
||||
while (!stopped)
|
||||
{
|
||||
try
|
||||
{
|
||||
HANDLE h[2];
|
||||
h[0] = _hStopped;
|
||||
h[1] = hChange;
|
||||
switch (WaitForMultipleObjects(2, h, FALSE, INFINITE))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
stopped = true;
|
||||
break;
|
||||
case WAIT_OBJECT_0 + 1:
|
||||
{
|
||||
ItemInfoMap newEntries;
|
||||
scan(newEntries);
|
||||
compare(entries, newEntries);
|
||||
std::swap(entries, newEntries);
|
||||
if (FindNextChangeNotification(hChange) == FALSE)
|
||||
{
|
||||
FileImpl::handleLastErrorImpl(path);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw SystemException("failed to wait for directory changes");
|
||||
}
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
owner().scanError(&owner(), exc);
|
||||
}
|
||||
}
|
||||
FindCloseChangeNotification(hChange);
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
SetEvent(_hStopped);
|
||||
}
|
||||
|
||||
bool supportsMoveEvents() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
HANDLE _hStopped;
|
||||
};
|
||||
|
||||
|
||||
#elif POCO_OS == POCO_OS_LINUX
|
||||
|
||||
|
||||
class LinuxDirectoryWatcherStrategy: public DirectoryWatcherStrategy
|
||||
{
|
||||
public:
|
||||
LinuxDirectoryWatcherStrategy(DirectoryWatcher& owner):
|
||||
DirectoryWatcherStrategy(owner),
|
||||
_fd(-1),
|
||||
_stopped(false)
|
||||
{
|
||||
_fd = inotify_init();
|
||||
if (_fd == -1) throw Poco::IOException("cannot initialize inotify", errno);
|
||||
}
|
||||
|
||||
~LinuxDirectoryWatcherStrategy()
|
||||
{
|
||||
close(_fd);
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
int mask = 0;
|
||||
if (owner().eventMask() & DirectoryWatcher::DW_ITEM_ADDED)
|
||||
mask |= IN_CREATE;
|
||||
if (owner().eventMask() & DirectoryWatcher::DW_ITEM_REMOVED)
|
||||
mask |= IN_DELETE;
|
||||
if (owner().eventMask() & DirectoryWatcher::DW_ITEM_MODIFIED)
|
||||
mask |= IN_MODIFY;
|
||||
if (owner().eventMask() & DirectoryWatcher::DW_ITEM_MOVED_FROM)
|
||||
mask |= IN_MOVED_FROM;
|
||||
if (owner().eventMask() & DirectoryWatcher::DW_ITEM_MOVED_TO)
|
||||
mask |= IN_MOVED_TO;
|
||||
int wd = inotify_add_watch(_fd, owner().directory().path().c_str(), mask);
|
||||
if (wd == -1)
|
||||
{
|
||||
try
|
||||
{
|
||||
FileImpl::handleLastErrorImpl(owner().directory().path());
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
owner().scanError(&owner(), exc);
|
||||
}
|
||||
}
|
||||
|
||||
Poco::Buffer<char> buffer(4096);
|
||||
while (!_stopped)
|
||||
{
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(_fd, &fds);
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 200000;
|
||||
|
||||
if (select(_fd + 1, &fds, NULL, NULL, &tv) == 1)
|
||||
{
|
||||
int n = read(_fd, buffer.begin(), buffer.size());
|
||||
int i = 0;
|
||||
if (n > 0)
|
||||
{
|
||||
while (n > 0)
|
||||
{
|
||||
struct inotify_event* pEvent = reinterpret_cast<struct inotify_event*>(buffer.begin() + i);
|
||||
|
||||
if (pEvent->len > 0)
|
||||
{
|
||||
if (!owner().eventsSuspended())
|
||||
{
|
||||
Poco::Path p(owner().directory().path());
|
||||
p.makeDirectory();
|
||||
p.setFileName(pEvent->name);
|
||||
Poco::File f(p.toString());
|
||||
|
||||
if ((pEvent->mask & IN_CREATE) && (owner().eventMask() & DirectoryWatcher::DW_ITEM_ADDED))
|
||||
{
|
||||
DirectoryWatcher::DirectoryEvent ev(f, DirectoryWatcher::DW_ITEM_ADDED);
|
||||
owner().itemAdded(&owner(), ev);
|
||||
}
|
||||
if ((pEvent->mask & IN_DELETE) && (owner().eventMask() & DirectoryWatcher::DW_ITEM_REMOVED))
|
||||
{
|
||||
DirectoryWatcher::DirectoryEvent ev(f, DirectoryWatcher::DW_ITEM_REMOVED);
|
||||
owner().itemRemoved(&owner(), ev);
|
||||
}
|
||||
if ((pEvent->mask & IN_MODIFY) && (owner().eventMask() & DirectoryWatcher::DW_ITEM_MODIFIED))
|
||||
{
|
||||
DirectoryWatcher::DirectoryEvent ev(f, DirectoryWatcher::DW_ITEM_MODIFIED);
|
||||
owner().itemModified(&owner(), ev);
|
||||
}
|
||||
if ((pEvent->mask & IN_MOVED_FROM) && (owner().eventMask() & DirectoryWatcher::DW_ITEM_MOVED_FROM))
|
||||
{
|
||||
DirectoryWatcher::DirectoryEvent ev(f, DirectoryWatcher::DW_ITEM_MOVED_FROM);
|
||||
owner().itemMovedFrom(&owner(), ev);
|
||||
}
|
||||
if ((pEvent->mask & IN_MOVED_TO) && (owner().eventMask() & DirectoryWatcher::DW_ITEM_MOVED_TO))
|
||||
{
|
||||
DirectoryWatcher::DirectoryEvent ev(f, DirectoryWatcher::DW_ITEM_MOVED_TO);
|
||||
owner().itemMovedTo(&owner(), ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i += sizeof(inotify_event) + pEvent->len;
|
||||
n -= sizeof(inotify_event) + pEvent->len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
_stopped = true;
|
||||
}
|
||||
|
||||
bool supportsMoveEvents() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
int _fd;
|
||||
bool _stopped;
|
||||
};
|
||||
|
||||
|
||||
#else
|
||||
|
||||
|
||||
class DefaultDirectoryWatcherStrategy: public DirectoryWatcherStrategy
|
||||
{
|
||||
public:
|
||||
DefaultDirectoryWatcherStrategy(DirectoryWatcher& owner):
|
||||
DirectoryWatcherStrategy(owner)
|
||||
{
|
||||
}
|
||||
|
||||
~DefaultDirectoryWatcherStrategy()
|
||||
{
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
ItemInfoMap entries;
|
||||
scan(entries);
|
||||
while (!_stopped.tryWait(1000*owner().scanInterval()))
|
||||
{
|
||||
try
|
||||
{
|
||||
ItemInfoMap newEntries;
|
||||
scan(newEntries);
|
||||
compare(entries, newEntries);
|
||||
std::swap(entries, newEntries);
|
||||
}
|
||||
catch (Poco::Exception& exc)
|
||||
{
|
||||
owner().scanError(&owner(), exc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stop()
|
||||
{
|
||||
_stopped.set();
|
||||
}
|
||||
|
||||
bool supportsMoveEvents() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
Poco::Event _stopped;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
DirectoryWatcher::DirectoryWatcher(const std::string& path, int eventMask, int scanInterval):
|
||||
_directory(path),
|
||||
_eventMask(eventMask),
|
||||
_scanInterval(scanInterval)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
DirectoryWatcher::DirectoryWatcher(const Poco::File& directory, int eventMask, int scanInterval):
|
||||
_directory(directory),
|
||||
_eventMask(eventMask),
|
||||
_scanInterval(scanInterval)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
DirectoryWatcher::~DirectoryWatcher()
|
||||
{
|
||||
stop();
|
||||
delete _pStrategy;
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcher::suspendEvents()
|
||||
{
|
||||
poco_assert (_eventsSuspended > 0);
|
||||
|
||||
_eventsSuspended--;
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcher::resumeEvents()
|
||||
{
|
||||
_eventsSuspended++;
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcher::init()
|
||||
{
|
||||
if (!_directory.exists())
|
||||
throw Poco::FileNotFoundException(_directory.path());
|
||||
|
||||
if (!_directory.isDirectory())
|
||||
throw Poco::InvalidArgumentException("not a directory", _directory.path());
|
||||
|
||||
#if POCO_OS == POCO_OS_WINDOWS_NT
|
||||
_pStrategy = new WindowsDirectoryWatcherStrategy(*this);
|
||||
#elif POCO_OS == POCO_OS_LINUX
|
||||
_pStrategy = new LinuxDirectoryWatcherStrategy(*this);
|
||||
#else
|
||||
_pStrategy = new DefaultDirectoryWatcherStrategy(*this);
|
||||
#endif
|
||||
_thread.start(*this);
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcher::run()
|
||||
{
|
||||
_pStrategy->run();
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcher::stop()
|
||||
{
|
||||
_pStrategy->stop();
|
||||
_thread.join();
|
||||
}
|
||||
|
||||
|
||||
bool DirectoryWatcher::supportsMoveEvents() const
|
||||
{
|
||||
return _pStrategy->supportsMoveEvents();
|
||||
}
|
||||
|
||||
|
||||
} // namespace Poco
|
@ -193,7 +193,7 @@ bool FileImpl::isDeviceImpl() const
|
||||
{
|
||||
poco_assert (!_path.empty());
|
||||
|
||||
FileHandle fh(_path, GENERIC_READ, 0, OPEN_EXISTING);
|
||||
FileHandle fh(_path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING);
|
||||
DWORD type = GetFileType(fh.get());
|
||||
if (type == FILE_TYPE_CHAR)
|
||||
return true;
|
||||
|
@ -39,7 +39,7 @@ objects = ActiveMethodTest ActivityTest ActiveDispatcherTest \
|
||||
HashSetTest HashMapTest SharedMemoryTest \
|
||||
UniqueExpireCacheTest UniqueExpireLRUCacheTest UnicodeConverterTest \
|
||||
TuplesTest NamedTuplesTest TypeListTest VarTest DynamicTestSuite FileStreamTest \
|
||||
MemoryStreamTest ObjectPoolTest
|
||||
MemoryStreamTest ObjectPoolTest DirectoryWatcherTest
|
||||
|
||||
target = testrunner
|
||||
target_version = 1
|
||||
|
@ -30,6 +30,7 @@ SOURCES="
|
||||
DateTimeTest.cpp
|
||||
DateTimeTestSuite.cpp
|
||||
DigestStreamTest.cpp
|
||||
DirectoryWatcherTest.cpp
|
||||
Driver.cpp
|
||||
DummyDelegate.cpp
|
||||
DynamicAnyTest.cpp
|
||||
|
@ -1261,6 +1261,10 @@
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\src\DirectoryWatcherTest.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\FilesystemTestSuite.cpp"
|
||||
>
|
||||
@ -1281,6 +1285,10 @@
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\src\DirectoryWatcherTest.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\FilesystemTestSuite.h"
|
||||
>
|
||||
|
@ -307,6 +307,7 @@
|
||||
<ClCompile Include="src\ByteOrderTest.cpp" />
|
||||
<ClCompile Include="src\CoreTest.cpp" />
|
||||
<ClCompile Include="src\CoreTestSuite.cpp" />
|
||||
<ClCompile Include="src\DirectoryWatcherTest.cpp" />
|
||||
<ClCompile Include="src\DynamicFactoryTest.cpp" />
|
||||
<ClCompile Include="src\FIFOBufferStreamTest.cpp" />
|
||||
<ClCompile Include="src\FormatTest.cpp" />
|
||||
@ -439,6 +440,7 @@
|
||||
<ClInclude Include="src\ByteOrderTest.h" />
|
||||
<ClInclude Include="src\CoreTest.h" />
|
||||
<ClInclude Include="src\CoreTestSuite.h" />
|
||||
<ClInclude Include="src\DirectoryWatcherTest.h" />
|
||||
<ClInclude Include="src\DynamicFactoryTest.h" />
|
||||
<ClInclude Include="src\FIFOBufferStreamTest.h" />
|
||||
<ClInclude Include="src\FormatTest.h" />
|
||||
|
@ -561,6 +561,9 @@
|
||||
<ClCompile Include="src\ObjectPoolTest.cpp">
|
||||
<Filter>Core\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\DirectoryWatcherTest.cpp">
|
||||
<Filter>Filesystem\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\VarTest.cpp">
|
||||
<Filter>Dynamic\Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -950,6 +953,9 @@
|
||||
<ClInclude Include="src\ObjectPoolTest.h">
|
||||
<Filter>Core\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\DirectoryWatcherTest.h">
|
||||
<Filter>Filesystem\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\VarTest.h">
|
||||
<Filter>Dynamic\Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
@ -925,6 +925,9 @@
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\src\DirectoryWatcherTest.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\FilesystemTestSuite.cpp">
|
||||
</File>
|
||||
@ -941,6 +944,9 @@
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath=".\src\DirectoryWatcherTest.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\FilesystemTestSuite.h">
|
||||
</File>
|
||||
|
@ -1239,6 +1239,10 @@
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\src\DirectoryWatcherTest.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\FilesystemTestSuite.cpp"
|
||||
>
|
||||
@ -1259,6 +1263,10 @@
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\src\DirectoryWatcherTest.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\FilesystemTestSuite.h"
|
||||
>
|
||||
|
@ -1225,6 +1225,10 @@
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\src\DirectoryWatcherTest.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\FilesystemTestSuite.cpp"
|
||||
>
|
||||
@ -1245,6 +1249,10 @@
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\src\DirectoryWatcherTest.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\FilesystemTestSuite.h"
|
||||
>
|
||||
|
@ -307,6 +307,7 @@
|
||||
<ClCompile Include="src\ByteOrderTest.cpp" />
|
||||
<ClCompile Include="src\CoreTest.cpp" />
|
||||
<ClCompile Include="src\CoreTestSuite.cpp" />
|
||||
<ClCompile Include="src\DirectoryWatcherTest.cpp" />
|
||||
<ClCompile Include="src\DynamicFactoryTest.cpp" />
|
||||
<ClCompile Include="src\FIFOBufferStreamTest.cpp" />
|
||||
<ClCompile Include="src\FormatTest.cpp" />
|
||||
@ -439,6 +440,7 @@
|
||||
<ClInclude Include="src\ByteOrderTest.h" />
|
||||
<ClInclude Include="src\CoreTest.h" />
|
||||
<ClInclude Include="src\CoreTestSuite.h" />
|
||||
<ClInclude Include="src\DirectoryWatcherTest.h" />
|
||||
<ClInclude Include="src\DynamicAnyTest.h" />
|
||||
<ClInclude Include="src\DynamicFactoryTest.h" />
|
||||
<ClInclude Include="src\FIFOBufferStreamTest.h" />
|
||||
|
@ -561,6 +561,9 @@
|
||||
<ClCompile Include="src\ObjectPoolTest.cpp">
|
||||
<Filter>Core\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\DirectoryWatcherTest.cpp">
|
||||
<Filter>Filesystem\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\VarTest.cpp">
|
||||
<Filter>Dynamic\Source Files</Filter>
|
||||
</ClCompile>
|
||||
@ -953,6 +956,9 @@
|
||||
<ClInclude Include="src\ObjectPoolTest.h">
|
||||
<Filter>Core\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\DirectoryWatcherTest.h">
|
||||
<Filter>Filesystem\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\VarTest.h">
|
||||
<Filter>Dynamic\Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
@ -1207,6 +1207,10 @@
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\src\DirectoryWatcherTest.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\FilesystemTestSuite.cpp"
|
||||
>
|
||||
@ -1227,6 +1231,10 @@
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\src\DirectoryWatcherTest.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\src\FilesystemTestSuite.h"
|
||||
>
|
||||
|
314
Foundation/testsuite/src/DirectoryWatcherTest.cpp
Normal file
314
Foundation/testsuite/src/DirectoryWatcherTest.cpp
Normal file
@ -0,0 +1,314 @@
|
||||
//
|
||||
// DirectoryWatcherTest.cpp
|
||||
//
|
||||
// $Id: //poco/1.4/Foundation/testsuite/src/DirectoryWatcherTest.cpp#1 $
|
||||
//
|
||||
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "DirectoryWatcherTest.h"
|
||||
#include "CppUnit/TestCaller.h"
|
||||
#include "CppUnit/TestSuite.h"
|
||||
#include "Poco/DirectoryWatcher.h"
|
||||
#include "Poco/Delegate.h"
|
||||
#include "Poco/FileStream.h"
|
||||
|
||||
|
||||
using Poco::DirectoryWatcher;
|
||||
|
||||
|
||||
DirectoryWatcherTest::DirectoryWatcherTest(const std::string& name):
|
||||
CppUnit::TestCase(name),
|
||||
_error(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
DirectoryWatcherTest::~DirectoryWatcherTest()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcherTest::testAdded()
|
||||
{
|
||||
DirectoryWatcher dw(path().toString(), DirectoryWatcher::DW_FILTER_ENABLE_ALL, 2);
|
||||
|
||||
dw.itemAdded += Poco::delegate(this, &DirectoryWatcherTest::onItemAdded);
|
||||
dw.itemRemoved += Poco::delegate(this, &DirectoryWatcherTest::onItemRemoved);
|
||||
dw.itemModified += Poco::delegate(this, &DirectoryWatcherTest::onItemModified);
|
||||
dw.itemMovedFrom += Poco::delegate(this, &DirectoryWatcherTest::onItemMovedFrom);
|
||||
dw.itemMovedTo += Poco::delegate(this, &DirectoryWatcherTest::onItemMovedTo);
|
||||
|
||||
Poco::Thread::sleep(1000);
|
||||
|
||||
Poco::Path p(path());
|
||||
p.setFileName("test.txt");
|
||||
Poco::FileOutputStream fos(p.toString());
|
||||
fos << "Hello, world!";
|
||||
fos.close();
|
||||
|
||||
Poco::Thread::sleep(2000*dw.scanInterval());
|
||||
|
||||
assert (_events.size() >= 1);
|
||||
assert (_events[0].callback == "onItemAdded");
|
||||
assert (Poco::Path(_events[0].path).getFileName() == "test.txt");
|
||||
assert (_events[0].type == DirectoryWatcher::DW_ITEM_ADDED);
|
||||
assert (!_error);
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcherTest::testRemoved()
|
||||
{
|
||||
Poco::Path p(path());
|
||||
p.setFileName("test.txt");
|
||||
Poco::FileOutputStream fos(p.toString());
|
||||
fos << "Hello, world!";
|
||||
fos.close();
|
||||
|
||||
DirectoryWatcher dw(path().toString(), DirectoryWatcher::DW_FILTER_ENABLE_ALL, 2);
|
||||
|
||||
dw.itemAdded += Poco::delegate(this, &DirectoryWatcherTest::onItemAdded);
|
||||
dw.itemRemoved += Poco::delegate(this, &DirectoryWatcherTest::onItemRemoved);
|
||||
dw.itemModified += Poco::delegate(this, &DirectoryWatcherTest::onItemModified);
|
||||
dw.itemMovedFrom += Poco::delegate(this, &DirectoryWatcherTest::onItemMovedFrom);
|
||||
dw.itemMovedTo += Poco::delegate(this, &DirectoryWatcherTest::onItemMovedTo);
|
||||
|
||||
Poco::Thread::sleep(1000);
|
||||
|
||||
Poco::File f(p.toString());
|
||||
f.remove();
|
||||
|
||||
Poco::Thread::sleep(2000*dw.scanInterval());
|
||||
|
||||
assert (_events.size() >= 1);
|
||||
assert (_events[0].callback == "onItemRemoved");
|
||||
assert (Poco::Path(_events[0].path).getFileName() == "test.txt");
|
||||
assert (_events[0].type == DirectoryWatcher::DW_ITEM_REMOVED);
|
||||
assert (!_error);
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcherTest::testModified()
|
||||
{
|
||||
Poco::Path p(path());
|
||||
p.setFileName("test.txt");
|
||||
Poco::FileOutputStream fos(p.toString());
|
||||
fos << "Hello, world!";
|
||||
fos.close();
|
||||
|
||||
DirectoryWatcher dw(path().toString(), DirectoryWatcher::DW_FILTER_ENABLE_ALL, 2);
|
||||
|
||||
dw.itemAdded += Poco::delegate(this, &DirectoryWatcherTest::onItemAdded);
|
||||
dw.itemRemoved += Poco::delegate(this, &DirectoryWatcherTest::onItemRemoved);
|
||||
dw.itemModified += Poco::delegate(this, &DirectoryWatcherTest::onItemModified);
|
||||
dw.itemMovedFrom += Poco::delegate(this, &DirectoryWatcherTest::onItemMovedFrom);
|
||||
dw.itemMovedTo += Poco::delegate(this, &DirectoryWatcherTest::onItemMovedTo);
|
||||
|
||||
Poco::Thread::sleep(1000);
|
||||
|
||||
Poco::FileOutputStream fos2(p.toString(), std::ios::app);
|
||||
fos2 << "Again!";
|
||||
fos2.close();
|
||||
|
||||
Poco::Thread::sleep(2000*dw.scanInterval());
|
||||
|
||||
assert (_events.size() >= 1);
|
||||
assert (_events[0].callback == "onItemModified");
|
||||
assert (Poco::Path(_events[0].path).getFileName() == "test.txt");
|
||||
assert (_events[0].type == DirectoryWatcher::DW_ITEM_MODIFIED);
|
||||
assert (!_error);
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcherTest::testMoved()
|
||||
{
|
||||
Poco::Path p(path());
|
||||
p.setFileName("test.txt");
|
||||
Poco::FileOutputStream fos(p.toString());
|
||||
fos << "Hello, world!";
|
||||
fos.close();
|
||||
|
||||
DirectoryWatcher dw(path().toString(), DirectoryWatcher::DW_FILTER_ENABLE_ALL, 2);
|
||||
|
||||
dw.itemAdded += Poco::delegate(this, &DirectoryWatcherTest::onItemAdded);
|
||||
dw.itemRemoved += Poco::delegate(this, &DirectoryWatcherTest::onItemRemoved);
|
||||
dw.itemModified += Poco::delegate(this, &DirectoryWatcherTest::onItemModified);
|
||||
dw.itemMovedFrom += Poco::delegate(this, &DirectoryWatcherTest::onItemMovedFrom);
|
||||
dw.itemMovedTo += Poco::delegate(this, &DirectoryWatcherTest::onItemMovedTo);
|
||||
|
||||
Poco::Thread::sleep(1000);
|
||||
|
||||
Poco::Path p2(path());
|
||||
p2.setFileName("test2.txt");
|
||||
Poco::File f(p.toString());
|
||||
f.renameTo(p2.toString());
|
||||
|
||||
Poco::Thread::sleep(2000*dw.scanInterval());
|
||||
|
||||
if (dw.supportsMoveEvents())
|
||||
{
|
||||
assert (_events.size() >= 2);
|
||||
assert (
|
||||
(_events[0].callback == "onItemMovedFrom" && _events[1].callback == "onItemMovedTo") ||
|
||||
(_events[1].callback == "onItemMovedFrom" && _events[0].callback == "onItemMovedTo")
|
||||
);
|
||||
assert (
|
||||
(Poco::Path(_events[0].path).getFileName() == "test.txt" && Poco::Path(_events[1].path).getFileName() == "test2.txt") ||
|
||||
(Poco::Path(_events[1].path).getFileName() == "test.txt" && Poco::Path(_events[0].path).getFileName() == "test2.txt")
|
||||
);
|
||||
assert (
|
||||
(_events[0].type == DirectoryWatcher::DW_ITEM_MOVED_FROM && _events[1].type == DirectoryWatcher::DW_ITEM_MOVED_TO) ||
|
||||
(_events[1].type == DirectoryWatcher::DW_ITEM_MOVED_FROM && _events[0].type == DirectoryWatcher::DW_ITEM_MOVED_TO)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert (_events.size() >= 2);
|
||||
assert (
|
||||
(_events[0].callback == "onItemAdded" && _events[1].callback == "onItemRemoved") ||
|
||||
(_events[1].callback == "onItemAdded" && _events[0].callback == "onItemRemoved")
|
||||
);
|
||||
assert (
|
||||
(Poco::Path(_events[0].path).getFileName() == "test.txt" && Poco::Path(_events[1].path).getFileName() == "test2.txt") ||
|
||||
(Poco::Path(_events[1].path).getFileName() == "test.txt" && Poco::Path(_events[0].path).getFileName() == "test2.txt")
|
||||
);
|
||||
assert (
|
||||
(_events[0].type == DirectoryWatcher::DW_ITEM_ADDED && _events[1].type == DirectoryWatcher::DW_ITEM_REMOVED) ||
|
||||
(_events[1].type == DirectoryWatcher::DW_ITEM_ADDED && _events[0].type == DirectoryWatcher::DW_ITEM_REMOVED)
|
||||
);
|
||||
}
|
||||
assert (!_error);
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcherTest::setUp()
|
||||
{
|
||||
_error = false;
|
||||
_events.clear();
|
||||
|
||||
try
|
||||
{
|
||||
Poco::File d(path().toString());
|
||||
d.remove(true);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
|
||||
Poco::File d(path().toString());
|
||||
d.createDirectories();
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcherTest::tearDown()
|
||||
{
|
||||
try
|
||||
{
|
||||
Poco::File d(path().toString());
|
||||
d.remove(true);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcherTest::onItemAdded(const Poco::DirectoryWatcher::DirectoryEvent& ev)
|
||||
{
|
||||
DirEvent de;
|
||||
de.callback = "onItemAdded";
|
||||
de.path = ev.item.path();
|
||||
de.type = ev.event;
|
||||
_events.push_back(de);
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcherTest::onItemRemoved(const Poco::DirectoryWatcher::DirectoryEvent& ev)
|
||||
{
|
||||
DirEvent de;
|
||||
de.callback = "onItemRemoved";
|
||||
de.path = ev.item.path();
|
||||
de.type = ev.event;
|
||||
_events.push_back(de);
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcherTest::onItemModified(const Poco::DirectoryWatcher::DirectoryEvent& ev)
|
||||
{
|
||||
DirEvent de;
|
||||
de.callback = "onItemModified";
|
||||
de.path = ev.item.path();
|
||||
de.type = ev.event;
|
||||
_events.push_back(de);
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcherTest::onItemMovedFrom(const Poco::DirectoryWatcher::DirectoryEvent& ev)
|
||||
{
|
||||
DirEvent de;
|
||||
de.callback = "onItemMovedFrom";
|
||||
de.path = ev.item.path();
|
||||
de.type = ev.event;
|
||||
_events.push_back(de);
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcherTest::onItemMovedTo(const Poco::DirectoryWatcher::DirectoryEvent& ev)
|
||||
{
|
||||
DirEvent de;
|
||||
de.callback = "onItemMovedTo";
|
||||
de.path = ev.item.path();
|
||||
de.type = ev.event;
|
||||
_events.push_back(de);
|
||||
}
|
||||
|
||||
|
||||
void DirectoryWatcherTest::onError(const Poco::Exception& exc)
|
||||
{
|
||||
_error = true;
|
||||
}
|
||||
|
||||
|
||||
Poco::Path DirectoryWatcherTest::path() const
|
||||
{
|
||||
Poco::Path p(Poco::Path::current());
|
||||
p.pushDirectory("DirectoryWatcherTest");
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
CppUnit::Test* DirectoryWatcherTest::suite()
|
||||
{
|
||||
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("DirectoryWatcherTest");
|
||||
|
||||
CppUnit_addTest(pSuite, DirectoryWatcherTest, testAdded);
|
||||
CppUnit_addTest(pSuite, DirectoryWatcherTest, testRemoved);
|
||||
CppUnit_addTest(pSuite, DirectoryWatcherTest, testModified);
|
||||
CppUnit_addTest(pSuite, DirectoryWatcherTest, testMoved);
|
||||
|
||||
return pSuite;
|
||||
}
|
83
Foundation/testsuite/src/DirectoryWatcherTest.h
Normal file
83
Foundation/testsuite/src/DirectoryWatcherTest.h
Normal file
@ -0,0 +1,83 @@
|
||||
//
|
||||
// DirectoryWatcherTest.h
|
||||
//
|
||||
// $Id: //poco/1.4/Foundation/testsuite/src/DirectoryWatcherTest.h#1 $
|
||||
//
|
||||
// Definition of the DirectoryWatcherTest class.
|
||||
//
|
||||
// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#ifndef DirectoryWatcherTest_INCLUDED
|
||||
#define DirectoryWatcherTest_INCLUDED
|
||||
|
||||
|
||||
#include "Poco/Foundation.h"
|
||||
#include "Poco/DirectoryWatcher.h"
|
||||
#include "Poco/Path.h"
|
||||
#include "CppUnit/TestCase.h"
|
||||
|
||||
|
||||
class DirectoryWatcherTest: public CppUnit::TestCase
|
||||
{
|
||||
public:
|
||||
DirectoryWatcherTest(const std::string& name);
|
||||
~DirectoryWatcherTest();
|
||||
|
||||
void testAdded();
|
||||
void testRemoved();
|
||||
void testModified();
|
||||
void testMoved();
|
||||
|
||||
void setUp();
|
||||
void tearDown();
|
||||
|
||||
static CppUnit::Test* suite();
|
||||
|
||||
protected:
|
||||
void onItemAdded(const Poco::DirectoryWatcher::DirectoryEvent& ev);
|
||||
void onItemRemoved(const Poco::DirectoryWatcher::DirectoryEvent& ev);
|
||||
void onItemModified(const Poco::DirectoryWatcher::DirectoryEvent& ev);
|
||||
void onItemMovedFrom(const Poco::DirectoryWatcher::DirectoryEvent& ev);
|
||||
void onItemMovedTo(const Poco::DirectoryWatcher::DirectoryEvent& ev);
|
||||
void onError(const Poco::Exception& exc);
|
||||
|
||||
Poco::Path path() const;
|
||||
|
||||
private:
|
||||
struct DirEvent
|
||||
{
|
||||
Poco::DirectoryWatcher::DirectoryEventType type;
|
||||
std::string callback;
|
||||
std::string path;
|
||||
};
|
||||
std::vector<DirEvent> _events;
|
||||
bool _error;
|
||||
};
|
||||
|
||||
|
||||
#endif // DirectoryWatcherTest_INCLUDED
|
@ -34,6 +34,7 @@
|
||||
#include "PathTest.h"
|
||||
#include "FileTest.h"
|
||||
#include "GlobTest.h"
|
||||
#include "DirectoryWatcherTest.h"
|
||||
|
||||
|
||||
CppUnit::Test* FilesystemTestSuite::suite()
|
||||
@ -43,6 +44,7 @@ CppUnit::Test* FilesystemTestSuite::suite()
|
||||
pSuite->addTest(PathTest::suite());
|
||||
pSuite->addTest(FileTest::suite());
|
||||
pSuite->addTest(GlobTest::suite());
|
||||
pSuite->addTest(DirectoryWatcherTest::suite());
|
||||
|
||||
return pSuite;
|
||||
}
|
||||
|
@ -1406,7 +1406,11 @@ void VarTest::testConversionOperator()
|
||||
assert (any == i);
|
||||
|
||||
any = 123;
|
||||
#if defined(_MSC_VER) // gcc bombs on s(any)
|
||||
std::string s(any);
|
||||
#else
|
||||
std::string s = any;
|
||||
#endif
|
||||
assert (s == "123");
|
||||
assert (s == any);
|
||||
assert (any == s);
|
||||
|
Loading…
x
Reference in New Issue
Block a user