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
52
CHANGELOG
52
CHANGELOG
@ -28,7 +28,6 @@ Release 1.5.0 (2012-08-??)
|
|||||||
- added IPAddress RFC 4291 compatible site-local prefix support
|
- added IPAddress RFC 4291 compatible site-local prefix support
|
||||||
- fixed SF#3012166: IPv6 patch
|
- fixed SF#3012166: IPv6 patch
|
||||||
- added SF#3558085: Add formatter to MACAddress object
|
- 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#3552774: Don't hide default target in subordinate makefile
|
||||||
- fixed SF#3534307: Building IPv6 for Linux by default
|
- fixed SF#3534307: Building IPv6 for Linux by default
|
||||||
- fixed SF#3516844: poco missing symbols with external >=lipcre-8.13
|
- fixed SF#3516844: poco missing symbols with external >=lipcre-8.13
|
||||||
@ -47,15 +46,15 @@ Release 1.4.4 (2012-08-??)
|
|||||||
handshake is enabled and the first attempt to complete the handshake fails
|
handshake is enabled and the first attempt to complete the handshake fails
|
||||||
- Poco::DateTimeParser::tryParse() without format specifier now correctly parses ISO8601
|
- Poco::DateTimeParser::tryParse() without format specifier now correctly parses ISO8601
|
||||||
date/times with fractional seconds.
|
date/times with fractional seconds.
|
||||||
- Poco::Process::launch() now has additional overloads allowing to specify an initial
|
- Poco::Process::launch() now has additional overloads allowing to specify an initial
|
||||||
directory and/or environment.
|
directory and/or environment.
|
||||||
- Poco::Net::FTPClientSession: timeout was not applied to data connection, only to
|
- Poco::Net::FTPClientSession: timeout was not applied to data connection, only to
|
||||||
control connection.
|
control connection.
|
||||||
- Fixed potential IPv6 issue with socket constructors if IPv6 SocketAddress is given
|
- Fixed potential IPv6 issue with socket constructors if IPv6 SocketAddress is given
|
||||||
(contributed by ??????? ????????? <milovidov@yandex-team.ru>).
|
(contributed by ??????? ????????? <milovidov@yandex-team.ru>).
|
||||||
- Added an additional (optional) parameter to Poco::Thread::setOSPriority() allowing to
|
- Added an additional (optional) parameter to Poco::Thread::setOSPriority() allowing to
|
||||||
specify a scheduling policy. Currently this is only used on POSIX platforms and allows
|
specify a scheduling policy. Currently this is only used on POSIX platforms and allows
|
||||||
specifying SCHED_OTHER (default), SCHED_FIFO or SCHED_RR, as well as other
|
specifying SCHED_OTHER (default), SCHED_FIFO or SCHED_RR, as well as other
|
||||||
platform-specific policy values.
|
platform-specific policy values.
|
||||||
- Added Poco::Crypto::DigestEngine class providing a Poco::DigestEngine interface to
|
- Added Poco::Crypto::DigestEngine class providing a Poco::DigestEngine interface to
|
||||||
the digest algorithms provided by OpenSSL.
|
the digest algorithms provided by OpenSSL.
|
||||||
@ -63,13 +62,50 @@ Release 1.4.4 (2012-08-??)
|
|||||||
- In some cases, when an SSL exception was unexpectedly closed, a generic Poco::IOException
|
- In some cases, when an SSL exception was unexpectedly closed, a generic Poco::IOException
|
||||||
was thrown. This was fixed to throw a SSLConnectionUnexpectedlyClosedException instead.
|
was thrown. This was fixed to throw a SSLConnectionUnexpectedlyClosedException instead.
|
||||||
- Added Poco::ObjectPool class template.
|
- Added Poco::ObjectPool class template.
|
||||||
- Poco::Net::HTTPServer has a new stopAll() method allowing stopping/aborting of all
|
- Poco::Net::HTTPServer has a new stopAll() method allowing stopping/aborting of all
|
||||||
currently active client connections.
|
currently active client connections.
|
||||||
- The HTTP server framework now actively prevents sending a message body in the
|
- The HTTP server framework now actively prevents sending a message body in the
|
||||||
response to a HEAD request, or in case of a 204 No Content or 304 Not Modified
|
response to a HEAD request, or in case of a 204 No Content or 304 Not Modified
|
||||||
response status.
|
response status.
|
||||||
- fixed a DOM parser performance bug (patch by Peter Klotz)
|
- fixed a DOM parser performance bug (patch by Peter Klotz)
|
||||||
- fixed SF# 3559325: Util Windows broken in non-Unicode
|
- 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)
|
Release 1.4.3p1 (2012-01-23)
|
||||||
============================
|
============================
|
||||||
|
@ -33,6 +33,7 @@ SOURCES="
|
|||||||
DigestEngine.cpp
|
DigestEngine.cpp
|
||||||
DigestStream.cpp
|
DigestStream.cpp
|
||||||
DirectoryIterator.cpp
|
DirectoryIterator.cpp
|
||||||
|
DirectoryWatcher.cpp
|
||||||
DynamicAny.cpp
|
DynamicAny.cpp
|
||||||
DynamicAnyHolder.cpp
|
DynamicAnyHolder.cpp
|
||||||
Environment.cpp
|
Environment.cpp
|
||||||
|
@ -3229,6 +3229,10 @@
|
|||||||
/>
|
/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\DirectoryWatcher.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\File.cpp"
|
RelativePath=".\src\File.cpp"
|
||||||
>
|
>
|
||||||
@ -3789,6 +3793,10 @@
|
|||||||
RelativePath=".\include\Poco\DirectoryIterator_WIN32U.h"
|
RelativePath=".\include\Poco\DirectoryIterator_WIN32U.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\include\Poco\DirectoryWatcher.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\include\Poco\File.h"
|
RelativePath=".\include\Poco\File.h"
|
||||||
>
|
>
|
||||||
|
@ -290,6 +290,7 @@
|
|||||||
<ClCompile Include="src\ByteOrder.cpp" />
|
<ClCompile Include="src\ByteOrder.cpp" />
|
||||||
<ClCompile Include="src\Checksum.cpp" />
|
<ClCompile Include="src\Checksum.cpp" />
|
||||||
<ClCompile Include="src\Debugger.cpp" />
|
<ClCompile Include="src\Debugger.cpp" />
|
||||||
|
<ClCompile Include="src\DirectoryWatcher.cpp" />
|
||||||
<ClCompile Include="src\Environment.cpp" />
|
<ClCompile Include="src\Environment.cpp" />
|
||||||
<ClCompile Include="src\Environment_UNIX.cpp">
|
<ClCompile Include="src\Environment_UNIX.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'">true</ExcludedFromBuild>
|
||||||
@ -976,6 +977,7 @@
|
|||||||
<ClInclude Include="include\Poco\ByteOrder.h" />
|
<ClInclude Include="include\Poco\ByteOrder.h" />
|
||||||
<ClInclude Include="include\Poco\Checksum.h" />
|
<ClInclude Include="include\Poco\Checksum.h" />
|
||||||
<ClInclude Include="include\Poco\Config.h" />
|
<ClInclude Include="include\Poco\Config.h" />
|
||||||
|
<ClInclude Include="include\Poco\DirectoryWatcher.h" />
|
||||||
<ClInclude Include="include\Poco\Debugger.h" />
|
<ClInclude Include="include\Poco\Debugger.h" />
|
||||||
<ClInclude Include="include\Poco\DynamicAny.h" />
|
<ClInclude Include="include\Poco\DynamicAny.h" />
|
||||||
<ClInclude Include="include\Poco\DynamicAnyHolder.h" />
|
<ClInclude Include="include\Poco\DynamicAnyHolder.h" />
|
||||||
|
@ -861,6 +861,9 @@
|
|||||||
<ClCompile Include="src\HashStatistic.cpp">
|
<ClCompile Include="src\HashStatistic.cpp">
|
||||||
<Filter>Hashing\Source Files</Filter>
|
<Filter>Hashing\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\DirectoryWatcher.cpp">
|
||||||
|
<Filter>Filesystem\Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="src\Var.cpp">
|
<ClCompile Include="src\Var.cpp">
|
||||||
<Filter>Dynamic\Source Files</Filter>
|
<Filter>Dynamic\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -1784,6 +1787,12 @@
|
|||||||
<ClInclude Include="include\Poco\PriorityStrategy.h">
|
<ClInclude Include="include\Poco\PriorityStrategy.h">
|
||||||
<Filter>Events\Header Files</Filter>
|
<Filter>Events\Header Files</Filter>
|
||||||
</ClInclude>
|
</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">
|
<ClInclude Include="include\Poco\Dynamic\Pair.h">
|
||||||
<Filter>Dynamic\Header Files</Filter>
|
<Filter>Dynamic\Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -2903,6 +2903,9 @@
|
|||||||
Name="VCCLCompilerTool"/>
|
Name="VCCLCompilerTool"/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\DirectoryWatcher.cpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\File.cpp">
|
RelativePath=".\src\File.cpp">
|
||||||
</File>
|
</File>
|
||||||
@ -3246,6 +3249,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath=".\include\Poco\DirectoryIterator_WIN32U.h">
|
RelativePath=".\include\Poco\DirectoryIterator_WIN32U.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\include\Poco\DirectoryWatcher.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\include\Poco\File.h">
|
RelativePath=".\include\Poco\File.h">
|
||||||
</File>
|
</File>
|
||||||
|
@ -3737,6 +3737,10 @@
|
|||||||
/>
|
/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\DirectoryWatcher.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\File.cpp"
|
RelativePath=".\src\File.cpp"
|
||||||
>
|
>
|
||||||
@ -4193,6 +4197,10 @@
|
|||||||
RelativePath=".\include\Poco\DirectoryIterator_WIN32U.h"
|
RelativePath=".\include\Poco\DirectoryIterator_WIN32U.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\include\Poco\DirectoryWatcher.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\include\Poco\File.h"
|
RelativePath=".\include\Poco\File.h"
|
||||||
>
|
>
|
||||||
|
@ -3730,6 +3730,10 @@
|
|||||||
/>
|
/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\DirectoryWatcher.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\File.cpp"
|
RelativePath=".\src\File.cpp"
|
||||||
>
|
>
|
||||||
@ -4186,6 +4190,10 @@
|
|||||||
RelativePath=".\include\Poco\DirectoryIterator_WIN32U.h"
|
RelativePath=".\include\Poco\DirectoryIterator_WIN32U.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\include\Poco\DirectoryWatcher.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\include\Poco\File.h"
|
RelativePath=".\include\Poco\File.h"
|
||||||
>
|
>
|
||||||
|
@ -300,6 +300,7 @@
|
|||||||
<ClCompile Include="src\ByteOrder.cpp" />
|
<ClCompile Include="src\ByteOrder.cpp" />
|
||||||
<ClCompile Include="src\Checksum.cpp" />
|
<ClCompile Include="src\Checksum.cpp" />
|
||||||
<ClCompile Include="src\Debugger.cpp" />
|
<ClCompile Include="src\Debugger.cpp" />
|
||||||
|
<ClCompile Include="src\DirectoryWatcher.cpp" />
|
||||||
<ClCompile Include="src\Environment.cpp" />
|
<ClCompile Include="src\Environment.cpp" />
|
||||||
<ClCompile Include="src\Environment_UNIX.cpp">
|
<ClCompile Include="src\Environment_UNIX.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'">true</ExcludedFromBuild>
|
||||||
@ -985,6 +986,7 @@
|
|||||||
<ClInclude Include="include\Poco\Checksum.h" />
|
<ClInclude Include="include\Poco\Checksum.h" />
|
||||||
<ClInclude Include="include\Poco\Config.h" />
|
<ClInclude Include="include\Poco\Config.h" />
|
||||||
<ClInclude Include="include\Poco\Debugger.h" />
|
<ClInclude Include="include\Poco\Debugger.h" />
|
||||||
|
<ClInclude Include="include\Poco\DirectoryWatcher.h" />
|
||||||
<ClInclude Include="include\Poco\DynamicAny.h" />
|
<ClInclude Include="include\Poco\DynamicAny.h" />
|
||||||
<ClInclude Include="include\Poco\DynamicAnyHolder.h" />
|
<ClInclude Include="include\Poco\DynamicAnyHolder.h" />
|
||||||
<ClInclude Include="include\Poco\DynamicFactory.h" />
|
<ClInclude Include="include\Poco\DynamicFactory.h" />
|
||||||
|
@ -861,6 +861,9 @@
|
|||||||
<ClCompile Include="src\HashStatistic.cpp">
|
<ClCompile Include="src\HashStatistic.cpp">
|
||||||
<Filter>Hashing\Source Files</Filter>
|
<Filter>Hashing\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\DirectoryWatcher.cpp">
|
||||||
|
<Filter>Filesystem\Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="src\FIFOBufferStream.cpp">
|
<ClCompile Include="src\FIFOBufferStream.cpp">
|
||||||
<Filter>Streams\Source Files</Filter>
|
<Filter>Streams\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -1805,6 +1808,12 @@
|
|||||||
<ClInclude Include="include\Poco\Windows1250Encoding.h">
|
<ClInclude Include="include\Poco\Windows1250Encoding.h">
|
||||||
<Filter>Text\Header Files</Filter>
|
<Filter>Text\Header Files</Filter>
|
||||||
</ClInclude>
|
</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>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="src\pocomsg.rc">
|
<ResourceCompile Include="src\pocomsg.rc">
|
||||||
|
@ -3728,6 +3728,10 @@
|
|||||||
/>
|
/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\DirectoryWatcher.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\File.cpp"
|
RelativePath=".\src\File.cpp"
|
||||||
>
|
>
|
||||||
@ -4184,6 +4188,10 @@
|
|||||||
RelativePath=".\include\Poco\DirectoryIterator_WIN32U.h"
|
RelativePath=".\include\Poco\DirectoryIterator_WIN32U.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\include\Poco\DirectoryWatcher.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\include\Poco\File.h"
|
RelativePath=".\include\Poco\File.h"
|
||||||
>
|
>
|
||||||
|
@ -11,7 +11,7 @@ include $(POCO_BASE)/build/rules/global
|
|||||||
objects = ArchiveStrategy Ascii ASCIIEncoding AsyncChannel Base64Decoder Base64Encoder \
|
objects = ArchiveStrategy Ascii ASCIIEncoding AsyncChannel Base64Decoder Base64Encoder \
|
||||||
BinaryReader BinaryWriter Bugcheck ByteOrder Channel Checksum Configurable ConsoleChannel \
|
BinaryReader BinaryWriter Bugcheck ByteOrder Channel Checksum Configurable ConsoleChannel \
|
||||||
CountingStream DateTime LocalDateTime DateTimeFormat DateTimeFormatter DateTimeParser \
|
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 \
|
Environment Event EventArgs ErrorHandler Exception FIFOBufferStream FPEnvironment File \
|
||||||
FileChannel Formatter FormattingChannel Glob HexBinaryDecoder LineEndingConverter \
|
FileChannel Formatter FormattingChannel Glob HexBinaryDecoder LineEndingConverter \
|
||||||
HexBinaryEncoder InflatingStream Latin1Encoding Latin2Encoding Latin9Encoding LogFile \
|
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;
|
std::string _path;
|
||||||
|
|
||||||
friend class DirectoryIteratorImpl;
|
friend class DirectoryIteratorImpl;
|
||||||
|
friend class LinuxDirectoryWatcherStrategy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,6 +86,7 @@ private:
|
|||||||
|
|
||||||
friend class FileHandle;
|
friend class FileHandle;
|
||||||
friend class DirectoryIteratorImpl;
|
friend class DirectoryIteratorImpl;
|
||||||
|
friend class WindowsDirectoryWatcherStrategy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -87,6 +87,7 @@ private:
|
|||||||
|
|
||||||
friend class FileHandle;
|
friend class FileHandle;
|
||||||
friend class DirectoryIteratorImpl;
|
friend class DirectoryIteratorImpl;
|
||||||
|
friend class WindowsDirectoryWatcherStrategy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,13 +102,15 @@
|
|||||||
|
|
||||||
// Turn off some annoying warnings
|
// Turn off some annoying warnings
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(disable:4018) // signed/unsigned comparison
|
#pragma warning(disable:4018) // signed/unsigned comparison
|
||||||
#pragma warning(disable:4251) // ... needs to have dll-interface warning
|
#pragma warning(disable:4251) // ... needs to have dll-interface warning
|
||||||
#pragma warning(disable:4355) // 'this' : used in base member initializer list
|
#pragma warning(disable:4355) // 'this' : used in base member initializer list
|
||||||
#pragma warning(disable:4996) // VC++ 8.0 deprecation warnings
|
#pragma warning(disable:4996) // VC++ 8.0 deprecation warnings
|
||||||
#pragma warning(disable:4351) // new behavior: elements of array '...' will be default initialized
|
#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: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: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
|
#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());
|
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());
|
DWORD type = GetFileType(fh.get());
|
||||||
if (type == FILE_TYPE_CHAR)
|
if (type == FILE_TYPE_CHAR)
|
||||||
return true;
|
return true;
|
||||||
|
@ -9,37 +9,37 @@
|
|||||||
include $(POCO_BASE)/build/rules/global
|
include $(POCO_BASE)/build/rules/global
|
||||||
|
|
||||||
objects = ActiveMethodTest ActivityTest ActiveDispatcherTest \
|
objects = ActiveMethodTest ActivityTest ActiveDispatcherTest \
|
||||||
AutoPtrTest ArrayTest SharedPtrTest AutoReleasePoolTest Base64Test \
|
AutoPtrTest ArrayTest SharedPtrTest AutoReleasePoolTest Base64Test \
|
||||||
BinaryReaderWriterTest LineEndingConverterTest \
|
BinaryReaderWriterTest LineEndingConverterTest \
|
||||||
ByteOrderTest ChannelTest ClassLoaderTest CoreTest CoreTestSuite \
|
ByteOrderTest ChannelTest ClassLoaderTest CoreTest CoreTestSuite \
|
||||||
CountingStreamTest CryptTestSuite DateTimeFormatterTest \
|
CountingStreamTest CryptTestSuite DateTimeFormatterTest \
|
||||||
DateTimeParserTest DateTimeTest LocalDateTimeTest DateTimeTestSuite DigestStreamTest \
|
DateTimeParserTest DateTimeTest LocalDateTimeTest DateTimeTestSuite DigestStreamTest \
|
||||||
Driver DynamicFactoryTest FPETest FileChannelTest FileTest GlobTest FilesystemTestSuite \
|
Driver DynamicFactoryTest FPETest FileChannelTest FileTest GlobTest FilesystemTestSuite \
|
||||||
FIFOBufferStreamTest FoundationTestSuite HMACEngineTest HexBinaryTest LoggerTest \
|
FIFOBufferStreamTest FoundationTestSuite HMACEngineTest HexBinaryTest LoggerTest \
|
||||||
LoggingFactoryTest LoggingRegistryTest LoggingTestSuite LogStreamTest \
|
LoggingFactoryTest LoggingRegistryTest LoggingTestSuite LogStreamTest \
|
||||||
NamedEventTest NamedMutexTest ProcessesTestSuite ProcessTest \
|
NamedEventTest NamedMutexTest ProcessesTestSuite ProcessTest \
|
||||||
MemoryPoolTest MD4EngineTest MD5EngineTest ManifestTest \
|
MemoryPoolTest MD4EngineTest MD5EngineTest ManifestTest \
|
||||||
NDCTest NotificationCenterTest NotificationQueueTest \
|
NDCTest NotificationCenterTest NotificationQueueTest \
|
||||||
PriorityNotificationQueueTest TimedNotificationQueueTest \
|
PriorityNotificationQueueTest TimedNotificationQueueTest \
|
||||||
NotificationsTestSuite NullStreamTest NumberFormatterTest \
|
NotificationsTestSuite NullStreamTest NumberFormatterTest \
|
||||||
NumberParserTest PathTest PatternFormatterTest RWLockTest \
|
NumberParserTest PathTest PatternFormatterTest RWLockTest \
|
||||||
RandomStreamTest RandomTest RegularExpressionTest SHA1EngineTest \
|
RandomStreamTest RandomTest RegularExpressionTest SHA1EngineTest \
|
||||||
SemaphoreTest ConditionTest SharedLibraryTest SharedLibraryTestSuite \
|
SemaphoreTest ConditionTest SharedLibraryTest SharedLibraryTestSuite \
|
||||||
SimpleFileChannelTest StopwatchTest \
|
SimpleFileChannelTest StopwatchTest \
|
||||||
StreamConverterTest StreamCopierTest StreamTokenizerTest \
|
StreamConverterTest StreamCopierTest StreamTokenizerTest \
|
||||||
StreamsTestSuite StringTest StringTokenizerTest TaskTestSuite TaskTest \
|
StreamsTestSuite StringTest StringTokenizerTest TaskTestSuite TaskTest \
|
||||||
TaskManagerTest TestChannel TeeStreamTest UTF8StringTest \
|
TaskManagerTest TestChannel TeeStreamTest UTF8StringTest \
|
||||||
TextConverterTest TextIteratorTest TextBufferIteratorTest TextTestSuite TextEncodingTest \
|
TextConverterTest TextIteratorTest TextBufferIteratorTest TextTestSuite TextEncodingTest \
|
||||||
ThreadLocalTest ThreadPoolTest ThreadTest ThreadingTestSuite TimerTest \
|
ThreadLocalTest ThreadPoolTest ThreadTest ThreadingTestSuite TimerTest \
|
||||||
TimespanTest TimestampTest TimezoneTest URIStreamOpenerTest URITest \
|
TimespanTest TimestampTest TimezoneTest URIStreamOpenerTest URITest \
|
||||||
URITestSuite UUIDGeneratorTest UUIDTest UUIDTestSuite ZLibTest \
|
URITestSuite UUIDGeneratorTest UUIDTest UUIDTestSuite ZLibTest \
|
||||||
TestPlugin DummyDelegate BasicEventTest FIFOEventTest PriorityEventTest EventTestSuite \
|
TestPlugin DummyDelegate BasicEventTest FIFOEventTest PriorityEventTest EventTestSuite \
|
||||||
LRUCacheTest ExpireCacheTest ExpireLRUCacheTest CacheTestSuite AnyTest FormatTest \
|
LRUCacheTest ExpireCacheTest ExpireLRUCacheTest CacheTestSuite AnyTest FormatTest \
|
||||||
HashingTestSuite HashTableTest SimpleHashTableTest LinearHashTableTest \
|
HashingTestSuite HashTableTest SimpleHashTableTest LinearHashTableTest \
|
||||||
HashSetTest HashMapTest SharedMemoryTest \
|
HashSetTest HashMapTest SharedMemoryTest \
|
||||||
UniqueExpireCacheTest UniqueExpireLRUCacheTest UnicodeConverterTest \
|
UniqueExpireCacheTest UniqueExpireLRUCacheTest UnicodeConverterTest \
|
||||||
TuplesTest NamedTuplesTest TypeListTest VarTest DynamicTestSuite FileStreamTest \
|
TuplesTest NamedTuplesTest TypeListTest VarTest DynamicTestSuite FileStreamTest \
|
||||||
MemoryStreamTest ObjectPoolTest
|
MemoryStreamTest ObjectPoolTest DirectoryWatcherTest
|
||||||
|
|
||||||
target = testrunner
|
target = testrunner
|
||||||
target_version = 1
|
target_version = 1
|
||||||
|
@ -30,6 +30,7 @@ SOURCES="
|
|||||||
DateTimeTest.cpp
|
DateTimeTest.cpp
|
||||||
DateTimeTestSuite.cpp
|
DateTimeTestSuite.cpp
|
||||||
DigestStreamTest.cpp
|
DigestStreamTest.cpp
|
||||||
|
DirectoryWatcherTest.cpp
|
||||||
Driver.cpp
|
Driver.cpp
|
||||||
DummyDelegate.cpp
|
DummyDelegate.cpp
|
||||||
DynamicAnyTest.cpp
|
DynamicAnyTest.cpp
|
||||||
|
@ -1261,6 +1261,10 @@
|
|||||||
<Filter
|
<Filter
|
||||||
Name="Source Files"
|
Name="Source Files"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\DirectoryWatcherTest.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\FilesystemTestSuite.cpp"
|
RelativePath=".\src\FilesystemTestSuite.cpp"
|
||||||
>
|
>
|
||||||
@ -1281,6 +1285,10 @@
|
|||||||
<Filter
|
<Filter
|
||||||
Name="Header Files"
|
Name="Header Files"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\DirectoryWatcherTest.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\FilesystemTestSuite.h"
|
RelativePath=".\src\FilesystemTestSuite.h"
|
||||||
>
|
>
|
||||||
|
@ -307,6 +307,7 @@
|
|||||||
<ClCompile Include="src\ByteOrderTest.cpp" />
|
<ClCompile Include="src\ByteOrderTest.cpp" />
|
||||||
<ClCompile Include="src\CoreTest.cpp" />
|
<ClCompile Include="src\CoreTest.cpp" />
|
||||||
<ClCompile Include="src\CoreTestSuite.cpp" />
|
<ClCompile Include="src\CoreTestSuite.cpp" />
|
||||||
|
<ClCompile Include="src\DirectoryWatcherTest.cpp" />
|
||||||
<ClCompile Include="src\DynamicFactoryTest.cpp" />
|
<ClCompile Include="src\DynamicFactoryTest.cpp" />
|
||||||
<ClCompile Include="src\FIFOBufferStreamTest.cpp" />
|
<ClCompile Include="src\FIFOBufferStreamTest.cpp" />
|
||||||
<ClCompile Include="src\FormatTest.cpp" />
|
<ClCompile Include="src\FormatTest.cpp" />
|
||||||
@ -439,6 +440,7 @@
|
|||||||
<ClInclude Include="src\ByteOrderTest.h" />
|
<ClInclude Include="src\ByteOrderTest.h" />
|
||||||
<ClInclude Include="src\CoreTest.h" />
|
<ClInclude Include="src\CoreTest.h" />
|
||||||
<ClInclude Include="src\CoreTestSuite.h" />
|
<ClInclude Include="src\CoreTestSuite.h" />
|
||||||
|
<ClInclude Include="src\DirectoryWatcherTest.h" />
|
||||||
<ClInclude Include="src\DynamicFactoryTest.h" />
|
<ClInclude Include="src\DynamicFactoryTest.h" />
|
||||||
<ClInclude Include="src\FIFOBufferStreamTest.h" />
|
<ClInclude Include="src\FIFOBufferStreamTest.h" />
|
||||||
<ClInclude Include="src\FormatTest.h" />
|
<ClInclude Include="src\FormatTest.h" />
|
||||||
|
@ -561,6 +561,9 @@
|
|||||||
<ClCompile Include="src\ObjectPoolTest.cpp">
|
<ClCompile Include="src\ObjectPoolTest.cpp">
|
||||||
<Filter>Core\Source Files</Filter>
|
<Filter>Core\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\DirectoryWatcherTest.cpp">
|
||||||
|
<Filter>Filesystem\Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="src\VarTest.cpp">
|
<ClCompile Include="src\VarTest.cpp">
|
||||||
<Filter>Dynamic\Source Files</Filter>
|
<Filter>Dynamic\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -950,6 +953,9 @@
|
|||||||
<ClInclude Include="src\ObjectPoolTest.h">
|
<ClInclude Include="src\ObjectPoolTest.h">
|
||||||
<Filter>Core\Header Files</Filter>
|
<Filter>Core\Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\DirectoryWatcherTest.h">
|
||||||
|
<Filter>Filesystem\Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="src\VarTest.h">
|
<ClInclude Include="src\VarTest.h">
|
||||||
<Filter>Dynamic\Header Files</Filter>
|
<Filter>Dynamic\Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -925,6 +925,9 @@
|
|||||||
<Filter
|
<Filter
|
||||||
Name="Source Files"
|
Name="Source Files"
|
||||||
Filter="">
|
Filter="">
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\DirectoryWatcherTest.cpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\FilesystemTestSuite.cpp">
|
RelativePath=".\src\FilesystemTestSuite.cpp">
|
||||||
</File>
|
</File>
|
||||||
@ -941,6 +944,9 @@
|
|||||||
<Filter
|
<Filter
|
||||||
Name="Header Files"
|
Name="Header Files"
|
||||||
Filter="">
|
Filter="">
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\DirectoryWatcherTest.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\FilesystemTestSuite.h">
|
RelativePath=".\src\FilesystemTestSuite.h">
|
||||||
</File>
|
</File>
|
||||||
|
@ -1239,6 +1239,10 @@
|
|||||||
<Filter
|
<Filter
|
||||||
Name="Source Files"
|
Name="Source Files"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\DirectoryWatcherTest.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\FilesystemTestSuite.cpp"
|
RelativePath=".\src\FilesystemTestSuite.cpp"
|
||||||
>
|
>
|
||||||
@ -1259,6 +1263,10 @@
|
|||||||
<Filter
|
<Filter
|
||||||
Name="Header Files"
|
Name="Header Files"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\DirectoryWatcherTest.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\FilesystemTestSuite.h"
|
RelativePath=".\src\FilesystemTestSuite.h"
|
||||||
>
|
>
|
||||||
|
@ -1225,6 +1225,10 @@
|
|||||||
<Filter
|
<Filter
|
||||||
Name="Source Files"
|
Name="Source Files"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\DirectoryWatcherTest.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\FilesystemTestSuite.cpp"
|
RelativePath=".\src\FilesystemTestSuite.cpp"
|
||||||
>
|
>
|
||||||
@ -1245,6 +1249,10 @@
|
|||||||
<Filter
|
<Filter
|
||||||
Name="Header Files"
|
Name="Header Files"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\DirectoryWatcherTest.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\FilesystemTestSuite.h"
|
RelativePath=".\src\FilesystemTestSuite.h"
|
||||||
>
|
>
|
||||||
|
@ -307,6 +307,7 @@
|
|||||||
<ClCompile Include="src\ByteOrderTest.cpp" />
|
<ClCompile Include="src\ByteOrderTest.cpp" />
|
||||||
<ClCompile Include="src\CoreTest.cpp" />
|
<ClCompile Include="src\CoreTest.cpp" />
|
||||||
<ClCompile Include="src\CoreTestSuite.cpp" />
|
<ClCompile Include="src\CoreTestSuite.cpp" />
|
||||||
|
<ClCompile Include="src\DirectoryWatcherTest.cpp" />
|
||||||
<ClCompile Include="src\DynamicFactoryTest.cpp" />
|
<ClCompile Include="src\DynamicFactoryTest.cpp" />
|
||||||
<ClCompile Include="src\FIFOBufferStreamTest.cpp" />
|
<ClCompile Include="src\FIFOBufferStreamTest.cpp" />
|
||||||
<ClCompile Include="src\FormatTest.cpp" />
|
<ClCompile Include="src\FormatTest.cpp" />
|
||||||
@ -439,6 +440,7 @@
|
|||||||
<ClInclude Include="src\ByteOrderTest.h" />
|
<ClInclude Include="src\ByteOrderTest.h" />
|
||||||
<ClInclude Include="src\CoreTest.h" />
|
<ClInclude Include="src\CoreTest.h" />
|
||||||
<ClInclude Include="src\CoreTestSuite.h" />
|
<ClInclude Include="src\CoreTestSuite.h" />
|
||||||
|
<ClInclude Include="src\DirectoryWatcherTest.h" />
|
||||||
<ClInclude Include="src\DynamicAnyTest.h" />
|
<ClInclude Include="src\DynamicAnyTest.h" />
|
||||||
<ClInclude Include="src\DynamicFactoryTest.h" />
|
<ClInclude Include="src\DynamicFactoryTest.h" />
|
||||||
<ClInclude Include="src\FIFOBufferStreamTest.h" />
|
<ClInclude Include="src\FIFOBufferStreamTest.h" />
|
||||||
|
@ -561,6 +561,9 @@
|
|||||||
<ClCompile Include="src\ObjectPoolTest.cpp">
|
<ClCompile Include="src\ObjectPoolTest.cpp">
|
||||||
<Filter>Core\Source Files</Filter>
|
<Filter>Core\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\DirectoryWatcherTest.cpp">
|
||||||
|
<Filter>Filesystem\Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="src\VarTest.cpp">
|
<ClCompile Include="src\VarTest.cpp">
|
||||||
<Filter>Dynamic\Source Files</Filter>
|
<Filter>Dynamic\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -953,6 +956,9 @@
|
|||||||
<ClInclude Include="src\ObjectPoolTest.h">
|
<ClInclude Include="src\ObjectPoolTest.h">
|
||||||
<Filter>Core\Header Files</Filter>
|
<Filter>Core\Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\DirectoryWatcherTest.h">
|
||||||
|
<Filter>Filesystem\Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="src\VarTest.h">
|
<ClInclude Include="src\VarTest.h">
|
||||||
<Filter>Dynamic\Header Files</Filter>
|
<Filter>Dynamic\Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -1207,6 +1207,10 @@
|
|||||||
<Filter
|
<Filter
|
||||||
Name="Source Files"
|
Name="Source Files"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\DirectoryWatcherTest.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\FilesystemTestSuite.cpp"
|
RelativePath=".\src\FilesystemTestSuite.cpp"
|
||||||
>
|
>
|
||||||
@ -1227,6 +1231,10 @@
|
|||||||
<Filter
|
<Filter
|
||||||
Name="Header Files"
|
Name="Header Files"
|
||||||
>
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\src\DirectoryWatcherTest.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\FilesystemTestSuite.h"
|
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 "PathTest.h"
|
||||||
#include "FileTest.h"
|
#include "FileTest.h"
|
||||||
#include "GlobTest.h"
|
#include "GlobTest.h"
|
||||||
|
#include "DirectoryWatcherTest.h"
|
||||||
|
|
||||||
|
|
||||||
CppUnit::Test* FilesystemTestSuite::suite()
|
CppUnit::Test* FilesystemTestSuite::suite()
|
||||||
@ -43,6 +44,7 @@ CppUnit::Test* FilesystemTestSuite::suite()
|
|||||||
pSuite->addTest(PathTest::suite());
|
pSuite->addTest(PathTest::suite());
|
||||||
pSuite->addTest(FileTest::suite());
|
pSuite->addTest(FileTest::suite());
|
||||||
pSuite->addTest(GlobTest::suite());
|
pSuite->addTest(GlobTest::suite());
|
||||||
|
pSuite->addTest(DirectoryWatcherTest::suite());
|
||||||
|
|
||||||
return pSuite;
|
return pSuite;
|
||||||
}
|
}
|
||||||
|
@ -1406,7 +1406,11 @@ void VarTest::testConversionOperator()
|
|||||||
assert (any == i);
|
assert (any == i);
|
||||||
|
|
||||||
any = 123;
|
any = 123;
|
||||||
|
#if defined(_MSC_VER) // gcc bombs on s(any)
|
||||||
|
std::string s(any);
|
||||||
|
#else
|
||||||
std::string s = any;
|
std::string s = any;
|
||||||
|
#endif
|
||||||
assert (s == "123");
|
assert (s == "123");
|
||||||
assert (s == any);
|
assert (s == any);
|
||||||
assert (any == s);
|
assert (any == s);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user