aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2024-05-29 12:23:06 +0200
committerOvahlord <dreadkiller@gmx.de>2024-06-20 01:13:20 +0200
commit6b89285966d8d21a5f43dac702d50b917f71b19d (patch)
treefdddad39ff2dff72a0beaf382b623737d5c614f6
parentd8c0b72006539951376fc86dbee245822f732e19 (diff)
Dep/efsw: Update to SpartanJ/efsw@36c1c7004a34b6f40719f0830bcfb10325415451
(cherry picked from commit 937e61853319ac0e5b29f0bcbe5390a71cb7625f)
-rw-r--r--dep/PackageList.txt6
-rw-r--r--dep/efsw/.hg_archival.txt6
-rw-r--r--dep/efsw/CMakeLists.txt85
-rw-r--r--dep/efsw/LICENSE4
-rw-r--r--dep/efsw/README.md100
-rw-r--r--dep/efsw/include/efsw/efsw.h37
-rw-r--r--dep/efsw/include/efsw/efsw.hpp291
-rw-r--r--dep/efsw/src/efsw/Atomic.hpp33
-rw-r--r--dep/efsw/src/efsw/Debug.cpp90
-rw-r--r--dep/efsw/src/efsw/Debug.hpp48
-rw-r--r--dep/efsw/src/efsw/DirWatcherGeneric.cpp317
-rw-r--r--dep/efsw/src/efsw/DirWatcherGeneric.hpp58
-rw-r--r--dep/efsw/src/efsw/DirectorySnapshot.cpp157
-rw-r--r--dep/efsw/src/efsw/DirectorySnapshot.hpp43
-rw-r--r--dep/efsw/src/efsw/DirectorySnapshotDiff.cpp19
-rw-r--r--dep/efsw/src/efsw/DirectorySnapshotDiff.hpp44
-rw-r--r--dep/efsw/src/efsw/FileInfo.cpp239
-rw-r--r--dep/efsw/src/efsw/FileInfo.hpp68
-rw-r--r--dep/efsw/src/efsw/FileSystem.cpp96
-rw-r--r--dep/efsw/src/efsw/FileSystem.hpp37
-rw-r--r--dep/efsw/src/efsw/FileWatcher.cpp119
-rw-r--r--dep/efsw/src/efsw/FileWatcherCWrapper.cpp132
-rw-r--r--dep/efsw/src/efsw/FileWatcherFSEvents.cpp213
-rw-r--r--dep/efsw/src/efsw/FileWatcherFSEvents.hpp152
-rw-r--r--dep/efsw/src/efsw/FileWatcherGeneric.cpp127
-rw-r--r--dep/efsw/src/efsw/FileWatcherGeneric.hpp70
-rw-r--r--dep/efsw/src/efsw/FileWatcherImpl.cpp33
-rw-r--r--dep/efsw/src/efsw/FileWatcherImpl.hpp72
-rw-r--r--dep/efsw/src/efsw/FileWatcherInotify.cpp630
-rw-r--r--dep/efsw/src/efsw/FileWatcherInotify.hpp89
-rw-r--r--dep/efsw/src/efsw/FileWatcherKqueue.cpp185
-rw-r--r--dep/efsw/src/efsw/FileWatcherKqueue.hpp83
-rw-r--r--dep/efsw/src/efsw/FileWatcherWin32.cpp332
-rw-r--r--dep/efsw/src/efsw/FileWatcherWin32.hpp79
-rw-r--r--dep/efsw/src/efsw/Lock.hpp20
-rw-r--r--dep/efsw/src/efsw/Log.cpp48
-rw-r--r--dep/efsw/src/efsw/Mutex.cpp16
-rw-r--r--dep/efsw/src/efsw/Mutex.hpp25
-rw-r--r--dep/efsw/src/efsw/String.cpp502
-rw-r--r--dep/efsw/src/efsw/String.hpp276
-rw-r--r--dep/efsw/src/efsw/System.cpp14
-rw-r--r--dep/efsw/src/efsw/System.hpp25
-rw-r--r--dep/efsw/src/efsw/Thread.cpp32
-rw-r--r--dep/efsw/src/efsw/Thread.hpp109
-rw-r--r--dep/efsw/src/efsw/Utf.hpp1305
-rw-r--r--dep/efsw/src/efsw/Utf.inl997
-rw-r--r--dep/efsw/src/efsw/Watcher.cpp19
-rw-r--r--dep/efsw/src/efsw/Watcher.hpp25
-rw-r--r--dep/efsw/src/efsw/WatcherFSEvents.cpp250
-rw-r--r--dep/efsw/src/efsw/WatcherFSEvents.hpp64
-rw-r--r--dep/efsw/src/efsw/WatcherGeneric.cpp29
-rw-r--r--dep/efsw/src/efsw/WatcherGeneric.hpp25
-rw-r--r--dep/efsw/src/efsw/WatcherInotify.cpp28
-rw-r--r--dep/efsw/src/efsw/WatcherInotify.hpp22
-rw-r--r--dep/efsw/src/efsw/WatcherKqueue.cpp462
-rw-r--r--dep/efsw/src/efsw/WatcherKqueue.hpp99
-rw-r--r--dep/efsw/src/efsw/WatcherWin32.cpp182
-rw-r--r--dep/efsw/src/efsw/WatcherWin32.hpp83
-rw-r--r--dep/efsw/src/efsw/base.hpp196
-rw-r--r--dep/efsw/src/efsw/platform/platformimpl.hpp18
-rw-r--r--dep/efsw/src/efsw/platform/posix/FileSystemImpl.cpp174
-rw-r--r--dep/efsw/src/efsw/platform/posix/FileSystemImpl.hpp21
-rw-r--r--dep/efsw/src/efsw/platform/posix/MutexImpl.cpp26
-rw-r--r--dep/efsw/src/efsw/platform/posix/MutexImpl.hpp21
-rw-r--r--dep/efsw/src/efsw/platform/posix/SystemImpl.cpp94
-rw-r--r--dep/efsw/src/efsw/platform/posix/SystemImpl.hpp15
-rw-r--r--dep/efsw/src/efsw/platform/posix/ThreadImpl.cpp58
-rw-r--r--dep/efsw/src/efsw/platform/posix/ThreadImpl.hpp32
-rw-r--r--dep/efsw/src/efsw/platform/win/FileSystemImpl.cpp71
-rw-r--r--dep/efsw/src/efsw/platform/win/FileSystemImpl.hpp23
-rw-r--r--dep/efsw/src/efsw/platform/win/MutexImpl.cpp22
-rw-r--r--dep/efsw/src/efsw/platform/win/MutexImpl.hpp23
-rw-r--r--dep/efsw/src/efsw/platform/win/SystemImpl.cpp34
-rw-r--r--dep/efsw/src/efsw/platform/win/SystemImpl.hpp15
-rw-r--r--dep/efsw/src/efsw/platform/win/ThreadImpl.cpp40
-rw-r--r--dep/efsw/src/efsw/platform/win/ThreadImpl.hpp37
-rw-r--r--dep/efsw/src/test/efsw-test.c164
-rw-r--r--dep/efsw/src/test/efsw-test.cpp126
78 files changed, 4670 insertions, 5291 deletions
diff --git a/dep/PackageList.txt b/dep/PackageList.txt
index a90a5b78584..ecb19b5b6f8 100644
--- a/dep/PackageList.txt
+++ b/dep/PackageList.txt
@@ -8,9 +8,9 @@ Boost Process (Proposed for boost, but its not an official part of it yet. Used
http://www.highscore.de/boost/process0.5/
Version: 0.5
-efws (Entropia File System Watcher - crossplatform file system watcher)
- https://bitbucket.org/SpartanJ/efsw
- Version: 1.0.0 e6afbec564e249771046c714b0c7f2154e4c7fef
+efsw (Entropia File System Watcher - crossplatform file system watcher)
+ https://github.com/SpartanJ/efsw
+ Version: 1.3.1+ 36c1c7004a34b6f40719f0830bcfb10325415451
fmt (a small, safe and fast formatting library)
https://github.com/fmtlib/fmt
diff --git a/dep/efsw/.hg_archival.txt b/dep/efsw/.hg_archival.txt
deleted file mode 100644
index f590482107c..00000000000
--- a/dep/efsw/.hg_archival.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-repo: 78c2ea8c48b213ee0078d6326a1dd719d0844764
-node: e6afbec564e249771046c714b0c7f2154e4c7fef
-branch: default
-latesttag: 1.0.0
-latesttagdistance: 12
-changessincelatesttag: 12
diff --git a/dep/efsw/CMakeLists.txt b/dep/efsw/CMakeLists.txt
index 03f6c153115..9817525931c 100644
--- a/dep/efsw/CMakeLists.txt
+++ b/dep/efsw/CMakeLists.txt
@@ -1,68 +1,109 @@
if (BUILD_SHARED_LIBS)
- set(SRCS
+ set(EFSW_CPP_SOURCE
+ src/efsw/Atomic.hpp
+ src/efsw/base.hpp
src/efsw/Debug.cpp
+ src/efsw/Debug.hpp
src/efsw/DirectorySnapshot.cpp
+ src/efsw/DirectorySnapshot.hpp
src/efsw/DirectorySnapshotDiff.cpp
+ src/efsw/DirectorySnapshotDiff.hpp
src/efsw/DirWatcherGeneric.cpp
+ src/efsw/DirWatcherGeneric.hpp
src/efsw/FileInfo.cpp
+ src/efsw/FileInfo.hpp
src/efsw/FileSystem.cpp
+ src/efsw/FileSystem.hpp
src/efsw/FileWatcher.cpp
src/efsw/FileWatcherCWrapper.cpp
src/efsw/FileWatcherGeneric.cpp
+ src/efsw/FileWatcherGeneric.hpp
src/efsw/FileWatcherImpl.cpp
+ src/efsw/FileWatcherImpl.hpp
+ src/efsw/Lock.hpp
src/efsw/Log.cpp
src/efsw/Mutex.cpp
+ src/efsw/Mutex.hpp
+ src/efsw/sophist.h
src/efsw/String.cpp
+ src/efsw/String.hpp
src/efsw/System.cpp
+ src/efsw/System.hpp
src/efsw/Thread.cpp
+ src/efsw/Thread.hpp
+ src/efsw/Utf.hpp
src/efsw/Watcher.cpp
- src/efsw/WatcherGeneric.cpp)
+ src/efsw/Watcher.hpp
+ src/efsw/WatcherGeneric.cpp
+ src/efsw/WatcherGeneric.hpp
+ src/efsw/platform/platformimpl.hpp
+ )
if (WIN32)
- list (APPEND SRCS
+ list (APPEND EFSW_CPP_SOURCE
src/efsw/platform/win/FileSystemImpl.cpp
+ src/efsw/platform/win/FileSystemImpl.hpp
src/efsw/platform/win/MutexImpl.cpp
+ src/efsw/platform/win/MutexImpl.hpp
src/efsw/platform/win/SystemImpl.cpp
- src/efsw/platform/win/ThreadImpl.cpp)
+ src/efsw/platform/win/SystemImpl.hpp
+ src/efsw/platform/win/ThreadImpl.cpp
+ src/efsw/platform/win/ThreadImpl.hpp)
else ()
- list (APPEND SRCS
+ list (APPEND EFSW_CPP_SOURCE
src/efsw/platform/posix/FileSystemImpl.cpp
+ src/efsw/platform/posix/FileSystemImpl.hpp
src/efsw/platform/posix/MutexImpl.cpp
+ src/efsw/platform/posix/MutexImpl.hpp
src/efsw/platform/posix/SystemImpl.cpp
- src/efsw/platform/posix/ThreadImpl.cpp)
+ src/efsw/platform/posix/SystemImpl.hpp
+ src/efsw/platform/posix/ThreadImpl.cpp
+ src/efsw/platform/posix/ThreadImpl.hpp)
endif()
if (APPLE)
- list (APPEND SRCS
+ list (APPEND EFSW_CPP_SOURCE
src/efsw/FileWatcherFSEvents.cpp
+ src/efsw/FileWatcherFSEvents.hpp
src/efsw/FileWatcherKqueue.cpp
+ src/efsw/FileWatcherKqueue.hpp
src/efsw/WatcherFSEvents.cpp
- src/efsw/WatcherKqueue.cpp)
-
- exec_program(uname ARGS -v OUTPUT_VARIABLE OSX_VERSION)
- string(REGEX MATCH "[0-9]+" OSX_VERSION ${OSX_VERSION})
- if (NOT OSX_VERSION GREATER 9)
- set(OPTIONAL_COMPILE_DEFINITIONS "-DEFSW_FSEVENTS_NOT_SUPPORTED")
- endif()
+ src/efsw/WatcherFSEvents.hpp
+ src/efsw/WatcherKqueue.cpp
+ src/efsw/WatcherKqueue.hpp)
set(OPTIONAL_LINK_LIBRARIES "-framework CoreFoundation" "-framework CoreServices")
elseif (WIN32)
- list (APPEND SRCS
+ list (APPEND EFSW_CPP_SOURCE
src/efsw/FileWatcherWin32.cpp
- src/efsw/WatcherWin32.cpp)
+ src/efsw/FileWatcherWin32.hpp
+ src/efsw/WatcherWin32.cpp
+ src/efsw/WatcherWin32.hpp)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
- list (APPEND SRCS
+ list (APPEND EFSW_CPP_SOURCE
src/efsw/FileWatcherInotify.cpp
- src/efsw/WatcherInotify.cpp)
- if (NOT EXISTS "/usr/include/sys/inotify.h" AND NOT EXISTS "/usr/local/include/sys/inotify.h")
+ src/efsw/FileWatcherInotify.hpp
+ src/efsw/WatcherInotify.cpp
+ src/efsw/WatcherInotify.hpp)
+ find_path(EFSW_INOTIFY_H
+ NAMES
+ sys/inotify.h
+ NO_CACHE
+ )
+ if (EFSW_INOTIFY_H STREQUAL "EFSW_INOTIFY_H-NOTFOUND")
+ list (APPEND EFSW_CPP_SOURCE
+ src/efsw/inotify-nosys.h
+ )
set(OPTIONAL_COMPILE_DEFINITIONS "-DEFSW_INOTIFY_NOSYS")
endif()
elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
- list (APPEND SRCS
+ list (APPEND EFSW_CPP_SOURCE
src/efsw/FileWatcherKqueue.cpp
- src/efsw/WatcherKqueue.cpp)
+ src/efsw/FileWatcherKqueue.hpp
+ src/efsw/WatcherKqueue.cpp
+ src/efsw/WatcherKqueue.hpp)
endif()
- add_library(efsw STATIC ${SRCS})
+ add_library(efsw STATIC ${EFSW_CPP_SOURCE})
target_include_directories(efsw
PUBLIC
diff --git a/dep/efsw/LICENSE b/dep/efsw/LICENSE
index ac8ac28988d..37f354a1952 100644
--- a/dep/efsw/LICENSE
+++ b/dep/efsw/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2012 Martín Lucas Golini
+Copyright (c) 2020 Martín Lucas Golini
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -19,4 +19,4 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
This software is a fork of the "simplefilewatcher" by James Wynn (james@jameswynn.com)
-http://code.google.com/p/simplefilewatcher/ also MIT licensed. \ No newline at end of file
+http://code.google.com/p/simplefilewatcher/ also MIT licensed.
diff --git a/dep/efsw/README.md b/dep/efsw/README.md
index f653088d575..1c719403005 100644
--- a/dep/efsw/README.md
+++ b/dep/efsw/README.md
@@ -1,5 +1,8 @@
-Entropia File System Watcher
+Entropia File System Watcher ![efsw](https://web.ensoft.dev/efsw/efsw-logo.svg)
============================
+
+[![build status](https://img.shields.io/github/actions/workflow/status/SpartanJ/efsw/main.yml?branch=master)](https://github.com/SpartanJ/efsw/actions?query=workflow%3Abuild)
+
**efsw** is a C++ cross-platform file system watcher and notifier.
**efsw** monitors the file system asynchronously for changes to files and directories by watching a list of specified paths, and raises events when a directory or file change.
@@ -19,8 +22,8 @@ Entropia File System Watcher
* OS-independent generic watcher
(polling the disk for directory snapshots and comparing them periodically)
-If any of the backend fails to start by any reason, it will fallback to the OS-independent implementation.
-This should never happen, except for the Kqueue implementation, see `Platform limitations and clarifications`.
+If any of the backend fails to start for any reason, it will fallback to the OS-independent implementation.
+This should never happen, except for the Kqueue implementation; see `Platform limitations and clarifications`.
**Code License**
--------------
@@ -31,39 +34,41 @@ This should never happen, except for the Kqueue implementation, see `Platform li
```c++
// Inherits from the abstract listener class, and implements the the file action handler
-class UpdateListener : public efsw::FileWatchListener
-{
-public:
- UpdateListener() {}
-
- void handleFileAction( efsw::WatchID watchid, const std::string& dir, const std::string& filename, efsw::Action action, std::string oldFilename = "" )
- {
- switch( action )
- {
- case efsw::Actions::Add:
- std::cout << "DIR (" << dir << ") FILE (" << filename << ") has event Added" << std::endl;
- break;
- case efsw::Actions::Delete:
- std::cout << "DIR (" << dir << ") FILE (" << filename << ") has event Delete" << std::endl;
- break;
- case efsw::Actions::Modified:
- std::cout << "DIR (" << dir << ") FILE (" << filename << ") has event Modified" << std::endl;
- break;
- case efsw::Actions::Moved:
- std::cout << "DIR (" << dir << ") FILE (" << filename << ") has event Moved from (" << oldFilename << ")" << std::endl;
- break;
- default:
- std::cout << "Should never happen!" << std::endl;
- }
- }
+class UpdateListener : public efsw::FileWatchListener {
+ public:
+ void handleFileAction( efsw::WatchID watchid, const std::string& dir,
+ const std::string& filename, efsw::Action action,
+ std::string oldFilename ) override {
+ switch ( action ) {
+ case efsw::Actions::Add:
+ std::cout << "DIR (" << dir << ") FILE (" << filename << ") has event Added"
+ << std::endl;
+ break;
+ case efsw::Actions::Delete:
+ std::cout << "DIR (" << dir << ") FILE (" << filename << ") has event Delete"
+ << std::endl;
+ break;
+ case efsw::Actions::Modified:
+ std::cout << "DIR (" << dir << ") FILE (" << filename << ") has event Modified"
+ << std::endl;
+ break;
+ case efsw::Actions::Moved:
+ std::cout << "DIR (" << dir << ") FILE (" << filename << ") has event Moved from ("
+ << oldFilename << ")" << std::endl;
+ break;
+ default:
+ std::cout << "Should never happen!" << std::endl;
+ }
+ }
};
// Create the file system watcher instance
-// efsw::FileWatcher allow a first boolean parameter that indicates if it should start with the generic file watcher instead of the platform specific backend
-efsw::FileWatcher * fileWatcher = new efsw::FileWatcher();
+// efsw::FileWatcher allow a first boolean parameter that indicates if it should start with the
+// generic file watcher instead of the platform specific backend
+efsw::FileWatcher* fileWatcher = new efsw::FileWatcher();
// Create the instance of your efsw::FileWatcherListener implementation
-UpdateListener * listener = new UpdateListener();
+UpdateListener* listener = new UpdateListener();
// Add a folder to watch, and get the efsw::WatchID
// It will watch the /tmp folder recursively ( the third parameter indicates that is recursive )
@@ -73,11 +78,16 @@ efsw::WatchID watchID = fileWatcher->addWatch( "/tmp", listener, true );
// Adds another directory to watch. This time as non-recursive.
efsw::WatchID watchID2 = fileWatcher->addWatch( "/usr", listener, false );
+// For Windows, adds another watch, specifying to use a bigger buffer, to not miss events
+// (do not use for network locations, see efsw.hpp for details).
+efsw::WatchID watchID3 = fileWatcher->addWatch( "c:\\temp", listener, true, { (BufferSize, 128*1024) } );
+
// Start watching asynchronously the directories
fileWatcher->watch();
// Remove the second watcher added
-// You can also call removeWatch by passing the watch path ( it must end with an slash or backslash in windows, since that's how internally it's saved )
+// You can also call removeWatch by passing the watch path ( it must end with an slash or backslash
+// in windows, since that's how internally it's saved )
fileWatcher->removeWatch( watchID2 );
```
@@ -87,21 +97,21 @@ None :)
**Compiling**
------------
-To generate project files you will need to [download and install](http://industriousone.com/premake/download) [Premake](http://industriousone.com/what-premake)
+To generate project files you will need to [download and install](https://premake.github.io/download) [Premake](https://premake.github.io/docs/What-Is-Premake)
-Then you can generate the project for your platform just going to the project directory where the premake4.lua file is located and then execute:
+Then you can generate the project for your platform by just going to the project directory where the premake4.lua file is located and executing:
-`premake4 gmake` to generate project Makefiles, then `cd make/*YOURPLATFORM*/`, and finally `make` or `make config=release` ( it will generate the static lib, the shared lib and the test application ).
+`premake5 gmake2` to generate project Makefiles, then `cd make/*YOURPLATFORM*/`, and finally `make` or `make config=release_x86_64` ( it will generate the static lib, the shared lib and the test application ).
-or
+or
-`premake4 vs2010` to generate Visual Studio 2010 project.
+`premake5 vs2022` to generate Visual Studio 2022 project.
or
-`premake4 xcode4` to generate Xcode 4 project.
+`premake5 xcode4` to generate Xcode 4 project.
-There is also a cmake file that i don't oficially support but it works just fine, provided by [Mohammed Nafees](https://bitbucket.org/binaryking).
+There is also a cmake file that I don't officially support but it works just fine, provided by [Mohammed Nafees](https://github.com/mnafees) and improved by [Eugene Shalygin](https://github.com/zeule).
**Platform limitations and clarifications**
-------------------------------------------
@@ -112,21 +122,21 @@ handleFileAction returns UTF-8 strings in all platforms.
Windows and FSEvents Mac OS X implementation can't follow symlinks ( it will ignore followSymlinks() and allowOutOfScopeLinks() ).
-Kqueue implementation is limited by the maximun number of file descriptors allowed per process by the OS, in the case of reaching the file descriptors limit ( in BSD around 18000 and in OS X around 10240 ) it will fallback to the generic file watcher.
+Kqueue implementation is limited by the maximum number of file descriptors allowed per process by the OS. In the case of reaching the file descriptors limit ( in BSD around 18000 and in OS X around 10240 ), it will fallback to the generic file watcher.
-OS X will only use Kqueue if OS X version is below to 10.5, and this implementation needs to be compiled separately from the OS X >= 10.5 implementation. Since there's no way to compile FSEvents backend in OS X below 10.5.
+OS X will use only Kqueue if the OS X version is below 10.5. This implementation needs to be compiled separately from the OS X >= 10.5 implementation, since there's no way to compile FSEvents backend in OS X below 10.5.
-FSEvents for OS X Lion and beyond in some cases will generate more actions that in reality ocurred, since fine-grained implementation of FSEvents doesn't give the order of the actions retrieved, in some cases i need to guess/aproximate the order of them.
+FSEvents for OS X Lion and beyond in some cases will generate more actions than in reality ocurred, since fine-grained implementation of FSEvents doesn't give the order of the actions retrieved. In some cases I need to guess/approximate the order of them.
Generic watcher relies on the inode information to detect file and directories renames/move. Since Windows has no concept of inodes as Unix platforms do, there is no current reliable way of determining file/directory movement on Windows without help from the Windows API ( this is replaced with Add/Delete events ).
-Linux versions below 2.6.13 are not supported, since inotify wasn't implemented yet. I'm not interested in support older kernels, since i don't see the point. If someone needs this open an issue in the issue tracker and i may consider implenent a dnotify backend.
+Linux versions below 2.6.13 are not supported, since inotify wasn't implemented yet. I'm not interested in supporting older kernels, since I don't see the point. If someone needs this, open an issue in the issue tracker and I may consider implementing a dnotify backend.
-OS-independent watcher, Kqueue and FSEvents for OS X below 10.5 keep cache of the directories structures, to be able to detect changes in the directories. This means that there's a memory overhead for this backends.
+OS-independent watcher, Kqueue and FSEvents for OS X below 10.5 keep cache of the directories structures, to be able to detect changes in the directories. This means that there's a memory overhead for these backends.
**Useful information**
--------------------
-The project also comes with a C API wrapper, contributed by [Sepul Sepehr Taghdisian](https://bitbucket.org/sepul).
+The project also comes with a C API wrapper, contributed by [Sepul Sepehr Taghdisian](https://github.com/septag).
There's a string manipulation class not exposed in the efsw header ( efsw::String ) that can be used to make string encoding conversion.
diff --git a/dep/efsw/include/efsw/efsw.h b/dep/efsw/include/efsw/efsw.h
index 28e63e2139e..ecb9ec41c26 100644
--- a/dep/efsw/include/efsw/efsw.h
+++ b/dep/efsw/include/efsw/efsw.h
@@ -80,7 +80,22 @@ enum efsw_error
EFSW_OUTOFSCOPE = -3,
EFSW_NOTREADABLE = -4,
EFSW_REMOTE = -5,
- EFSW_UNSPECIFIED = -6
+ EFSW_WATCHER_FAILED = -6,
+ EFSW_UNSPECIFIED = -7
+};
+
+enum efsw_option
+{
+ /// For Windows, the default buffer size of 63*1024 bytes sometimes is not enough and
+ /// file system events may be dropped. For that, using a different (bigger) buffer size
+ /// can be defined here, but note that this does not work for network drives,
+ /// because a buffer larger than 64K will fail the folder being watched, see
+ /// http://msdn.microsoft.com/en-us/library/windows/desktop/aa365465(v=vs.85).aspx)
+ EFSW_OPT_WIN_BUFFER_SIZE = 1,
+ /// For Windows, per default all events are captured but we might only be interested
+ /// in a subset; the value of the option should be set to a bitwise or'ed set of
+ /// FILE_NOTIFY_CHANGE_* flags.
+ EFSW_OPT_WIN_NOTIFY_FILTER = 2
};
/// Basic interface for listening for file events.
@@ -94,6 +109,11 @@ typedef void (*efsw_pfn_fileaction_callback) (
void* param
);
+typedef struct {
+ enum efsw_option option;
+ int value;
+} efsw_watcher_option;
+
/**
* Creates a new file-watcher
* @param generic_mode Force the use of the Generic file watcher
@@ -103,15 +123,24 @@ efsw_watcher EFSW_API efsw_create(int generic_mode);
/// Release the file-watcher and unwatch any directories
void EFSW_API efsw_release(efsw_watcher watcher);
-/// Retreive last error occured by file-watcher
+/// Retrieve last error occured by file-watcher
EFSW_API const char* efsw_getlasterror();
-/// Add a directory watch. Same as the other addWatch, but doesn't have recursive option.
-/// For backwards compatibility.
+/// Reset file-watcher last error
+EFSW_API void efsw_clearlasterror();
+
+/// Add a directory watch
/// On error returns WatchID with Error type.
efsw_watchid EFSW_API efsw_addwatch(efsw_watcher watcher, const char* directory,
efsw_pfn_fileaction_callback callback_fn, int recursive, void* param);
+/// Add a directory watch, specifying options
+/// @param options Pointer to an array of watcher options
+/// @param nr_options Number of options referenced by \p options
+efsw_watchid EFSW_API efsw_addwatch_withoptions(efsw_watcher watcher, const char* directory,
+ efsw_pfn_fileaction_callback callback_fn, int recursive, efsw_watcher_option *options,
+ int options_number, void* param);
+
/// Remove a directory watch. This is a brute force search O(nlogn).
void EFSW_API efsw_removewatch(efsw_watcher watcher, const char* directory);
diff --git a/dep/efsw/include/efsw/efsw.hpp b/dep/efsw/include/efsw/efsw.hpp
index 72ae1a61d7c..cb78ef3797f 100644
--- a/dep/efsw/include/efsw/efsw.hpp
+++ b/dep/efsw/include/efsw/efsw.hpp
@@ -28,34 +28,37 @@
#ifndef ESFW_HPP
#define ESFW_HPP
+#include <vector>
#include <string>
-#include <list>
-
-#if defined(_WIN32)
- #ifdef EFSW_DYNAMIC
- // Windows platforms
- #ifdef EFSW_EXPORTS
- // From DLL side, we must export
- #define EFSW_API __declspec(dllexport)
- #else
- // From client application side, we must import
- #define EFSW_API __declspec(dllimport)
- #endif
- #else
- // No specific directive needed for static build
- #ifndef EFSW_API
- #define EFSW_API
- #endif
- #endif
+#include <vector>
+
+#if defined( _WIN32 )
+#ifdef EFSW_DYNAMIC
+// Windows platforms
+#ifdef EFSW_EXPORTS
+// From DLL side, we must export
+#define EFSW_API __declspec( dllexport )
#else
- #if ( __GNUC__ >= 4 ) && defined( EFSW_EXPORTS )
- #define EFSW_API __attribute__ ((visibility("default")))
- #endif
-
- // Other platforms don't need to define anything
- #ifndef EFSW_API
- #define EFSW_API
- #endif
+// From client application side, we must import
+#define EFSW_API __declspec( dllimport )
+#endif
+#else
+// No specific directive needed for static build
+#ifndef EFSW_API
+#define EFSW_API
+#endif
+#endif
+#else
+#if ( __GNUC__ >= 4 ) && defined( EFSW_EXPORTS )
+#ifndef EFSW_API
+#define EFSW_API __attribute__( ( visibility( "default" ) ) )
+#endif
+#endif
+
+// Other platforms don't need to define anything
+#ifndef EFSW_API
+#define EFSW_API
+#endif
#endif
namespace efsw {
@@ -66,128 +69,174 @@ typedef long WatchID;
// forward declarations
class FileWatcherImpl;
class FileWatchListener;
+class WatcherOption;
/// Actions to listen for. Rename will send two events, one for
/// the deletion of the old file, and one for the creation of the
/// new file.
namespace Actions {
- enum Action
- {
- /// Sent when a file is created or renamed
- Add = 1,
- /// Sent when a file is deleted or renamed
- Delete = 2,
- /// Sent when a file is modified
- Modified = 3,
- /// Sent when a file is moved
- Moved = 4
- };
+enum Action {
+ /// Sent when a file is created or renamed
+ Add = 1,
+ /// Sent when a file is deleted or renamed
+ Delete = 2,
+ /// Sent when a file is modified
+ Modified = 3,
+ /// Sent when a file is moved
+ Moved = 4
+};
}
typedef Actions::Action Action;
/// Errors log namespace
namespace Errors {
-enum Error
-{
- FileNotFound = -1,
- FileRepeated = -2,
- FileOutOfScope = -3,
- FileNotReadable = -4,
- FileRemote = -5, /** Directory in remote file system ( create a generic FileWatcher instance to watch this directory ). */
- Unspecified = -6
+enum Error {
+ NoError = 0,
+ FileNotFound = -1,
+ FileRepeated = -2,
+ FileOutOfScope = -3,
+ FileNotReadable = -4,
+ /// Directory in remote file system
+ /// ( create a generic FileWatcher instance to watch this directory ).
+ FileRemote = -5,
+ /// File system watcher failed to watch for changes.
+ WatcherFailed = -6,
+ Unspecified = -7
};
-class EFSW_API Log
-{
- public:
- /// @return The last error logged
- static std::string getLastErrorLog();
+class EFSW_API Log {
+ public:
+ /// @return The last error logged
+ static std::string getLastErrorLog();
+
+ /// @return The code of the last error logged
+ static Error getLastErrorCode();
+
+ /// Reset last error
+ static void clearLastError();
- /// Creates an error of the type specified
- static Error createLastError( Error err, std::string log );
+ /// Creates an error of the type specified
+ static Error createLastError( Error err, std::string log );
};
-}
+} // namespace Errors
typedef Errors::Error Error;
+/// Optional file watcher settings.
+namespace Options {
+enum Option {
+ /// For Windows, the default buffer size of 63*1024 bytes sometimes is not enough and
+ /// file system events may be dropped. For that, using a different (bigger) buffer size
+ /// can be defined here, but note that this does not work for network drives,
+ /// because a buffer larger than 64K will fail the folder being watched, see
+ /// http://msdn.microsoft.com/en-us/library/windows/desktop/aa365465(v=vs.85).aspx)
+ WinBufferSize = 1,
+ /// For Windows, per default all events are captured but we might only be interested
+ /// in a subset; the value of the option should be set to a bitwise or'ed set of
+ /// FILE_NOTIFY_CHANGE_* flags.
+ WinNotifyFilter = 2
+};
+}
+typedef Options::Option Option;
+
/// Listens to files and directories and dispatches events
/// to notify the listener of files and directories changes.
/// @class FileWatcher
-class EFSW_API FileWatcher
-{
- public:
- /// Default constructor, will use the default platform file watcher
- FileWatcher();
-
- /// Constructor that lets you force the use of the Generic File Watcher
- explicit FileWatcher( bool useGenericFileWatcher );
-
- virtual ~FileWatcher();
-
- /// Add a directory watch. Same as the other addWatch, but doesn't have recursive option.
- /// For backwards compatibility.
- /// On error returns WatchID with Error type.
- WatchID addWatch(const std::string& directory, FileWatchListener* watcher);
-
- /// Add a directory watch
- /// On error returns WatchID with Error type.
- WatchID addWatch(const std::string& directory, FileWatchListener* watcher, bool recursive);
-
- /// Remove a directory watch. This is a brute force search O(nlogn).
- void removeWatch(const std::string& directory);
-
- /// Remove a directory watch. This is a map lookup O(logn).
- void removeWatch(WatchID watchid);
-
- /// Starts watching ( in other thread )
- void watch();
-
- /// @return Returns a list of the directories that are being watched
- std::list<std::string> directories();
-
- /** Allow recursive watchers to follow symbolic links to other directories
- * followSymlinks is disabled by default
- */
- void followSymlinks( bool follow );
-
- /** @return If can follow symbolic links to directorioes */
- const bool& followSymlinks() const;
-
- /** When enable this it will allow symlinks to watch recursively out of the pointed directory.
- * follorSymlinks must be enabled to this work.
- * For example, added symlink to /home/folder, and the symlink points to /, this by default is not allowed,
- * it's only allowed to symlink anything from /home/ and deeper. This is to avoid great levels of recursion.
- * Enabling this could lead in infinite recursion, and crash the watcher ( it will try not to avoid this ).
- * Buy enabling out of scope links, it will allow this behavior.
- * allowOutOfScopeLinks are disabled by default.
- */
- void allowOutOfScopeLinks( bool allow );
-
- /// @return Returns if out of scope links are allowed
- const bool& allowOutOfScopeLinks() const;
- private:
- /// The implementation
- FileWatcherImpl * mImpl;
- bool mFollowSymlinks;
- bool mOutOfScopeLinks;
+class EFSW_API FileWatcher {
+ public:
+ /// Default constructor, will use the default platform file watcher
+ FileWatcher();
+
+ /// Constructor that lets you force the use of the Generic File Watcher
+ explicit FileWatcher( bool useGenericFileWatcher );
+
+ virtual ~FileWatcher();
+
+ /// Add a directory watch. Same as the other addWatch, but doesn't have recursive option.
+ /// For backwards compatibility.
+ /// On error returns WatchID with Error type.
+ WatchID addWatch( const std::string& directory, FileWatchListener* watcher );
+
+ /// Add a directory watch
+ /// On error returns WatchID with Error type.
+ WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive );
+
+ /// Add a directory watch, allowing customization with options
+ /// @param directory The folder to be watched
+ /// @param watcher The listener to receive events
+ /// @param recursive Set this to true to include subdirectories
+ /// @param options Allows customization of a watcher
+ /// @return Returns the watch id for the directory or, on error, a WatchID with Error type.
+ WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive,
+ const std::vector<WatcherOption> &options );
+
+ /// Remove a directory watch. This is a brute force search O(nlogn).
+ void removeWatch( const std::string& directory );
+
+ /// Remove a directory watch. This is a map lookup O(logn).
+ void removeWatch( WatchID watchid );
+
+ /// Starts watching ( in other thread )
+ void watch();
+
+ /// @return Returns a list of the directories that are being watched
+ std::vector<std::string> directories();
+
+ /** Allow recursive watchers to follow symbolic links to other directories
+ * followSymlinks is disabled by default
+ */
+ void followSymlinks( bool follow );
+
+ /** @return If can follow symbolic links to directorioes */
+ const bool& followSymlinks() const;
+
+ /** When enable this it will allow symlinks to watch recursively out of the pointed directory.
+ * follorSymlinks must be enabled to this work.
+ * For example, added symlink to /home/folder, and the symlink points to /, this by default is
+ * not allowed, it's only allowed to symlink anything from /home/ and deeper. This is to avoid
+ * great levels of recursion. Enabling this could lead in infinite recursion, and crash the
+ * watcher ( it will try not to avoid this ). Buy enabling out of scope links, it will allow
+ * this behavior. allowOutOfScopeLinks are disabled by default.
+ */
+ void allowOutOfScopeLinks( bool allow );
+
+ /// @return Returns if out of scope links are allowed
+ const bool& allowOutOfScopeLinks() const;
+
+ private:
+ /// The implementation
+ FileWatcherImpl* mImpl;
+ bool mFollowSymlinks;
+ bool mOutOfScopeLinks;
};
/// Basic interface for listening for file events.
/// @class FileWatchListener
-class FileWatchListener
-{
- public:
- /// Handles the action file action
- /// @param watchid The watch id for the directory
- /// @param dir The directory
- /// @param filename The filename that was accessed (not full path)
- /// @param action Action that was performed
- /// @param oldFilename The name of the file or directory moved
- virtual void handleFileAction(WatchID watchid, const std::string& dir, const std::string& filename, Action action, std::string oldFilename = "" ) = 0;
+class FileWatchListener {
+ public:
+ virtual ~FileWatchListener() {}
+
+ /// Handles the action file action
+ /// @param watchid The watch id for the directory
+ /// @param dir The directory
+ /// @param filename The filename that was accessed (not full path)
+ /// @param action Action that was performed
+ /// @param oldFilename The name of the file or directory moved
+ virtual void handleFileAction( WatchID watchid, const std::string& dir,
+ const std::string& filename, Action action,
+ std::string oldFilename = "" ) = 0;
+};
+/// Optional, typically platform specific parameter for customization of a watcher.
+/// @class WatcherOption
+class WatcherOption {
+ public:
+ WatcherOption(Option option, int value) : mOption(option), mValue(value) {};
+ Option mOption;
+ int mValue;
};
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/Atomic.hpp b/dep/efsw/src/efsw/Atomic.hpp
new file mode 100644
index 00000000000..9015c60038b
--- /dev/null
+++ b/dep/efsw/src/efsw/Atomic.hpp
@@ -0,0 +1,33 @@
+#ifndef EFSW_ATOMIC_BOOL_HPP
+#define EFSW_ATOMIC_BOOL_HPP
+
+#include <efsw/base.hpp>
+
+#include <atomic>
+
+namespace efsw {
+
+template <typename T> class Atomic {
+ public:
+ explicit Atomic( T set = false ) : set_( set ) {}
+
+ Atomic& operator=( T set ) {
+ set_.store( set, std::memory_order_release );
+ return *this;
+ }
+
+ explicit operator T() const {
+ return set_.load( std::memory_order_acquire );
+ }
+
+ T load() const {
+ return set_.load( std::memory_order_acquire );
+ }
+
+ private:
+ std::atomic<T> set_;
+};
+
+} // namespace efsw
+
+#endif
diff --git a/dep/efsw/src/efsw/Debug.cpp b/dep/efsw/src/efsw/Debug.cpp
index 9c4ee02e5b6..18cfd315bdc 100644
--- a/dep/efsw/src/efsw/Debug.cpp
+++ b/dep/efsw/src/efsw/Debug.cpp
@@ -3,83 +3,79 @@
#ifdef EFSW_COMPILER_MSVC
#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
#include <crtdbg.h>
+#include <windows.h>
#endif
#include <cassert>
-#include <cstdio>
#include <cstdarg>
+#include <cstdio>
namespace efsw {
#ifdef DEBUG
-void efREPORT_ASSERT( const char * File, int Line, const char * Exp )
-{
- #ifdef EFSW_COMPILER_MSVC
- _CrtDbgReport( _CRT_ASSERT, File, Line, "", Exp);
-
- DebugBreak();
- #else
- std::cout << "ASSERT: " << Exp << " file: " << File << " line: " << Line << std::endl;
-
- #if defined(EFSW_COMPILER_GCC) && defined(EFSW_32BIT) && !defined(EFSW_ARM)
- asm("int3");
- #else
- assert( false );
- #endif
- #endif
+void efREPORT_ASSERT( const char* File, int Line, const char* Exp ) {
+#ifdef EFSW_COMPILER_MSVC
+ _CrtDbgReport( _CRT_ASSERT, File, Line, "", Exp );
+
+ DebugBreak();
+#else
+ std::cout << "ASSERT: " << Exp << " file: " << File << " line: " << Line << std::endl;
+
+#if defined( EFSW_COMPILER_GCC ) && defined( EFSW_32BIT ) && !defined( EFSW_ARM )
+ asm( "int3" );
+#else
+ assert( false );
+#endif
+#endif
}
-void efPRINT( const char * format, ... )
-{
- char buf[2048];
- va_list args;
+void efPRINT( const char* format, ... ) {
+ char buf[2048];
+ va_list args;
va_start( args, format );
- #ifdef EFSW_COMPILER_MSVC
- _vsnprintf_s( buf, sizeof( buf ), sizeof( buf ) / sizeof( buf[0]), format, args );
- #else
- vsnprintf( buf, sizeof( buf ) / sizeof( buf[0]), format, args );
- #endif
+#ifdef EFSW_COMPILER_MSVC
+ _vsnprintf_s( buf, sizeof( buf ), sizeof( buf ) / sizeof( buf[0] ), format, args );
+#else
+ vsnprintf( buf, sizeof( buf ) / sizeof( buf[0] ), format, args );
+#endif
va_end( args );
- #ifdef EFSW_COMPILER_MSVC
- OutputDebugStringA( buf );
- #else
- std::cout << buf;
- #endif
+#ifdef EFSW_COMPILER_MSVC
+ OutputDebugStringA( buf );
+#else
+ std::cout << buf;
+#endif
}
-void efPRINTC( unsigned int cond, const char * format, ...)
-{
+void efPRINTC( unsigned int cond, const char* format, ... ) {
if ( 0 == cond )
return;
- char buf[2048];
- va_list args;
+ char buf[2048];
+ va_list args;
va_start( args, format );
- #ifdef EFSW_COMPILER_MSVC
- _vsnprintf_s( buf, efARRAY_SIZE( buf ), efARRAY_SIZE( buf ), format, args );
- #else
- vsnprintf( buf, sizeof( buf ) / sizeof( buf[0]), format, args );
- #endif
+#ifdef EFSW_COMPILER_MSVC
+ _vsnprintf_s( buf, efARRAY_SIZE( buf ), efARRAY_SIZE( buf ), format, args );
+#else
+ vsnprintf( buf, sizeof( buf ) / sizeof( buf[0] ), format, args );
+#endif
va_end( args );
- #ifdef EFSW_COMPILER_MSVC
- OutputDebugStringA( buf );
- #else
- std::cout << buf;
- #endif
+#ifdef EFSW_COMPILER_MSVC
+ OutputDebugStringA( buf );
+#else
+ std::cout << buf;
+#endif
}
#endif
-}
-
+} // namespace efsw
diff --git a/dep/efsw/src/efsw/Debug.hpp b/dep/efsw/src/efsw/Debug.hpp
index 75d6dce0466..78d35573b62 100644
--- a/dep/efsw/src/efsw/Debug.hpp
+++ b/dep/efsw/src/efsw/Debug.hpp
@@ -7,13 +7,19 @@ namespace efsw {
#ifdef DEBUG
-void efREPORT_ASSERT( const char * File, const int Line, const char * Exp );
+void efREPORT_ASSERT( const char* File, const int Line, const char* Exp );
-#define efASSERT( expr ) if ( !(expr) ) { efREPORT_ASSERT( __FILE__, __LINE__, #expr ); }
-#define efASSERTM( expr, msg ) if ( !(expr) ) { efREPORT_ASSERT( __FILE__, __LINE__, #msg ); }
+#define efASSERT( expr ) \
+ if ( !( expr ) ) { \
+ efREPORT_ASSERT( __FILE__, __LINE__, #expr ); \
+ }
+#define efASSERTM( expr, msg ) \
+ if ( !( expr ) ) { \
+ efREPORT_ASSERT( __FILE__, __LINE__, #msg ); \
+ }
-void efPRINT ( const char * format, ... );
-void efPRINTC ( unsigned int cond, const char * format, ... );
+void efPRINT( const char* format, ... );
+void efPRINTC( unsigned int cond, const char* format, ... );
#else
@@ -21,30 +27,34 @@ void efPRINTC ( unsigned int cond, const char * format, ... );
#define efASSERTM( expr, msg )
#ifndef EFSW_COMPILER_MSVC
- #define efPRINT( format, args... ) {}
- #define efPRINTC( cond, format, args... ) {}
+#define efPRINT( format, args... ) \
+ {}
+#define efPRINTC( cond, format, args... ) \
+ {}
#else
- #define efPRINT
- #define efPRINTC
+#define efPRINT
+#define efPRINTC
#endif
#endif
#ifdef EFSW_VERBOSE
- #define efDEBUG efPRINT
- #define efDEBUGC efPRINTC
+#define efDEBUG efPRINT
+#define efDEBUGC efPRINTC
#else
- #ifndef EFSW_COMPILER_MSVC
- #define efDEBUG( format, args... ) {}
- #define efDEBUGC( cond, format, args... ) {}
- #else
- #define efDEBUG
- #define efDEBUGC
- #endif
+#ifndef EFSW_COMPILER_MSVC
+#define efDEBUG( format, args... ) \
+ {}
+#define efDEBUGC( cond, format, args... ) \
+ {}
+#else
+#define efDEBUG
+#define efDEBUGC
+#endif
#endif
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/DirWatcherGeneric.cpp b/dep/efsw/src/efsw/DirWatcherGeneric.cpp
index a5751148863..8b6bc8a99ab 100644
--- a/dep/efsw/src/efsw/DirWatcherGeneric.cpp
+++ b/dep/efsw/src/efsw/DirWatcherGeneric.cpp
@@ -1,67 +1,53 @@
+#include <efsw/Debug.hpp>
#include <efsw/DirWatcherGeneric.hpp>
#include <efsw/FileSystem.hpp>
-#include <efsw/Debug.hpp>
#include <efsw/String.hpp>
namespace efsw {
-DirWatcherGeneric::DirWatcherGeneric( DirWatcherGeneric * parent, WatcherGeneric * ws, const std::string& directory, bool recursive, bool reportNewFiles ) :
- Parent( parent ),
- Watch( ws ),
- Recursive( recursive ),
- Deleted( false )
-{
+DirWatcherGeneric::DirWatcherGeneric( DirWatcherGeneric* parent, WatcherGeneric* ws,
+ const std::string& directory, bool recursive,
+ bool reportNewFiles ) :
+ Parent( parent ), Watch( ws ), Recursive( recursive ), Deleted( false ) {
resetDirectory( directory );
- if ( !reportNewFiles )
- {
+ if ( !reportNewFiles ) {
DirSnap.scan();
- }
- else
- {
+ } else {
DirectorySnapshotDiff Diff = DirSnap.scan();
- if ( Diff.changed() )
- {
+ if ( Diff.changed() ) {
FileInfoList::iterator it;
- DiffIterator( FilesCreated )
- {
+ DiffIterator( FilesCreated ) {
handleAction( ( *it ).Filepath, Actions::Add );
}
}
}
}
-DirWatcherGeneric::~DirWatcherGeneric()
-{
+DirWatcherGeneric::~DirWatcherGeneric() {
/// If the directory was deleted mark the files as deleted
- if ( Deleted )
- {
+ if ( Deleted ) {
DirectorySnapshotDiff Diff = DirSnap.scan();
- if ( !DirSnap.exists() )
- {
+ if ( !DirSnap.exists() ) {
FileInfoList::iterator it;
- DiffIterator( FilesDeleted )
- {
- handleAction( (*it).Filepath, Actions::Delete );
+ DiffIterator( FilesDeleted ) {
+ handleAction( ( *it ).Filepath, Actions::Delete );
}
- DiffIterator( DirsDeleted )
- {
- handleAction( (*it).Filepath, Actions::Delete );
+ DiffIterator( DirsDeleted ) {
+ handleAction( ( *it ).Filepath, Actions::Delete );
}
}
}
DirWatchMap::iterator it = Directories.begin();
- for ( ; it != Directories.end(); ++it )
- {
- if ( Deleted )
- {
+ for ( ; it != Directories.end(); ++it ) {
+ if ( Deleted ) {
/// If the directory was deleted, mark the flag for file deletion
it->second->Deleted = true;
}
@@ -70,24 +56,22 @@ DirWatcherGeneric::~DirWatcherGeneric()
}
}
-void DirWatcherGeneric::resetDirectory( std::string directory )
-{
+void DirWatcherGeneric::resetDirectory( std::string directory ) {
std::string dir( directory );
/// Is this a recursive watch?
- if ( Watch->Directory != directory )
- {
- if ( !( directory.size() && ( directory.at(0) == FileSystem::getOSSlash() || directory.at( directory.size() - 1 ) == FileSystem::getOSSlash() ) ) )
- {
+ if ( Watch->Directory != directory ) {
+ if ( !( directory.size() &&
+ ( directory.at( 0 ) == FileSystem::getOSSlash() ||
+ directory.at( directory.size() - 1 ) == FileSystem::getOSSlash() ) ) ) {
/// Get the real directory
- if ( NULL != Parent )
- {
- FileSystem::dirAddSlashAtEnd(directory);
+ if ( NULL != Parent ) {
+ std::string parentPath( Parent->DirSnap.DirectoryInfo.Filepath );
+ FileSystem::dirAddSlashAtEnd( parentPath );
+ FileSystem::dirAddSlashAtEnd( directory );
- dir = Parent->DirSnap.DirectoryInfo.Filepath + directory;
- }
- else
- {
+ dir = parentPath + directory;
+ } else {
efDEBUG( "resetDirectory(): Parent is NULL. Fatal error." );
}
}
@@ -96,161 +80,140 @@ void DirWatcherGeneric::resetDirectory( std::string directory )
DirSnap.setDirectoryInfo( dir );
}
-void DirWatcherGeneric::handleAction( const std::string &filename, unsigned long action, std::string oldFilename)
-{
- Watch->Listener->handleFileAction( Watch->ID, DirSnap.DirectoryInfo.Filepath, FileSystem::fileNameFromPath( filename ), (Action)action, oldFilename );
+void DirWatcherGeneric::handleAction( const std::string& filename, unsigned long action,
+ std::string oldFilename ) {
+ Watch->Listener->handleFileAction( Watch->ID, DirSnap.DirectoryInfo.Filepath,
+ FileSystem::fileNameFromPath( filename ), (Action)action,
+ oldFilename );
}
-void DirWatcherGeneric::addChilds( bool reportNewFiles )
-{
- if ( Recursive )
- {
+void DirWatcherGeneric::addChilds( bool reportNewFiles ) {
+ if ( Recursive ) {
/// Create the subdirectories watchers
std::string dir;
- for ( FileInfoMap::iterator it = DirSnap.Files.begin(); it != DirSnap.Files.end(); it++ )
- {
- if ( it->second.isDirectory() && it->second.isReadable() && !FileSystem::isRemoteFS( it->second.Filepath ) )
- {
+ for ( FileInfoMap::iterator it = DirSnap.Files.begin(); it != DirSnap.Files.end(); it++ ) {
+ if ( it->second.isDirectory() && it->second.isReadable() &&
+ !FileSystem::isRemoteFS( it->second.Filepath ) ) {
/// Check if the directory is a symbolic link
std::string curPath;
std::string link( FileSystem::getLinkRealPath( it->second.Filepath, curPath ) );
dir = it->first;
- if ( "" != link )
- {
+ if ( "" != link ) {
/// Avoid adding symlinks directories if it's now enabled
- if ( !Watch->WatcherImpl->mFileWatcher->followSymlinks() )
- {
+ if ( !Watch->WatcherImpl->mFileWatcher->followSymlinks() ) {
continue;
}
/// If it's a symlink check if the realpath exists as a watcher, or
/// if the path is outside the current dir
- if ( Watch->WatcherImpl->pathInWatches( link ) || Watch->pathInWatches( link ) || !Watch->WatcherImpl->linkAllowed( curPath, link ) )
- {
+ if ( Watch->WatcherImpl->pathInWatches( link ) ||
+ Watch->pathInWatches( link ) ||
+ !Watch->WatcherImpl->linkAllowed( curPath, link ) ) {
continue;
- }
- else
- {
+ } else {
dir = link;
}
- }
- else
- {
- if ( Watch->pathInWatches( dir ) || Watch->WatcherImpl->pathInWatches( dir ) )
- {
+ } else {
+ if ( Watch->pathInWatches( dir ) || Watch->WatcherImpl->pathInWatches( dir ) ) {
continue;
}
}
- if ( reportNewFiles )
- {
+ if ( reportNewFiles ) {
handleAction( dir, Actions::Add );
}
- Directories[dir] = new DirWatcherGeneric( this, Watch, dir, Recursive, reportNewFiles );
+ Directories[dir] =
+ new DirWatcherGeneric( this, Watch, dir, Recursive, reportNewFiles );
- Directories[dir]->addChilds( reportNewFiles );
+ Directories[dir]->addChilds( reportNewFiles );
}
}
}
}
-void DirWatcherGeneric::watch( bool reportOwnChange )
-{
+void DirWatcherGeneric::watch( bool reportOwnChange ) {
DirectorySnapshotDiff Diff = DirSnap.scan();
- if ( reportOwnChange && Diff.DirChanged && NULL != Parent )
- {
- Watch->Listener->handleFileAction( Watch->ID, FileSystem::pathRemoveFileName( DirSnap.DirectoryInfo.Filepath ), FileSystem::fileNameFromPath( DirSnap.DirectoryInfo.Filepath ), Actions::Modified );
+ if ( reportOwnChange && Diff.DirChanged && NULL != Parent ) {
+ Watch->Listener->handleFileAction(
+ Watch->ID, FileSystem::pathRemoveFileName( DirSnap.DirectoryInfo.Filepath ),
+ FileSystem::fileNameFromPath( DirSnap.DirectoryInfo.Filepath ), Actions::Modified );
}
- if ( Diff.changed() )
- {
+ if ( Diff.changed() ) {
FileInfoList::iterator it;
MovedList::iterator mit;
/// Files
- DiffIterator( FilesCreated )
- {
- handleAction( (*it).Filepath, Actions::Add );
+ DiffIterator( FilesCreated ) {
+ handleAction( ( *it ).Filepath, Actions::Add );
}
- DiffIterator( FilesModified )
- {
- handleAction( (*it).Filepath, Actions::Modified );
+ DiffIterator( FilesModified ) {
+ handleAction( ( *it ).Filepath, Actions::Modified );
}
- DiffIterator( FilesDeleted )
- {
- handleAction( (*it).Filepath, Actions::Delete );
+ DiffIterator( FilesDeleted ) {
+ handleAction( ( *it ).Filepath, Actions::Delete );
}
- DiffMovedIterator( FilesMoved )
- {
- handleAction( (*mit).second.Filepath, Actions::Moved, (*mit).first );
+ DiffMovedIterator( FilesMoved ) {
+ handleAction( ( *mit ).second.Filepath, Actions::Moved, ( *mit ).first );
}
/// Directories
- DiffIterator( DirsCreated )
- {
- createDirectory( (*it).Filepath );
+ DiffIterator( DirsCreated ) {
+ createDirectory( ( *it ).Filepath );
}
- DiffIterator( DirsModified )
- {
- handleAction( (*it).Filepath, Actions::Modified );
+ DiffIterator( DirsModified ) {
+ handleAction( ( *it ).Filepath, Actions::Modified );
}
- DiffIterator( DirsDeleted )
- {
- handleAction( (*it).Filepath, Actions::Delete );
- removeDirectory( (*it).Filepath );
+ DiffIterator( DirsDeleted ) {
+ handleAction( ( *it ).Filepath, Actions::Delete );
+ removeDirectory( ( *it ).Filepath );
}
- DiffMovedIterator( DirsMoved )
- {
- handleAction( (*mit).second.Filepath, Actions::Moved, (*mit).first );
- moveDirectory( (*mit).first, (*mit).second.Filepath );
+ DiffMovedIterator( DirsMoved ) {
+ handleAction( ( *mit ).second.Filepath, Actions::Moved, ( *mit ).first );
+ moveDirectory( ( *mit ).first, ( *mit ).second.Filepath );
}
}
/// Process the subdirectories looking for changes
- for ( DirWatchMap::iterator dit = Directories.begin(); dit != Directories.end(); ++dit )
- {
+ for ( DirWatchMap::iterator dit = Directories.begin(); dit != Directories.end(); ++dit ) {
/// Just watch
dit->second->watch();
}
}
-void DirWatcherGeneric::watchDir( std::string &dir )
-{
- DirWatcherGeneric * watcher = Watch->WatcherImpl->mFileWatcher->allowOutOfScopeLinks() ?
- findDirWatcher( dir ) :
- findDirWatcherFast( dir );
+void DirWatcherGeneric::watchDir( std::string& dir ) {
+ DirWatcherGeneric* watcher = Watch->WatcherImpl->mFileWatcher->allowOutOfScopeLinks()
+ ? findDirWatcher( dir )
+ : findDirWatcherFast( dir );
- if ( NULL != watcher )
- {
+ if ( NULL != watcher ) {
watcher->watch( true );
}
}
-DirWatcherGeneric * DirWatcherGeneric::findDirWatcherFast( std::string dir )
-{
+DirWatcherGeneric* DirWatcherGeneric::findDirWatcherFast( std::string dir ) {
// remove the common base ( dir should always start with the same base as the watcher )
efASSERT( !dir.empty() );
efASSERT( dir.size() >= DirSnap.DirectoryInfo.Filepath.size() );
- efASSERT( DirSnap.DirectoryInfo.Filepath == dir.substr( 0, DirSnap.DirectoryInfo.Filepath.size() ) );
+ efASSERT( DirSnap.DirectoryInfo.Filepath ==
+ dir.substr( 0, DirSnap.DirectoryInfo.Filepath.size() ) );
- if ( dir.size() >= DirSnap.DirectoryInfo.Filepath.size() )
- {
+ if ( dir.size() >= DirSnap.DirectoryInfo.Filepath.size() ) {
dir = dir.substr( DirSnap.DirectoryInfo.Filepath.size() - 1 );
}
- if ( dir.size() == 1 )
- {
+ if ( dir.size() == 1 ) {
efASSERT( dir[0] == FileSystem::getOSSlash() );
return this;
}
@@ -258,22 +221,18 @@ DirWatcherGeneric * DirWatcherGeneric::findDirWatcherFast( std::string dir )
size_t level = 0;
std::vector<std::string> dirv = String::split( dir, FileSystem::getOSSlash(), false );
- DirWatcherGeneric * watcher = this;
+ DirWatcherGeneric* watcher = this;
- while ( level < dirv.size() )
- {
+ while ( level < dirv.size() ) {
// search the dir level in the current watcher
- DirWatchMap::iterator it = watcher->Directories.find( dirv[ level ] );
+ DirWatchMap::iterator it = watcher->Directories.find( dirv[level] );
// found? continue with the next level
- if ( it != watcher->Directories.end() )
- {
+ if ( it != watcher->Directories.end() ) {
watcher = it->second;
level++;
- }
- else
- {
+ } else {
// couldn't found the folder level?
// directory not watched
return NULL;
@@ -283,22 +242,16 @@ DirWatcherGeneric * DirWatcherGeneric::findDirWatcherFast( std::string dir )
return watcher;
}
-DirWatcherGeneric * DirWatcherGeneric::findDirWatcher( std::string dir )
-{
- if ( DirSnap.DirectoryInfo.Filepath == dir )
- {
+DirWatcherGeneric* DirWatcherGeneric::findDirWatcher( std::string dir ) {
+ if ( DirSnap.DirectoryInfo.Filepath == dir ) {
return this;
- }
- else
- {
- DirWatcherGeneric * watcher = NULL;
+ } else {
+ DirWatcherGeneric* watcher = NULL;
- for ( DirWatchMap::iterator it = Directories.begin(); it != Directories.end(); ++it )
- {
+ for ( DirWatchMap::iterator it = Directories.begin(); it != Directories.end(); ++it ) {
watcher = it->second->findDirWatcher( dir );
- if ( NULL != watcher )
- {
+ if ( NULL != watcher ) {
return watcher;
}
}
@@ -307,22 +260,22 @@ DirWatcherGeneric * DirWatcherGeneric::findDirWatcher( std::string dir )
return NULL;
}
-DirWatcherGeneric * DirWatcherGeneric::createDirectory( std::string newdir )
-{
+DirWatcherGeneric* DirWatcherGeneric::createDirectory( std::string newdir ) {
FileSystem::dirRemoveSlashAtEnd( newdir );
newdir = FileSystem::fileNameFromPath( newdir );
- DirWatcherGeneric * dw = NULL;
+ DirWatcherGeneric* dw = NULL;
/// Check if the directory is a symbolic link
- std::string dir( DirSnap.DirectoryInfo.Filepath + newdir );
+ std::string parentPath( DirSnap.DirectoryInfo.Filepath );
+ FileSystem::dirAddSlashAtEnd( parentPath );
+ std::string dir( parentPath + newdir );
FileSystem::dirAddSlashAtEnd( dir );
FileInfo fi( dir );
- if ( !fi.isDirectory() || !fi.isReadable() || FileSystem::isRemoteFS( dir ) )
- {
+ if ( !fi.isDirectory() || !fi.isReadable() || FileSystem::isRemoteFS( dir ) ) {
return NULL;
}
@@ -330,57 +283,48 @@ DirWatcherGeneric * DirWatcherGeneric::createDirectory( std::string newdir )
std::string link( FileSystem::getLinkRealPath( dir, curPath ) );
bool skip = false;
- if ( "" != link )
- {
+ if ( "" != link ) {
/// Avoid adding symlinks directories if it's now enabled
- if ( !Watch->WatcherImpl->mFileWatcher->followSymlinks() )
- {
+ if ( !Watch->WatcherImpl->mFileWatcher->followSymlinks() ) {
skip = true;
}
/// If it's a symlink check if the realpath exists as a watcher, or
/// if the path is outside the current dir
- if ( Watch->WatcherImpl->pathInWatches( link ) || Watch->pathInWatches( link ) || !Watch->WatcherImpl->linkAllowed( curPath, link ) )
- {
+ if ( Watch->WatcherImpl->pathInWatches( link ) || Watch->pathInWatches( link ) ||
+ !Watch->WatcherImpl->linkAllowed( curPath, link ) ) {
skip = true;
- }
- else
- {
+ } else {
dir = link;
}
- }
- else
- {
- if ( Watch->pathInWatches( dir ) || Watch->WatcherImpl->pathInWatches( dir ) )
- {
+ } else {
+ if ( Watch->pathInWatches( dir ) || Watch->WatcherImpl->pathInWatches( dir ) ) {
skip = true;
}
}
- if ( !skip )
- {
+ if ( !skip ) {
handleAction( newdir, Actions::Add );
/// Creates the new directory watcher of the subfolder and check for new files
dw = new DirWatcherGeneric( this, Watch, dir, Recursive );
-
+
dw->addChilds();
dw->watch();
/// Add it to the list of directories
- Directories[ newdir ] = dw;
+ Directories[newdir] = dw;
}
return dw;
}
-void DirWatcherGeneric::removeDirectory( std::string dir )
-{
+void DirWatcherGeneric::removeDirectory( std::string dir ) {
FileSystem::dirRemoveSlashAtEnd( dir );
dir = FileSystem::fileNameFromPath( dir );
- DirWatcherGeneric * dw = NULL;
+ DirWatcherGeneric* dw = NULL;
DirWatchMap::iterator dit;
/// Folder deleted
@@ -388,8 +332,7 @@ void DirWatcherGeneric::removeDirectory( std::string dir )
/// Search the folder, it should exists
dit = Directories.find( dir );
- if ( dit != Directories.end() )
- {
+ if ( dit != Directories.end() ) {
dw = dit->second;
/// Flag it as deleted so it fire the event for every file inside deleted
@@ -403,49 +346,43 @@ void DirWatcherGeneric::removeDirectory( std::string dir )
}
}
-void DirWatcherGeneric::moveDirectory( std::string oldDir, std::string newDir )
-{
+void DirWatcherGeneric::moveDirectory( std::string oldDir, std::string newDir ) {
FileSystem::dirRemoveSlashAtEnd( oldDir );
oldDir = FileSystem::fileNameFromPath( oldDir );
FileSystem::dirRemoveSlashAtEnd( newDir );
newDir = FileSystem::fileNameFromPath( newDir );
- DirWatcherGeneric * dw = NULL;
+ DirWatcherGeneric* dw = NULL;
DirWatchMap::iterator dit;
/// Directory existed?
dit = Directories.find( oldDir );
- if ( dit != Directories.end() )
- {
+ if ( dit != Directories.end() ) {
dw = dit->second;
/// Remove the directory from the map
Directories.erase( dit->first );
- Directories[ newDir ] = dw;
+ Directories[newDir] = dw;
dw->resetDirectory( newDir );
}
}
-bool DirWatcherGeneric::pathInWatches( std::string path )
-{
- if ( DirSnap.DirectoryInfo.Filepath == path )
- {
+bool DirWatcherGeneric::pathInWatches( std::string path ) {
+ if ( DirSnap.DirectoryInfo.Filepath == path ) {
return true;
}
- for ( DirWatchMap::iterator it = Directories.begin(); it != Directories.end(); ++it )
- {
- if ( it->second->pathInWatches( path ) )
- {
- return true;
- }
+ for ( DirWatchMap::iterator it = Directories.begin(); it != Directories.end(); ++it ) {
+ if ( it->second->pathInWatches( path ) ) {
+ return true;
+ }
}
return false;
}
-}
+} // namespace efsw
diff --git a/dep/efsw/src/efsw/DirWatcherGeneric.hpp b/dep/efsw/src/efsw/DirWatcherGeneric.hpp
index a7581904422..ca52de7f22b 100644
--- a/dep/efsw/src/efsw/DirWatcherGeneric.hpp
+++ b/dep/efsw/src/efsw/DirWatcherGeneric.hpp
@@ -1,55 +1,57 @@
#ifndef EFSW_DIRWATCHERGENERIC_HPP
#define EFSW_DIRWATCHERGENERIC_HPP
-#include <efsw/WatcherGeneric.hpp>
-#include <efsw/FileInfo.hpp>
#include <efsw/DirectorySnapshot.hpp>
+#include <efsw/FileInfo.hpp>
+#include <efsw/WatcherGeneric.hpp>
#include <map>
namespace efsw {
-class DirWatcherGeneric
-{
- public:
- typedef std::map<std::string, DirWatcherGeneric*> DirWatchMap;
+class DirWatcherGeneric {
+ public:
+ typedef std::map<std::string, DirWatcherGeneric*> DirWatchMap;
+
+ DirWatcherGeneric* Parent;
+ WatcherGeneric* Watch;
+ DirectorySnapshot DirSnap;
+ DirWatchMap Directories;
+ bool Recursive;
- DirWatcherGeneric * Parent;
- WatcherGeneric * Watch;
- DirectorySnapshot DirSnap;
- DirWatchMap Directories;
- bool Recursive;
+ DirWatcherGeneric( DirWatcherGeneric* parent, WatcherGeneric* ws, const std::string& directory,
+ bool recursive, bool reportNewFiles = false );
- DirWatcherGeneric( DirWatcherGeneric * parent, WatcherGeneric * ws, const std::string& directory, bool recursive, bool reportNewFiles = false );
+ ~DirWatcherGeneric();
- ~DirWatcherGeneric();
+ void watch( bool reportOwnChange = false );
- void watch( bool reportOwnChange = false );
+ void watchDir( std::string& dir );
- void watchDir( std::string& dir );
+ static bool isDir( const std::string& directory );
- static bool isDir( const std::string& directory );
+ bool pathInWatches( std::string path );
- bool pathInWatches( std::string path );
+ void addChilds( bool reportNewFiles = true );
- void addChilds( bool reportNewFiles = true );
+ DirWatcherGeneric* findDirWatcher( std::string dir );
- DirWatcherGeneric * findDirWatcher( std::string dir );
+ DirWatcherGeneric* findDirWatcherFast( std::string dir );
- DirWatcherGeneric * findDirWatcherFast( std::string dir );
- protected:
- bool Deleted;
+ protected:
+ bool Deleted;
- DirWatcherGeneric * createDirectory( std::string newdir );
+ DirWatcherGeneric* createDirectory( std::string newdir );
- void removeDirectory( std::string dir );
+ void removeDirectory( std::string dir );
- void moveDirectory( std::string oldDir, std::string newDir );
+ void moveDirectory( std::string oldDir, std::string newDir );
- void resetDirectory( std::string directory );
+ void resetDirectory( std::string directory );
- void handleAction( const std::string& filename, unsigned long action, std::string oldFilename = "");
+ void handleAction( const std::string& filename, unsigned long action,
+ std::string oldFilename = "" );
};
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/DirectorySnapshot.cpp b/dep/efsw/src/efsw/DirectorySnapshot.cpp
index e0680483e6b..f78475f546f 100644
--- a/dep/efsw/src/efsw/DirectorySnapshot.cpp
+++ b/dep/efsw/src/efsw/DirectorySnapshot.cpp
@@ -3,44 +3,32 @@
namespace efsw {
-DirectorySnapshot::DirectorySnapshot()
-{
-}
+DirectorySnapshot::DirectorySnapshot() {}
-DirectorySnapshot::DirectorySnapshot( std::string directory )
-{
+DirectorySnapshot::DirectorySnapshot( std::string directory ) {
init( directory );
}
-DirectorySnapshot::~DirectorySnapshot()
-{
-}
+DirectorySnapshot::~DirectorySnapshot() {}
-void DirectorySnapshot::init( std::string directory )
-{
+void DirectorySnapshot::init( std::string directory ) {
setDirectoryInfo( directory );
initFiles();
}
-bool DirectorySnapshot::exists()
-{
+bool DirectorySnapshot::exists() {
return DirectoryInfo.exists();
}
-void DirectorySnapshot::deleteAll( DirectorySnapshotDiff& Diff )
-{
+void DirectorySnapshot::deleteAll( DirectorySnapshotDiff& Diff ) {
FileInfo fi;
- for ( FileInfoMap::iterator it = Files.begin(); it != Files.end(); it++ )
- {
+ for ( FileInfoMap::iterator it = Files.begin(); it != Files.end(); it++ ) {
fi = it->second;
- if ( fi.isDirectory() )
- {
+ if ( fi.isDirectory() ) {
Diff.DirsDeleted.push_back( fi );
- }
- else
- {
+ } else {
Diff.FilesDeleted.push_back( fi );
}
}
@@ -48,51 +36,44 @@ void DirectorySnapshot::deleteAll( DirectorySnapshotDiff& Diff )
Files.clear();
}
-void DirectorySnapshot::setDirectoryInfo( std::string directory )
-{
+void DirectorySnapshot::setDirectoryInfo( std::string directory ) {
DirectoryInfo = FileInfo( directory );
}
-void DirectorySnapshot::initFiles()
-{
+void DirectorySnapshot::initFiles() {
Files = FileSystem::filesInfoFromPath( DirectoryInfo.Filepath );
FileInfoMap::iterator it = Files.begin();
- std::list<std::string> eraseFiles;
+ std::vector<std::string> eraseFiles;
/// Remove all non regular files and non directories
- for ( ; it != Files.end(); it++ )
- {
- if ( !it->second.isRegularFile() && !it->second.isDirectory() )
- {
+ for ( ; it != Files.end(); it++ ) {
+ if ( !it->second.isRegularFile() && !it->second.isDirectory() ) {
eraseFiles.push_back( it->first );
}
}
- for ( std::list<std::string>::iterator eit = eraseFiles.begin(); eit != eraseFiles.end(); eit++ )
- {
+ for ( std::vector<std::string>::iterator eit = eraseFiles.begin(); eit != eraseFiles.end();
+ eit++ ) {
Files.erase( *eit );
}
}
-DirectorySnapshotDiff DirectorySnapshot::scan()
-{
- DirectorySnapshotDiff Diff;
+DirectorySnapshotDiff DirectorySnapshot::scan() {
+ DirectorySnapshotDiff Diff;
Diff.clear();
FileInfo curFI( DirectoryInfo.Filepath );
- Diff.DirChanged = DirectoryInfo != curFI;
+ Diff.DirChanged = DirectoryInfo != curFI;
- if ( Diff.DirChanged )
- {
+ if ( Diff.DirChanged ) {
DirectoryInfo = curFI;
}
/// If the directory was erased, create the events for files and directories deletion
- if ( !curFI.exists() )
- {
+ if ( !curFI.exists() ) {
deleteAll( Diff );
return Diff;
@@ -100,8 +81,7 @@ DirectorySnapshotDiff DirectorySnapshot::scan()
FileInfoMap files = FileSystem::filesInfoFromPath( DirectoryInfo.Filepath );
- if ( files.empty() && Files.empty() )
- {
+ if ( files.empty() && Files.empty() ) {
return Diff;
}
@@ -110,52 +90,43 @@ DirectorySnapshotDiff DirectorySnapshot::scan()
FileInfoMap::iterator it;
FileInfoMap::iterator fiIt;
- if ( Diff.DirChanged )
- {
+ if ( Diff.DirChanged ) {
FilesCpy = Files;
}
- for ( it = files.begin(); it != files.end(); it++ )
- {
- fi = it->second;
+ for ( it = files.begin(); it != files.end(); it++ ) {
+ fi = it->second;
/// File existed before?
fiIt = Files.find( it->first );
- if ( fiIt != Files.end() )
- {
+ if ( fiIt != Files.end() ) {
/// Erase from the file list copy
FilesCpy.erase( it->first );
/// File changed?
- if ( (*fiIt).second != fi )
- {
+ if ( ( *fiIt ).second != fi ) {
/// Update the new file info
- Files[ it->first ] = fi;
+ Files[it->first] = fi;
/// handle modified event
- if ( fi.isDirectory() )
- {
+ if ( fi.isDirectory() ) {
Diff.DirsModified.push_back( fi );
- }
- else
- {
+ } else {
Diff.FilesModified.push_back( fi );
}
}
}
/// Only add regular files or directories
- else if ( fi.isRegularFile() || fi.isDirectory() )
- {
+ else if ( fi.isRegularFile() || fi.isDirectory() ) {
/// New file found
- Files[ it->first ] = fi;
+ Files[it->first] = fi;
FileInfoMap::iterator fit;
std::string oldFile = "";
/// Check if the same inode already existed
- if ( ( fit = nodeInFiles( fi ) ) != Files.end() )
- {
+ if ( ( fit = nodeInFiles( fi ) ) != Files.end() ) {
oldFile = fit->first;
/// Avoid firing a Delete event
@@ -164,45 +135,32 @@ DirectorySnapshotDiff DirectorySnapshot::scan()
/// Delete the old file name
Files.erase( fit->first );
- if ( fi.isDirectory() )
- {
+ if ( fi.isDirectory() ) {
Diff.DirsMoved.push_back( std::make_pair( oldFile, fi ) );
- }
- else
- {
+ } else {
Diff.FilesMoved.push_back( std::make_pair( oldFile, fi ) );
}
- }
- else
- {
- if ( fi.isDirectory() )
- {
+ } else {
+ if ( fi.isDirectory() ) {
Diff.DirsCreated.push_back( fi );
- }
- else
- {
+ } else {
Diff.FilesCreated.push_back( fi );
}
}
}
}
- if ( !Diff.DirChanged )
- {
+ if ( !Diff.DirChanged ) {
return Diff;
}
/// The files or directories that remains were deleted
- for ( it = FilesCpy.begin(); it != FilesCpy.end(); it++ )
- {
+ for ( it = FilesCpy.begin(); it != FilesCpy.end(); it++ ) {
fi = it->second;
- if ( fi.isDirectory() )
- {
+ if ( fi.isDirectory() ) {
Diff.DirsDeleted.push_back( fi );
- }
- else
- {
+ } else {
Diff.FilesDeleted.push_back( fi );
}
@@ -213,16 +171,12 @@ DirectorySnapshotDiff DirectorySnapshot::scan()
return Diff;
}
-FileInfoMap::iterator DirectorySnapshot::nodeInFiles( FileInfo& fi )
-{
+FileInfoMap::iterator DirectorySnapshot::nodeInFiles( FileInfo& fi ) {
FileInfoMap::iterator it;
- if ( FileInfo::inodeSupported() )
- {
- for ( it = Files.begin(); it != Files.end(); it++ )
- {
- if ( it->second.sameInode( fi ) && it->second.Filepath != fi.Filepath )
- {
+ if ( FileInfo::inodeSupported() ) {
+ for ( it = Files.begin(); it != Files.end(); it++ ) {
+ if ( it->second.sameInode( fi ) && it->second.Filepath != fi.Filepath ) {
return it;
}
}
@@ -231,33 +185,28 @@ FileInfoMap::iterator DirectorySnapshot::nodeInFiles( FileInfo& fi )
return Files.end();
}
-void DirectorySnapshot::addFile( std::string path )
-{
+void DirectorySnapshot::addFile( std::string path ) {
std::string name( FileSystem::fileNameFromPath( path ) );
- Files[ name ] = FileInfo( path );
+ Files[name] = FileInfo( path );
}
-void DirectorySnapshot::removeFile( std::string path )
-{
+void DirectorySnapshot::removeFile( std::string path ) {
std::string name( FileSystem::fileNameFromPath( path ) );
FileInfoMap::iterator it = Files.find( name );
- if ( Files.end() != it )
- {
+ if ( Files.end() != it ) {
Files.erase( it );
}
}
-void DirectorySnapshot::moveFile( std::string oldPath, std::string newPath )
-{
+void DirectorySnapshot::moveFile( std::string oldPath, std::string newPath ) {
removeFile( oldPath );
addFile( newPath );
}
-void DirectorySnapshot::updateFile(std::string path)
-{
+void DirectorySnapshot::updateFile( std::string path ) {
addFile( path );
}
-}
+} // namespace efsw
diff --git a/dep/efsw/src/efsw/DirectorySnapshot.hpp b/dep/efsw/src/efsw/DirectorySnapshot.hpp
index 1ada66fe980..0e6054293cd 100644
--- a/dep/efsw/src/efsw/DirectorySnapshot.hpp
+++ b/dep/efsw/src/efsw/DirectorySnapshot.hpp
@@ -5,42 +5,41 @@
namespace efsw {
-class DirectorySnapshot
-{
- public:
- FileInfo DirectoryInfo;
- FileInfoMap Files;
+class DirectorySnapshot {
+ public:
+ FileInfo DirectoryInfo;
+ FileInfoMap Files;
- void setDirectoryInfo( std::string directory );
+ void setDirectoryInfo( std::string directory );
- DirectorySnapshot();
+ DirectorySnapshot();
- DirectorySnapshot( std::string directory );
+ DirectorySnapshot( std::string directory );
- ~DirectorySnapshot();
+ ~DirectorySnapshot();
- void init( std::string directory );
+ void init( std::string directory );
- bool exists();
+ bool exists();
- DirectorySnapshotDiff scan();
+ DirectorySnapshotDiff scan();
- FileInfoMap::iterator nodeInFiles( FileInfo& fi );
+ FileInfoMap::iterator nodeInFiles( FileInfo& fi );
- void addFile( std::string path );
+ void addFile( std::string path );
- void removeFile( std::string path );
+ void removeFile( std::string path );
- void moveFile( std::string oldPath, std::string newPath );
+ void moveFile( std::string oldPath, std::string newPath );
- void updateFile( std::string path );
- protected:
- void initFiles();
+ void updateFile( std::string path );
- void deleteAll( DirectorySnapshotDiff &Diff );
+ protected:
+ void initFiles();
+
+ void deleteAll( DirectorySnapshotDiff& Diff );
};
-}
+} // namespace efsw
#endif
-
diff --git a/dep/efsw/src/efsw/DirectorySnapshotDiff.cpp b/dep/efsw/src/efsw/DirectorySnapshotDiff.cpp
index eabc6fdbda1..37ee507fdc6 100644
--- a/dep/efsw/src/efsw/DirectorySnapshotDiff.cpp
+++ b/dep/efsw/src/efsw/DirectorySnapshotDiff.cpp
@@ -2,8 +2,7 @@
namespace efsw {
-void DirectorySnapshotDiff::clear()
-{
+void DirectorySnapshotDiff::clear() {
FilesCreated.clear();
FilesModified.clear();
FilesMoved.clear();
@@ -14,16 +13,10 @@ void DirectorySnapshotDiff::clear()
DirsDeleted.clear();
}
-bool DirectorySnapshotDiff::changed()
-{
- return !FilesCreated.empty() ||
- !FilesModified.empty() ||
- !FilesMoved.empty() ||
- !FilesDeleted.empty() ||
- !DirsCreated.empty() ||
- !DirsModified.empty() ||
- !DirsMoved.empty() ||
- !DirsDeleted.empty();
+bool DirectorySnapshotDiff::changed() {
+ return !FilesCreated.empty() || !FilesModified.empty() || !FilesMoved.empty() ||
+ !FilesDeleted.empty() || !DirsCreated.empty() || !DirsModified.empty() ||
+ !DirsMoved.empty() || !DirsDeleted.empty();
}
-}
+} // namespace efsw
diff --git a/dep/efsw/src/efsw/DirectorySnapshotDiff.hpp b/dep/efsw/src/efsw/DirectorySnapshotDiff.hpp
index 042de9ce02c..26a29ec4436 100644
--- a/dep/efsw/src/efsw/DirectorySnapshotDiff.hpp
+++ b/dep/efsw/src/efsw/DirectorySnapshotDiff.hpp
@@ -5,31 +5,31 @@
namespace efsw {
-class DirectorySnapshotDiff
-{
- public:
- FileInfoList FilesDeleted;
- FileInfoList FilesCreated;
- FileInfoList FilesModified;
- MovedList FilesMoved;
- FileInfoList DirsDeleted;
- FileInfoList DirsCreated;
- FileInfoList DirsModified;
- MovedList DirsMoved;
- bool DirChanged;
-
- void clear();
-
- bool changed();
+class DirectorySnapshotDiff {
+ public:
+ FileInfoList FilesDeleted;
+ FileInfoList FilesCreated;
+ FileInfoList FilesModified;
+ MovedList FilesMoved;
+ FileInfoList DirsDeleted;
+ FileInfoList DirsCreated;
+ FileInfoList DirsModified;
+ MovedList DirsMoved;
+ bool DirChanged;
+
+ void clear();
+
+ bool changed();
};
-#define DiffIterator( FileInfoListName ) it = Diff.FileInfoListName.begin(); \
- for ( ; it != Diff.FileInfoListName.end(); it++ )
+#define DiffIterator( FileInfoListName ) \
+ it = Diff.FileInfoListName.begin(); \
+ for ( ; it != Diff.FileInfoListName.end(); it++ )
-#define DiffMovedIterator( MovedListName ) mit = Diff.MovedListName.begin(); \
- for ( ; mit != Diff.MovedListName.end(); mit++ )
+#define DiffMovedIterator( MovedListName ) \
+ mit = Diff.MovedListName.begin(); \
+ for ( ; mit != Diff.MovedListName.end(); mit++ )
-}
+} // namespace efsw
#endif
-
diff --git a/dep/efsw/src/efsw/FileInfo.cpp b/dep/efsw/src/efsw/FileInfo.cpp
index f5518225b48..707f617fe41 100644
--- a/dep/efsw/src/efsw/FileInfo.cpp
+++ b/dep/efsw/src/efsw/FileInfo.cpp
@@ -16,208 +16,175 @@
#include <stdlib.h>
#ifdef EFSW_COMPILER_MSVC
- #ifndef S_ISDIR
- #define S_ISDIR(f) ((f)&_S_IFDIR)
- #endif
+#ifndef S_ISDIR
+#define S_ISDIR( f ) ( (f)&_S_IFDIR )
+#endif
- #ifndef S_ISREG
- #define S_ISREG(f) ((f)&_S_IFREG)
- #endif
+#ifndef S_ISREG
+#define S_ISREG( f ) ( (f)&_S_IFREG )
+#endif
- #ifndef S_ISRDBL
- #define S_ISRDBL(f) ((f)&_S_IREAD)
- #endif
+#ifndef S_ISRDBL
+#define S_ISRDBL( f ) ( (f)&_S_IREAD )
+#endif
#else
- #include <unistd.h>
+#include <unistd.h>
- #ifndef S_ISRDBL
- #define S_ISRDBL(f) ((f)&S_IRUSR)
- #endif
+#ifndef S_ISRDBL
+#define S_ISRDBL( f ) ( (f)&S_IRUSR )
+#endif
#endif
namespace efsw {
-bool FileInfo::exists( const std::string& filePath )
-{
+bool FileInfo::exists( const std::string& filePath ) {
FileInfo fi( filePath );
return fi.exists();
}
-bool FileInfo::isLink( const std::string& filePath )
-{
+bool FileInfo::isLink( const std::string& filePath ) {
FileInfo fi( filePath, true );
return fi.isLink();
}
-bool FileInfo::inodeSupported()
-{
- #if EFSW_PLATFORM != EFSW_PLATFORM_WIN32
+bool FileInfo::inodeSupported() {
+#if EFSW_PLATFORM != EFSW_PLATFORM_WIN32
return true;
- #else
+#else
return false;
- #endif
+#endif
}
FileInfo::FileInfo() :
- ModificationTime(0),
- OwnerId(0),
- GroupId(0),
- Permissions(0),
- Inode(0)
-{}
+ ModificationTime( 0 ), OwnerId( 0 ), GroupId( 0 ), Permissions( 0 ), Inode( 0 ) {}
FileInfo::FileInfo( const std::string& filepath ) :
Filepath( filepath ),
- ModificationTime(0),
- OwnerId(0),
- GroupId(0),
- Permissions(0),
- Inode(0)
-{
+ ModificationTime( 0 ),
+ OwnerId( 0 ),
+ GroupId( 0 ),
+ Permissions( 0 ),
+ Inode( 0 ) {
getInfo();
}
FileInfo::FileInfo( const std::string& filepath, bool linkInfo ) :
Filepath( filepath ),
- ModificationTime(0),
- OwnerId(0),
- GroupId(0),
- Permissions(0),
- Inode(0)
-{
- if ( linkInfo )
- {
+ ModificationTime( 0 ),
+ OwnerId( 0 ),
+ GroupId( 0 ),
+ Permissions( 0 ),
+ Inode( 0 ) {
+ if ( linkInfo ) {
getRealInfo();
- }
- else
- {
+ } else {
getInfo();
}
}
-void FileInfo::getInfo()
-{
- #if EFSW_PLATFORM == EFSW_PLATFORM_WIN32
- if ( Filepath.size() == 3 && Filepath[1] == ':' && Filepath[2] == FileSystem::getOSSlash() )
- {
+void FileInfo::getInfo() {
+#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32
+ if ( Filepath.size() == 3 && Filepath[1] == ':' && Filepath[2] == FileSystem::getOSSlash() ) {
Filepath += FileSystem::getOSSlash();
}
- #endif
+#endif
- /// Why i'm doing this? stat in mingw32 doesn't work for directories if the dir path ends with a path slash
+ /// Why i'm doing this? stat in mingw32 doesn't work for directories if the dir path ends with a
+ /// path slash
bool slashAtEnd = FileSystem::slashAtEnd( Filepath );
- if ( slashAtEnd )
- {
+ if ( slashAtEnd ) {
FileSystem::dirRemoveSlashAtEnd( Filepath );
}
- #if EFSW_PLATFORM != EFSW_PLATFORM_WIN32
+#if EFSW_PLATFORM != EFSW_PLATFORM_WIN32
struct stat st;
int res = stat( Filepath.c_str(), &st );
- #else
+#else
struct _stat st;
int res = _wstat( String::fromUtf8( Filepath ).toWideString().c_str(), &st );
- #endif
-
- if ( 0 == res )
- {
- ModificationTime = st.st_mtime;
- Size = st.st_size;
- OwnerId = st.st_uid;
- GroupId = st.st_gid;
- Permissions = st.st_mode;
- Inode = st.st_ino;
+#endif
+
+ if ( 0 == res ) {
+ ModificationTime = st.st_mtime;
+ Size = st.st_size;
+ OwnerId = st.st_uid;
+ GroupId = st.st_gid;
+ Permissions = st.st_mode;
+ Inode = st.st_ino;
}
- if ( slashAtEnd )
- {
+ if ( slashAtEnd ) {
FileSystem::dirAddSlashAtEnd( Filepath );
}
}
-void FileInfo::getRealInfo()
-{
+void FileInfo::getRealInfo() {
bool slashAtEnd = FileSystem::slashAtEnd( Filepath );
- if ( slashAtEnd )
- {
+ if ( slashAtEnd ) {
FileSystem::dirRemoveSlashAtEnd( Filepath );
}
- #if EFSW_PLATFORM != EFSW_PLATFORM_WIN32
+#if EFSW_PLATFORM != EFSW_PLATFORM_WIN32
struct stat st;
int res = lstat( Filepath.c_str(), &st );
- #else
+#else
struct _stat st;
int res = _wstat( String::fromUtf8( Filepath ).toWideString().c_str(), &st );
- #endif
-
- if ( 0 == res )
- {
- ModificationTime = st.st_mtime;
- Size = st.st_size;
- OwnerId = st.st_uid;
- GroupId = st.st_gid;
- Permissions = st.st_mode;
- Inode = st.st_ino;
+#endif
+
+ if ( 0 == res ) {
+ ModificationTime = st.st_mtime;
+ Size = st.st_size;
+ OwnerId = st.st_uid;
+ GroupId = st.st_gid;
+ Permissions = st.st_mode;
+ Inode = st.st_ino;
}
- if ( slashAtEnd )
- {
+ if ( slashAtEnd ) {
FileSystem::dirAddSlashAtEnd( Filepath );
}
}
-bool FileInfo::operator==( const FileInfo& Other ) const
-{
- return ( ModificationTime == Other.ModificationTime &&
- Size == Other.Size &&
- OwnerId == Other.OwnerId &&
- GroupId == Other.GroupId &&
- Permissions == Other.Permissions &&
- Inode == Other.Inode
- );
+bool FileInfo::operator==( const FileInfo& Other ) const {
+ return ( ModificationTime == Other.ModificationTime && Size == Other.Size &&
+ OwnerId == Other.OwnerId && GroupId == Other.GroupId &&
+ Permissions == Other.Permissions && Inode == Other.Inode );
}
-bool FileInfo::isDirectory() const
-{
- return 0 != S_ISDIR(Permissions);
+bool FileInfo::isDirectory() const {
+ return 0 != S_ISDIR( Permissions );
}
-bool FileInfo::isRegularFile() const
-{
- return 0 != S_ISREG(Permissions);
+bool FileInfo::isRegularFile() const {
+ return 0 != S_ISREG( Permissions );
}
-bool FileInfo::isReadable() const
-{
+bool FileInfo::isReadable() const {
#if EFSW_PLATFORM != EFSW_PLATFORM_WIN32
static bool isRoot = getuid() == 0;
- return isRoot || 0 != S_ISRDBL(Permissions);
+ return isRoot || 0 != S_ISRDBL( Permissions );
#else
- return 0 != S_ISRDBL(Permissions);
+ return 0 != S_ISRDBL( Permissions );
#endif
}
-bool FileInfo::isLink() const
-{
+bool FileInfo::isLink() const {
#if EFSW_PLATFORM != EFSW_PLATFORM_WIN32
- return S_ISLNK(Permissions);
+ return S_ISLNK( Permissions );
#else
return false;
#endif
}
-std::string FileInfo::linksTo()
-{
+std::string FileInfo::linksTo() {
#if EFSW_PLATFORM != EFSW_PLATFORM_WIN32
- if ( isLink() )
- {
- char * ch = realpath( Filepath.c_str(), NULL);
+ if ( isLink() ) {
+ char* ch = realpath( Filepath.c_str(), NULL );
- if ( NULL != ch )
- {
+ if ( NULL != ch ) {
std::string tstr( ch );
free( ch );
@@ -226,16 +193,14 @@ std::string FileInfo::linksTo()
}
}
#endif
- return std::string("");
+ return std::string( "" );
}
-bool FileInfo::exists()
-{
+bool FileInfo::exists() {
bool slashAtEnd = FileSystem::slashAtEnd( Filepath );
- if ( slashAtEnd )
- {
- FileSystem::dirRemoveSlashAtEnd(Filepath);
+ if ( slashAtEnd ) {
+ FileSystem::dirRemoveSlashAtEnd( Filepath );
}
#if EFSW_PLATFORM != EFSW_PLATFORM_WIN32
@@ -246,34 +211,30 @@ bool FileInfo::exists()
int res = _wstat( String::fromUtf8( Filepath ).toWideString().c_str(), &st );
#endif
- if (slashAtEnd)
- {
- FileSystem::dirAddSlashAtEnd(Filepath);
+ if ( slashAtEnd ) {
+ FileSystem::dirAddSlashAtEnd( Filepath );
}
return 0 == res;
}
-FileInfo& FileInfo::operator=( const FileInfo& Other )
-{
- this->Filepath = Other.Filepath;
- this->Size = Other.Size;
- this->ModificationTime = Other.ModificationTime;
- this->GroupId = Other.GroupId;
- this->OwnerId = Other.OwnerId;
- this->Permissions = Other.Permissions;
- this->Inode = Other.Inode;
+FileInfo& FileInfo::operator=( const FileInfo& Other ) {
+ this->Filepath = Other.Filepath;
+ this->Size = Other.Size;
+ this->ModificationTime = Other.ModificationTime;
+ this->GroupId = Other.GroupId;
+ this->OwnerId = Other.OwnerId;
+ this->Permissions = Other.Permissions;
+ this->Inode = Other.Inode;
return *this;
}
-bool FileInfo::sameInode( const FileInfo& Other ) const
-{
+bool FileInfo::sameInode( const FileInfo& Other ) const {
return inodeSupported() && Inode == Other.Inode;
}
-bool FileInfo::operator!=( const FileInfo& Other ) const
-{
- return !(*this == Other);
+bool FileInfo::operator!=( const FileInfo& Other ) const {
+ return !( *this == Other );
}
-}
+} // namespace efsw
diff --git a/dep/efsw/src/efsw/FileInfo.hpp b/dep/efsw/src/efsw/FileInfo.hpp
index c86e5749a70..1aca2a87581 100644
--- a/dep/efsw/src/efsw/FileInfo.hpp
+++ b/dep/efsw/src/efsw/FileInfo.hpp
@@ -2,65 +2,63 @@
#define EFSW_FILEINFO_HPP
#include <efsw/base.hpp>
-#include <string>
+#include <vector>
#include <map>
-#include <list>
+#include <string>
namespace efsw {
-class FileInfo
-{
- public:
- static bool exists( const std::string& filePath );
+class FileInfo {
+ public:
+ static bool exists( const std::string& filePath );
- static bool isLink( const std::string& filePath );
+ static bool isLink( const std::string& filePath );
- static bool inodeSupported();
+ static bool inodeSupported();
- FileInfo();
+ FileInfo();
- FileInfo( const std::string& filepath );
+ FileInfo( const std::string& filepath );
- FileInfo( const std::string& filepath, bool linkInfo );
+ FileInfo( const std::string& filepath, bool linkInfo );
- bool operator==( const FileInfo& Other ) const;
+ bool operator==( const FileInfo& Other ) const;
- bool operator!=( const FileInfo& Other ) const;
+ bool operator!=( const FileInfo& Other ) const;
- FileInfo& operator=( const FileInfo& Other );
+ FileInfo& operator=( const FileInfo& Other );
- bool isDirectory() const;
+ bool isDirectory() const;
- bool isRegularFile() const;
+ bool isRegularFile() const;
- bool isReadable() const;
+ bool isReadable() const;
- bool sameInode( const FileInfo& Other ) const;
+ bool sameInode( const FileInfo& Other ) const;
- bool isLink() const;
+ bool isLink() const;
- std::string linksTo();
+ std::string linksTo();
- bool exists();
+ bool exists();
- void getInfo();
+ void getInfo();
- void getRealInfo();
+ void getRealInfo();
- std::string Filepath;
- Uint64 ModificationTime;
- Uint64 Size;
- Uint32 OwnerId;
- Uint32 GroupId;
- Uint32 Permissions;
- Uint64 Inode;
+ std::string Filepath;
+ Uint64 ModificationTime;
+ Uint64 Size;
+ Uint32 OwnerId;
+ Uint32 GroupId;
+ Uint32 Permissions;
+ Uint64 Inode;
};
-typedef std::map<std::string, FileInfo> FileInfoMap;
-typedef std::list<FileInfo> FileInfoList;
-typedef std::list< std::pair< std::string, FileInfo> > MovedList;
+typedef std::map<std::string, FileInfo> FileInfoMap;
+typedef std::vector<FileInfo> FileInfoList;
+typedef std::vector<std::pair<std::string, FileInfo>> MovedList;
-}
+} // namespace efsw
#endif
-
diff --git a/dep/efsw/src/efsw/FileSystem.cpp b/dep/efsw/src/efsw/FileSystem.cpp
index 1bca40558c6..b6d2d63ddce 100644
--- a/dep/efsw/src/efsw/FileSystem.cpp
+++ b/dep/efsw/src/efsw/FileSystem.cpp
@@ -1,3 +1,4 @@
+#include <cstring>
#include <efsw/FileSystem.hpp>
#include <efsw/platform/platformimpl.hpp>
@@ -7,8 +8,7 @@
namespace efsw {
-bool FileSystem::isDirectory( const std::string& path )
-{
+bool FileSystem::isDirectory( const std::string& path ) {
return Platform::FileSystem::isDirectory( path );
}
@@ -18,68 +18,56 @@ FileInfoMap FileSystem::filesInfoFromPath( std::string path ) {
return Platform::FileSystem::filesInfoFromPath( path );
}
-char FileSystem::getOSSlash()
-{
+char FileSystem::getOSSlash() {
return Platform::FileSystem::getOSSlash();
}
-bool FileSystem::slashAtEnd( std::string &dir )
-{
- return ( dir.size() && dir[ dir.size() - 1 ] == getOSSlash() );
+bool FileSystem::slashAtEnd( std::string& dir ) {
+ return ( dir.size() && dir[dir.size() - 1] == getOSSlash() );
}
-void FileSystem::dirAddSlashAtEnd( std::string& dir )
-{
- if ( dir.size() > 1 && dir[ dir.size() - 1 ] != getOSSlash() )
- {
+void FileSystem::dirAddSlashAtEnd( std::string& dir ) {
+ if ( dir.size() >= 1 && dir[dir.size() - 1] != getOSSlash() ) {
dir.push_back( getOSSlash() );
}
}
-void FileSystem::dirRemoveSlashAtEnd( std::string& dir )
-{
- if ( dir.size() > 1 && dir[ dir.size() - 1 ] == getOSSlash() )
- {
+void FileSystem::dirRemoveSlashAtEnd( std::string& dir ) {
+ if ( dir.size() >= 1 && dir[dir.size() - 1] == getOSSlash() ) {
dir.erase( dir.size() - 1 );
}
}
-std::string FileSystem::fileNameFromPath( std::string filepath )
-{
+std::string FileSystem::fileNameFromPath( std::string filepath ) {
dirRemoveSlashAtEnd( filepath );
size_t pos = filepath.find_last_of( getOSSlash() );
- if ( pos != std::string::npos )
- {
+ if ( pos != std::string::npos ) {
return filepath.substr( pos + 1 );
}
return filepath;
}
-std::string FileSystem::pathRemoveFileName( std::string filepath )
-{
+std::string FileSystem::pathRemoveFileName( std::string filepath ) {
dirRemoveSlashAtEnd( filepath );
size_t pos = filepath.find_last_of( getOSSlash() );
- if ( pos != std::string::npos )
- {
+ if ( pos != std::string::npos ) {
return filepath.substr( 0, pos + 1 );
}
return filepath;
}
-std::string FileSystem::getLinkRealPath( std::string dir, std::string& curPath )
-{
+std::string FileSystem::getLinkRealPath( std::string dir, std::string& curPath ) {
FileSystem::dirRemoveSlashAtEnd( dir );
FileInfo fi( dir, true );
/// Check with lstat and see if it's a link
- if ( fi.isLink() )
- {
+ if ( fi.isLink() ) {
/// get the real path of the link
std::string link( fi.linksTo() );
@@ -96,39 +84,53 @@ std::string FileSystem::getLinkRealPath( std::string dir, std::string& curPath )
return "";
}
-std::string FileSystem::precomposeFileName( const std::string& name )
-{
+std::string FileSystem::precomposeFileName( const std::string& name ) {
#if EFSW_OS == EFSW_OS_MACOSX
- CFStringRef cfStringRef = CFStringCreateWithCString(kCFAllocatorDefault, name.c_str(), kCFStringEncodingUTF8);
- CFMutableStringRef cfMutable = CFStringCreateMutableCopy(NULL, 0, cfStringRef);
-
- CFStringNormalize(cfMutable,kCFStringNormalizationFormC);
-
- char c_str[255 + 1];
- CFStringGetCString(cfMutable, c_str, sizeof(c_str)-1, kCFStringEncodingUTF8);
-
- CFRelease(cfStringRef);
- CFRelease(cfMutable);
+ CFStringRef cfStringRef =
+ CFStringCreateWithCString( kCFAllocatorDefault, name.c_str(), kCFStringEncodingUTF8 );
+ CFMutableStringRef cfMutable = CFStringCreateMutableCopy( NULL, 0, cfStringRef );
+
+ CFStringNormalize( cfMutable, kCFStringNormalizationFormC );
+
+ const char* c_str = CFStringGetCStringPtr( cfMutable, kCFStringEncodingUTF8 );
+ if ( c_str != NULL ) {
+ std::string result( c_str );
+ CFRelease( cfStringRef );
+ CFRelease( cfMutable );
+ return result;
+ }
+ CFIndex length = CFStringGetLength( cfMutable );
+ CFIndex maxSize = CFStringGetMaximumSizeForEncoding( length, kCFStringEncodingUTF8 );
+ if ( maxSize == kCFNotFound ) {
+ CFRelease( cfStringRef );
+ CFRelease( cfMutable );
+ return std::string();
+ }
- return std::string(c_str);
+ std::string result( maxSize + 1, '\0' );
+ if ( CFStringGetCString( cfMutable, &result[0], result.size(), kCFStringEncodingUTF8 ) ) {
+ result.resize( std::strlen( result.c_str() ) );
+ CFRelease( cfStringRef );
+ CFRelease( cfMutable );
+ } else {
+ result.clear();
+ }
+ return result;
#else
return name;
#endif
}
-bool FileSystem::isRemoteFS( const std::string& directory )
-{
+bool FileSystem::isRemoteFS( const std::string& directory ) {
return Platform::FileSystem::isRemoteFS( directory );
}
-bool FileSystem::changeWorkingDirectory( const std::string& directory )
-{
+bool FileSystem::changeWorkingDirectory( const std::string& directory ) {
return Platform::FileSystem::changeWorkingDirectory( directory );
}
-std::string FileSystem::getCurrentWorkingDirectory()
-{
+std::string FileSystem::getCurrentWorkingDirectory() {
return Platform::FileSystem::getCurrentWorkingDirectory();
}
-}
+} // namespace efsw
diff --git a/dep/efsw/src/efsw/FileSystem.hpp b/dep/efsw/src/efsw/FileSystem.hpp
index 07c7ade8baa..6c24386c585 100644
--- a/dep/efsw/src/efsw/FileSystem.hpp
+++ b/dep/efsw/src/efsw/FileSystem.hpp
@@ -1,44 +1,41 @@
#ifndef EFSW_FILESYSTEM_HPP
#define EFSW_FILESYSTEM_HPP
-#include <efsw/base.hpp>
#include <efsw/FileInfo.hpp>
+#include <efsw/base.hpp>
#include <map>
namespace efsw {
-class FileSystem
-{
- public:
- static bool isDirectory( const std::string& path );
-
- static FileInfoMap filesInfoFromPath( std::string path );
+class FileSystem {
+ public:
+ static bool isDirectory( const std::string& path );
- static char getOSSlash();
+ static FileInfoMap filesInfoFromPath( std::string path );
- static bool slashAtEnd( std::string& dir );
+ static char getOSSlash();
- static void dirAddSlashAtEnd( std::string& dir );
+ static bool slashAtEnd( std::string& dir );
- static void dirRemoveSlashAtEnd( std::string& dir );
+ static void dirAddSlashAtEnd( std::string& dir );
- static std::string fileNameFromPath( std::string filepath );
+ static void dirRemoveSlashAtEnd( std::string& dir );
- static std::string pathRemoveFileName( std::string filepath );
+ static std::string fileNameFromPath( std::string filepath );
- static void realPath( std::string curdir, std::string& path );
+ static std::string pathRemoveFileName( std::string filepath );
- static std::string getLinkRealPath( std::string dir, std::string& curPath );
+ static std::string getLinkRealPath( std::string dir, std::string& curPath );
- static std::string precomposeFileName(const std::string& name);
+ static std::string precomposeFileName( const std::string& name );
- static bool isRemoteFS( const std::string& directory );
+ static bool isRemoteFS( const std::string& directory );
- static bool changeWorkingDirectory( const std::string & path );
+ static bool changeWorkingDirectory( const std::string& path );
- static std::string getCurrentWorkingDirectory();
+ static std::string getCurrentWorkingDirectory();
};
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/FileWatcher.cpp b/dep/efsw/src/efsw/FileWatcher.cpp
index e33d5ec46fb..ab3ec4bd679 100644
--- a/dep/efsw/src/efsw/FileWatcher.cpp
+++ b/dep/efsw/src/efsw/FileWatcher.cpp
@@ -1,43 +1,39 @@
-#include <efsw/efsw.hpp>
-#include <efsw/FileWatcherImpl.hpp>
-#include <efsw/FileWatcherGeneric.hpp>
#include <efsw/FileSystem.hpp>
+#include <efsw/FileWatcherGeneric.hpp>
+#include <efsw/FileWatcherImpl.hpp>
+#include <efsw/efsw.hpp>
#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32
-# include <efsw/FileWatcherWin32.hpp>
-# define FILEWATCHER_IMPL FileWatcherWin32
-# define BACKEND_NAME "Win32"
+#include <efsw/FileWatcherWin32.hpp>
+#define FILEWATCHER_IMPL FileWatcherWin32
+#define BACKEND_NAME "Win32"
#elif EFSW_PLATFORM == EFSW_PLATFORM_INOTIFY
-# include <efsw/FileWatcherInotify.hpp>
-# define FILEWATCHER_IMPL FileWatcherInotify
-# define BACKEND_NAME "Inotify"
+#include <efsw/FileWatcherInotify.hpp>
+#define FILEWATCHER_IMPL FileWatcherInotify
+#define BACKEND_NAME "Inotify"
#elif EFSW_PLATFORM == EFSW_PLATFORM_KQUEUE
-# include <efsw/FileWatcherKqueue.hpp>
-# define FILEWATCHER_IMPL FileWatcherKqueue
-# define BACKEND_NAME "Kqueue"
+#include <efsw/FileWatcherKqueue.hpp>
+#define FILEWATCHER_IMPL FileWatcherKqueue
+#define BACKEND_NAME "Kqueue"
#elif EFSW_PLATFORM == EFSW_PLATFORM_FSEVENTS
-# include <efsw/FileWatcherFSEvents.hpp>
-# define FILEWATCHER_IMPL FileWatcherFSEvents
-# define BACKEND_NAME "FSEvents"
+#include <efsw/FileWatcherFSEvents.hpp>
+#define FILEWATCHER_IMPL FileWatcherFSEvents
+#define BACKEND_NAME "FSEvents"
#else
-# define FILEWATCHER_IMPL FileWatcherGeneric
-# define BACKEND_NAME "Generic"
+#define FILEWATCHER_IMPL FileWatcherGeneric
+#define BACKEND_NAME "Generic"
#endif
#include <efsw/Debug.hpp>
namespace efsw {
-FileWatcher::FileWatcher() :
- mFollowSymlinks(false),
- mOutOfScopeLinks(false)
-{
+FileWatcher::FileWatcher() : mFollowSymlinks( false ), mOutOfScopeLinks( false ) {
efDEBUG( "Using backend: %s\n", BACKEND_NAME );
mImpl = new FILEWATCHER_IMPL( this );
- if ( !mImpl->initOK() )
- {
+ if ( !mImpl->initOK() ) {
efSAFE_DELETE( mImpl );
efDEBUG( "Falled back to backend: %s\n", BACKEND_NAME );
@@ -47,23 +43,17 @@ FileWatcher::FileWatcher() :
}
FileWatcher::FileWatcher( bool useGenericFileWatcher ) :
- mFollowSymlinks(false),
- mOutOfScopeLinks(false)
-{
- if ( useGenericFileWatcher )
- {
+ mFollowSymlinks( false ), mOutOfScopeLinks( false ) {
+ if ( useGenericFileWatcher ) {
efDEBUG( "Using backend: Generic\n" );
mImpl = new FileWatcherGeneric( this );
- }
- else
- {
+ } else {
efDEBUG( "Using backend: %s\n", BACKEND_NAME );
mImpl = new FILEWATCHER_IMPL( this );
- if ( !mImpl->initOK() )
- {
+ if ( !mImpl->initOK() ) {
efSAFE_DELETE( mImpl );
efDEBUG( "Falled back to backend: %s\n", BACKEND_NAME );
@@ -73,73 +63,58 @@ FileWatcher::FileWatcher( bool useGenericFileWatcher ) :
}
}
-FileWatcher::~FileWatcher()
-{
+FileWatcher::~FileWatcher() {
efSAFE_DELETE( mImpl );
}
-WatchID FileWatcher::addWatch(const std::string& directory, FileWatchListener* watcher)
-{
- if ( mImpl->mIsGeneric || !FileSystem::isRemoteFS( directory ) )
- {
- return mImpl->addWatch(directory, watcher, false);
- }
- else
- {
- return Errors::Log::createLastError( Errors::FileRemote, directory );
- }
+WatchID FileWatcher::addWatch( const std::string& directory, FileWatchListener* watcher ) {
+ return addWatch( directory, watcher, false, {} );
}
-WatchID FileWatcher::addWatch(const std::string& directory, FileWatchListener* watcher, bool recursive)
-{
- if ( mImpl->mIsGeneric || !FileSystem::isRemoteFS( directory ) )
- {
- return mImpl->addWatch(directory, watcher, recursive);
- }
- else
- {
+WatchID FileWatcher::addWatch( const std::string& directory, FileWatchListener* watcher,
+ bool recursive ) {
+ return addWatch( directory, watcher, recursive, {} );
+}
+
+WatchID FileWatcher::addWatch( const std::string& directory, FileWatchListener* watcher,
+ bool recursive, const std::vector<WatcherOption>& options ) {
+ if ( mImpl->mIsGeneric || !FileSystem::isRemoteFS( directory ) ) {
+ return mImpl->addWatch( directory, watcher, recursive, options );
+ } else {
return Errors::Log::createLastError( Errors::FileRemote, directory );
}
}
-void FileWatcher::removeWatch(const std::string& directory)
-{
- mImpl->removeWatch(directory);
+void FileWatcher::removeWatch( const std::string& directory ) {
+ mImpl->removeWatch( directory );
}
-void FileWatcher::removeWatch(WatchID watchid)
-{
- mImpl->removeWatch(watchid);
+void FileWatcher::removeWatch( WatchID watchid ) {
+ mImpl->removeWatch( watchid );
}
-void FileWatcher::watch()
-{
+void FileWatcher::watch() {
mImpl->watch();
}
-std::list<std::string> FileWatcher::directories()
-{
+std::vector<std::string> FileWatcher::directories() {
return mImpl->directories();
}
-void FileWatcher::followSymlinks( bool follow )
-{
+void FileWatcher::followSymlinks( bool follow ) {
mFollowSymlinks = follow;
}
-const bool& FileWatcher::followSymlinks() const
-{
+const bool& FileWatcher::followSymlinks() const {
return mFollowSymlinks;
}
-void FileWatcher::allowOutOfScopeLinks( bool allow )
-{
+void FileWatcher::allowOutOfScopeLinks( bool allow ) {
mOutOfScopeLinks = allow;
}
-const bool& FileWatcher::allowOutOfScopeLinks() const
-{
+const bool& FileWatcher::allowOutOfScopeLinks() const {
return mOutOfScopeLinks;
}
-}
+} // namespace efsw
diff --git a/dep/efsw/src/efsw/FileWatcherCWrapper.cpp b/dep/efsw/src/efsw/FileWatcherCWrapper.cpp
index 30a36eacc35..860d7d50c8b 100644
--- a/dep/efsw/src/efsw/FileWatcherCWrapper.cpp
+++ b/dep/efsw/src/efsw/FileWatcherCWrapper.cpp
@@ -2,27 +2,24 @@
#include <efsw/efsw.hpp>
#include <vector>
-#define TOBOOL(i) ((i) == 0 ? false : true)
+#define TOBOOL( i ) ( ( i ) == 0 ? false : true )
/*************************************************************************************************/
-class Watcher_CAPI : public efsw::FileWatchListener
-{
-public:
+class Watcher_CAPI : public efsw::FileWatchListener {
+ public:
efsw_watcher mWatcher;
efsw_pfn_fileaction_callback mFn;
void* mParam;
-public:
- Watcher_CAPI(efsw_watcher watcher, efsw_pfn_fileaction_callback fn, void* param) :
- mWatcher( watcher ),
- mFn( fn ),
- mParam( param )
- {}
-
- void handleFileAction(efsw::WatchID watchid, const std::string& dir, const std::string& filename,
- efsw::Action action, std::string oldFilename = "")
- {
- mFn(mWatcher, watchid, dir.c_str(), filename.c_str(), (enum efsw_action)action,
- oldFilename.c_str(), mParam );
+
+ public:
+ Watcher_CAPI( efsw_watcher watcher, efsw_pfn_fileaction_callback fn, void* param ) :
+ mWatcher( watcher ), mFn( fn ), mParam( param ) {}
+
+ void handleFileAction( efsw::WatchID watchid, const std::string& dir,
+ const std::string& filename, efsw::Action action,
+ std::string oldFilename = "" ) {
+ mFn( mWatcher, watchid, dir.c_str(), filename.c_str(), (enum efsw_action)action,
+ oldFilename.c_str(), mParam );
}
};
@@ -31,28 +28,26 @@ public:
*/
static std::vector<Watcher_CAPI*> g_callbacks;
-Watcher_CAPI* find_callback(efsw_watcher watcher, efsw_pfn_fileaction_callback fn)
-{
- for (std::vector<Watcher_CAPI*>::iterator i = g_callbacks.begin(); i != g_callbacks.end(); ++i )
- {
+Watcher_CAPI* find_callback( efsw_watcher watcher, efsw_pfn_fileaction_callback fn ) {
+ for ( std::vector<Watcher_CAPI*>::iterator i = g_callbacks.begin(); i != g_callbacks.end();
+ ++i ) {
Watcher_CAPI* callback = *i;
- if (callback->mFn == fn && callback->mWatcher == watcher)
+ if ( callback->mFn == fn && callback->mWatcher == watcher )
return *i;
}
return NULL;
}
-Watcher_CAPI* remove_callback(efsw_watcher watcher)
-{
+Watcher_CAPI* remove_callback( efsw_watcher watcher ) {
std::vector<Watcher_CAPI*>::iterator i = g_callbacks.begin();
- while (i != g_callbacks.end()) {
+ while ( i != g_callbacks.end() ) {
Watcher_CAPI* callback = *i;
- if (callback->mWatcher == watcher)
- i = g_callbacks.erase(i);
+ if ( callback->mWatcher == watcher )
+ i = g_callbacks.erase( i );
else
++i;
}
@@ -60,72 +55,77 @@ Watcher_CAPI* remove_callback(efsw_watcher watcher)
return NULL;
}
-
/*************************************************************************************************/
-efsw_watcher efsw_create(int generic_mode)
-{
- return (efsw_watcher)new efsw::FileWatcher(TOBOOL(generic_mode));
+efsw_watcher efsw_create( int generic_mode ) {
+ return ( efsw_watcher ) new efsw::FileWatcher( TOBOOL( generic_mode ) );
}
-void efsw_release(efsw_watcher watcher)
-{
- remove_callback(watcher);
+void efsw_release( efsw_watcher watcher ) {
+ remove_callback( watcher );
delete (efsw::FileWatcher*)watcher;
}
-const char* efsw_getlasterror()
-{
+const char* efsw_getlasterror() {
static std::string log_str;
log_str = efsw::Errors::Log::getLastErrorLog();
return log_str.c_str();
}
-efsw_watchid efsw_addwatch(efsw_watcher watcher, const char* directory,
- efsw_pfn_fileaction_callback callback_fn, int recursive, void * param)
-{
- Watcher_CAPI* callback = find_callback(watcher, callback_fn);
+EFSW_API void efsw_clearlasterror() {
+ efsw::Errors::Log::clearLastError();
+}
+
+efsw_watchid efsw_addwatch( efsw_watcher watcher, const char* directory,
+ efsw_pfn_fileaction_callback callback_fn, int recursive, void* param ) {
+ return efsw_addwatch_withoptions( watcher, directory, callback_fn, recursive, 0, 0, param );
+}
+
+efsw_watchid efsw_addwatch_withoptions(efsw_watcher watcher, const char* directory,
+ efsw_pfn_fileaction_callback callback_fn, int recursive,
+ efsw_watcher_option *options, int options_number,
+ void* param) {
+ Watcher_CAPI* callback = find_callback( watcher, callback_fn );
- if (callback == NULL) {
- callback = new Watcher_CAPI(watcher, callback_fn, param);
- g_callbacks.push_back(callback);
+ if ( callback == NULL ) {
+ callback = new Watcher_CAPI( watcher, callback_fn, param );
+ g_callbacks.push_back( callback );
}
- return ((efsw::FileWatcher*)watcher)->addWatch(std::string(directory), callback,
- TOBOOL(recursive));
-}
+ std::vector<efsw::WatcherOption> watcher_options{};
+ for ( int i = 0; i < options_number; i++ ) {
+ efsw_watcher_option* option = &options[i];
+ watcher_options.emplace_back( efsw::WatcherOption{
+ static_cast<efsw::Option>(option->option), option->value } );
+ }
-void efsw_removewatch(efsw_watcher watcher, const char* directory)
-{
- ((efsw::FileWatcher*)watcher)->removeWatch(std::string(directory));
+ return ( (efsw::FileWatcher*)watcher )
+ ->addWatch( std::string( directory ), callback, TOBOOL( recursive ), watcher_options );
}
-void efsw_removewatch_byid(efsw_watcher watcher, efsw_watchid watchid)
-{
- ((efsw::FileWatcher*)watcher)->removeWatch(watchid);
+void efsw_removewatch( efsw_watcher watcher, const char* directory ) {
+ ( (efsw::FileWatcher*)watcher )->removeWatch( std::string( directory ) );
}
-void efsw_watch(efsw_watcher watcher)
-{
- ((efsw::FileWatcher*)watcher)->watch();
+void efsw_removewatch_byid( efsw_watcher watcher, efsw_watchid watchid ) {
+ ( (efsw::FileWatcher*)watcher )->removeWatch( watchid );
}
-void efsw_follow_symlinks(efsw_watcher watcher, int enable)
-{
- ((efsw::FileWatcher*)watcher)->followSymlinks(TOBOOL(enable));
+void efsw_watch( efsw_watcher watcher ) {
+ ( (efsw::FileWatcher*)watcher )->watch();
}
-int efsw_follow_symlinks_isenabled(efsw_watcher watcher)
-{
- return (int)((efsw::FileWatcher*)watcher)->followSymlinks();
+void efsw_follow_symlinks( efsw_watcher watcher, int enable ) {
+ ( (efsw::FileWatcher*)watcher )->followSymlinks( TOBOOL( enable ) );
}
-void efsw_allow_outofscopelinks(efsw_watcher watcher, int allow)
-{
- ((efsw::FileWatcher*)watcher)->allowOutOfScopeLinks(TOBOOL(allow));
+int efsw_follow_symlinks_isenabled( efsw_watcher watcher ) {
+ return (int)( (efsw::FileWatcher*)watcher )->followSymlinks();
}
-int efsw_outofscopelinks_isallowed(efsw_watcher watcher)
-{
- return (int)((efsw::FileWatcher*)watcher)->allowOutOfScopeLinks();
+void efsw_allow_outofscopelinks( efsw_watcher watcher, int allow ) {
+ ( (efsw::FileWatcher*)watcher )->allowOutOfScopeLinks( TOBOOL( allow ) );
}
+int efsw_outofscopelinks_isallowed( efsw_watcher watcher ) {
+ return (int)( (efsw::FileWatcher*)watcher )->allowOutOfScopeLinks();
+}
diff --git a/dep/efsw/src/efsw/FileWatcherFSEvents.cpp b/dep/efsw/src/efsw/FileWatcherFSEvents.cpp
index 5aac14282c9..0fa745242cf 100644
--- a/dep/efsw/src/efsw/FileWatcherFSEvents.cpp
+++ b/dep/efsw/src/efsw/FileWatcherFSEvents.cpp
@@ -1,67 +1,58 @@
-#include <efsw/FileWatcherFSEvents.hpp>
-#include <efsw/FileSystem.hpp>
-#include <efsw/System.hpp>
#include <efsw/Debug.hpp>
-#include <efsw/String.hpp>
+#include <efsw/FileSystem.hpp>
+#include <efsw/FileWatcherFSEvents.hpp>
#include <efsw/Lock.hpp>
+#include <efsw/String.hpp>
+#include <efsw/System.hpp>
#if EFSW_PLATFORM == EFSW_PLATFORM_FSEVENTS
#include <sys/utsname.h>
-namespace efsw
-{
+namespace efsw {
-int getOSXReleaseNumber()
-{
+int getOSXReleaseNumber() {
static int osxR = -1;
-
- if ( -1 == osxR )
- {
+
+ if ( -1 == osxR ) {
struct utsname os;
-
+
if ( -1 != uname( &os ) ) {
std::string release( os.release );
-
+
size_t pos = release.find_first_of( '.' );
-
- if ( pos != std::string::npos )
- {
+
+ if ( pos != std::string::npos ) {
release = release.substr( 0, pos );
}
-
+
int rel = 0;
-
- if ( String::fromString<int>( rel, release ) )
- {
+
+ if ( String::fromString<int>( rel, release ) ) {
osxR = rel;
}
}
}
-
+
return osxR;
}
-bool FileWatcherFSEvents::isGranular()
-{
+bool FileWatcherFSEvents::isGranular() {
return getOSXReleaseNumber() >= 11;
}
-void FileWatcherFSEvents::FSEventCallback( ConstFSEventStreamRef streamRef,
- void *userData,
- size_t numEvents,
- void *eventPaths,
- const FSEventStreamEventFlags eventFlags[],
- const FSEventStreamEventId eventIds[] )
-{
- WatcherFSEvents * watcher = static_cast<WatcherFSEvents*>( userData );
+void FileWatcherFSEvents::FSEventCallback( ConstFSEventStreamRef streamRef, void* userData,
+ size_t numEvents, void* eventPaths,
+ const FSEventStreamEventFlags eventFlags[],
+ const FSEventStreamEventId eventIds[] ) {
+ WatcherFSEvents* watcher = static_cast<WatcherFSEvents*>( userData );
std::vector<FSEvent> events;
events.reserve( numEvents );
- for ( size_t i = 0; i < numEvents; i++ )
- {
- events.push_back( FSEvent( std::string( ((char**)eventPaths)[i] ), (long)eventFlags[i], (Uint64)eventIds[i] ) );
+ for ( size_t i = 0; i < numEvents; i++ ) {
+ events.push_back( FSEvent( std::string( ( (char**)eventPaths )[i] ), (long)eventFlags[i],
+ (Uint64)eventIds[i] ) );
}
watcher->handleActions( events );
@@ -71,60 +62,42 @@ void FileWatcherFSEvents::FSEventCallback( ConstFSEventStreamRef streamRef,
efDEBUG( "\n" );
}
-FileWatcherFSEvents::FileWatcherFSEvents( FileWatcher * parent ) :
- FileWatcherImpl( parent ),
- mRunLoopRef( NULL ),
- mLastWatchID(0),
- mThread( NULL )
-{
+FileWatcherFSEvents::FileWatcherFSEvents( FileWatcher* parent ) :
+ FileWatcherImpl( parent ), mLastWatchID( 0 ) {
mInitOK = true;
-
+
watch();
}
-FileWatcherFSEvents::~FileWatcherFSEvents()
-{
+FileWatcherFSEvents::~FileWatcherFSEvents() {
mInitOK = false;
- efSAFE_DELETE( mThread );
+ mWatchCond.notify_all();
WatchMap::iterator iter = mWatches.begin();
- for( ; iter != mWatches.end(); ++iter )
- {
- WatcherFSEvents * watch = iter->second;
-
+ for ( ; iter != mWatches.end(); ++iter ) {
+ WatcherFSEvents* watch = iter->second;
+
efSAFE_DELETE( watch );
}
-
- mWatches.clear();
}
-WatchID FileWatcherFSEvents::addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive )
-{
- /// Wait to the RunLoopRef to be ready
- while ( NULL == mRunLoopRef )
- {
- System::sleep( 1 );
- }
-
+WatchID FileWatcherFSEvents::addWatch( const std::string& directory, FileWatchListener* watcher,
+ bool recursive, const std::vector<WatcherOption> &options ) {
std::string dir( directory );
FileInfo fi( dir );
- if ( !fi.isDirectory() )
- {
+ if ( !fi.isDirectory() ) {
return Errors::Log::createLastError( Errors::FileNotFound, dir );
- }
- else if ( !fi.isReadable() )
- {
+ } else if ( !fi.isReadable() ) {
return Errors::Log::createLastError( Errors::FileNotReadable, dir );
}
FileSystem::dirAddSlashAtEnd( dir );
- if ( pathInWatches( dir ) )
- {
+ if ( pathInWatches( dir ) ) {
return Errors::Log::createLastError( Errors::FileRepeated, directory );
}
@@ -132,67 +105,60 @@ WatchID FileWatcherFSEvents::addWatch( const std::string& directory, FileWatchLi
std::string curPath;
std::string link( FileSystem::getLinkRealPath( dir, curPath ) );
- if ( "" != link )
- {
+ if ( "" != link ) {
/// If it's a symlink check if the realpath exists as a watcher, or
/// if the path is outside the current dir
- if ( pathInWatches( link ) )
- {
+ if ( pathInWatches( link ) ) {
return Errors::Log::createLastError( Errors::FileRepeated, directory );
- }
- else if ( !linkAllowed( curPath, link ) )
- {
+ } else if ( !linkAllowed( curPath, link ) ) {
return Errors::Log::createLastError( Errors::FileOutOfScope, dir );
- }
- else
- {
+ } else {
dir = link;
}
}
-
+
mLastWatchID++;
- WatcherFSEvents * pWatch = new WatcherFSEvents();
- pWatch->Listener = watcher;
- pWatch->ID = mLastWatchID;
- pWatch->Directory = dir;
- pWatch->Recursive = recursive;
- pWatch->FWatcher = this;
-
+ WatcherFSEvents* pWatch = new WatcherFSEvents();
+ pWatch->Listener = watcher;
+ pWatch->ID = mLastWatchID;
+ pWatch->Directory = dir;
+ pWatch->Recursive = recursive;
+ pWatch->FWatcher = this;
+
pWatch->init();
- Lock lock( mWatchesLock );
- mWatches.insert(std::make_pair(mLastWatchID, pWatch));
+ {
+ Lock lock( mWatchesLock );
+ mWatches.insert( std::make_pair( mLastWatchID, pWatch ) );
+ }
+ mWatchCond.notify_all();
return pWatch->ID;
}
-void FileWatcherFSEvents::removeWatch(const std::string& directory)
-{
+void FileWatcherFSEvents::removeWatch( const std::string& directory ) {
Lock lock( mWatchesLock );
WatchMap::iterator iter = mWatches.begin();
- for(; iter != mWatches.end(); ++iter)
- {
- if( directory == iter->second->Directory )
- {
+ for ( ; iter != mWatches.end(); ++iter ) {
+ if ( directory == iter->second->Directory ) {
removeWatch( iter->second->ID );
return;
}
}
}
-void FileWatcherFSEvents::removeWatch(WatchID watchid)
-{
+void FileWatcherFSEvents::removeWatch( WatchID watchid ) {
Lock lock( mWatchesLock );
WatchMap::iterator iter = mWatches.find( watchid );
- if( iter == mWatches.end() )
+ if ( iter == mWatches.end() )
return;
- WatcherFSEvents * watch = iter->second;
+ WatcherFSEvents* watch = iter->second;
mWatches.erase( iter );
@@ -201,63 +167,30 @@ void FileWatcherFSEvents::removeWatch(WatchID watchid)
efSAFE_DELETE( watch );
}
-void FileWatcherFSEvents::watch()
-{
- if ( NULL == mThread )
- {
- mThread = new Thread( &FileWatcherFSEvents::run, this );
- mThread->launch();
- }
-}
-
-void FileWatcherFSEvents::run()
-{
- mRunLoopRef = CFRunLoopGetCurrent();
-
- while ( mInitOK )
- {
- if ( !mNeedInit.empty() )
- {
- for ( std::list<WatcherFSEvents*>::iterator it = mNeedInit.begin(); it != mNeedInit.end(); ++it )
- {
- (*it)->initAsync();
- }
-
- mNeedInit.clear();
- }
-
- CFRunLoopRunInMode( kCFRunLoopDefaultMode, 0.5, kCFRunLoopRunTimedOut );
- }
+void FileWatcherFSEvents::watch() {}
- CFRunLoopStop( mRunLoopRef );
- mRunLoopRef = NULL;
-}
-
-void FileWatcherFSEvents::handleAction(Watcher* watch, const std::string& filename, unsigned long action, std::string oldFilename)
-{
+void FileWatcherFSEvents::handleAction( Watcher* watch, const std::string& filename,
+ unsigned long action, std::string oldFilename ) {
/// Not used
}
-std::list<std::string> FileWatcherFSEvents::directories()
-{
- std::list<std::string> dirs;
+std::vector<std::string> FileWatcherFSEvents::directories() {
+ std::vector<std::string> dirs;
Lock lock( mWatchesLock );
- for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); ++it )
- {
+ dirs.reserve( mWatches.size() );
+
+ for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); ++it ) {
dirs.push_back( std::string( it->second->Directory ) );
}
return dirs;
}
-bool FileWatcherFSEvents::pathInWatches( const std::string& path )
-{
- for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); ++it )
- {
- if ( it->second->Directory == path )
- {
+bool FileWatcherFSEvents::pathInWatches( const std::string& path ) {
+ for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); ++it ) {
+ if ( it->second->Directory == path ) {
return true;
}
}
@@ -265,6 +198,6 @@ bool FileWatcherFSEvents::pathInWatches( const std::string& path )
return false;
}
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/FileWatcherFSEvents.hpp b/dep/efsw/src/efsw/FileWatcherFSEvents.hpp
index 9a2c956ed10..5ad182ed43f 100644
--- a/dep/efsw/src/efsw/FileWatcherFSEvents.hpp
+++ b/dep/efsw/src/efsw/FileWatcherFSEvents.hpp
@@ -7,98 +7,94 @@
#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
+#include <dispatch/dispatch.h>
#include <efsw/WatcherFSEvents.hpp>
#include <map>
-#include <list>
#include <vector>
+#include <condition_variable>
+#include <mutex>
-namespace efsw
-{
+namespace efsw {
/* OSX < 10.7 has no file events */
/* So i declare the events constants */
-enum FSEventEvents
-{
- efswFSEventStreamCreateFlagFileEvents = 0x00000010,
- efswFSEventStreamEventFlagItemCreated = 0x00000100,
- efswFSEventStreamEventFlagItemRemoved = 0x00000200,
- efswFSEventStreamEventFlagItemInodeMetaMod = 0x00000400,
- efswFSEventStreamEventFlagItemRenamed = 0x00000800,
- efswFSEventStreamEventFlagItemModified = 0x00001000,
- efswFSEventStreamEventFlagItemFinderInfoMod = 0x00002000,
- efswFSEventStreamEventFlagItemChangeOwner = 0x00004000,
- efswFSEventStreamEventFlagItemXattrMod = 0x00008000,
- efswFSEventStreamEventFlagItemIsFile = 0x00010000,
- efswFSEventStreamEventFlagItemIsDir = 0x00020000,
- efswFSEventStreamEventFlagItemIsSymlink = 0x00040000,
- efswFSEventsModified = efswFSEventStreamEventFlagItemFinderInfoMod |
- efswFSEventStreamEventFlagItemModified |
- efswFSEventStreamEventFlagItemInodeMetaMod
+enum FSEventEvents {
+ efswFSEventStreamCreateFlagNoDefer = 0x00000002,
+ efswFSEventStreamCreateFlagFileEvents = 0x00000010,
+ efswFSEventStreamEventFlagItemCreated = 0x00000100,
+ efswFSEventStreamEventFlagItemRemoved = 0x00000200,
+ efswFSEventStreamEventFlagItemInodeMetaMod = 0x00000400,
+ efswFSEventStreamEventFlagItemRenamed = 0x00000800,
+ efswFSEventStreamEventFlagItemModified = 0x00001000,
+ efswFSEventStreamEventFlagItemFinderInfoMod = 0x00002000,
+ efswFSEventStreamEventFlagItemChangeOwner = 0x00004000,
+ efswFSEventStreamEventFlagItemXattrMod = 0x00008000,
+ efswFSEventStreamEventFlagItemIsFile = 0x00010000,
+ efswFSEventStreamEventFlagItemIsDir = 0x00020000,
+ efswFSEventStreamEventFlagItemIsSymlink = 0x00040000,
+ efswFSEventsModified = efswFSEventStreamEventFlagItemFinderInfoMod |
+ efswFSEventStreamEventFlagItemModified |
+ efswFSEventStreamEventFlagItemInodeMetaMod
};
/// Implementation for Win32 based on ReadDirectoryChangesW.
/// @class FileWatcherFSEvents
-class FileWatcherFSEvents : public FileWatcherImpl
-{
+class FileWatcherFSEvents : public FileWatcherImpl {
friend class WatcherFSEvents;
- public:
- /// @return If FSEvents supports file-level notifications ( true if OS X >= 10.7 )
- static bool isGranular();
-
- /// type for a map from WatchID to WatcherWin32 pointer
- typedef std::map<WatchID, WatcherFSEvents*> WatchMap;
-
- FileWatcherFSEvents( FileWatcher * parent );
-
- virtual ~FileWatcherFSEvents();
-
- /// Add a directory watch
- /// On error returns WatchID with Error type.
- WatchID addWatch(const std::string& directory, FileWatchListener* watcher, bool recursive);
-
- /// Remove a directory watch. This is a brute force lazy search O(nlogn).
- void removeWatch(const std::string& directory);
-
- /// Remove a directory watch. This is a map lookup O(logn).
- void removeWatch(WatchID watchid);
-
- /// Updates the watcher. Must be called often.
- void watch();
-
- /// Handles the action
- void handleAction(Watcher* watch, const std::string& filename, unsigned long action, std::string oldFilename = "");
-
- /// @return Returns a list of the directories that are being watched
- std::list<std::string> directories();
- protected:
- static void FSEventCallback( ConstFSEventStreamRef streamRef,
- void *userData,
- size_t numEvents,
- void *eventPaths,
- const FSEventStreamEventFlags eventFlags[],
- const FSEventStreamEventId eventIds[]
- );
-
- CFRunLoopRef mRunLoopRef;
-
- /// Vector of WatcherWin32 pointers
- WatchMap mWatches;
-
- /// The last watchid
- WatchID mLastWatchID;
-
- Thread * mThread;
-
- Mutex mWatchesLock;
-
- bool pathInWatches( const std::string& path );
-
- std::list<WatcherFSEvents*> mNeedInit;
- private:
- void run();
+
+ public:
+ /// @return If FSEvents supports file-level notifications ( true if OS X >= 10.7 )
+ static bool isGranular();
+
+ /// type for a map from WatchID to WatcherWin32 pointer
+ typedef std::map<WatchID, WatcherFSEvents*> WatchMap;
+
+ FileWatcherFSEvents( FileWatcher* parent );
+
+ virtual ~FileWatcherFSEvents();
+
+ /// Add a directory watch
+ /// On error returns WatchID with Error type.
+ WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive,
+ const std::vector<WatcherOption> &options ) override;
+
+ /// Remove a directory watch. This is a brute force lazy search O(nlogn).
+ void removeWatch( const std::string& directory ) override;
+
+ /// Remove a directory watch. This is a map lookup O(logn).
+ void removeWatch( WatchID watchid ) override;
+
+ /// Updates the watcher. Must be called often.
+ void watch() override;
+
+ /// Handles the action
+ void handleAction( Watcher* watch, const std::string& filename, unsigned long action,
+ std::string oldFilename = "" ) override;
+
+ /// @return Returns a list of the directories that are being watched
+ std::vector<std::string> directories() override;
+
+ protected:
+ static void FSEventCallback( ConstFSEventStreamRef streamRef, void* userData, size_t numEvents,
+ void* eventPaths, const FSEventStreamEventFlags eventFlags[],
+ const FSEventStreamEventId eventIds[] );
+
+ /// Vector of WatcherWin32 pointers
+ WatchMap mWatches;
+
+ /// The last watchid
+ WatchID mLastWatchID;
+
+ Mutex mWatchesLock;
+
+ bool pathInWatches( const std::string& path ) override;
+
+ std::mutex mWatchesMutex;
+ std::condition_variable mWatchCond;
+
};
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/FileWatcherGeneric.cpp b/dep/efsw/src/efsw/FileWatcherGeneric.cpp
index fd423b1476b..3f3c52e47fb 100644
--- a/dep/efsw/src/efsw/FileWatcherGeneric.cpp
+++ b/dep/efsw/src/efsw/FileWatcherGeneric.cpp
@@ -1,22 +1,17 @@
-#include <efsw/FileWatcherGeneric.hpp>
#include <efsw/FileSystem.hpp>
-#include <efsw/System.hpp>
+#include <efsw/FileWatcherGeneric.hpp>
#include <efsw/Lock.hpp>
+#include <efsw/System.hpp>
-namespace efsw
-{
+namespace efsw {
-FileWatcherGeneric::FileWatcherGeneric( FileWatcher * parent ) :
- FileWatcherImpl( parent ),
- mThread( NULL ),
- mLastWatchID( 0 )
-{
+FileWatcherGeneric::FileWatcherGeneric( FileWatcher* parent ) :
+ FileWatcherImpl( parent ), mThread( NULL ), mLastWatchID( 0 ) {
mInitOK = true;
mIsGeneric = true;
}
-FileWatcherGeneric::~FileWatcherGeneric()
-{
+FileWatcherGeneric::~FileWatcherGeneric() {
mInitOK = false;
efSAFE_DELETE( mThread );
@@ -24,161 +19,135 @@ FileWatcherGeneric::~FileWatcherGeneric()
/// Delete the watches
WatchList::iterator it = mWatches.begin();
- for ( ; it != mWatches.end(); ++it )
- {
- efSAFE_DELETE( (*it) );
+ for ( ; it != mWatches.end(); ++it ) {
+ efSAFE_DELETE( ( *it ) );
}
}
-WatchID FileWatcherGeneric::addWatch(const std::string& directory, FileWatchListener* watcher, bool recursive)
-{
+WatchID FileWatcherGeneric::addWatch( const std::string& directory, FileWatchListener* watcher,
+ bool recursive, const std::vector<WatcherOption>& options ) {
std::string dir( directory );
FileSystem::dirAddSlashAtEnd( dir );
FileInfo fi( dir );
- if ( !fi.isDirectory() )
- {
+ if ( !fi.isDirectory() ) {
return Errors::Log::createLastError( Errors::FileNotFound, dir );
- }
- else if ( !fi.isReadable() )
- {
+ } else if ( !fi.isReadable() ) {
return Errors::Log::createLastError( Errors::FileNotReadable, dir );
- }
- else if ( pathInWatches( dir ) )
- {
+ } else if ( pathInWatches( dir ) ) {
return Errors::Log::createLastError( Errors::FileRepeated, dir );
}
std::string curPath;
std::string link( FileSystem::getLinkRealPath( dir, curPath ) );
- if ( "" != link )
- {
- if ( pathInWatches( link ) )
- {
+ if ( "" != link ) {
+ if ( pathInWatches( link ) ) {
return Errors::Log::createLastError( Errors::FileRepeated, dir );
- }
- else if ( !linkAllowed( curPath, link ) )
- {
+ } else if ( !linkAllowed( curPath, link ) ) {
return Errors::Log::createLastError( Errors::FileOutOfScope, dir );
- }
- else
- {
+ } else {
dir = link;
}
}
mLastWatchID++;
- WatcherGeneric * pWatch = new WatcherGeneric( mLastWatchID, dir, watcher, this, recursive );
+ WatcherGeneric* pWatch = new WatcherGeneric( mLastWatchID, dir, watcher, this, recursive );
Lock lock( mWatchesLock );
- mWatches.push_back(pWatch);
+ mWatches.push_back( pWatch );
return pWatch->ID;
}
-void FileWatcherGeneric::removeWatch( const std::string& directory )
-{
+void FileWatcherGeneric::removeWatch( const std::string& directory ) {
WatchList::iterator it = mWatches.begin();
- for ( ; it != mWatches.end(); ++it )
- {
- if ( (*it)->Directory == directory )
- {
- WatcherGeneric * watch = (*it);
+ for ( ; it != mWatches.end(); ++it ) {
+ if ( ( *it )->Directory == directory ) {
+ WatcherGeneric* watch = ( *it );
Lock lock( mWatchesLock );
mWatches.erase( it );
- efSAFE_DELETE( watch ) ;
+ efSAFE_DELETE( watch );
return;
}
}
}
-void FileWatcherGeneric::removeWatch(WatchID watchid)
-{
+void FileWatcherGeneric::removeWatch( WatchID watchid ) {
WatchList::iterator it = mWatches.begin();
- for ( ; it != mWatches.end(); ++it )
- {
- if ( (*it)->ID == watchid )
- {
- WatcherGeneric * watch = (*it);
+ for ( ; it != mWatches.end(); ++it ) {
+ if ( ( *it )->ID == watchid ) {
+ WatcherGeneric* watch = ( *it );
Lock lock( mWatchesLock );
mWatches.erase( it );
- efSAFE_DELETE( watch ) ;
+ efSAFE_DELETE( watch );
return;
}
}
}
-void FileWatcherGeneric::watch()
-{
- if ( NULL == mThread )
- {
+void FileWatcherGeneric::watch() {
+ if ( NULL == mThread ) {
mThread = new Thread( &FileWatcherGeneric::run, this );
mThread->launch();
}
}
-void FileWatcherGeneric::run()
-{
- do
- {
+void FileWatcherGeneric::run() {
+ do {
{
- Lock lock( mWatchesLock);
+ Lock lock( mWatchesLock );
WatchList::iterator it = mWatches.begin();
- for ( ; it != mWatches.end(); ++it )
- {
+ for ( ; it != mWatches.end(); ++it ) {
( *it )->watch();
}
}
- if ( mInitOK ) System::sleep( 1000 );
+ if ( mInitOK )
+ System::sleep( 1000 );
} while ( mInitOK );
}
-void FileWatcherGeneric::handleAction(Watcher *, const std::string&, unsigned long, std::string)
-{
+void FileWatcherGeneric::handleAction( Watcher*, const std::string&, unsigned long, std::string ) {
/// Not used
}
-std::list<std::string> FileWatcherGeneric::directories()
-{
- std::list<std::string> dirs;
+std::vector<std::string> FileWatcherGeneric::directories() {
+ std::vector<std::string> dirs;
Lock lock( mWatchesLock );
+ dirs.reserve( mWatches.size() );
+
WatchList::iterator it = mWatches.begin();
- for ( ; it != mWatches.end(); ++it )
- {
- dirs.push_back( (*it)->Directory );
+ for ( ; it != mWatches.end(); ++it ) {
+ dirs.push_back( ( *it )->Directory );
}
return dirs;
}
-bool FileWatcherGeneric::pathInWatches( const std::string& path )
-{
+bool FileWatcherGeneric::pathInWatches( const std::string& path ) {
WatchList::iterator it = mWatches.begin();
- for ( ; it != mWatches.end(); ++it )
- {
- if ( (*it)->Directory == path || (*it)->pathInWatches( path ) )
- {
+ for ( ; it != mWatches.end(); ++it ) {
+ if ( ( *it )->Directory == path || ( *it )->pathInWatches( path ) ) {
return true;
}
}
@@ -186,4 +155,4 @@ bool FileWatcherGeneric::pathInWatches( const std::string& path )
return false;
}
-}
+} // namespace efsw
diff --git a/dep/efsw/src/efsw/FileWatcherGeneric.hpp b/dep/efsw/src/efsw/FileWatcherGeneric.hpp
index fc9826580ab..47f7e04718d 100644
--- a/dep/efsw/src/efsw/FileWatcherGeneric.hpp
+++ b/dep/efsw/src/efsw/FileWatcherGeneric.hpp
@@ -1,59 +1,61 @@
#ifndef EFSW_FILEWATCHERGENERIC_HPP
#define EFSW_FILEWATCHERGENERIC_HPP
+#include <efsw/DirWatcherGeneric.hpp>
#include <efsw/FileWatcherImpl.hpp>
#include <efsw/WatcherGeneric.hpp>
-#include <efsw/DirWatcherGeneric.hpp>
-#include <list>
+#include <vector>
-namespace efsw
-{
+namespace efsw {
/// Implementation for Generic File Watcher.
/// @class FileWatcherGeneric
-class FileWatcherGeneric : public FileWatcherImpl
-{
- public:
- typedef std::list<WatcherGeneric*> WatchList;
+class FileWatcherGeneric : public FileWatcherImpl {
+ public:
+ typedef std::vector<WatcherGeneric*> WatchList;
+
+ FileWatcherGeneric( FileWatcher* parent );
+
+ virtual ~FileWatcherGeneric();
- FileWatcherGeneric( FileWatcher * parent );
+ /// Add a directory watch
+ /// On error returns WatchID with Error type.
+ WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive,
+ const std::vector<WatcherOption> &options ) override;
- virtual ~FileWatcherGeneric();
+ /// Remove a directory watch. This is a brute force lazy search O(nlogn).
+ void removeWatch( const std::string& directory ) override;
- /// Add a directory watch
- /// On error returns WatchID with Error type.
- WatchID addWatch(const std::string& directory, FileWatchListener* watcher, bool recursive);
+ /// Remove a directory watch. This is a map lookup O(logn).
+ void removeWatch( WatchID watchid ) override;
- /// Remove a directory watch. This is a brute force lazy search O(nlogn).
- void removeWatch(const std::string& directory);
+ /// Updates the watcher. Must be called often.
+ void watch() override;
- /// Remove a directory watch. This is a map lookup O(logn).
- void removeWatch(WatchID watchid);
+ /// Handles the action
+ void handleAction( Watcher* watch, const std::string& filename, unsigned long action,
+ std::string oldFilename = "" ) override;
- /// Updates the watcher. Must be called often.
- void watch();
+ /// @return Returns a list of the directories that are being watched
+ std::vector<std::string> directories() override;
- /// Handles the action
- void handleAction(Watcher * watch, const std::string& filename, unsigned long action, std::string oldFilename = "");
+ protected:
+ Thread* mThread;
- /// @return Returns a list of the directories that are being watched
- std::list<std::string> directories();
- protected:
- Thread * mThread;
+ /// The last watchid
+ WatchID mLastWatchID;
- /// The last watchid
- WatchID mLastWatchID;
+ /// Map of WatchID to WatchStruct pointers
+ WatchList mWatches;
- /// Map of WatchID to WatchStruct pointers
- WatchList mWatches;
+ Mutex mWatchesLock;
- Mutex mWatchesLock;
+ bool pathInWatches( const std::string& path ) override;
- bool pathInWatches( const std::string& path );
- private:
- void run();
+ private:
+ void run();
};
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/FileWatcherImpl.cpp b/dep/efsw/src/efsw/FileWatcherImpl.cpp
index e6e0fc72a13..f8313daba8d 100644
--- a/dep/efsw/src/efsw/FileWatcherImpl.cpp
+++ b/dep/efsw/src/efsw/FileWatcherImpl.cpp
@@ -4,26 +4,31 @@
namespace efsw {
-FileWatcherImpl::FileWatcherImpl( FileWatcher * parent ) :
- mFileWatcher( parent ),
- mInitOK( false ),
- mIsGeneric( false )
-{
+FileWatcherImpl::FileWatcherImpl( FileWatcher* parent ) :
+ mFileWatcher( parent ), mInitOK( false ), mIsGeneric( false ) {
System::maxFD();
}
-FileWatcherImpl::~FileWatcherImpl()
-{
-}
+FileWatcherImpl::~FileWatcherImpl() {}
-bool FileWatcherImpl::initOK()
-{
- return mInitOK;
+bool FileWatcherImpl::initOK() {
+ return static_cast<bool>( mInitOK );
}
-bool FileWatcherImpl::linkAllowed( const std::string& curPath, const std::string& link )
-{
- return ( mFileWatcher->followSymlinks() && mFileWatcher->allowOutOfScopeLinks() ) || -1 != String::strStartsWith( curPath, link );
+bool FileWatcherImpl::linkAllowed( const std::string& curPath, const std::string& link ) {
+ return ( mFileWatcher->followSymlinks() && mFileWatcher->allowOutOfScopeLinks() ) ||
+ -1 != String::strStartsWith( curPath, link );
}
+int FileWatcherImpl::getOptionValue( const std::vector<WatcherOption>& options, Option option,
+ int defaultValue ) {
+ for ( size_t i = 0; i < options.size(); i++ ) {
+ if ( options[i].mOption == option ) {
+ return options[i].mValue;
+ }
+ }
+
+ return defaultValue;
}
+
+} // namespace efsw
diff --git a/dep/efsw/src/efsw/FileWatcherImpl.hpp b/dep/efsw/src/efsw/FileWatcherImpl.hpp
index 8f472bf56c5..d82209c902c 100644
--- a/dep/efsw/src/efsw/FileWatcherImpl.hpp
+++ b/dep/efsw/src/efsw/FileWatcherImpl.hpp
@@ -1,54 +1,64 @@
#ifndef EFSW_FILEWATCHERIMPL_HPP
#define EFSW_FILEWATCHERIMPL_HPP
+#include <efsw/Atomic.hpp>
+#include <efsw/Mutex.hpp>
+#include <efsw/Thread.hpp>
+#include <efsw/Watcher.hpp>
#include <efsw/base.hpp>
#include <efsw/efsw.hpp>
-#include <efsw/Watcher.hpp>
-#include <efsw/Thread.hpp>
-#include <efsw/Mutex.hpp>
namespace efsw {
-class FileWatcherImpl
-{
- public:
- FileWatcherImpl( FileWatcher * parent );
+class FileWatcherImpl {
+ public:
+ FileWatcherImpl( FileWatcher* parent );
+
+ virtual ~FileWatcherImpl();
+
+ /// Add a directory watch
+ /// On error returns WatchID with Error type.
+ virtual WatchID addWatch( const std::string& directory, FileWatchListener* watcher,
+ bool recursive, const std::vector<WatcherOption>& options = {} ) = 0;
- virtual ~FileWatcherImpl();
+ /// Remove a directory watch. This is a brute force lazy search O(nlogn).
+ virtual void removeWatch( const std::string& directory ) = 0;
- /// Add a directory watch
- /// On error returns WatchID with Error type.
- virtual WatchID addWatch(const std::string& directory, FileWatchListener* watcher, bool recursive) = 0;
+ /// Remove a directory watch. This is a map lookup O(logn).
+ virtual void removeWatch( WatchID watchid ) = 0;
- /// Remove a directory watch. This is a brute force lazy search O(nlogn).
- virtual void removeWatch(const std::string& directory) = 0;
+ /// Updates the watcher. Must be called often.
+ virtual void watch() = 0;
- /// Remove a directory watch. This is a map lookup O(logn).
- virtual void removeWatch(WatchID watchid) = 0;
+ /// Handles the action
+ virtual void handleAction( Watcher* watch, const std::string& filename, unsigned long action,
+ std::string oldFilename = "" ) = 0;
- /// Updates the watcher. Must be called often.
- virtual void watch() = 0;
+ /// @return Returns a list of the directories that are being watched
+ virtual std::vector<std::string> directories() = 0;
- /// Handles the action
- virtual void handleAction(Watcher * watch, const std::string& filename, unsigned long action, std::string oldFilename = "") = 0;
+ /// @return true if the backend init successfully
+ virtual bool initOK();
- /// @return Returns a list of the directories that are being watched
- virtual std::list<std::string> directories() = 0;
+ /// @return If the link is allowed according to the current path and the state of out scope
+ /// links
+ virtual bool linkAllowed( const std::string& curPath, const std::string& link );
- /// @return true if the backend init successfully
- virtual bool initOK();
+ /// Search if a directory already exists in the watches
+ virtual bool pathInWatches( const std::string& path ) = 0;
- /// @return If the link is allowed according to the current path and the state of out scope links
- virtual bool linkAllowed( const std::string& curPath, const std::string& link );
+ protected:
+ friend class FileWatcher;
+ friend class DirWatcherGeneric;
- /// Search if a directory already exists in the watches
- virtual bool pathInWatches( const std::string& path ) = 0;
+ FileWatcher* mFileWatcher;
+ Atomic<bool> mInitOK;
+ bool mIsGeneric;
- FileWatcher * mFileWatcher;
- bool mInitOK;
- bool mIsGeneric;
+ int getOptionValue( const std::vector<WatcherOption>& options, Option option,
+ int defaultValue );
};
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/FileWatcherInotify.cpp b/dep/efsw/src/efsw/FileWatcherInotify.cpp
index 71ae3bcd97d..29be12b6262 100644
--- a/dep/efsw/src/efsw/FileWatcherInotify.cpp
+++ b/dep/efsw/src/efsw/FileWatcherInotify.cpp
@@ -1,13 +1,14 @@
+#include <algorithm>
#include <efsw/FileWatcherInotify.hpp>
#if EFSW_PLATFORM == EFSW_PLATFORM_INOTIFY
-#include <unistd.h>
-#include <sys/stat.h>
+#include <errno.h>
#include <fcntl.h>
-#include <string.h>
#include <stdio.h>
-#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
#ifdef EFSW_INOTIFY_NOSYS
#include <efsw/inotify-nosys.h>
@@ -15,84 +16,81 @@
#include <sys/inotify.h>
#endif
-#include <efsw/FileSystem.hpp>
-#include <efsw/System.hpp>
#include <efsw/Debug.hpp>
+#include <efsw/FileSystem.hpp>
#include <efsw/Lock.hpp>
#include <efsw/String.hpp>
+#include <efsw/System.hpp>
-#define BUFF_SIZE ((sizeof(struct inotify_event)+FILENAME_MAX)*1024)
+#define BUFF_SIZE ( ( sizeof( struct inotify_event ) + FILENAME_MAX ) * 1024 )
-namespace efsw
-{
+namespace efsw {
-FileWatcherInotify::FileWatcherInotify( FileWatcher * parent ) :
- FileWatcherImpl( parent ),
- mFD(-1),
- mThread(NULL)
-{
+FileWatcherInotify::FileWatcherInotify( FileWatcher* parent ) :
+ FileWatcherImpl( parent ), mFD( -1 ), mThread( NULL ), mIsTakingAction( false ) {
mFD = inotify_init();
- if (mFD < 0)
- {
- efDEBUG( "Error: %s\n", strerror(errno) );
- }
- else
- {
+ if ( mFD < 0 ) {
+ efDEBUG( "Error: %s\n", strerror( errno ) );
+ } else {
mInitOK = true;
}
}
-FileWatcherInotify::~FileWatcherInotify()
-{
+FileWatcherInotify::~FileWatcherInotify() {
mInitOK = false;
+ // There is deadlock when release FileWatcherInotify instance since its handAction
+ // function is still running and hangs in requiring lock without init lock captured.
+ while ( mIsTakingAction ) {
+ // It'd use condition-wait instead of sleep. Actually efsw has no such
+ // implementation so we just skip and sleep while for that to avoid deadlock.
+ usleep( 1000 );
+ };
+ Lock initLock( mInitLock );
efSAFE_DELETE( mThread );
-
+
+ Lock l( mWatchesLock );
+ Lock l2( mRealWatchesLock );
+
WatchMap::iterator iter = mWatches.begin();
WatchMap::iterator end = mWatches.end();
- for(; iter != end; ++iter)
- {
+ for ( ; iter != end; ++iter ) {
efSAFE_DELETE( iter->second );
}
mWatches.clear();
- if ( mFD != -1 )
- {
- close(mFD);
+ if ( mFD != -1 ) {
+ close( mFD );
mFD = -1;
}
}
-WatchID FileWatcherInotify::addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive )
-{
+WatchID FileWatcherInotify::addWatch( const std::string& directory, FileWatchListener* watcher,
+ bool recursive, const std::vector<WatcherOption>& ) {
+ if ( !mInitOK )
+ return Errors::Log::createLastError( Errors::Unspecified, directory );
+ Lock initLock( mInitLock );
return addWatch( directory, watcher, recursive, NULL );
}
-WatchID FileWatcherInotify::addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive, WatcherInotify * parent )
-{
+WatchID FileWatcherInotify::addWatch( const std::string& directory, FileWatchListener* watcher,
+ bool recursive, WatcherInotify* parent ) {
std::string dir( directory );
FileSystem::dirAddSlashAtEnd( dir );
FileInfo fi( dir );
- if ( !fi.isDirectory() )
- {
+ if ( !fi.isDirectory() ) {
return Errors::Log::createLastError( Errors::FileNotFound, dir );
- }
- else if ( !fi.isReadable() )
- {
+ } else if ( !fi.isReadable() ) {
return Errors::Log::createLastError( Errors::FileNotReadable, dir );
- }
- else if ( pathInWatches( dir ) )
- {
+ } else if ( pathInWatches( dir ) ) {
return Errors::Log::createLastError( Errors::FileRepeated, directory );
- }
- else if ( NULL != parent && FileSystem::isRemoteFS( dir ) )
- {
+ } else if ( NULL != parent && FileSystem::isRemoteFS( dir ) ) {
return Errors::Log::createLastError( Errors::FileRemote, dir );
}
@@ -100,74 +98,68 @@ WatchID FileWatcherInotify::addWatch( const std::string& directory, FileWatchLis
std::string curPath;
std::string link( FileSystem::getLinkRealPath( dir, curPath ) );
- if ( "" != link )
- {
+ if ( "" != link ) {
/// Avoid adding symlinks directories if it's now enabled
- if ( NULL != parent && !mFileWatcher->followSymlinks() )
- {
+ if ( NULL != parent && !mFileWatcher->followSymlinks() ) {
return Errors::Log::createLastError( Errors::FileOutOfScope, dir );
}
/// If it's a symlink check if the realpath exists as a watcher, or
/// if the path is outside the current dir
- if ( pathInWatches( link ) )
- {
+ if ( pathInWatches( link ) ) {
return Errors::Log::createLastError( Errors::FileRepeated, directory );
- }
- else if ( !linkAllowed( curPath, link ) )
- {
+ } else if ( !linkAllowed( curPath, link ) ) {
return Errors::Log::createLastError( Errors::FileOutOfScope, dir );
- }
- else
- {
+ } else {
dir = link;
}
}
- int wd = inotify_add_watch (mFD, dir.c_str(), IN_CLOSE_WRITE | IN_MOVED_TO | IN_CREATE | IN_MOVED_FROM | IN_DELETE | IN_MODIFY);
+ int wd = inotify_add_watch( mFD, dir.c_str(),
+ IN_CLOSE_WRITE | IN_MOVED_TO | IN_CREATE | IN_MOVED_FROM |
+ IN_DELETE | IN_MODIFY );
- if ( wd < 0 )
- {
- if( errno == ENOENT )
- {
+ if ( wd < 0 ) {
+ if ( errno == ENOENT ) {
return Errors::Log::createLastError( Errors::FileNotFound, dir );
- }
- else
- {
- return Errors::Log::createLastError( Errors::Unspecified, std::string(strerror(errno)) );
+ } else {
+ return Errors::Log::createLastError( Errors::Unspecified,
+ std::string( strerror( errno ) ) );
}
}
efDEBUG( "Added watch %s with id: %d\n", dir.c_str(), wd );
- WatcherInotify * pWatch = new WatcherInotify();
- pWatch->Listener = watcher;
- pWatch->ID = wd;
- pWatch->Directory = dir;
- pWatch->Recursive = recursive;
- pWatch->Parent = parent;
+ WatcherInotify* pWatch = new WatcherInotify();
+ pWatch->Listener = watcher;
+ pWatch->ID = parent ? parent->ID : wd;
+ pWatch->InotifyID = wd;
+ pWatch->Directory = dir;
+ pWatch->Recursive = recursive;
+ pWatch->Parent = parent;
{
Lock lock( mWatchesLock );
- mWatches.insert(std::make_pair(wd, pWatch));
+ mWatches.insert( std::make_pair( wd, pWatch ) );
+ mWatchesRef[pWatch->Directory] = wd;
}
- if ( NULL == pWatch->Parent )
- {
- mRealWatches[ pWatch->ID ] = pWatch;
+ if ( NULL == pWatch->Parent ) {
+ Lock l( mRealWatchesLock );
+ mRealWatches[pWatch->InotifyID] = pWatch;
}
- if ( pWatch->Recursive )
- {
+ if ( pWatch->Recursive ) {
std::map<std::string, FileInfo> files = FileSystem::filesInfoFromPath( pWatch->Directory );
std::map<std::string, FileInfo>::iterator it = files.begin();
- for ( ; it != files.end(); ++it )
- {
+ for ( ; it != files.end(); ++it ) {
+ if ( !mInitOK )
+ break;
+
const FileInfo& cfi = it->second;
- if ( cfi.isDirectory() && cfi.isReadable() )
- {
+ if ( cfi.isDirectory() && cfi.isReadable() ) {
addWatch( cfi.Filepath, watcher, recursive, pWatch );
}
}
@@ -176,401 +168,395 @@ WatchID FileWatcherInotify::addWatch( const std::string& directory, FileWatchLis
return wd;
}
-void FileWatcherInotify::removeWatchLocked(WatchID watchid)
-{
+void FileWatcherInotify::removeWatchLocked( WatchID watchid ) {
WatchMap::iterator iter = mWatches.find( watchid );
+ if ( iter == mWatches.end() )
+ return;
- WatcherInotify * watch = iter->second;
+ WatcherInotify* watch = iter->second;
- if ( watch->Recursive )
- {
+ for ( std::vector<std::pair<WatcherInotify*, std::string>>::iterator itm =
+ mMovedOutsideWatches.begin();
+ mMovedOutsideWatches.end() != itm; ++itm ) {
+ if ( itm->first == watch ) {
+ mMovedOutsideWatches.erase( itm );
+ break;
+ }
+ }
+
+ if ( watch->Recursive && NULL == watch->Parent ) {
WatchMap::iterator it = mWatches.begin();
- std::list<WatchID> eraseWatches;
+ std::vector<WatchID> eraseWatches;
- for(; it != mWatches.end(); ++it)
- {
- if ( it->second != watch &&
- it->second->inParentTree( watch )
- )
- {
- eraseWatches.push_back( it->second->ID );
- }
- }
+ for ( ; it != mWatches.end(); ++it )
+ if ( it->second != watch && it->second->inParentTree( watch ) )
+ eraseWatches.push_back( it->second->InotifyID );
- for ( std::list<WatchID>::iterator eit = eraseWatches.begin(); eit != eraseWatches.end(); ++eit )
- {
+ for ( std::vector<WatchID>::iterator eit = eraseWatches.begin(); eit != eraseWatches.end();
+ ++eit ) {
removeWatch( *eit );
}
}
+ mWatchesRef.erase( watch->Directory );
mWatches.erase( iter );
- if ( NULL == watch->Parent )
- {
- WatchMap::iterator eraseit = mRealWatches.find( watch->ID );
+ if ( NULL == watch->Parent ) {
+ WatchMap::iterator eraseit = mRealWatches.find( watch->InotifyID );
- if ( eraseit != mRealWatches.end() )
- {
+ if ( eraseit != mRealWatches.end() ) {
mRealWatches.erase( eraseit );
}
}
- int err = inotify_rm_watch(mFD, watchid);
+ int err = inotify_rm_watch( mFD, watchid );
- if ( err < 0 )
- {
- efDEBUG( "Error removing watch %d: %s\n", watchid, strerror(errno) );
- }
- else
- {
+ if ( err < 0 ) {
+ efDEBUG( "Error removing watch %d: %s\n", watchid, strerror( errno ) );
+ } else {
efDEBUG( "Removed watch %s with id: %d\n", watch->Directory.c_str(), watchid );
}
efSAFE_DELETE( watch );
}
-void FileWatcherInotify::removeWatch(const std::string& directory)
-{
+void FileWatcherInotify::removeWatch( const std::string& directory ) {
+ if ( !mInitOK )
+ return;
+ Lock initLock( mInitLock );
Lock lock( mWatchesLock );
+ Lock l( mRealWatchesLock );
- WatchMap::iterator iter = mWatches.begin();
-
- for(; iter != mWatches.end(); ++iter)
- {
- if( directory == iter->second->Directory )
- {
- WatcherInotify * watch = iter->second;
-
- if ( watch->Recursive )
- {
- WatchMap::iterator it = mWatches.begin();
- std::list<WatchID> eraseWatches;
-
- for(; it != mWatches.end(); ++it)
- {
- if ( it->second->inParentTree( watch ) )
- {
- eraseWatches.push_back( it->second->ID );
- }
- }
-
- for ( std::list<WatchID>::iterator eit = eraseWatches.begin(); eit != eraseWatches.end(); ++eit )
- {
- removeWatchLocked( *eit );
- }
- }
-
- mWatches.erase( iter );
-
- if ( NULL == watch->Parent )
- {
- WatchMap::iterator eraseit = mRealWatches.find( watch->ID );
-
- if ( eraseit != mRealWatches.end() )
- {
- mRealWatches.erase( eraseit );
- }
- }
-
- int err = inotify_rm_watch(mFD, watch->ID);
-
- if ( err < 0 )
- {
- efDEBUG( "Error removing watch %d: %s\n", watch->ID, strerror(errno) );
- }
- else
- {
- efDEBUG( "Removed watch %s with id: %d\n", watch->Directory.c_str(), watch->ID );
- }
-
- efSAFE_DELETE( watch );
+ std::unordered_map<std::string, WatchID>::iterator ref = mWatchesRef.find( directory );
+ if ( ref == mWatchesRef.end() )
+ return;
- break;
- }
- }
+ removeWatchLocked( ref->second );
}
-void FileWatcherInotify::removeWatch( WatchID watchid )
-{
- Lock lock( mWatchesLock );
-
- WatchMap::iterator iter = mWatches.find( watchid );
-
- if( iter == mWatches.end() )
- {
+void FileWatcherInotify::removeWatch( WatchID watchid ) {
+ if ( !mInitOK )
return;
- }
-
+ Lock initLock( mInitLock );
+ Lock lock( mWatchesLock );
removeWatchLocked( watchid );
}
-void FileWatcherInotify::watch()
-{
- if ( NULL == mThread )
- {
+void FileWatcherInotify::watch() {
+ if ( NULL == mThread ) {
mThread = new Thread( &FileWatcherInotify::run, this );
mThread->launch();
}
}
-Watcher * FileWatcherInotify::watcherContainsDirectory( std::string dir )
-{
+Watcher* FileWatcherInotify::watcherContainsDirectory( std::string dir ) {
FileSystem::dirRemoveSlashAtEnd( dir );
std::string watcherPath = FileSystem::pathRemoveFileName( dir );
FileSystem::dirAddSlashAtEnd( watcherPath );
+ Lock lock( mWatchesLock );
- for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); ++it )
- {
- Watcher * watcher = it->second;
-
+ for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); ++it ) {
+ Watcher* watcher = it->second;
if ( watcher->Directory == watcherPath )
- {
return watcher;
- }
}
return NULL;
}
-void FileWatcherInotify::run()
-{
- static char buff[BUFF_SIZE] = {0};
+void FileWatcherInotify::run() {
+ char* buff = new char[BUFF_SIZE];
+ memset( buff, 0, BUFF_SIZE );
WatchMap::iterator wit;
- std::list<WatcherInotify*> movedOutsideWatches;
- do
- {
+ WatcherInotify* currentMoveFrom = NULL;
+ u_int32_t currentMoveCookie = -1;
+ bool lastWasMovedFrom = false;
+ std::string prevOldFileName;
+
+ do {
fd_set rfds;
- FD_ZERO (&rfds);
- FD_SET (mFD, &rfds);
+ FD_ZERO( &rfds );
+ FD_SET( mFD, &rfds );
timeval timeout;
- timeout.tv_sec=0;
- timeout.tv_usec=100000;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 100000;
- if( select (FD_SETSIZE, &rfds, NULL, NULL, &timeout) > 0 )
- {
+ if ( select( FD_SETSIZE, &rfds, NULL, NULL, &timeout ) > 0 ) {
ssize_t len;
- len = read (mFD, buff, BUFF_SIZE);
+ len = read( mFD, buff, BUFF_SIZE );
- if (len != -1)
- {
+ if ( len != -1 ) {
ssize_t i = 0;
- while (i < len)
- {
- struct inotify_event *pevent = (struct inotify_event *)&buff[i];
+ while ( i < len ) {
+ struct inotify_event* pevent = (struct inotify_event*)&buff[i];
{
- Lock lock( mWatchesLock );
+ {
+ Lock lock( mWatchesLock );
- wit = mWatches.find( pevent->wd );
+ wit = mWatches.find( pevent->wd );
+ }
- if ( wit != mWatches.end() )
- {
- handleAction(wit->second, pevent->name, pevent->mask);
+ if ( wit != mWatches.end() ) {
+ handleAction( wit->second, (char*)pevent->name, pevent->mask );
+
+ if ( ( pevent->mask & IN_MOVED_TO ) && wit->second == currentMoveFrom &&
+ pevent->cookie == currentMoveCookie ) {
+ /// make pair success
+ currentMoveFrom = NULL;
+ currentMoveCookie = -1;
+ } else if ( pevent->mask & IN_MOVED_FROM ) {
+ // Previous event was moved from and current event is moved from
+ // Treat it as a DELETE or moved ouside watches
+ if ( lastWasMovedFrom && currentMoveFrom ) {
+ mMovedOutsideWatches.push_back(
+ std::make_pair( currentMoveFrom, prevOldFileName ) );
+ }
+
+ currentMoveFrom = wit->second;
+ currentMoveCookie = pevent->cookie;
+ } else {
+ /// Keep track of the IN_MOVED_FROM events to know
+ /// if the IN_MOVED_TO event is also fired
+ if ( currentMoveFrom ) {
+ mMovedOutsideWatches.push_back(
+ std::make_pair( currentMoveFrom, prevOldFileName ) );
+ }
- /// Keep track of the IN_MOVED_FROM events to know if the IN_MOVED_TO event is also fired
- if ( !wit->second->OldFileName.empty() )
- {
- movedOutsideWatches.push_back( wit->second );
+ currentMoveFrom = NULL;
+ currentMoveCookie = -1;
}
}
+
+ lastWasMovedFrom = ( pevent->mask & IN_MOVED_FROM ) != 0;
+ if ( pevent->mask & IN_MOVED_FROM )
+ prevOldFileName = std::string( (char*)pevent->name );
}
- i += sizeof(struct inotify_event) + pevent->len;
+ i += sizeof( struct inotify_event ) + pevent->len;
}
+ }
+ } else {
+ // Here means no event received
+ // If last event is IN_MOVED_FROM, we assume no IN_MOVED_TO
+ if ( currentMoveFrom ) {
+ mMovedOutsideWatches.push_back(
+ std::make_pair( currentMoveFrom, currentMoveFrom->OldFileName ) );
+ }
- if ( !movedOutsideWatches.empty() )
- {
- /// In case that the IN_MOVED_TO is never fired means that the file was moved to other folder
- for ( std::list<WatcherInotify*>::iterator it = movedOutsideWatches.begin(); it != movedOutsideWatches.end(); ++it )
- {
- Watcher * watch = (*it);
-
- if ( !watch->OldFileName.empty() )
- {
- /// Check if the file move was a folder already being watched
- std::list<Watcher*> eraseWatches;
-
- for(; wit != mWatches.end(); ++wit)
- {
- Watcher * oldWatch = wit->second;
+ currentMoveFrom = NULL;
+ currentMoveCookie = -1;
+ }
- if ( oldWatch != watch &&
- -1 != String::strStartsWith( watch->Directory + watch->OldFileName + "/", oldWatch->Directory ) )
- {
- eraseWatches.push_back( oldWatch );
- }
- }
+ if ( !mMovedOutsideWatches.empty() ) {
+ // We need to make a copy since the element mMovedOutsideWatches could be modified
+ // during the iteration.
+ std::vector<std::pair<WatcherInotify*, std::string>> movedOutsideWatches(
+ mMovedOutsideWatches );
+
+ /// In case that the IN_MOVED_TO is never fired means that the file was moved to other
+ /// folder
+ for ( std::vector<std::pair<WatcherInotify*, std::string>>::iterator it =
+ movedOutsideWatches.begin();
+ it != movedOutsideWatches.end(); ++it ) {
+
+ // Skip if the watch has already being removed
+ if ( mMovedOutsideWatches.size() != movedOutsideWatches.size() ) {
+ bool found = false;
+ for ( std::vector<std::pair<WatcherInotify*, std::string>>::iterator itm =
+ mMovedOutsideWatches.begin();
+ mMovedOutsideWatches.end() != itm; ++itm ) {
+ if ( itm->first == it->first ) {
+ found = true;
+ break;
+ }
+ }
+ if ( !found )
+ continue;
+ }
- /// Remove invalid watches
- eraseWatches.sort();
+ Watcher* watch = ( *it ).first;
+ const std::string& oldFileName = ( *it ).second;
- for ( std::list<Watcher*>::reverse_iterator eit = eraseWatches.rbegin(); eit != eraseWatches.rend(); ++eit )
- {
- Watcher * rmWatch = *eit;
+ /// Check if the file move was a folder already being watched
+ std::vector<Watcher*> eraseWatches;
- /// Create Delete event for removed watches that have been moved too
- if ( Watcher * cntWatch = watcherContainsDirectory( rmWatch->Directory ) )
- {
- handleAction( cntWatch, FileSystem::fileNameFromPath( rmWatch->Directory ), IN_DELETE );
- }
+ {
+ Lock lock( mWatchesLock );
- removeWatch( rmWatch->ID );
- }
+ for ( ; wit != mWatches.end(); ++wit ) {
+ Watcher* oldWatch = wit->second;
- /// Remove the OldFileName
- watch->OldFileName = "";
+ if ( oldWatch != watch &&
+ -1 != String::strStartsWith( watch->Directory + oldFileName + "/",
+ oldWatch->Directory ) ) {
+ eraseWatches.push_back( oldWatch );
}
}
+ }
- movedOutsideWatches.clear();
+ /// Remove invalid watches
+ std::stable_sort( eraseWatches.begin(), eraseWatches.end(),
+ []( const Watcher* left, const Watcher* right ) {
+ return left->Directory < right->Directory;
+ } );
+
+ if ( eraseWatches.empty() ) {
+ handleAction( watch, oldFileName, IN_DELETE );
+ } else {
+ for ( std::vector<Watcher*>::reverse_iterator eit = eraseWatches.rbegin();
+ eit != eraseWatches.rend(); ++eit ) {
+ Watcher* rmWatch = *eit;
+
+ /// Create Delete event for removed watches that have been moved too
+ if ( Watcher* cntWatch = watcherContainsDirectory( rmWatch->Directory ) ) {
+ handleAction( cntWatch,
+ FileSystem::fileNameFromPath( rmWatch->Directory ),
+ IN_DELETE );
+ }
+ }
}
}
+
+ mMovedOutsideWatches.clear();
}
- } while( mInitOK );
+ } while ( mInitOK );
+
+ delete[] buff;
}
-void FileWatcherInotify::checkForNewWatcher( Watcher* watch, std::string fpath )
-{
+void FileWatcherInotify::checkForNewWatcher( Watcher* watch, std::string fpath ) {
FileSystem::dirAddSlashAtEnd( fpath );
/// If the watcher is recursive, checks if the new file is a folder, and creates a watcher
- if ( watch->Recursive && FileSystem::isDirectory( fpath ) )
- {
+ if ( watch->Recursive && FileSystem::isDirectory( fpath ) ) {
bool found = false;
- /// First check if exists
- for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); ++it )
{
- if ( it->second->Directory == fpath )
- {
- found = true;
- break;
+ Lock lock( mWatchesLock );
+
+ /// First check if exists
+ for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); ++it ) {
+ if ( it->second->Directory == fpath ) {
+ found = true;
+ break;
+ }
}
}
- if ( !found )
- {
- addWatch( fpath, watch->Listener, watch->Recursive, static_cast<WatcherInotify*>( watch ) );
+ if ( !found ) {
+ addWatch( fpath, watch->Listener, watch->Recursive,
+ static_cast<WatcherInotify*>( watch ) );
}
}
}
-void FileWatcherInotify::handleAction( Watcher* watch, const std::string& filename, unsigned long action, std::string )
-{
- if ( !watch || !watch->Listener )
- {
+void FileWatcherInotify::handleAction( Watcher* watch, const std::string& filename,
+ unsigned long action, std::string ) {
+ if ( !watch || !watch->Listener || !mInitOK ) {
return;
}
+ mIsTakingAction = true;
+ Lock initLock( mInitLock );
std::string fpath( watch->Directory + filename );
- if ( ( IN_CLOSE_WRITE & action ) || ( IN_MODIFY & action ) )
- {
- watch->Listener->handleFileAction( watch->ID, watch->Directory, filename, Actions::Modified );
- }
- else if( IN_MOVED_TO & action )
- {
- /// If OldFileName doesn't exist means that the file has been moved from other folder, so we just send the Add event
- if ( watch->OldFileName.empty() )
- {
- watch->Listener->handleFileAction( watch->ID, watch->Directory, filename, Actions::Add );
+ if ( ( IN_CLOSE_WRITE & action ) || ( IN_MODIFY & action ) ) {
+ watch->Listener->handleFileAction( watch->ID, watch->Directory, filename,
+ Actions::Modified );
+ } else if ( IN_MOVED_TO & action ) {
+ /// If OldFileName doesn't exist means that the file has been moved from other folder, so we
+ /// just send the Add event
+ if ( watch->OldFileName.empty() ) {
+ watch->Listener->handleFileAction( watch->ID, watch->Directory, filename,
+ Actions::Add );
- watch->Listener->handleFileAction( watch->ID, watch->Directory, filename, Actions::Modified );
+ watch->Listener->handleFileAction( watch->ID, watch->Directory, filename,
+ Actions::Modified );
checkForNewWatcher( watch, fpath );
- }
- else
- {
- watch->Listener->handleFileAction( watch->ID, watch->Directory, filename, Actions::Moved, watch->OldFileName );
+ } else {
+ watch->Listener->handleFileAction( watch->ID, watch->Directory, filename,
+ Actions::Moved, watch->OldFileName );
}
- if ( watch->Recursive && FileSystem::isDirectory( fpath ) )
- {
+ if ( watch->Recursive && FileSystem::isDirectory( fpath ) ) {
/// Update the new directory path
std::string opath( watch->Directory + watch->OldFileName );
FileSystem::dirAddSlashAtEnd( opath );
FileSystem::dirAddSlashAtEnd( fpath );
- for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); ++it )
- {
- if ( it->second->Directory == opath && it->second->DirInfo.Inode == FileInfo( opath ).Inode )
- {
- it->second->Directory = fpath;
- it->second->DirInfo = FileInfo( fpath );
+ Lock lock( mWatchesLock );
- break;
+ for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); ++it ) {
+ if ( it->second->Directory == opath ) {
+ it->second->Directory = fpath;
+ it->second->DirInfo = FileInfo( fpath );
+ } else if ( -1 != String::strStartsWith( opath, it->second->Directory ) ) {
+ it->second->Directory = fpath + it->second->Directory.substr( opath.size() );
+ it->second->DirInfo.Filepath = it->second->Directory;
}
}
}
watch->OldFileName = "";
- }
- else if( IN_CREATE & action )
- {
+ } else if ( IN_CREATE & action ) {
watch->Listener->handleFileAction( watch->ID, watch->Directory, filename, Actions::Add );
checkForNewWatcher( watch, fpath );
- }
- else if ( IN_MOVED_FROM & action )
- {
+ } else if ( IN_MOVED_FROM & action ) {
watch->OldFileName = filename;
- }
- else if( IN_DELETE & action )
- {
+ } else if ( IN_DELETE & action ) {
watch->Listener->handleFileAction( watch->ID, watch->Directory, filename, Actions::Delete );
FileSystem::dirAddSlashAtEnd( fpath );
/// If the file erased is a directory and recursive is enabled, removes the directory erased
- if ( watch->Recursive )
- {
- for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); ++it )
- {
- if ( it->second->Directory == fpath )
- {
- removeWatch( it->second->ID );
+ if ( watch->Recursive ) {
+ Lock l( mWatchesLock );
+
+ for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); ++it ) {
+ if ( it->second->Directory == fpath ) {
+ removeWatchLocked( it->second->InotifyID );
break;
}
}
}
}
+ mIsTakingAction = false;
}
-std::list<std::string> FileWatcherInotify::directories()
-{
- std::list<std::string> dirs;
+std::vector<std::string> FileWatcherInotify::directories() {
+ std::vector<std::string> dirs;
- Lock lock( mWatchesLock );
+ Lock l( mRealWatchesLock );
+
+ dirs.reserve( mRealWatches.size() );
WatchMap::iterator it = mRealWatches.begin();
for ( ; it != mRealWatches.end(); ++it )
- {
dirs.push_back( it->second->Directory );
- }
return dirs;
}
-bool FileWatcherInotify::pathInWatches( const std::string& path )
-{
+bool FileWatcherInotify::pathInWatches( const std::string& path ) {
+ Lock l( mRealWatchesLock );
+
/// Search in the real watches, since it must allow adding a watch already watched as a subdir
WatchMap::iterator it = mRealWatches.begin();
for ( ; it != mRealWatches.end(); ++it )
- {
if ( it->second->Directory == path )
- {
return true;
- }
- }
return false;
}
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/FileWatcherInotify.hpp b/dep/efsw/src/efsw/FileWatcherInotify.hpp
index b68314050a1..84174a0676a 100644
--- a/dep/efsw/src/efsw/FileWatcherInotify.hpp
+++ b/dep/efsw/src/efsw/FileWatcherInotify.hpp
@@ -7,68 +7,79 @@
#include <efsw/WatcherInotify.hpp>
#include <map>
+#include <unordered_map>
+#include <vector>
-namespace efsw
-{
+namespace efsw {
/// Implementation for Linux based on inotify.
/// @class FileWatcherInotify
-class FileWatcherInotify : public FileWatcherImpl
-{
- public:
- /// type for a map from WatchID to WatchStruct pointer
- typedef std::map<WatchID, WatcherInotify*> WatchMap;
+class FileWatcherInotify : public FileWatcherImpl {
+ public:
+ /// type for a map from WatchID to WatchStruct pointer
+ typedef std::map<WatchID, WatcherInotify*> WatchMap;
- FileWatcherInotify( FileWatcher * parent );
+ FileWatcherInotify( FileWatcher* parent );
- virtual ~FileWatcherInotify();
+ virtual ~FileWatcherInotify();
- /// Add a directory watch
- /// On error returns WatchID with Error type.
- WatchID addWatch(const std::string& directory, FileWatchListener* watcher, bool recursive);
+ /// Add a directory watch
+ /// On error returns WatchID with Error type.
+ WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive,
+ const std::vector<WatcherOption>& options ) override;
- /// Remove a directory watch. This is a brute force lazy search O(nlogn).
- void removeWatch(const std::string& directory);
+ /// Remove a directory watch. This is a brute force lazy search O(nlogn).
+ void removeWatch( const std::string& directory ) override;
- /// Remove a directory watch. This is a map lookup O(logn).
- void removeWatch(WatchID watchid);
+ /// Remove a directory watch. This is a map lookup O(logn).
+ void removeWatch( WatchID watchid ) override;
- /// Updates the watcher. Must be called often.
- void watch();
+ /// Updates the watcher. Must be called often.
+ void watch() override;
- /// Handles the action
- void handleAction(Watcher * watch, const std::string& filename, unsigned long action, std::string oldFilename = "");
+ /// Handles the action
+ void handleAction( Watcher* watch, const std::string& filename, unsigned long action,
+ std::string oldFilename = "" ) override;
- /// @return Returns a list of the directories that are being watched
- std::list<std::string> directories();
- protected:
- /// Map of WatchID to WatchStruct pointers
- WatchMap mWatches;
+ /// @return Returns a list of the directories that are being watched
+ std::vector<std::string> directories() override;
- /// User added watches
- WatchMap mRealWatches;
+ protected:
+ /// Map of WatchID to WatchStruct pointers
+ WatchMap mWatches;
- /// inotify file descriptor
- int mFD;
+ /// User added watches
+ WatchMap mRealWatches;
- Thread * mThread;
+ std::unordered_map<std::string, WatchID> mWatchesRef;
- Mutex mWatchesLock;
+ /// inotify file descriptor
+ int mFD;
- WatchID addWatch(const std::string& directory, FileWatchListener* watcher, bool recursive, WatcherInotify * parent = NULL );
+ Thread* mThread;
- bool pathInWatches( const std::string& path );
- private:
- void run();
+ Mutex mWatchesLock;
+ Mutex mRealWatchesLock;
+ Mutex mInitLock;
+ bool mIsTakingAction;
+ std::vector<std::pair<WatcherInotify*, std::string>> mMovedOutsideWatches;
- void removeWatchLocked(WatchID watchid);
+ WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive,
+ WatcherInotify* parent = NULL );
- void checkForNewWatcher( Watcher* watch, std::string fpath );
+ bool pathInWatches( const std::string& path ) override;
- Watcher * watcherContainsDirectory( std::string dir );
+ private:
+ void run();
+
+ void removeWatchLocked( WatchID watchid );
+
+ void checkForNewWatcher( Watcher* watch, std::string fpath );
+
+ Watcher* watcherContainsDirectory( std::string dir );
};
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/FileWatcherKqueue.cpp b/dep/efsw/src/efsw/FileWatcherKqueue.cpp
index 3373a68d0ce..32ef3dc82c8 100644
--- a/dep/efsw/src/efsw/FileWatcherKqueue.cpp
+++ b/dep/efsw/src/efsw/FileWatcherKqueue.cpp
@@ -2,42 +2,38 @@
#if EFSW_PLATFORM == EFSW_PLATFORM_KQUEUE || EFSW_PLATFORM == EFSW_PLATFORM_FSEVENTS
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
#include <dirent.h>
-#include <string.h>
+#include <efsw/Debug.hpp>
#include <efsw/FileSystem.hpp>
+#include <efsw/Lock.hpp>
#include <efsw/System.hpp>
-#include <efsw/Debug.hpp>
#include <efsw/WatcherGeneric.hpp>
-#include <efsw/Lock.hpp>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <unistd.h>
-namespace efsw
-{
+namespace efsw {
-FileWatcherKqueue::FileWatcherKqueue( FileWatcher * parent ) :
+FileWatcherKqueue::FileWatcherKqueue( FileWatcher* parent ) :
FileWatcherImpl( parent ),
- mLastWatchID(0),
+ mLastWatchID( 0 ),
mThread( NULL ),
mFileDescriptorCount( 1 ),
- mAddingWatcher( false )
-{
- mTimeOut.tv_sec = 0;
- mTimeOut.tv_nsec = 0;
- mInitOK = true;
+ mAddingWatcher( false ) {
+ mTimeOut.tv_sec = 0;
+ mTimeOut.tv_nsec = 0;
+ mInitOK = true;
}
-FileWatcherKqueue::~FileWatcherKqueue()
-{
+FileWatcherKqueue::~FileWatcherKqueue() {
WatchMap::iterator iter = mWatches.begin();
- for(; iter != mWatches.end(); ++iter)
- {
+ for ( ; iter != mWatches.end(); ++iter ) {
efSAFE_DELETE( iter->second );
}
@@ -48,8 +44,8 @@ FileWatcherKqueue::~FileWatcherKqueue()
efSAFE_DELETE( mThread );
}
-WatchID FileWatcherKqueue::addWatch(const std::string& directory, FileWatchListener* watcher, bool recursive)
-{
+WatchID FileWatcherKqueue::addWatch( const std::string& directory, FileWatchListener* watcher,
+ bool recursive, const std::vector<WatcherOption>& options ) {
static bool s_ug = false;
std::string dir( directory );
@@ -58,55 +54,43 @@ WatchID FileWatcherKqueue::addWatch(const std::string& directory, FileWatchListe
FileInfo fi( dir );
- if ( !fi.isDirectory() )
- {
+ if ( !fi.isDirectory() ) {
return Errors::Log::createLastError( Errors::FileNotFound, dir );
- }
- else if ( !fi.isReadable() )
- {
+ } else if ( !fi.isReadable() ) {
return Errors::Log::createLastError( Errors::FileNotReadable, dir );
- }
- else if ( pathInWatches( dir ) )
- {
+ } else if ( pathInWatches( dir ) ) {
return Errors::Log::createLastError( Errors::FileRepeated, directory );
}
std::string curPath;
std::string link( FileSystem::getLinkRealPath( dir, curPath ) );
- if ( "" != link )
- {
- if ( pathInWatches( link ) )
- {
+ if ( "" != link ) {
+ if ( pathInWatches( link ) ) {
return Errors::Log::createLastError( Errors::FileRepeated, directory );
- }
- else if ( !linkAllowed( curPath, link ) )
- {
+ } else if ( !linkAllowed( curPath, link ) ) {
return Errors::Log::createLastError( Errors::FileOutOfScope, dir );
- }
- else
- {
+ } else {
dir = link;
}
}
- /// Check first if are enough file descriptors available to create another kqueue watcher, otherwise it creates a generic watcher
- if ( availablesFD() )
- {
+ /// Check first if are enough file descriptors available to create another kqueue watcher,
+ /// otherwise it creates a generic watcher
+ if ( availablesFD() ) {
mAddingWatcher = true;
- WatcherKqueue * watch = new WatcherKqueue( ++mLastWatchID, dir, watcher, recursive, this );
+ WatcherKqueue* watch = new WatcherKqueue( ++mLastWatchID, dir, watcher, recursive, this );
{
Lock lock( mWatchesLock );
- mWatches.insert(std::make_pair(mLastWatchID, watch));
+ mWatches.insert( std::make_pair( mLastWatchID, watch ) );
}
watch->addAll();
// if failed to open the directory... erase the watcher
- if ( !watch->initOK() )
- {
+ if ( !watch->initOK() ) {
int le = watch->lastErrno();
mWatches.erase( watch->ID );
@@ -116,129 +100,111 @@ WatchID FileWatcherKqueue::addWatch(const std::string& directory, FileWatchListe
mLastWatchID--;
// Probably the folder has too many files, create a generic watcher
- if ( EACCES != le )
- {
- WatcherGeneric * genericWatch = new WatcherGeneric( ++mLastWatchID, dir, watcher, this, recursive );
+ if ( EACCES != le ) {
+ WatcherGeneric* genericWatch =
+ new WatcherGeneric( ++mLastWatchID, dir, watcher, this, recursive );
Lock lock( mWatchesLock );
- mWatches.insert(std::make_pair(mLastWatchID, genericWatch));
- }
- else
- {
+ mWatches.insert( std::make_pair( mLastWatchID, genericWatch ) );
+ } else {
return Errors::Log::createLastError( Errors::Unspecified, link );
}
}
mAddingWatcher = false;
- }
- else
- {
- if ( !s_ug )
- {
- efDEBUG( "Started using generic watcher, file descriptor limit reached: %ld\n", mFileDescriptorCount );
+ } else {
+ if ( !s_ug ) {
+ efDEBUG( "Started using generic watcher, file descriptor limit reached: %ld\n",
+ mFileDescriptorCount );
s_ug = true;
}
- WatcherGeneric * watch = new WatcherGeneric( ++mLastWatchID, dir, watcher, this, recursive );
+ WatcherGeneric* watch = new WatcherGeneric( ++mLastWatchID, dir, watcher, this, recursive );
Lock lock( mWatchesLock );
- mWatches.insert(std::make_pair(mLastWatchID, watch));
+ mWatches.insert( std::make_pair( mLastWatchID, watch ) );
}
return mLastWatchID;
}
-void FileWatcherKqueue::removeWatch(const std::string& directory)
-{
+void FileWatcherKqueue::removeWatch( const std::string& directory ) {
Lock lock( mWatchesLock );
WatchMap::iterator iter = mWatches.begin();
- for(; iter != mWatches.end(); ++iter)
- {
- if(directory == iter->second->Directory)
- {
- removeWatch(iter->first);
+ for ( ; iter != mWatches.end(); ++iter ) {
+ if ( directory == iter->second->Directory ) {
+ removeWatch( iter->first );
return;
}
}
}
-void FileWatcherKqueue::removeWatch(WatchID watchid)
-{
+void FileWatcherKqueue::removeWatch( WatchID watchid ) {
Lock lock( mWatchesLock );
- WatchMap::iterator iter = mWatches.find(watchid);
+ WatchMap::iterator iter = mWatches.find( watchid );
- if(iter == mWatches.end())
+ if ( iter == mWatches.end() )
return;
Watcher* watch = iter->second;
- mWatches.erase(iter);
+ mWatches.erase( iter );
efSAFE_DELETE( watch );
}
-bool FileWatcherKqueue::isAddingWatcher() const
-{
+bool FileWatcherKqueue::isAddingWatcher() const {
return mAddingWatcher;
}
-void FileWatcherKqueue::watch()
-{
- if ( NULL == mThread )
- {
+void FileWatcherKqueue::watch() {
+ if ( NULL == mThread ) {
mThread = new Thread( &FileWatcherKqueue::run, this );
mThread->launch();
}
}
-void FileWatcherKqueue::run()
-{
- do
- {
+void FileWatcherKqueue::run() {
+ do {
{
Lock lock( mWatchesLock );
- for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); ++it )
- {
+ for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); ++it ) {
it->second->watch();
}
}
System::sleep( 500 );
- } while( mInitOK );
+ } while ( mInitOK );
}
-void FileWatcherKqueue::handleAction(Watcher* watch, const std::string& filename, unsigned long action, std::string oldFilename)
-{
-}
+void FileWatcherKqueue::handleAction( Watcher* watch, const std::string& filename,
+ unsigned long action, std::string oldFilename ) {}
-std::list<std::string> FileWatcherKqueue::directories()
-{
- std::list<std::string> dirs;
+std::vector<std::string> FileWatcherKqueue::directories() {
+ std::vector<std::string> dirs;
Lock lock( mWatchesLock );
+ dirs.reserve( mWatches.size() );
+
WatchMap::iterator it = mWatches.begin();
- for ( ; it != mWatches.end(); ++it )
- {
+ for ( ; it != mWatches.end(); ++it ) {
dirs.push_back( it->second->Directory );
}
return dirs;
}
-bool FileWatcherKqueue::pathInWatches( const std::string& path )
-{
+bool FileWatcherKqueue::pathInWatches( const std::string& path ) {
WatchMap::iterator it = mWatches.begin();
- for ( ; it != mWatches.end(); ++it )
- {
- if ( it->second->Directory == path )
- {
+ for ( ; it != mWatches.end(); ++it ) {
+ if ( it->second->Directory == path ) {
return true;
}
}
@@ -246,21 +212,18 @@ bool FileWatcherKqueue::pathInWatches( const std::string& path )
return false;
}
-void FileWatcherKqueue::addFD()
-{
+void FileWatcherKqueue::addFD() {
mFileDescriptorCount++;
}
-void FileWatcherKqueue::removeFD()
-{
+void FileWatcherKqueue::removeFD() {
mFileDescriptorCount--;
}
-bool FileWatcherKqueue::availablesFD()
-{
+bool FileWatcherKqueue::availablesFD() {
return mFileDescriptorCount <= (Int64)System::getMaxFD() - 500;
}
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/FileWatcherKqueue.hpp b/dep/efsw/src/efsw/FileWatcherKqueue.hpp
index 0a2431e3777..ff5327b23fb 100644
--- a/dep/efsw/src/efsw/FileWatcherKqueue.hpp
+++ b/dep/efsw/src/efsw/FileWatcherKqueue.hpp
@@ -7,71 +7,74 @@
#include <efsw/WatcherKqueue.hpp>
-namespace efsw
-{
+namespace efsw {
/// Implementation for OSX based on kqueue.
/// @class FileWatcherKqueue
-class FileWatcherKqueue : public FileWatcherImpl
-{
+class FileWatcherKqueue : public FileWatcherImpl {
friend class WatcherKqueue;
- public:
- FileWatcherKqueue( FileWatcher * parent );
- virtual ~FileWatcherKqueue();
+ public:
+ FileWatcherKqueue( FileWatcher* parent );
- /// Add a directory watch
- /// On error returns WatchID with Error type.
- WatchID addWatch(const std::string& directory, FileWatchListener* watcher, bool recursive);
+ virtual ~FileWatcherKqueue();
- /// Remove a directory watch. This is a brute force lazy search O(nlogn).
- void removeWatch(const std::string& directory);
+ /// Add a directory watch
+ /// On error returns WatchID with Error type.
+ WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive,
+ const std::vector<WatcherOption> &options ) override;
- /// Remove a directory watch. This is a map lookup O(logn).
- void removeWatch(WatchID watchid);
+ /// Remove a directory watch. This is a brute force lazy search O(nlogn).
+ void removeWatch( const std::string& directory ) override;
- /// Updates the watcher. Must be called often.
- void watch();
+ /// Remove a directory watch. This is a map lookup O(logn).
+ void removeWatch( WatchID watchid ) override;
- /// Handles the action
- void handleAction(Watcher* watch, const std::string& filename, unsigned long action, std::string oldFilename = "");
+ /// Updates the watcher. Must be called often.
+ void watch() override;
- /// @return Returns a list of the directories that are being watched
- std::list<std::string> directories();
- protected:
- /// Map of WatchID to WatchStruct pointers
- WatchMap mWatches;
+ /// Handles the action
+ void handleAction( Watcher* watch, const std::string& filename, unsigned long action,
+ std::string oldFilename = "" ) override;
- /// time out data
- struct timespec mTimeOut;
+ /// @return Returns a list of the directories that are being watched
+ std::vector<std::string> directories() override;
- /// WatchID allocator
- int mLastWatchID;
+ protected:
+ /// Map of WatchID to WatchStruct pointers
+ WatchMap mWatches;
- Thread * mThread;
+ /// time out data
+ struct timespec mTimeOut;
- Mutex mWatchesLock;
+ /// WatchID allocator
+ int mLastWatchID;
- std::list<WatchID> mRemoveList;
+ Thread* mThread;
- long mFileDescriptorCount;
+ Mutex mWatchesLock;
- bool mAddingWatcher;
+ std::vector<WatchID> mRemoveList;
- bool isAddingWatcher() const;
+ long mFileDescriptorCount;
- bool pathInWatches( const std::string& path );
+ bool mAddingWatcher;
- void addFD();
+ bool isAddingWatcher() const;
- void removeFD();
+ bool pathInWatches( const std::string& path ) override;
- bool availablesFD();
- private:
- void run();
+ void addFD();
+
+ void removeFD();
+
+ bool availablesFD();
+
+ private:
+ void run();
};
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/FileWatcherWin32.cpp b/dep/efsw/src/efsw/FileWatcherWin32.cpp
index 317506fb3e3..37f43cc27da 100644
--- a/dep/efsw/src/efsw/FileWatcherWin32.cpp
+++ b/dep/efsw/src/efsw/FileWatcherWin32.cpp
@@ -1,41 +1,43 @@
-#include <efsw/FileWatcherWin32.hpp>
#include <efsw/FileSystem.hpp>
-#include <efsw/System.hpp>
-#include <efsw/String.hpp>
+#include <efsw/FileWatcherWin32.hpp>
#include <efsw/Lock.hpp>
+#include <efsw/String.hpp>
+#include <efsw/System.hpp>
#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32
-namespace efsw
-{
+namespace efsw {
-FileWatcherWin32::FileWatcherWin32( FileWatcher * parent ) :
- FileWatcherImpl( parent ),
- mLastWatchID(0),
- mThread( NULL )
-{
- mInitOK = true;
+FileWatcherWin32::FileWatcherWin32( FileWatcher* parent ) :
+ FileWatcherImpl( parent ), mLastWatchID( 0 ), mThread( NULL ) {
+ mIOCP = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, 1 );
+ if ( mIOCP && mIOCP != INVALID_HANDLE_VALUE )
+ mInitOK = true;
}
-FileWatcherWin32::~FileWatcherWin32()
-{
+FileWatcherWin32::~FileWatcherWin32() {
mInitOK = false;
+
+ if ( mIOCP && mIOCP != INVALID_HANDLE_VALUE ) {
+ PostQueuedCompletionStatus( mIOCP, 0, reinterpret_cast<ULONG_PTR>( this ), NULL );
+ }
+
efSAFE_DELETE( mThread );
+
removeAllWatches();
+
+ CloseHandle( mIOCP );
}
-WatchID FileWatcherWin32::addWatch(const std::string& directory, FileWatchListener* watcher, bool recursive)
-{
+WatchID FileWatcherWin32::addWatch( const std::string& directory, FileWatchListener* watcher,
+ bool recursive, const std::vector<WatcherOption> &options ) {
std::string dir( directory );
FileInfo fi( dir );
- if ( !fi.isDirectory() )
- {
+ if ( !fi.isDirectory() ) {
return Errors::Log::createLastError( Errors::FileNotFound, dir );
- }
- else if ( !fi.isReadable() )
- {
+ } else if ( !fi.isReadable() ) {
return Errors::Log::createLastError( Errors::FileNotReadable, dir );
}
@@ -43,22 +45,22 @@ WatchID FileWatcherWin32::addWatch(const std::string& directory, FileWatchListen
Lock lock( mWatchesLock );
- if ( pathInWatches( dir ) )
- {
+ if ( pathInWatches( dir ) ) {
return Errors::Log::createLastError( Errors::FileRepeated, dir );
}
WatchID watchid = ++mLastWatchID;
- WatcherStructWin32 * watch = CreateWatch( String::fromUtf8( dir ).toWideString().c_str(), recursive, FILE_NOTIFY_CHANGE_CREATION |
- FILE_NOTIFY_CHANGE_LAST_WRITE |
- FILE_NOTIFY_CHANGE_FILE_NAME |
- FILE_NOTIFY_CHANGE_DIR_NAME |
- FILE_NOTIFY_CHANGE_SIZE
- );
+ DWORD bufferSize = static_cast<DWORD>( getOptionValue(options, Option::WinBufferSize, 63 * 1024) );
+ DWORD notifyFilter = static_cast<DWORD>( getOptionValue(options, Option::WinNotifyFilter,
+ FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_LAST_WRITE |
+ FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME |
+ FILE_NOTIFY_CHANGE_SIZE) );
- if( NULL == watch )
- {
+ WatcherStructWin32* watch = CreateWatch( String::fromUtf8( dir ).toWideString().c_str(),
+ recursive, bufferSize, notifyFilter, mIOCP );
+
+ if ( NULL == watch ) {
return Errors::Log::createLastError( Errors::FileNotFound, dir );
}
@@ -66,241 +68,191 @@ WatchID FileWatcherWin32::addWatch(const std::string& directory, FileWatchListen
watch->Watch->ID = watchid;
watch->Watch->Watch = this;
watch->Watch->Listener = watcher;
- watch->Watch->DirName = new char[dir.length()+1];
- strcpy(watch->Watch->DirName, dir.c_str());
+ watch->Watch->DirName = new char[dir.length() + 1];
+ strcpy( watch->Watch->DirName, dir.c_str() );
- mWatchesNew.insert( watch );
mWatches.insert( watch );
return watchid;
}
-void FileWatcherWin32::removeWatch(const std::string& directory)
-{
+void FileWatcherWin32::removeWatch( const std::string& directory ) {
Lock lock( mWatchesLock );
Watches::iterator iter = mWatches.begin();
- for(; iter != mWatches.end(); ++iter)
- {
- if(directory == (*iter)->Watch->DirName)
- {
- removeWatch(*iter);
+ for ( ; iter != mWatches.end(); ++iter ) {
+ if ( directory == ( *iter )->Watch->DirName ) {
+ removeWatch( *iter );
break;
}
}
}
-void FileWatcherWin32::removeWatch(WatchID watchid)
-{
+void FileWatcherWin32::removeWatch( WatchID watchid ) {
Lock lock( mWatchesLock );
Watches::iterator iter = mWatches.begin();
- for(; iter != mWatches.end(); ++iter)
- {
+ for ( ; iter != mWatches.end(); ++iter ) {
// Find the watch ID
- if ( (*iter)->Watch->ID == watchid )
- {
- removeWatch(*iter);
+ if ( ( *iter )->Watch->ID == watchid ) {
+ removeWatch( *iter );
return;
}
}
}
-void FileWatcherWin32::removeWatch(WatcherStructWin32* watch)
-{
- mWatchesRemoved.insert(watch);
-
- if( NULL == mThread )
- {
- removeWatches();
- }
-}
-
-void FileWatcherWin32::removeWatches()
-{
+void FileWatcherWin32::removeWatch( WatcherStructWin32* watch ) {
Lock lock( mWatchesLock );
- Watches::iterator remWatchIter = mWatchesRemoved.begin();
-
- for( ; remWatchIter != mWatchesRemoved.end(); ++remWatchIter )
- {
- Watches::iterator iter = mWatches.find(*remWatchIter);
-
- if( iter != mWatches.end() )
- {
- DestroyWatch(*iter);
-
- mWatches.erase( iter );
- }
-
- iter = mWatchesNew.find(*remWatchIter);
-
- if( iter != mWatchesNew.end() )
- {
- mWatchesNew.erase( iter );
- }
- }
-
- mWatchesRemoved.clear();
+ DestroyWatch( watch );
+ mWatches.erase( watch );
}
-void FileWatcherWin32::watch()
-{
- if ( NULL == mThread )
- {
+void FileWatcherWin32::watch() {
+ if ( NULL == mThread ) {
mThread = new Thread( &FileWatcherWin32::run, this );
mThread->launch();
}
}
-void FileWatcherWin32::removeAllWatches()
-{
+void FileWatcherWin32::removeAllWatches() {
Lock lock( mWatchesLock );
Watches::iterator iter = mWatches.begin();
- for( ; iter != mWatches.end(); ++iter )
- {
- DestroyWatch((*iter));
+ for ( ; iter != mWatches.end(); ++iter ) {
+ DestroyWatch( ( *iter ) );
}
mWatches.clear();
- mWatchesRemoved.clear();
- mWatchesNew.clear();
}
-void FileWatcherWin32::run()
-{
- do
- {
- if ( !mWatches.empty() )
- {
- {
- Lock lock( mWatchesLock );
-
- for( Watches::iterator iter = mWatches.begin() ; iter != mWatches.end(); ++iter )
- {
- WatcherStructWin32 * watch = *iter;
-
- if ( HasOverlappedIoCompleted( &watch->Overlapped ) )
- {
- DWORD bytes;
-
- if ( GetOverlappedResult( watch->Watch->DirHandle, &watch->Overlapped, &bytes, FALSE ) )
- {
- WatchCallback( ERROR_SUCCESS, bytes, &watch->Overlapped );
- }
- }
+void FileWatcherWin32::run() {
+ do {
+ if ( mInitOK && !mWatches.empty() ) {
+ DWORD numOfBytes = 0;
+ OVERLAPPED* ov = NULL;
+ ULONG_PTR compKey = 0;
+ BOOL res = FALSE;
+
+ while ( ( res = GetQueuedCompletionStatus( mIOCP, &numOfBytes, &compKey, &ov,
+ INFINITE ) ) != FALSE ) {
+ if ( compKey != 0 && compKey == reinterpret_cast<ULONG_PTR>( this ) ) {
+ break;
+ } else {
+ Lock lock( mWatchesLock );
+ WatchCallback( numOfBytes, ov );
}
}
-
- if ( mInitOK )
- {
- System::sleep( 10 );
- }
- }
- else
- {
- // Wait for a new handle to be added
+ } else {
System::sleep( 10 );
}
-
- removeWatches();
-
- for ( Watches::iterator it = mWatchesNew.begin(); it != mWatchesNew.end(); ++it )
- {
- RefreshWatch(*it);
- }
-
- mWatchesNew.clear();
} while ( mInitOK );
removeAllWatches();
}
-void FileWatcherWin32::handleAction(Watcher* watch, const std::string& filename, unsigned long action, std::string oldFilename)
-{
+void FileWatcherWin32::handleAction( Watcher* watch, const std::string& filename,
+ unsigned long action, std::string /*oldFilename*/ ) {
Action fwAction;
- switch(action)
- {
- case FILE_ACTION_RENAMED_OLD_NAME:
- watch->OldFileName = filename;
- return;
- case FILE_ACTION_ADDED:
- fwAction = Actions::Add;
- break;
- case FILE_ACTION_RENAMED_NEW_NAME:
- {
- fwAction = Actions::Moved;
-
- std::string fpath( watch->Directory + filename );
-
- // Update the directory path
- if ( watch->Recursive && FileSystem::isDirectory( fpath ) )
- {
- // Update the new directory path
- std::string opath( watch->Directory + watch->OldFileName );
- FileSystem::dirAddSlashAtEnd( opath );
- FileSystem::dirAddSlashAtEnd( fpath );
-
- for ( Watches::iterator it = mWatches.begin(); it != mWatches.end(); ++it )
- {
- if ( (*it)->Watch->Directory == opath )
- {
- (*it)->Watch->Directory = fpath;
+ switch ( action ) {
+ case FILE_ACTION_RENAMED_OLD_NAME:
+ watch->OldFileName = filename;
+ return;
+ case FILE_ACTION_ADDED:
+ fwAction = Actions::Add;
+ break;
+ case FILE_ACTION_RENAMED_NEW_NAME: {
+ fwAction = Actions::Moved;
+
+ std::string fpath( watch->Directory + filename );
- break;
+ // Update the directory path
+ if ( watch->Recursive && FileSystem::isDirectory( fpath ) ) {
+ // Update the new directory path
+ std::string opath( watch->Directory + watch->OldFileName );
+ FileSystem::dirAddSlashAtEnd( opath );
+ FileSystem::dirAddSlashAtEnd( fpath );
+
+ for ( Watches::iterator it = mWatches.begin(); it != mWatches.end(); ++it ) {
+ if ( ( *it )->Watch->Directory == opath ) {
+ ( *it )->Watch->Directory = fpath;
+
+ break;
+ }
}
}
- }
- watch->Listener->handleFileAction(watch->ID, static_cast<WatcherWin32*>( watch )->DirName, filename, fwAction, watch->OldFileName);
- return;
- }
- case FILE_ACTION_REMOVED:
- fwAction = Actions::Delete;
- break;
- case FILE_ACTION_MODIFIED:
- fwAction = Actions::Modified;
- break;
+ std::string folderPath( static_cast<WatcherWin32*>( watch )->DirName );
+ std::string realFilename = filename;
+ std::size_t sepPos = filename.find_last_of( "/\\" );
+ std::string oldFolderPath =
+ static_cast<WatcherWin32*>( watch )->DirName +
+ watch->OldFileName.substr( 0, watch->OldFileName.find_last_of( "/\\" ) );
+
+ if ( sepPos != std::string::npos ) {
+ folderPath +=
+ filename.substr( 0, sepPos + 1 < filename.size() ? sepPos + 1 : sepPos );
+ realFilename = filename.substr( sepPos + 1 );
+ }
+
+ if ( folderPath == oldFolderPath ) {
+ watch->Listener->handleFileAction(
+ watch->ID, folderPath, realFilename, fwAction,
+ FileSystem::fileNameFromPath( watch->OldFileName ) );
+ } else {
+ watch->Listener->handleFileAction( watch->ID,
+ static_cast<WatcherWin32*>( watch )->DirName,
+ filename, fwAction, watch->OldFileName );
+ }
+ return;
+ }
+ case FILE_ACTION_REMOVED:
+ fwAction = Actions::Delete;
+ break;
+ case FILE_ACTION_MODIFIED:
+ fwAction = Actions::Modified;
+ break;
+ default:
+ return;
};
std::string folderPath( static_cast<WatcherWin32*>( watch )->DirName );
std::string realFilename = filename;
- std::size_t sepPos = filename.find_last_of("/\\");
+ std::size_t sepPos = filename.find_last_of( "/\\" );
- if ( sepPos != std::string::npos )
- {
- folderPath += filename.substr( 0, sepPos );
+ if ( sepPos != std::string::npos ) {
+ folderPath += filename.substr( 0, sepPos + 1 < filename.size() ? sepPos + 1 : sepPos );
realFilename = filename.substr( sepPos + 1 );
}
- watch->Listener->handleFileAction(watch->ID, folderPath, realFilename, fwAction);
+ FileSystem::dirAddSlashAtEnd( folderPath );
+
+ watch->Listener->handleFileAction( watch->ID, folderPath, realFilename, fwAction );
}
-std::list<std::string> FileWatcherWin32::directories()
-{
- std::list<std::string> dirs;
+std::vector<std::string> FileWatcherWin32::directories() {
+ std::vector<std::string> dirs;
Lock lock( mWatchesLock );
- for ( Watches::iterator it = mWatches.begin(); it != mWatches.end(); ++it )
- {
- dirs.push_back( std::string( (*it)->Watch->DirName ) );
+ dirs.reserve( mWatches.size() );
+
+ for ( Watches::iterator it = mWatches.begin(); it != mWatches.end(); ++it ) {
+ dirs.push_back( std::string( ( *it )->Watch->DirName ) );
}
return dirs;
}
-bool FileWatcherWin32::pathInWatches( const std::string& path )
-{
- for ( Watches::iterator it = mWatches.begin(); it != mWatches.end(); ++it )
- {
- if ( (*it)->Watch->DirName == path )
- {
+bool FileWatcherWin32::pathInWatches( const std::string& path ) {
+ Lock lock( mWatchesLock );
+
+ for ( Watches::iterator it = mWatches.begin(); it != mWatches.end(); ++it ) {
+ if ( ( *it )->Watch->DirName == path ) {
return true;
}
}
@@ -308,6 +260,6 @@ bool FileWatcherWin32::pathInWatches( const std::string& path )
return false;
}
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/FileWatcherWin32.hpp b/dep/efsw/src/efsw/FileWatcherWin32.hpp
index 983ee1853d0..de3f9538dcd 100644
--- a/dep/efsw/src/efsw/FileWatcherWin32.hpp
+++ b/dep/efsw/src/efsw/FileWatcherWin32.hpp
@@ -6,68 +6,65 @@
#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32
#include <efsw/WatcherWin32.hpp>
-#include <set>
#include <map>
+#include <set>
+#include <vector>
-namespace efsw
-{
+namespace efsw {
/// Implementation for Win32 based on ReadDirectoryChangesW.
/// @class FileWatcherWin32
-class FileWatcherWin32 : public FileWatcherImpl
-{
- public:
- /// type for a map from WatchID to WatcherWin32 pointer
- typedef std::set<WatcherStructWin32*> Watches;
-
- FileWatcherWin32( FileWatcher * parent );
+class FileWatcherWin32 : public FileWatcherImpl {
+ public:
+ /// type for a map from WatchID to WatcherWin32 pointer
+ typedef std::set<WatcherStructWin32*> Watches;
- virtual ~FileWatcherWin32();
+ FileWatcherWin32( FileWatcher* parent );
- /// Add a directory watch
- /// On error returns WatchID with Error type.
- WatchID addWatch(const std::string& directory, FileWatchListener* watcher, bool recursive);
+ virtual ~FileWatcherWin32();
- /// Remove a directory watch. This is a brute force lazy search O(nlogn).
- void removeWatch(const std::string& directory);
+ /// Add a directory watch
+ /// On error returns WatchID with Error type.
+ WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive,
+ const std::vector<WatcherOption> &options ) override;
- /// Remove a directory watch. This is a map lookup O(logn).
- void removeWatch(WatchID watchid);
+ /// Remove a directory watch. This is a brute force lazy search O(nlogn).
+ void removeWatch( const std::string& directory ) override;
- /// Updates the watcher. Must be called often.
- void watch();
+ /// Remove a directory watch. This is a map lookup O(logn).
+ void removeWatch( WatchID watchid ) override;
- /// Handles the action
- void handleAction(Watcher* watch, const std::string& filename, unsigned long action, std::string oldFilename = "");
+ /// Updates the watcher. Must be called often.
+ void watch() override;
- /// @return Returns a list of the directories that are being watched
- std::list<std::string> directories();
- protected:
- Watches mWatches;
- Watches mWatchesRemoved;
- Watches mWatchesNew;
+ /// Handles the action
+ void handleAction( Watcher* watch, const std::string& filename, unsigned long action,
+ std::string oldFilename = "" ) override;
- /// The last watchid
- WatchID mLastWatchID;
+ /// @return Returns a list of the directories that are being watched
+ std::vector<std::string> directories() override;
- Thread * mThread;
+ protected:
+ HANDLE mIOCP;
+ Watches mWatches;
- Mutex mWatchesLock;
+ /// The last watchid
+ WatchID mLastWatchID;
+ Thread* mThread;
+ Mutex mWatchesLock;
- bool pathInWatches( const std::string& path );
+ bool pathInWatches( const std::string& path ) override;
- /// Remove all directory watches.
- void removeAllWatches();
+ /// Remove all directory watches.
+ void removeAllWatches();
- /// Remove needed directory watches.
- void removeWatches();
+ void removeWatch( WatcherStructWin32* watch );
- void removeWatch(WatcherStructWin32* watch);
- private:
- void run();
+ private:
+ void run();
};
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/Lock.hpp b/dep/efsw/src/efsw/Lock.hpp
index 5dbf11e39ce..e8c522abf0d 100644
--- a/dep/efsw/src/efsw/Lock.hpp
+++ b/dep/efsw/src/efsw/Lock.hpp
@@ -7,21 +7,15 @@ namespace efsw {
/** Simple mutex class */
class Lock {
- public:
- explicit Lock( Mutex& mutex ) :
- mMutex( mutex )
- {
- mMutex.lock();
- }
+ public:
+ explicit Lock( Mutex& mutex ) : mMutex( mutex ) { mMutex.lock(); }
- ~Lock()
- {
- mMutex.unlock();
- }
- private:
- Mutex& mMutex;
+ ~Lock() { mMutex.unlock(); }
+
+ private:
+ Mutex& mMutex;
};
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/Log.cpp b/dep/efsw/src/efsw/Log.cpp
index 8e2860ac099..6f32df7c64a 100644
--- a/dep/efsw/src/efsw/Log.cpp
+++ b/dep/efsw/src/efsw/Log.cpp
@@ -1,27 +1,49 @@
#include <efsw/efsw.hpp>
+#include <efsw/Debug.hpp>
namespace efsw { namespace Errors {
-static std::string LastError;
+static std::string LastError = "";
+static Error LastErrorCode = NoError;
-std::string Log::getLastErrorLog()
-{
+std::string Log::getLastErrorLog() {
return LastError;
}
-Error Log::createLastError( Error err, std::string log )
-{
- switch ( err )
- {
- case FileNotFound: LastError = "File not found ( " + log + " )"; break;
- case FileRepeated: LastError = "File reapeated in watches ( " + log + " )"; break;
- case FileOutOfScope: LastError = "Symlink file out of scope ( " + log + " )"; break;
- case FileRemote: LastError = "File is located in a remote file system, use a generic watcher. ( " + log + " )"; break;
+Error Log::getLastErrorCode() {
+ return LastErrorCode;
+}
+
+void Log::clearLastError() {
+ LastErrorCode = NoError;
+ LastError = "";
+}
+
+Error Log::createLastError( Error err, std::string log ) {
+ switch ( err ) {
+ case FileNotFound:
+ LastError = "File not found ( " + log + " )";
+ break;
+ case FileRepeated:
+ LastError = "File repeated in watches ( " + log + " )";
+ break;
+ case FileOutOfScope:
+ LastError = "Symlink file out of scope ( " + log + " )";
+ break;
+ case FileRemote:
+ LastError =
+ "File is located in a remote file system, use a generic watcher. ( " + log + " )";
+ break;
+ case WatcherFailed:
+ LastError = "File system watcher failed ( " + log + " )";
+ break;
case Unspecified:
- default: LastError = log;
+ default:
+ LastError = log;
}
+ efDEBUG( "%s\n", LastError.c_str() );
return err;
}
-}}
+}} // namespace efsw::Errors
diff --git a/dep/efsw/src/efsw/Mutex.cpp b/dep/efsw/src/efsw/Mutex.cpp
index b34ba066ee9..c961db18124 100644
--- a/dep/efsw/src/efsw/Mutex.cpp
+++ b/dep/efsw/src/efsw/Mutex.cpp
@@ -3,24 +3,18 @@
namespace efsw {
-Mutex::Mutex() :
- mMutexImpl( new Platform::MutexImpl() )
-{
-}
+Mutex::Mutex() : mMutexImpl( new Platform::MutexImpl() ) {}
-Mutex::~Mutex()
-{
+Mutex::~Mutex() {
efSAFE_DELETE( mMutexImpl );
}
-void Mutex::lock()
-{
+void Mutex::lock() {
mMutexImpl->lock();
}
-void Mutex::unlock()
-{
+void Mutex::unlock() {
mMutexImpl->unlock();
}
-}
+} // namespace efsw
diff --git a/dep/efsw/src/efsw/Mutex.hpp b/dep/efsw/src/efsw/Mutex.hpp
index e6e89def175..d98ad17c237 100644
--- a/dep/efsw/src/efsw/Mutex.hpp
+++ b/dep/efsw/src/efsw/Mutex.hpp
@@ -5,24 +5,27 @@
namespace efsw {
-namespace Platform { class MutexImpl; }
+namespace Platform {
+class MutexImpl;
+}
/** Simple mutex class */
class Mutex {
- public:
- Mutex();
+ public:
+ Mutex();
+
+ ~Mutex();
- ~Mutex();
+ /** Lock the mutex */
+ void lock();
- /** Lock the mutex */
- void lock();
+ /** Unlock the mutex */
+ void unlock();
- /** Unlock the mutex */
- void unlock();
- private:
- Platform::MutexImpl * mMutexImpl;
+ private:
+ Platform::MutexImpl* mMutexImpl;
};
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/String.cpp b/dep/efsw/src/efsw/String.cpp
index f703d25cb35..8c9a3cc6cac 100644
--- a/dep/efsw/src/efsw/String.cpp
+++ b/dep/efsw/src/efsw/String.cpp
@@ -1,84 +1,66 @@
-#include <iterator>
#include <efsw/String.hpp>
#include <efsw/Utf.hpp>
+#include <iterator>
namespace efsw {
const std::size_t String::InvalidPos = StringType::npos;
-std::vector < std::string > String::split ( const std::string& str, const char& splitchar, const bool& pushEmptyString )
-{
- std::vector < std::string > tmp;
+std::vector<std::string> String::split( const std::string& str, const char& splitchar,
+ const bool& pushEmptyString ) {
+ std::vector<std::string> tmp;
std::string tmpstr;
- for ( size_t i = 0; i < str.size(); i++ )
- {
- if ( str[i] == splitchar )
- {
- if ( pushEmptyString || tmpstr.size() )
- {
- tmp.push_back(tmpstr);
+ for ( size_t i = 0; i < str.size(); i++ ) {
+ if ( str[i] == splitchar ) {
+ if ( pushEmptyString || tmpstr.size() ) {
+ tmp.push_back( tmpstr );
tmpstr = "";
}
- }
- else
- {
+ } else {
tmpstr += str[i];
}
}
- if ( tmpstr.size() )
- {
+ if ( tmpstr.size() ) {
tmp.push_back( tmpstr );
}
return tmp;
}
-std::vector < String > String::split ( const String& str, const Uint32& splitchar, const bool& pushEmptyString )
-{
- std::vector < String > tmp;
+std::vector<String> String::split( const String& str, const Uint32& splitchar,
+ const bool& pushEmptyString ) {
+ std::vector<String> tmp;
String tmpstr;
- for ( size_t i = 0; i < str.size(); i++ )
- {
- if ( str[i] == splitchar )
- {
- if ( pushEmptyString || tmpstr.size() )
- {
- tmp.push_back(tmpstr);
+ for ( size_t i = 0; i < str.size(); i++ ) {
+ if ( str[i] == splitchar ) {
+ if ( pushEmptyString || tmpstr.size() ) {
+ tmp.push_back( tmpstr );
tmpstr = "";
}
- }
- else
- {
+ } else {
tmpstr += str[i];
}
}
- if ( tmpstr.size() )
- {
+ if ( tmpstr.size() ) {
tmp.push_back( tmpstr );
}
return tmp;
}
-int String::strStartsWith( const std::string& start, const std::string& str )
-{
- int pos = -1;
- size_t size = start.size();
+int String::strStartsWith( const std::string& start, const std::string& str ) {
+ int pos = -1;
+ size_t size = start.size();
- if ( str.size() >= size )
- {
- for ( std::size_t i = 0; i < size; i++ )
- {
- if ( start[i] == str[i] )
- {
+ if ( str.size() >= size ) {
+ for ( std::size_t i = 0; i < size; i++ ) {
+ if ( start[i] == str[i] ) {
pos = (int)i;
- }
- else
- {
+ } else {
pos = -1;
break;
}
@@ -88,21 +70,15 @@ int String::strStartsWith( const std::string& start, const std::string& str )
return pos;
}
-int String::strStartsWith( const String& start, const String& str )
-{
- int pos = -1;
- size_t size = start.size();
+int String::strStartsWith( const String& start, const String& str ) {
+ int pos = -1;
+ size_t size = start.size();
- if ( str.size() >= size )
- {
- for ( std::size_t i = 0; i < size; i++ )
- {
- if ( start[i] == str[i] )
- {
+ if ( str.size() >= size ) {
+ for ( std::size_t i = 0; i < size; i++ ) {
+ if ( start[i] == str[i] ) {
pos = (int)i;
- }
- else
- {
+ } else {
pos = -1;
break;
}
@@ -112,37 +88,30 @@ int String::strStartsWith( const String& start, const String& str )
return pos;
}
-String::String()
-{
-}
+String::String() {}
-String::String(char ansiChar, const std::locale& locale)
-{
- mString += Utf32::DecodeAnsi(ansiChar, locale);
+String::String( char ansiChar, const std::locale& locale ) {
+ mString += Utf32::DecodeAnsi( ansiChar, locale );
}
#ifndef EFSW_NO_WIDECHAR
-String::String(wchar_t wideChar)
-{
- mString += Utf32::DecodeWide(wideChar);
+String::String( wchar_t wideChar ) {
+ mString += Utf32::DecodeWide( wideChar );
}
#endif
-String::String(StringBaseType utf32Char)
-{
+String::String( StringBaseType utf32Char ) {
mString += utf32Char;
}
String::String( const char* uf8String ) {
- if (uf8String)
- {
- std::size_t length = strlen(uf8String);
+ if ( uf8String ) {
+ std::size_t length = strlen( uf8String );
- if (length > 0)
- {
- mString.reserve(length + 1);
+ if ( length > 0 ) {
+ mString.reserve( length + 1 );
- Utf8::ToUtf32(uf8String, uf8String + length, std::back_inserter(mString));
+ Utf8::ToUtf32( uf8String, uf8String + length, std::back_inserter( mString ) );
}
}
}
@@ -153,64 +122,49 @@ String::String( const std::string& utf8String ) {
Utf8::ToUtf32( utf8String.begin(), utf8String.end(), std::back_inserter( mString ) );
}
-String::String(const char* ansiString, const std::locale& locale)
-{
- if (ansiString)
- {
- std::size_t length = strlen(ansiString);
- if (length > 0)
- {
- mString.reserve(length + 1);
- Utf32::FromAnsi(ansiString, ansiString + length, std::back_inserter(mString), locale);
+String::String( const char* ansiString, const std::locale& locale ) {
+ if ( ansiString ) {
+ std::size_t length = strlen( ansiString );
+ if ( length > 0 ) {
+ mString.reserve( length + 1 );
+ Utf32::FromAnsi( ansiString, ansiString + length, std::back_inserter( mString ),
+ locale );
}
}
}
-String::String(const std::string& ansiString, const std::locale& locale)
-{
- mString.reserve(ansiString.length() + 1);
- Utf32::FromAnsi(ansiString.begin(), ansiString.end(), std::back_inserter(mString), locale);
+String::String( const std::string& ansiString, const std::locale& locale ) {
+ mString.reserve( ansiString.length() + 1 );
+ Utf32::FromAnsi( ansiString.begin(), ansiString.end(), std::back_inserter( mString ), locale );
}
#ifndef EFSW_NO_WIDECHAR
-String::String(const wchar_t* wideString)
-{
- if (wideString)
- {
- std::size_t length = std::wcslen(wideString);
- if (length > 0)
- {
- mString.reserve(length + 1);
- Utf32::FromWide(wideString, wideString + length, std::back_inserter(mString));
+String::String( const wchar_t* wideString ) {
+ if ( wideString ) {
+ std::size_t length = std::wcslen( wideString );
+ if ( length > 0 ) {
+ mString.reserve( length + 1 );
+ Utf32::FromWide( wideString, wideString + length, std::back_inserter( mString ) );
}
}
}
-String::String(const std::wstring& wideString)
-{
- mString.reserve(wideString.length() + 1);
- Utf32::FromWide(wideString.begin(), wideString.end(), std::back_inserter(mString));
+String::String( const std::wstring& wideString ) {
+ mString.reserve( wideString.length() + 1 );
+ Utf32::FromWide( wideString.begin(), wideString.end(), std::back_inserter( mString ) );
}
#endif
-String::String(const StringBaseType* utf32String)
-{
- if (utf32String)
+String::String( const StringBaseType* utf32String ) {
+ if ( utf32String )
mString = utf32String;
}
-String::String(const StringType& utf32String) :
-mString(utf32String)
-{
-}
+String::String( const StringType& utf32String ) : mString( utf32String ) {}
-String::String(const String& str) :
-mString(str.mString)
-{
-}
+String::String( const String& str ) : mString( str.mString ) {}
-String String::fromUtf8( const std::string& utf8String )
-{
+String String::fromUtf8( const std::string& utf8String ) {
String::StringType utf32;
utf32.reserve( utf8String.length() + 1 );
@@ -220,32 +174,29 @@ String String::fromUtf8( const std::string& utf8String )
return String( utf32 );
}
-String::operator std::string() const
-{
+String::operator std::string() const {
return toAnsiString();
}
-std::string String::toAnsiString(const std::locale& locale) const
-{
+std::string String::toAnsiString( const std::locale& locale ) const {
// Prepare the output string
std::string output;
- output.reserve(mString.length() + 1);
+ output.reserve( mString.length() + 1 );
// Convert
- Utf32::ToAnsi(mString.begin(), mString.end(), std::back_inserter(output), 0, locale);
+ Utf32::ToAnsi( mString.begin(), mString.end(), std::back_inserter( output ), 0, locale );
return output;
}
#ifndef EFSW_NO_WIDECHAR
-std::wstring String::toWideString() const
-{
+std::wstring String::toWideString() const {
// Prepare the output string
std::wstring output;
- output.reserve(mString.length() + 1);
+ output.reserve( mString.length() + 1 );
// Convert
- Utf32::ToWide(mString.begin(), mString.end(), std::back_inserter(output), 0);
+ Utf32::ToWide( mString.begin(), mString.end(), std::back_inserter( output ), 0 );
return output;
}
@@ -254,103 +205,85 @@ std::wstring String::toWideString() const
std::string String::toUtf8() const {
// Prepare the output string
std::string output;
- output.reserve(mString.length() + 1);
+ output.reserve( mString.length() + 1 );
// Convert
- Utf32::toUtf8(mString.begin(), mString.end(), std::back_inserter(output) );
+ Utf32::toUtf8( mString.begin(), mString.end(), std::back_inserter( output ) );
return output;
}
-String& String::operator =(const String& right)
-{
+String& String::operator=( const String& right ) {
mString = right.mString;
return *this;
}
-String& String::operator =( const StringBaseType& right )
-{
+String& String::operator=( const StringBaseType& right ) {
mString = right;
return *this;
}
-String& String::operator +=(const String& right)
-{
+String& String::operator+=( const String& right ) {
mString += right.mString;
return *this;
}
-String& String::operator +=( const StringBaseType& right )
-{
+String& String::operator+=( const StringBaseType& right ) {
mString += right;
return *this;
}
-
-String::StringBaseType String::operator [](std::size_t index) const
-{
+String::StringBaseType String::operator[]( std::size_t index ) const {
return mString[index];
}
-String::StringBaseType& String::operator [](std::size_t index)
-{
+String::StringBaseType& String::operator[]( std::size_t index ) {
return mString[index];
}
-String::StringBaseType String::at( std::size_t index ) const
-{
+String::StringBaseType String::at( std::size_t index ) const {
return mString.at( index );
}
-void String::push_back( StringBaseType c )
-{
+void String::push_back( StringBaseType c ) {
mString.push_back( c );
}
-void String::swap ( String& str )
-{
+void String::swap( String& str ) {
mString.swap( str.mString );
}
-void String::clear()
-{
+void String::clear() {
mString.clear();
}
-std::size_t String::size() const
-{
+std::size_t String::size() const {
return mString.size();
}
-std::size_t String::length() const
-{
+std::size_t String::length() const {
return mString.length();
}
-bool String::empty() const
-{
+bool String::empty() const {
return mString.empty();
}
-void String::erase(std::size_t position, std::size_t count)
-{
- mString.erase(position, count);
+void String::erase( std::size_t position, std::size_t count ) {
+ mString.erase( position, count );
}
-String& String::insert(std::size_t position, const String& str)
-{
- mString.insert(position, str.mString);
+String& String::insert( std::size_t position, const String& str ) {
+ mString.insert( position, str.mString );
return *this;
}
-String& String::insert( std::size_t pos1, const String& str, std::size_t pos2, std::size_t n )
-{
+String& String::insert( std::size_t pos1, const String& str, std::size_t pos2, std::size_t n ) {
mString.insert( pos1, str.mString, pos2, n );
return *this;
}
-String& String::insert ( size_t pos1, const char* s, size_t n )
-{
+String& String::insert( size_t pos1, const char* s, size_t n ) {
String tmp( s );
mString.insert( pos1, tmp.data(), n );
@@ -358,14 +291,12 @@ String& String::insert ( size_t pos1, const char* s, size_t n )
return *this;
}
-String& String::insert ( size_t pos1, size_t n, char c )
-{
+String& String::insert( size_t pos1, size_t n, char c ) {
mString.insert( pos1, n, c );
return *this;
}
-String& String::insert ( size_t pos1, const char* s )
-{
+String& String::insert( size_t pos1, const char* s ) {
String tmp( s );
mString.insert( pos1, tmp.data() );
@@ -373,105 +304,85 @@ String& String::insert ( size_t pos1, const char* s )
return *this;
}
-String::Iterator String::insert ( Iterator p, char c )
-{
+String::Iterator String::insert( Iterator p, char c ) {
return mString.insert( p, c );
}
-void String::insert ( Iterator p, size_t n, char c )
-{
+void String::insert( Iterator p, size_t n, char c ) {
mString.insert( p, n, c );
}
-const String::StringBaseType* String::c_str() const
-{
+const String::StringBaseType* String::c_str() const {
return mString.c_str();
}
-const String::StringBaseType* String::data() const
-{
+const String::StringBaseType* String::data() const {
return mString.data();
}
-String::Iterator String::begin()
-{
+String::Iterator String::begin() {
return mString.begin();
}
-String::ConstIterator String::begin() const
-{
+String::ConstIterator String::begin() const {
return mString.begin();
}
-String::Iterator String::end()
-{
+String::Iterator String::end() {
return mString.end();
}
-String::ConstIterator String::end() const
-{
+String::ConstIterator String::end() const {
return mString.end();
}
-String::ReverseIterator String::rbegin()
-{
+String::ReverseIterator String::rbegin() {
return mString.rbegin();
}
-String::ConstReverseIterator String::rbegin() const
-{
+String::ConstReverseIterator String::rbegin() const {
return mString.rbegin();
}
-String::ReverseIterator String::rend()
-{
+String::ReverseIterator String::rend() {
return mString.rend();
}
-String::ConstReverseIterator String::rend() const
-{
+String::ConstReverseIterator String::rend() const {
return mString.rend();
}
-void String::resize( std::size_t n, StringBaseType c )
-{
+void String::resize( std::size_t n, StringBaseType c ) {
mString.resize( n, c );
}
-void String::resize( std::size_t n )
-{
+void String::resize( std::size_t n ) {
mString.resize( n );
}
-std::size_t String::max_size() const
-{
+std::size_t String::max_size() const {
return mString.max_size();
}
-void String::reserve( size_t res_arg )
-{
+void String::reserve( size_t res_arg ) {
mString.reserve( res_arg );
}
-std::size_t String::capacity() const
-{
+std::size_t String::capacity() const {
return mString.capacity();
}
-String& String::assign ( const String& str )
-{
+String& String::assign( const String& str ) {
mString.assign( str.mString );
return *this;
}
-String& String::assign ( const String& str, size_t pos, size_t n )
-{
+String& String::assign( const String& str, size_t pos, size_t n ) {
mString.assign( str.mString, pos, n );
return *this;
}
-String& String::assign ( const char* s, size_t n )
-{
+String& String::assign( const char* s, size_t n ) {
String tmp( s );
mString.assign( tmp.mString );
@@ -479,8 +390,7 @@ String& String::assign ( const char* s, size_t n )
return *this;
}
-String& String::assign ( const char* s )
-{
+String& String::assign( const char* s ) {
String tmp( s );
mString.assign( tmp.mString );
@@ -488,29 +398,25 @@ String& String::assign ( const char* s )
return *this;
}
-String& String::assign ( size_t n, char c )
-{
+String& String::assign( size_t n, char c ) {
mString.assign( n, c );
return *this;
}
-String& String::append ( const String& str )
-{
+String& String::append( const String& str ) {
mString.append( str.mString );
return *this;
}
-String& String::append ( const String& str, size_t pos, size_t n )
-{
+String& String::append( const String& str, size_t pos, size_t n ) {
mString.append( str.mString, pos, n );
return *this;
}
-String& String::append ( const char* s, size_t n )
-{
+String& String::append( const char* s, size_t n ) {
String tmp( s );
mString.append( tmp.mString );
@@ -518,8 +424,7 @@ String& String::append ( const char* s, size_t n )
return *this;
}
-String& String::append ( const char* s )
-{
+String& String::append( const char* s ) {
String tmp( s );
mString.append( tmp.mString );
@@ -527,43 +432,37 @@ String& String::append ( const char* s )
return *this;
}
-String& String::append ( size_t n, char c )
-{
+String& String::append( size_t n, char c ) {
mString.append( n, c );
return *this;
}
-String& String::append ( std::size_t n, StringBaseType c )
-{
+String& String::append( std::size_t n, StringBaseType c ) {
mString.append( n, c );
return *this;
}
-String& String::replace ( size_t pos1, size_t n1, const String& str )
-{
+String& String::replace( size_t pos1, size_t n1, const String& str ) {
mString.replace( pos1, n1, str.mString );
return *this;
}
-String& String::replace ( Iterator i1, Iterator i2, const String& str )
-{
+String& String::replace( Iterator i1, Iterator i2, const String& str ) {
mString.replace( i1, i2, str.mString );
return *this;
}
-String& String::replace ( size_t pos1, size_t n1, const String& str, size_t pos2, size_t n2 )
-{
+String& String::replace( size_t pos1, size_t n1, const String& str, size_t pos2, size_t n2 ) {
mString.replace( pos1, n1, str.mString, pos2, n2 );
return *this;
}
-String& String::replace ( size_t pos1, size_t n1, const char* s, size_t n2 )
-{
+String& String::replace( size_t pos1, size_t n1, const char* s, size_t n2 ) {
String tmp( s );
mString.replace( pos1, n1, tmp.data(), n2 );
@@ -571,8 +470,7 @@ String& String::replace ( size_t pos1, size_t n1, const char* s, size_t n2 )
return *this;
}
-String& String::replace ( Iterator i1, Iterator i2, const char* s, size_t n2 )
-{
+String& String::replace( Iterator i1, Iterator i2, const char* s, size_t n2 ) {
String tmp( s );
mString.replace( i1, i2, tmp.data(), n2 );
@@ -580,8 +478,7 @@ String& String::replace ( Iterator i1, Iterator i2, const char* s, size_t n2 )
return *this;
}
-String& String::replace ( size_t pos1, size_t n1, const char* s )
-{
+String& String::replace( size_t pos1, size_t n1, const char* s ) {
String tmp( s );
mString.replace( pos1, n1, tmp.mString );
@@ -589,8 +486,7 @@ String& String::replace ( size_t pos1, size_t n1, const char* s )
return *this;
}
-String& String::replace ( Iterator i1, Iterator i2, const char* s )
-{
+String& String::replace( Iterator i1, Iterator i2, const char* s ) {
String tmp( s );
mString.replace( i1, i2, tmp.mString );
@@ -598,216 +494,176 @@ String& String::replace ( Iterator i1, Iterator i2, const char* s )
return *this;
}
-String& String::replace ( size_t pos1, size_t n1, size_t n2, char c )
-{
+String& String::replace( size_t pos1, size_t n1, size_t n2, char c ) {
mString.replace( pos1, n1, n2, (StringBaseType)c );
return *this;
}
-String& String::replace ( Iterator i1, Iterator i2, size_t n2, char c )
-{
+String& String::replace( Iterator i1, Iterator i2, size_t n2, char c ) {
mString.replace( i1, i2, n2, (StringBaseType)c );
return *this;
}
-std::size_t String::find( const String& str, std::size_t start ) const
-{
+std::size_t String::find( const String& str, std::size_t start ) const {
return mString.find( str.mString, start );
}
-std::size_t String::find ( const char* s, std::size_t pos, std::size_t n ) const
-{
+std::size_t String::find( const char* s, std::size_t pos, std::size_t n ) const {
return find( String( s ), pos );
}
-std::size_t String::find ( const char* s, std::size_t pos ) const
-{
+std::size_t String::find( const char* s, std::size_t pos ) const {
return find( String( s ), pos );
}
-size_t String::find ( char c, std::size_t pos ) const
-{
+size_t String::find( char c, std::size_t pos ) const {
return mString.find( (StringBaseType)c, pos );
}
-std::size_t String::rfind ( const String& str, std::size_t pos ) const
-{
+std::size_t String::rfind( const String& str, std::size_t pos ) const {
return mString.rfind( str.mString, pos );
}
-std::size_t String::rfind ( const char* s, std::size_t pos, std::size_t n ) const
-{
+std::size_t String::rfind( const char* s, std::size_t pos, std::size_t n ) const {
return rfind( String( s ), pos );
}
-std::size_t String::rfind ( const char* s, std::size_t pos ) const
-{
+std::size_t String::rfind( const char* s, std::size_t pos ) const {
return rfind( String( s ), pos );
}
-std::size_t String::rfind ( char c, std::size_t pos ) const
-{
+std::size_t String::rfind( char c, std::size_t pos ) const {
return mString.rfind( c, pos );
}
-std::size_t String::copy ( StringBaseType* s, std::size_t n, std::size_t pos ) const
-{
+std::size_t String::copy( StringBaseType* s, std::size_t n, std::size_t pos ) const {
return mString.copy( s, n, pos );
}
-String String::substr ( std::size_t pos, std::size_t n ) const
-{
+String String::substr( std::size_t pos, std::size_t n ) const {
return String( mString.substr( pos, n ) );
}
-int String::compare ( const String& str ) const
-{
+int String::compare( const String& str ) const {
return mString.compare( str.mString );
}
-int String::compare ( const char* s ) const
-{
+int String::compare( const char* s ) const {
return compare( String( s ) );
}
-int String::compare ( std::size_t pos1, std::size_t n1, const String& str ) const
-{
+int String::compare( std::size_t pos1, std::size_t n1, const String& str ) const {
return mString.compare( pos1, n1, str.mString );
}
-int String::compare ( std::size_t pos1, std::size_t n1, const char* s) const
-{
+int String::compare( std::size_t pos1, std::size_t n1, const char* s ) const {
return compare( pos1, n1, String( s ) );
}
-int String::compare ( std::size_t pos1, std::size_t n1, const String& str, std::size_t pos2, std::size_t n2 ) const
-{
+int String::compare( std::size_t pos1, std::size_t n1, const String& str, std::size_t pos2,
+ std::size_t n2 ) const {
return mString.compare( pos1, n1, str.mString, pos2, n2 );
}
-int String::compare ( std::size_t pos1, std::size_t n1, const char* s, std::size_t n2) const
-{
+int String::compare( std::size_t pos1, std::size_t n1, const char* s, std::size_t n2 ) const {
return compare( pos1, n1, String( s ), 0, n2 );
}
-std::size_t String::find_first_of ( const String& str, std::size_t pos ) const
-{
+std::size_t String::find_first_of( const String& str, std::size_t pos ) const {
return mString.find_first_of( str.mString, pos );
}
-std::size_t String::find_first_of ( const char* s, std::size_t pos, std::size_t n ) const
-{
+std::size_t String::find_first_of( const char* s, std::size_t pos, std::size_t n ) const {
return find_first_of( String( s ), pos );
}
-std::size_t String::find_first_of ( const char* s, std::size_t pos ) const
-{
+std::size_t String::find_first_of( const char* s, std::size_t pos ) const {
return find_first_of( String( s ), pos );
}
-std::size_t String::find_first_of ( StringBaseType c, std::size_t pos ) const
-{
+std::size_t String::find_first_of( StringBaseType c, std::size_t pos ) const {
return mString.find_first_of( c, pos );
}
-std::size_t String::find_last_of ( const String& str, std::size_t pos ) const
-{
+std::size_t String::find_last_of( const String& str, std::size_t pos ) const {
return mString.find_last_of( str.mString, pos );
}
-std::size_t String::find_last_of ( const char* s, std::size_t pos, std::size_t n ) const
-{
+std::size_t String::find_last_of( const char* s, std::size_t pos, std::size_t n ) const {
return find_last_of( String( s ), pos );
}
-std::size_t String::find_last_of ( const char* s, std::size_t pos ) const
-{
+std::size_t String::find_last_of( const char* s, std::size_t pos ) const {
return find_last_of( String( s ), pos );
}
-std::size_t String::find_last_of ( StringBaseType c, std::size_t pos) const
-{
+std::size_t String::find_last_of( StringBaseType c, std::size_t pos ) const {
return mString.find_last_of( c, pos );
}
-std::size_t String::find_first_not_of ( const String& str, std::size_t pos ) const
-{
+std::size_t String::find_first_not_of( const String& str, std::size_t pos ) const {
return mString.find_first_not_of( str.mString, pos );
}
-std::size_t String::find_first_not_of ( const char* s, std::size_t pos, std::size_t n ) const
-{
+std::size_t String::find_first_not_of( const char* s, std::size_t pos, std::size_t n ) const {
return find_first_not_of( String( s ), pos );
}
-std::size_t String::find_first_not_of ( const char* s, std::size_t pos ) const
-{
+std::size_t String::find_first_not_of( const char* s, std::size_t pos ) const {
return find_first_not_of( String( s ), pos );
}
-std::size_t String::find_first_not_of ( StringBaseType c, std::size_t pos ) const
-{
+std::size_t String::find_first_not_of( StringBaseType c, std::size_t pos ) const {
return mString.find_first_not_of( c, pos );
}
-std::size_t String::find_last_not_of ( const String& str, std::size_t pos ) const
-{
+std::size_t String::find_last_not_of( const String& str, std::size_t pos ) const {
return mString.find_last_not_of( str.mString, pos );
}
-std::size_t String::find_last_not_of ( const char* s, std::size_t pos, std::size_t n ) const
-{
+std::size_t String::find_last_not_of( const char* s, std::size_t pos, std::size_t n ) const {
return find_last_not_of( String( s ), pos );
}
-std::size_t String::find_last_not_of ( const char* s, std::size_t pos ) const
-{
+std::size_t String::find_last_not_of( const char* s, std::size_t pos ) const {
return find_last_not_of( String( s ), pos );
}
-std::size_t String::find_last_not_of ( StringBaseType c, std::size_t pos ) const
-{
+std::size_t String::find_last_not_of( StringBaseType c, std::size_t pos ) const {
return mString.find_last_not_of( c, pos );
}
-bool operator ==(const String& left, const String& right)
-{
+bool operator==( const String& left, const String& right ) {
return left.mString == right.mString;
}
-bool operator !=(const String& left, const String& right)
-{
- return !(left == right);
+bool operator!=( const String& left, const String& right ) {
+ return !( left == right );
}
-bool operator <(const String& left, const String& right)
-{
+bool operator<( const String& left, const String& right ) {
return left.mString < right.mString;
}
-bool operator >(const String& left, const String& right)
-{
+bool operator>( const String& left, const String& right ) {
return right < left;
}
-bool operator <=(const String& left, const String& right)
-{
- return !(right < left);
+bool operator<=( const String& left, const String& right ) {
+ return !( right < left );
}
-bool operator >=(const String& left, const String& right)
-{
- return !(left < right);
+bool operator>=( const String& left, const String& right ) {
+ return !( left < right );
}
-String operator +(const String& left, const String& right)
-{
+String operator+( const String& left, const String& right ) {
String string = left;
string += right;
return string;
}
-}
+} // namespace efsw
diff --git a/dep/efsw/src/efsw/String.hpp b/dep/efsw/src/efsw/String.hpp
index ce7e3b75f89..65bce3328c2 100644
--- a/dep/efsw/src/efsw/String.hpp
+++ b/dep/efsw/src/efsw/String.hpp
@@ -1,39 +1,39 @@
/** NOTE:
-* This code is based on the Utf implementation from SFML2. License zlib/png ( http://www.sfml-dev.org/license.php )
-* The class was modified to fit efsw own needs. This is not the original implementation from SFML2.
-* Functions and methods are the same that in std::string to facilitate portability.
-**/
+ * This code is based on the Utf implementation from SFML2. License zlib/png (
+ *http://www.sfml-dev.org/license.php ) The class was modified to fit efsw own needs. This is not
+ *the original implementation from SFML2. Functions and methods are the same that in std::string to
+ *facilitate portability.
+ **/
#ifndef EFSW_STRING_HPP
#define EFSW_STRING_HPP
-#include <efsw/base.hpp>
-#include <locale>
-#include <string>
-#include <cstring>
#include <cstdlib>
-#include <iostream>
+#include <cstring>
+#include <efsw/base.hpp>
#include <fstream>
+#include <iostream>
+#include <locale>
#include <sstream>
+#include <string>
#include <vector>
namespace efsw {
-/** @brief Utility string class that automatically handles conversions between types and encodings **/
-class String
-{
- public :
- typedef Uint32 StringBaseType;
- typedef std::basic_string<StringBaseType> StringType;
- typedef StringType::iterator Iterator; //! Iterator type
- typedef StringType::const_iterator ConstIterator; //! Constant iterator type
- typedef StringType::reverse_iterator ReverseIterator; //! Reverse Iterator type
- typedef StringType::const_reverse_iterator ConstReverseIterator; //! Constant iterator type
+/** @brief Utility string class that automatically handles conversions between types and encodings
+ * **/
+class String {
+ public:
+ typedef Uint32 StringBaseType;
+ typedef std::basic_string<StringBaseType> StringType;
+ typedef StringType::iterator Iterator; //! Iterator type
+ typedef StringType::const_iterator ConstIterator; //! Constant iterator type
+ typedef StringType::reverse_iterator ReverseIterator; //! Reverse Iterator type
+ typedef StringType::const_reverse_iterator ConstReverseIterator; //! Constant iterator type
static const std::size_t InvalidPos; ///< Represents an invalid position in the string
- template <class T>
- static std::string toStr(const T& i) {
+ template <class T> static std::string toStr( const T& i ) {
std::ostringstream ss;
ss << i;
return ss.str();
@@ -41,23 +41,27 @@ class String
/** Converts from a string to type */
template <class T>
- static bool fromString(T& t, const std::string& s, std::ios_base& (*f)(std::ios_base&) = std::dec ) {
- std::istringstream iss(s);
- return !(iss >> f >> t).fail();
+ static bool fromString( T& t, const std::string& s,
+ std::ios_base& ( *f )( std::ios_base& ) = std::dec ) {
+ std::istringstream iss( s );
+ return !( iss >> f >> t ).fail();
}
/** Converts from a String to type */
template <class T>
- static bool fromString(T& t, const String& s, std::ios_base& (*f)(std::ios_base&) = std::dec ) {
+ static bool fromString( T& t, const String& s,
+ std::ios_base& ( *f )( std::ios_base& ) = std::dec ) {
std::istringstream iss( s.toUtf8() );
- return !(iss >> f >> t).fail();
+ return !( iss >> f >> t ).fail();
}
/** Split a string and hold it on a vector */
- static std::vector < std::string > split( const std::string& str, const char& splitchar, const bool& pushEmptyString = false );
+ static std::vector<std::string> split( const std::string& str, const char& splitchar,
+ const bool& pushEmptyString = false );
/** Split a string and hold it on a vector */
- static std::vector < String > split( const String& str, const Uint32& splitchar, const bool& pushEmptyString = false );
+ static std::vector<String> split( const String& str, const Uint32& splitchar,
+ const bool& pushEmptyString = false );
/** Determine if a string starts with the string passed
** @param start The substring expected to start
@@ -149,7 +153,6 @@ class String
**/
String( const StringType& utf32String );
-
/** @brief Copy constructor
** @param str Instance to copy
**/
@@ -196,17 +199,17 @@ class String
** @param right Instance to assign
** @return Reference to self
**/
- String& operator =(const String& right);
+ String& operator=( const String& right );
- String& operator =( const StringBaseType& right );
+ String& operator=( const StringBaseType& right );
/** @brief Overload of += operator to append an UTF-32 string
** @param right String to append
** @return Reference to self
**/
- String& operator +=(const String& right);
+ String& operator+=( const String& right );
- String& operator +=( const StringBaseType& right );
+ String& operator+=( const StringBaseType& right );
/** @brief Overload of [] operator to access a character by its position
** This function provides read-only access to characters.
@@ -214,7 +217,7 @@ class String
** @param index Index of the character to get
** @return Character at position \a index
**/
- StringBaseType operator [](std::size_t index) const;
+ StringBaseType operator[]( std::size_t index ) const;
/** @brief Overload of [] operator to access a character by its position
** This function provides read and write access to characters.
@@ -223,14 +226,15 @@ class String
** @return Reference to the character at position \a index
**/
- StringBaseType& operator [](std::size_t index);
+ StringBaseType& operator[]( std::size_t index );
/** @brief Get character in string
- ** Performs a range check, throwing an exception of type out_of_range in case that pos is not an actual position in the string.
+ ** Performs a range check, throwing an exception of type out_of_range in case that pos is not an
+ *actual position in the string.
** @return The character at position pos in the string.
*/
StringBaseType at( std::size_t index ) const;
-
+
/** @brief clear the string
** This function removes all the characters from the string.
** @see empty, erase
@@ -242,7 +246,7 @@ class String
** @see empty
**/
std::size_t size() const;
-
+
/** @see size() */
std::size_t length() const;
@@ -258,8 +262,7 @@ class String
** @param position Position of the first character to erase
** @param count Number of characters to erase
**/
- void erase(std::size_t position, std::size_t count = 1);
-
+ void erase( std::size_t position, std::size_t count = 1 );
/** @brief Insert one or more characters into the string
** This function inserts the characters of \a str
@@ -267,23 +270,22 @@ class String
** @param position Position of insertion
** @param str Characters to insert
**/
- String& insert(std::size_t position, const String& str);
+ String& insert( std::size_t position, const String& str );
String& insert( std::size_t pos1, const String& str, std::size_t pos2, std::size_t n );
- String& insert ( std::size_t pos1, const char* s, std::size_t n );
+ String& insert( std::size_t pos1, const char* s, std::size_t n );
- String& insert ( std::size_t pos1, const char* s );
+ String& insert( std::size_t pos1, const char* s );
- String& insert ( std::size_t pos1, size_t n, char c );
+ String& insert( std::size_t pos1, size_t n, char c );
- Iterator insert ( Iterator p, char c );
+ Iterator insert( Iterator p, char c );
- void insert ( Iterator p, std::size_t n, char c );
+ void insert( Iterator p, std::size_t n, char c );
- template<class InputIterator>
- void insert ( Iterator p, InputIterator first, InputIterator last )
- {
+ template <class InputIterator>
+ void insert( Iterator p, InputIterator first, InputIterator last ) {
mString.insert( p, first, last );
}
@@ -296,11 +298,11 @@ class String
**/
std::size_t find( const String& str, std::size_t start = 0 ) const;
- std::size_t find ( const char* s, std::size_t pos, std::size_t n ) const;
+ std::size_t find( const char* s, std::size_t pos, std::size_t n ) const;
- std::size_t find ( const char* s, std::size_t pos = 0 ) const;
+ std::size_t find( const char* s, std::size_t pos = 0 ) const;
- std::size_t find ( char c, std::size_t pos = 0 ) const;
+ std::size_t find( char c, std::size_t pos = 0 ) const;
/** @brief Get a pointer to the C-style array of characters
** This functions provides a read-only access to a
@@ -310,11 +312,14 @@ class String
** @return Read-only pointer to the array of characters
**/
const StringBaseType* c_str() const;
-
+
/** @brief Get string data
- ** Notice that no terminating null character is appended (see member c_str for such a functionality).
- ** The returned array points to an internal location which should not be modified directly in the program.
- ** Its contents are guaranteed to remain unchanged only until the next call to a non-constant member function of the string object.
+ ** Notice that no terminating null character is appended (see member c_str for such a
+ *functionality).
+ ** The returned array points to an internal location which should not be modified directly in
+ *the program.
+ ** Its contents are guaranteed to remain unchanged only until the next call to a non-constant
+ *member function of the string object.
** @return Pointer to an internal array containing the same content as the string.
**/
const StringBaseType* data() const;
@@ -348,7 +353,7 @@ class String
** @see begin
**/
ConstIterator end() const;
-
+
/** @brief Return an reverse iterator to the beginning of the string
** @return Read-write reverse iterator to the beginning of the string characters
** @see end
@@ -370,7 +375,6 @@ class String
**/
ReverseIterator rend();
-
/** @brief Return an reverse iterator to the beginning of the string
** The end reverse iterator refers to 1 position past the last character;
** thus it represents an invalid character and should never be
@@ -379,147 +383,145 @@ class String
** @see begin
**/
ConstReverseIterator rend() const;
-
+
/** @brief Resize String */
- void resize ( std::size_t n, StringBaseType c );
-
+ void resize( std::size_t n, StringBaseType c );
+
/** @brief Resize String */
- void resize ( std::size_t n );
-
+ void resize( std::size_t n );
+
/** @return Maximum size of string */
std::size_t max_size() const;
-
+
/** @brief Request a change in capacity */
- void reserve ( size_t res_arg=0 );
-
+ void reserve( size_t res_arg = 0 );
+
/** @return Size of allocated storage */
std::size_t capacity() const;
/** @brief Append character to string */
void push_back( StringBaseType c );
-
+
/** @brief Swap contents with another string */
- void swap ( String& str );
-
- String& assign ( const String& str );
+ void swap( String& str );
- String& assign ( const String& str, std::size_t pos, std::size_t n );
+ String& assign( const String& str );
- String& assign ( const char* s, std::size_t n );
+ String& assign( const String& str, std::size_t pos, std::size_t n );
- String& assign ( const char* s );
+ String& assign( const char* s, std::size_t n );
- String& assign ( std::size_t n, char c );
+ String& assign( const char* s );
- template <class InputIterator>
- String& assign ( InputIterator first, InputIterator last )
- {
+ String& assign( std::size_t n, char c );
+
+ template <class InputIterator> String& assign( InputIterator first, InputIterator last ) {
mString.assign( first, last );
return *this;
}
- String& append ( const String& str );
+ String& append( const String& str );
- String& append ( const String& str, std::size_t pos, std::size_t n );
+ String& append( const String& str, std::size_t pos, std::size_t n );
- String& append ( const char* s, std::size_t n );
+ String& append( const char* s, std::size_t n );
- String& append ( const char* s );
+ String& append( const char* s );
- String& append ( std::size_t n, char c );
+ String& append( std::size_t n, char c );
- String& append ( std::size_t n, StringBaseType c );
+ String& append( std::size_t n, StringBaseType c );
- template <class InputIterator>
- String& append ( InputIterator first, InputIterator last )
- {
+ template <class InputIterator> String& append( InputIterator first, InputIterator last ) {
mString.append( first, last );
return *this;
}
- String& replace ( std::size_t pos1, std::size_t n1, const String& str );
+ String& replace( std::size_t pos1, std::size_t n1, const String& str );
- String& replace ( Iterator i1, Iterator i2, const String& str );
+ String& replace( Iterator i1, Iterator i2, const String& str );
- String& replace ( std::size_t pos1, std::size_t n1, const String& str, std::size_t pos2, std::size_t n2 );
+ String& replace( std::size_t pos1, std::size_t n1, const String& str, std::size_t pos2,
+ std::size_t n2 );
- String& replace ( std::size_t pos1, std::size_t n1, const char* s, std::size_t n2 );
+ String& replace( std::size_t pos1, std::size_t n1, const char* s, std::size_t n2 );
- String& replace ( Iterator i1, Iterator i2, const char* s, std::size_t n2 );
+ String& replace( Iterator i1, Iterator i2, const char* s, std::size_t n2 );
- String& replace ( std::size_t pos1, std::size_t n1, const char* s );
+ String& replace( std::size_t pos1, std::size_t n1, const char* s );
- String& replace ( Iterator i1, Iterator i2, const char* s );
+ String& replace( Iterator i1, Iterator i2, const char* s );
- String& replace ( std::size_t pos1, std::size_t n1, std::size_t n2, char c );
+ String& replace( std::size_t pos1, std::size_t n1, std::size_t n2, char c );
- String& replace ( Iterator i1, Iterator i2, std::size_t n2, char c );
+ String& replace( Iterator i1, Iterator i2, std::size_t n2, char c );
- template<class InputIterator>
- String& replace ( Iterator i1, Iterator i2, InputIterator j1, InputIterator j2 )
- {
+ template <class InputIterator>
+ String& replace( Iterator i1, Iterator i2, InputIterator j1, InputIterator j2 ) {
mString.replace( i1, i2, j1, j2 );
return *this;
}
- std::size_t rfind ( const String& str, std::size_t pos = StringType::npos ) const;
+ std::size_t rfind( const String& str, std::size_t pos = StringType::npos ) const;
+
+ std::size_t rfind( const char* s, std::size_t pos, std::size_t n ) const;
- std::size_t rfind ( const char* s, std::size_t pos, std::size_t n ) const;
+ std::size_t rfind( const char* s, std::size_t pos = StringType::npos ) const;
- std::size_t rfind ( const char* s, std::size_t pos = StringType::npos ) const;
+ std::size_t rfind( char c, std::size_t pos = StringType::npos ) const;
- std::size_t rfind ( char c, std::size_t pos = StringType::npos ) const;
+ String substr( std::size_t pos = 0, std::size_t n = StringType::npos ) const;
- String substr ( std::size_t pos = 0, std::size_t n = StringType::npos ) const;
+ std::size_t copy( StringBaseType* s, std::size_t n, std::size_t pos = 0 ) const;
- std::size_t copy ( StringBaseType* s, std::size_t n, std::size_t pos = 0 ) const;
+ int compare( const String& str ) const;
- int compare ( const String& str ) const;
+ int compare( const char* s ) const;
- int compare ( const char* s ) const;
+ int compare( std::size_t pos1, std::size_t n1, const String& str ) const;
- int compare ( std::size_t pos1, std::size_t n1, const String& str ) const;
+ int compare( std::size_t pos1, std::size_t n1, const char* s ) const;
- int compare ( std::size_t pos1, std::size_t n1, const char* s) const;
+ int compare( std::size_t pos1, std::size_t n1, const String& str, std::size_t pos2,
+ std::size_t n2 ) const;
- int compare ( std::size_t pos1, std::size_t n1, const String& str, std::size_t pos2, std::size_t n2 ) const;
+ int compare( std::size_t pos1, std::size_t n1, const char* s, std::size_t n2 ) const;
- int compare ( std::size_t pos1, std::size_t n1, const char* s, std::size_t n2) const;
+ std::size_t find_first_of( const String& str, std::size_t pos = 0 ) const;
- std::size_t find_first_of ( const String& str, std::size_t pos = 0 ) const;
+ std::size_t find_first_of( const char* s, std::size_t pos, std::size_t n ) const;
- std::size_t find_first_of ( const char* s, std::size_t pos, std::size_t n ) const;
+ std::size_t find_first_of( const char* s, std::size_t pos = 0 ) const;
- std::size_t find_first_of ( const char* s, std::size_t pos = 0 ) const;
+ std::size_t find_first_of( StringBaseType c, std::size_t pos = 0 ) const;
- std::size_t find_first_of ( StringBaseType c, std::size_t pos = 0 ) const;
+ std::size_t find_last_of( const String& str, std::size_t pos = StringType::npos ) const;
- std::size_t find_last_of ( const String& str, std::size_t pos = StringType::npos ) const;
+ std::size_t find_last_of( const char* s, std::size_t pos, std::size_t n ) const;
- std::size_t find_last_of ( const char* s, std::size_t pos, std::size_t n ) const;
+ std::size_t find_last_of( const char* s, std::size_t pos = StringType::npos ) const;
- std::size_t find_last_of ( const char* s, std::size_t pos = StringType::npos ) const;
+ std::size_t find_last_of( StringBaseType c, std::size_t pos = StringType::npos ) const;
- std::size_t find_last_of ( StringBaseType c, std::size_t pos = StringType::npos ) const;
+ std::size_t find_first_not_of( const String& str, std::size_t pos = 0 ) const;
- std::size_t find_first_not_of ( const String& str, std::size_t pos = 0 ) const;
+ std::size_t find_first_not_of( const char* s, std::size_t pos, std::size_t n ) const;
- std::size_t find_first_not_of ( const char* s, std::size_t pos, std::size_t n ) const;
+ std::size_t find_first_not_of( const char* s, std::size_t pos = 0 ) const;
- std::size_t find_first_not_of ( const char* s, std::size_t pos = 0 ) const;
+ std::size_t find_first_not_of( StringBaseType c, std::size_t pos = 0 ) const;
- std::size_t find_first_not_of ( StringBaseType c, std::size_t pos = 0 ) const;
+ std::size_t find_last_not_of( const String& str, std::size_t pos = StringType::npos ) const;
- std::size_t find_last_not_of ( const String& str, std::size_t pos = StringType::npos ) const;
+ std::size_t find_last_not_of( const char* s, std::size_t pos, std::size_t n ) const;
- std::size_t find_last_not_of ( const char* s, std::size_t pos, std::size_t n ) const;
+ std::size_t find_last_not_of( const char* s, std::size_t pos = StringType::npos ) const;
- std::size_t find_last_not_of ( const char* s, std::size_t pos = StringType::npos ) const;
+ std::size_t find_last_not_of( StringBaseType c, std::size_t pos = StringType::npos ) const;
- std::size_t find_last_not_of ( StringBaseType c, std::size_t pos = StringType::npos ) const;
-private :
- friend bool operator ==(const String& left, const String& right);
- friend bool operator <(const String& left, const String& right);
+ private:
+ friend bool operator==( const String& left, const String& right );
+ friend bool operator<( const String& left, const String& right );
StringType mString; ///< Internal string of UTF-32 characters
};
@@ -530,7 +532,7 @@ private :
** @param right Right operand (a string)
** @return True if both strings are equal
**/
- bool operator ==(const String& left, const String& right);
+bool operator==( const String& left, const String& right );
/** @relates String
** @brief Overload of != operator to compare two UTF-32 strings
@@ -538,7 +540,7 @@ private :
** @param right Right operand (a string)
** @return True if both strings are different
**/
- bool operator !=(const String& left, const String& right);
+bool operator!=( const String& left, const String& right );
/** @relates String
** @brief Overload of < operator to compare two UTF-32 strings
@@ -546,7 +548,7 @@ private :
** @param right Right operand (a string)
** @return True if \a left is alphabetically lesser than \a right
**/
- bool operator <(const String& left, const String& right);
+bool operator<( const String& left, const String& right );
/** @relates String
** @brief Overload of > operator to compare two UTF-32 strings
@@ -554,7 +556,7 @@ private :
** @param right Right operand (a string)
** @return True if \a left is alphabetically greater than \a right
**/
- bool operator >(const String& left, const String& right);
+bool operator>( const String& left, const String& right );
/** @relates String
** @brief Overload of <= operator to compare two UTF-32 strings
@@ -562,7 +564,7 @@ private :
** @param right Right operand (a string)
** @return True if \a left is alphabetically lesser or equal than \a right
**/
- bool operator <=(const String& left, const String& right);
+bool operator<=( const String& left, const String& right );
/** @relates String
** @brief Overload of >= operator to compare two UTF-32 strings
@@ -570,7 +572,7 @@ private :
** @param right Right operand (a string)
** @return True if \a left is alphabetically greater or equal than \a right
**/
- bool operator >=(const String& left, const String& right);
+bool operator>=( const String& left, const String& right );
/** @relates String
** @brief Overload of binary + operator to concatenate two strings
@@ -578,9 +580,9 @@ private :
** @param right Right operand (a string)
** @return Concatenated string
**/
- String operator +( const String& left, const String& right );
+String operator+( const String& left, const String& right );
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/System.cpp b/dep/efsw/src/efsw/System.cpp
index f8767cbc58f..ba68bf4a74f 100644
--- a/dep/efsw/src/efsw/System.cpp
+++ b/dep/efsw/src/efsw/System.cpp
@@ -3,24 +3,20 @@
namespace efsw {
-void System::sleep( const unsigned long& ms )
-{
+void System::sleep( const unsigned long& ms ) {
Platform::System::sleep( ms );
}
-std::string System::getProcessPath()
-{
+std::string System::getProcessPath() {
return Platform::System::getProcessPath();
}
-void System::maxFD()
-{
+void System::maxFD() {
Platform::System::maxFD();
}
-Uint64 System::getMaxFD()
-{
+Uint64 System::getMaxFD() {
return Platform::System::getMaxFD();
}
-}
+} // namespace efsw
diff --git a/dep/efsw/src/efsw/System.hpp b/dep/efsw/src/efsw/System.hpp
index 1d6f4a70f91..498e1211531 100644
--- a/dep/efsw/src/efsw/System.hpp
+++ b/dep/efsw/src/efsw/System.hpp
@@ -5,22 +5,21 @@
namespace efsw {
-class System
-{
- public:
- /// Sleep for x milliseconds
- static void sleep( const unsigned long& ms );
+class System {
+ public:
+ /// Sleep for x milliseconds
+ static void sleep( const unsigned long& ms );
- /// @return The process binary path
- static std::string getProcessPath();
+ /// @return The process binary path
+ static std::string getProcessPath();
- /// Maximize the number of file descriptors allowed per process in the current OS
- static void maxFD();
+ /// Maximize the number of file descriptors allowed per process in the current OS
+ static void maxFD();
- /// @return The number of supported file descriptors for the process
- static Uint64 getMaxFD();
+ /// @return The number of supported file descriptors for the process
+ static Uint64 getMaxFD();
};
-
-}
+
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/Thread.cpp b/dep/efsw/src/efsw/Thread.cpp
index fff41517dc1..cfa88b482d3 100644
--- a/dep/efsw/src/efsw/Thread.cpp
+++ b/dep/efsw/src/efsw/Thread.cpp
@@ -3,49 +3,39 @@
namespace efsw {
-Thread::Thread() :
- mThreadImpl(NULL),
- mEntryPoint(NULL)
-{
-}
+Thread::Thread() : mThreadImpl( NULL ), mEntryPoint( NULL ) {}
-Thread::~Thread()
-{
+Thread::~Thread() {
wait();
efSAFE_DELETE( mEntryPoint );
}
-void Thread::launch()
-{
+void Thread::launch() {
wait();
mThreadImpl = new Platform::ThreadImpl( this );
}
-void Thread::wait()
-{
- if ( mThreadImpl )
- {
+void Thread::wait() {
+ if ( mThreadImpl ) {
mThreadImpl->wait();
efSAFE_DELETE( mThreadImpl );
}
}
-void Thread::terminate()
-{
- if ( mThreadImpl )
- {
+void Thread::terminate() {
+ if ( mThreadImpl ) {
mThreadImpl->terminate();
efSAFE_DELETE( mThreadImpl );
}
}
-void Thread::run()
-{
- mEntryPoint->run();
+void Thread::run() {
+ if ( mEntryPoint )
+ mEntryPoint->run();
}
-}
+} // namespace efsw
diff --git a/dep/efsw/src/efsw/Thread.hpp b/dep/efsw/src/efsw/Thread.hpp
index c7da9e8b33c..b60373c2075 100644
--- a/dep/efsw/src/efsw/Thread.hpp
+++ b/dep/efsw/src/efsw/Thread.hpp
@@ -5,107 +5,96 @@
namespace efsw {
-namespace Platform { class ThreadImpl; }
-namespace Private { struct ThreadFunc; }
+namespace Platform {
+class ThreadImpl;
+}
+namespace Private {
+struct ThreadFunc;
+}
/** @brief Thread manager class */
class Thread {
- public:
- typedef void (*FuncType)(void*);
+ public:
+ typedef void ( *FuncType )( void* );
- template <typename F>
- Thread( F function );
+ template <typename F> Thread( F function );
- template <typename F, typename A>
- Thread( F function, A argument );
+ template <typename F, typename A> Thread( F function, A argument );
- template <typename C>
- Thread( void(C::*function)(), C* object );
+ template <typename C> Thread( void ( C::*function )(), C* object );
- virtual ~Thread();
+ virtual ~Thread();
- /** Launch the thread */
- virtual void launch();
+ /** Launch the thread */
+ virtual void launch();
- /** Wait the thread until end */
- void wait();
+ /** Wait the thread until end */
+ void wait();
- /** Terminate the thread */
- void terminate();
- protected:
- Thread();
- private:
- friend class Platform::ThreadImpl;
+ /** Terminate the thread */
+ void terminate();
- /** The virtual function to run in the thread */
- virtual void run();
+ protected:
+ Thread();
- Platform::ThreadImpl * mThreadImpl; ///< OS-specific implementation of the thread
- Private::ThreadFunc * mEntryPoint; ///< Abstraction of the function to run
+ private:
+ friend class Platform::ThreadImpl;
+
+ /** The virtual function to run in the thread */
+ virtual void run();
+
+ Platform::ThreadImpl* mThreadImpl; ///< OS-specific implementation of the thread
+ Private::ThreadFunc* mEntryPoint; ///< Abstraction of the function to run
};
//! NOTE: Taken from SFML2 threads
namespace Private {
// Base class for abstract thread functions
-struct ThreadFunc
-{
+struct ThreadFunc {
virtual ~ThreadFunc() {}
virtual void run() = 0;
};
// Specialization using a functor (including free functions) with no argument
-template <typename T>
-struct ThreadFunctor : ThreadFunc
-{
- ThreadFunctor(T functor) : m_functor(functor) {}
- virtual void run() {m_functor();}
+template <typename T> struct ThreadFunctor : ThreadFunc {
+ ThreadFunctor( T functor ) : m_functor( functor ) {}
+ virtual void run() { m_functor(); }
T m_functor;
};
// Specialization using a functor (including free functions) with one argument
-template <typename F, typename A>
-struct ThreadFunctorWithArg : ThreadFunc
-{
- ThreadFunctorWithArg(F function, A arg) : m_function(function), m_arg(arg) {}
- virtual void run() {m_function(m_arg);}
+template <typename F, typename A> struct ThreadFunctorWithArg : ThreadFunc {
+ ThreadFunctorWithArg( F function, A arg ) : m_function( function ), m_arg( arg ) {}
+ virtual void run() { m_function( m_arg ); }
F m_function;
A m_arg;
};
// Specialization using a member function
-template <typename C>
-struct ThreadMemberFunc : ThreadFunc
-{
- ThreadMemberFunc(void(C::*function)(), C* object) : m_function(function), m_object(object) {}
- virtual void run() {(m_object->*m_function)();}
- void(C::*m_function)();
+template <typename C> struct ThreadMemberFunc : ThreadFunc {
+ ThreadMemberFunc( void ( C::*function )(), C* object ) :
+ m_function( function ), m_object( object ) {}
+ virtual void run() { ( m_object->*m_function )(); }
+ void ( C::*m_function )();
C* m_object;
};
-}
+} // namespace Private
template <typename F>
-Thread::Thread(F functor) :
- mThreadImpl (NULL),
- mEntryPoint( new Private::ThreadFunctor<F>(functor) )
-{
-}
+Thread::Thread( F functor ) :
+ mThreadImpl( NULL ), mEntryPoint( new Private::ThreadFunctor<F>( functor ) ) {}
template <typename F, typename A>
-Thread::Thread(F function, A argument) :
- mThreadImpl(NULL),
- mEntryPoint( new Private::ThreadFunctorWithArg<F efCOMMA A>(function, argument) )
-{
-}
+Thread::Thread( F function, A argument ) :
+ mThreadImpl( NULL ),
+ mEntryPoint( new Private::ThreadFunctorWithArg<F efCOMMA A>( function, argument ) ) {}
template <typename C>
-Thread::Thread(void(C::*function)(), C* object) :
- mThreadImpl(NULL),
- mEntryPoint( new Private::ThreadMemberFunc<C>(function, object) )
-{
-}
+Thread::Thread( void ( C::*function )(), C* object ) :
+ mThreadImpl( NULL ), mEntryPoint( new Private::ThreadMemberFunc<C>( function, object ) ) {}
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/Utf.hpp b/dep/efsw/src/efsw/Utf.hpp
index 925a7cc149b..6e9ea719d01 100644
--- a/dep/efsw/src/efsw/Utf.hpp
+++ b/dep/efsw/src/efsw/Utf.hpp
@@ -1,7 +1,8 @@
/** NOTE:
-* This code is based on the Utf implementation from SFML2. License zlib/png ( http://www.sfml-dev.org/license.php )
-* The class was modified to fit efsw own needs. This is not the original implementation from SFML2.
-* */
+ * This code is based on the Utf implementation from SFML2. License zlib/png (
+ *http://www.sfml-dev.org/license.php ) The class was modified to fit efsw own needs. This is not
+ *the original implementation from SFML2.
+ * */
#ifndef EFSW_UTF_HPP
#define EFSW_UTF_HPP
@@ -9,721 +10,693 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
-#include <locale>
-#include <string>
#include <cstdlib>
#include <efsw/base.hpp>
+#include <locale>
+#include <string>
namespace efsw {
-template <unsigned int N>
-class Utf;
+template <unsigned int N> class Utf;
////////////////////////////////////////////////////////////
/// \brief Specialization of the Utf template for UTF-8
///
////////////////////////////////////////////////////////////
-template <>
-class Utf<8> {
-public :
- ////////////////////////////////////////////////////////////
- /// \brief Decode a single UTF-8 character
- ///
- /// Decoding a character means finding its unique 32-bits
- /// code (called the codepoint) in the Unicode standard.
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Codepoint of the decoded UTF-8 character
- /// \param replacement Replacement character to use in case the UTF-8 sequence is invalid
- ///
- /// \return Iterator pointing to one past the last read element of the input sequence
- ///
- ////////////////////////////////////////////////////////////
- template <typename In>
- static In Decode(In begin, In end, Uint32& output, Uint32 replacement = 0);
-
- ////////////////////////////////////////////////////////////
- /// \brief Encode a single UTF-8 character
- ///
- /// Encoding a character means converting a unique 32-bits
- /// code (called the codepoint) in the target encoding, UTF-8.
- ///
- /// \param input Codepoint to encode as UTF-8
- /// \param output Iterator pointing to the beginning of the output sequence
- /// \param replacement Replacement for characters not convertible to UTF-8 (use 0 to skip them)
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename Out>
- static Out Encode(Uint32 input, Out output, Uint8 replacement = 0);
-
- ////////////////////////////////////////////////////////////
- /// \brief Advance to the next UTF-8 character
- ///
- /// This function is necessary for multi-elements encodings, as
- /// a single character may use more than 1 storage element.
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- ///
- /// \return Iterator pointing to one past the last read element of the input sequence
- ///
- ////////////////////////////////////////////////////////////
- template <typename In>
- static In Next(In begin, In end);
-
- ////////////////////////////////////////////////////////////
- /// \brief Count the number of characters of a UTF-8 sequence
- ///
- /// This function is necessary for multi-elements encodings, as
- /// a single character may use more than 1 storage element, thus the
- /// total size can be different from (begin - end).
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- ///
- /// \return Iterator pointing to one past the last read element of the input sequence
- ///
- ////////////////////////////////////////////////////////////
- template <typename In>
- static std::size_t Count(In begin, In end);
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert an ANSI characters range to UTF-8
- ///
- /// The current global locale will be used by default, unless you
- /// pass a custom one in the \a locale parameter.
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- /// \param locale Locale to use for conversion
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out FromAnsi(In begin, In end, Out output, const std::locale& locale = std::locale());
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert a wide characters range to UTF-8
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out FromWide(In begin, In end, Out output);
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-8
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- /// \param locale Locale to use for conversion
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out FromLatin1(In begin, In end, Out output);
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert an UTF-8 characters range to ANSI characters
- ///
- /// The current global locale will be used by default, unless you
- /// pass a custom one in the \a locale parameter.
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- /// \param replacement Replacement for characters not convertible to ANSI (use 0 to skip them)
- /// \param locale Locale to use for conversion
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out ToAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = std::locale());
+template <> class Utf<8> {
+ public:
+ ////////////////////////////////////////////////////////////
+ /// \brief Decode a single UTF-8 character
+ ///
+ /// Decoding a character means finding its unique 32-bits
+ /// code (called the codepoint) in the Unicode standard.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Codepoint of the decoded UTF-8 character
+ /// \param replacement Replacement character to use in case the UTF-8 sequence is invalid
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static In Decode( In begin, In end, Uint32& output, Uint32 replacement = 0 );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Encode a single UTF-8 character
+ ///
+ /// Encoding a character means converting a unique 32-bits
+ /// code (called the codepoint) in the target encoding, UTF-8.
+ ///
+ /// \param input Codepoint to encode as UTF-8
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to UTF-8 (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename Out> static Out Encode( Uint32 input, Out output, Uint8 replacement = 0 );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Advance to the next UTF-8 character
+ ///
+ /// This function is necessary for multi-elements encodings, as
+ /// a single character may use more than 1 storage element.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In> static In Next( In begin, In end );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Count the number of characters of a UTF-8 sequence
+ ///
+ /// This function is necessary for multi-elements encodings, as
+ /// a single character may use more than 1 storage element, thus the
+ /// total size can be different from (begin - end).
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In> static std::size_t Count( In begin, In end );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an ANSI characters range to UTF-8
+ ///
+ /// The current global locale will be used by default, unless you
+ /// pass a custom one in the \a locale parameter.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromAnsi( In begin, In end, Out output, const std::locale& locale = std::locale() );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a wide characters range to UTF-8
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out> static Out FromWide( In begin, In end, Out output );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-8
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out> static Out FromLatin1( In begin, In end, Out output );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-8 characters range to ANSI characters
+ ///
+ /// The current global locale will be used by default, unless you
+ /// pass a custom one in the \a locale parameter.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to ANSI (use 0 to skip them)
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToAnsi( In begin, In end, Out output, char replacement = 0,
+ const std::locale& locale = std::locale() );
#ifndef EFSW_NO_WIDECHAR
- ////////////////////////////////////////////////////////////
- /// \brief Convert an UTF-8 characters range to wide characters
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out ToWide(In begin, In end, Out output, wchar_t replacement = 0);
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-8 characters range to wide characters
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToWide( In begin, In end, Out output, wchar_t replacement = 0 );
#endif
- ////////////////////////////////////////////////////////////
- /// \brief Convert an UTF-8 characters range to latin-1 (ISO-5589-1) characters
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out ToLatin1(In begin, In end, Out output, char replacement = 0);
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert a UTF-8 characters range to UTF-8
- ///
- /// This functions does nothing more than a direct copy;
- /// it is defined only to provide the same interface as other
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-8 characters range to latin-1 (ISO-5589-1) characters
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToLatin1( In begin, In end, Out output, char replacement = 0 );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-8 characters range to UTF-8
+ ///
+ /// This functions does nothing more than a direct copy;
+ /// it is defined only to provide the same interface as other
/// specializations of the efsw::Utf<> template, and allow
- /// generic code to be written on top of it.
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out toUtf8(In begin, In end, Out output);
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert a UTF-8 characters range to UTF-16
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out ToUtf16(In begin, In end, Out output);
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert a UTF-8 characters range to UTF-32
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out ToUtf32(In begin, In end, Out output);
+ /// generic code to be written on top of it.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out> static Out toUtf8( In begin, In end, Out output );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-8 characters range to UTF-16
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out> static Out ToUtf16( In begin, In end, Out output );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-8 characters range to UTF-32
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out> static Out ToUtf32( In begin, In end, Out output );
};
////////////////////////////////////////////////////////////
/// \brief Specialization of the Utf template for UTF-16
///
////////////////////////////////////////////////////////////
-template <>
-class Utf<16>
-{
-public :
-
- ////////////////////////////////////////////////////////////
- /// \brief Decode a single UTF-16 character
- ///
- /// Decoding a character means finding its unique 32-bits
- /// code (called the codepoint) in the Unicode standard.
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Codepoint of the decoded UTF-16 character
- /// \param replacement Replacement character to use in case the UTF-8 sequence is invalid
- ///
- /// \return Iterator pointing to one past the last read element of the input sequence
- ///
- ////////////////////////////////////////////////////////////
- template <typename In>
- static In Decode(In begin, In end, Uint32& output, Uint32 replacement = 0);
-
- ////////////////////////////////////////////////////////////
- /// \brief Encode a single UTF-16 character
- ///
- /// Encoding a character means converting a unique 32-bits
- /// code (called the codepoint) in the target encoding, UTF-16.
- ///
- /// \param input Codepoint to encode as UTF-16
- /// \param output Iterator pointing to the beginning of the output sequence
- /// \param replacement Replacement for characters not convertible to UTF-16 (use 0 to skip them)
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename Out>
- static Out Encode(Uint32 input, Out output, Uint16 replacement = 0);
-
- ////////////////////////////////////////////////////////////
- /// \brief Advance to the next UTF-16 character
- ///
- /// This function is necessary for multi-elements encodings, as
- /// a single character may use more than 1 storage element.
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- ///
- /// \return Iterator pointing to one past the last read element of the input sequence
- ///
- ////////////////////////////////////////////////////////////
- template <typename In>
- static In Next(In begin, In end);
-
- ////////////////////////////////////////////////////////////
- /// \brief Count the number of characters of a UTF-16 sequence
- ///
- /// This function is necessary for multi-elements encodings, as
- /// a single character may use more than 1 storage element, thus the
- /// total size can be different from (begin - end).
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- ///
- /// \return Iterator pointing to one past the last read element of the input sequence
- ///
- ////////////////////////////////////////////////////////////
- template <typename In>
- static std::size_t Count(In begin, In end);
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert an ANSI characters range to UTF-16
- ///
- /// The current global locale will be used by default, unless you
- /// pass a custom one in the \a locale parameter.
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- /// \param locale Locale to use for conversion
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out FromAnsi(In begin, In end, Out output, const std::locale& locale = std::locale());
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert a wide characters range to UTF-16
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out FromWide(In begin, In end, Out output);
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-16
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- /// \param locale Locale to use for conversion
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out FromLatin1(In begin, In end, Out output);
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert an UTF-16 characters range to ANSI characters
- ///
- /// The current global locale will be used by default, unless you
- /// pass a custom one in the \a locale parameter.
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- /// \param replacement Replacement for characters not convertible to ANSI (use 0 to skip them)
- /// \param locale Locale to use for conversion
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out ToAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = std::locale());
+template <> class Utf<16> {
+ public:
+ ////////////////////////////////////////////////////////////
+ /// \brief Decode a single UTF-16 character
+ ///
+ /// Decoding a character means finding its unique 32-bits
+ /// code (called the codepoint) in the Unicode standard.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Codepoint of the decoded UTF-16 character
+ /// \param replacement Replacement character to use in case the UTF-8 sequence is invalid
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static In Decode( In begin, In end, Uint32& output, Uint32 replacement = 0 );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Encode a single UTF-16 character
+ ///
+ /// Encoding a character means converting a unique 32-bits
+ /// code (called the codepoint) in the target encoding, UTF-16.
+ ///
+ /// \param input Codepoint to encode as UTF-16
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to UTF-16 (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename Out> static Out Encode( Uint32 input, Out output, Uint16 replacement = 0 );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Advance to the next UTF-16 character
+ ///
+ /// This function is necessary for multi-elements encodings, as
+ /// a single character may use more than 1 storage element.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In> static In Next( In begin, In end );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Count the number of characters of a UTF-16 sequence
+ ///
+ /// This function is necessary for multi-elements encodings, as
+ /// a single character may use more than 1 storage element, thus the
+ /// total size can be different from (begin - end).
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In> static std::size_t Count( In begin, In end );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an ANSI characters range to UTF-16
+ ///
+ /// The current global locale will be used by default, unless you
+ /// pass a custom one in the \a locale parameter.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromAnsi( In begin, In end, Out output, const std::locale& locale = std::locale() );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a wide characters range to UTF-16
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out> static Out FromWide( In begin, In end, Out output );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-16
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out> static Out FromLatin1( In begin, In end, Out output );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-16 characters range to ANSI characters
+ ///
+ /// The current global locale will be used by default, unless you
+ /// pass a custom one in the \a locale parameter.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to ANSI (use 0 to skip them)
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToAnsi( In begin, In end, Out output, char replacement = 0,
+ const std::locale& locale = std::locale() );
#ifndef EFSW_NO_WIDECHAR
- ////////////////////////////////////////////////////////////
- /// \brief Convert an UTF-16 characters range to wide characters
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out ToWide(In begin, In end, Out output, wchar_t replacement = 0);
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-16 characters range to wide characters
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToWide( In begin, In end, Out output, wchar_t replacement = 0 );
#endif
- ////////////////////////////////////////////////////////////
- /// \brief Convert an UTF-16 characters range to latin-1 (ISO-5589-1) characters
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out ToLatin1(In begin, In end, Out output, char replacement = 0);
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert a UTF-16 characters range to UTF-8
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out toUtf8(In begin, In end, Out output);
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert a UTF-16 characters range to UTF-16
- ///
- /// This functions does nothing more than a direct copy;
- /// it is defined only to provide the same interface as other
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-16 characters range to latin-1 (ISO-5589-1) characters
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToLatin1( In begin, In end, Out output, char replacement = 0 );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-16 characters range to UTF-8
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out> static Out toUtf8( In begin, In end, Out output );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-16 characters range to UTF-16
+ ///
+ /// This functions does nothing more than a direct copy;
+ /// it is defined only to provide the same interface as other
/// specializations of the efsw::Utf<> template, and allow
- /// generic code to be written on top of it.
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out ToUtf16(In begin, In end, Out output);
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert a UTF-16 characters range to UTF-32
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out ToUtf32(In begin, In end, Out output);
+ /// generic code to be written on top of it.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out> static Out ToUtf16( In begin, In end, Out output );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-16 characters range to UTF-32
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out> static Out ToUtf32( In begin, In end, Out output );
};
////////////////////////////////////////////////////////////
/// \brief Specialization of the Utf template for UTF-32
///
////////////////////////////////////////////////////////////
-template <>
-class Utf<32>
-{
-public :
-
- ////////////////////////////////////////////////////////////
- /// \brief Decode a single UTF-32 character
- ///
- /// Decoding a character means finding its unique 32-bits
- /// code (called the codepoint) in the Unicode standard.
- /// For UTF-32, the character value is the same as the codepoint.
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Codepoint of the decoded UTF-32 character
- /// \param replacement Replacement character to use in case the UTF-8 sequence is invalid
- ///
- /// \return Iterator pointing to one past the last read element of the input sequence
- ///
- ////////////////////////////////////////////////////////////
- template <typename In>
- static In Decode(In begin, In end, Uint32& output, Uint32 replacement = 0);
-
- ////////////////////////////////////////////////////////////
- /// \brief Encode a single UTF-32 character
- ///
- /// Encoding a character means converting a unique 32-bits
- /// code (called the codepoint) in the target encoding, UTF-32.
- /// For UTF-32, the codepoint is the same as the character value.
- ///
- /// \param input Codepoint to encode as UTF-32
- /// \param output Iterator pointing to the beginning of the output sequence
- /// \param replacement Replacement for characters not convertible to UTF-32 (use 0 to skip them)
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename Out>
- static Out Encode(Uint32 input, Out output, Uint32 replacement = 0);
-
- ////////////////////////////////////////////////////////////
- /// \brief Advance to the next UTF-32 character
- ///
- /// This function is trivial for UTF-32, which can store
- /// every character in a single storage element.
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- ///
- /// \return Iterator pointing to one past the last read element of the input sequence
- ///
- ////////////////////////////////////////////////////////////
- template <typename In>
- static In Next(In begin, In end);
-
- ////////////////////////////////////////////////////////////
- /// \brief Count the number of characters of a UTF-32 sequence
- ///
- /// This function is trivial for UTF-32, which can store
- /// every character in a single storage element.
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- ///
- /// \return Iterator pointing to one past the last read element of the input sequence
- ///
- ////////////////////////////////////////////////////////////
- template <typename In>
- static std::size_t Count(In begin, In end);
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert an ANSI characters range to UTF-32
- ///
- /// The current global locale will be used by default, unless you
- /// pass a custom one in the \a locale parameter.
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- /// \param locale Locale to use for conversion
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out FromAnsi(In begin, In end, Out output, const std::locale& locale = std::locale());
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert a wide characters range to UTF-32
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out FromWide(In begin, In end, Out output);
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-32
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- /// \param locale Locale to use for conversion
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out FromLatin1(In begin, In end, Out output);
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert an UTF-32 characters range to ANSI characters
- ///
- /// The current global locale will be used by default, unless you
- /// pass a custom one in the \a locale parameter.
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- /// \param replacement Replacement for characters not convertible to ANSI (use 0 to skip them)
- /// \param locale Locale to use for conversion
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out ToAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = std::locale());
+template <> class Utf<32> {
+ public:
+ ////////////////////////////////////////////////////////////
+ /// \brief Decode a single UTF-32 character
+ ///
+ /// Decoding a character means finding its unique 32-bits
+ /// code (called the codepoint) in the Unicode standard.
+ /// For UTF-32, the character value is the same as the codepoint.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Codepoint of the decoded UTF-32 character
+ /// \param replacement Replacement character to use in case the UTF-8 sequence is invalid
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static In Decode( In begin, In end, Uint32& output, Uint32 replacement = 0 );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Encode a single UTF-32 character
+ ///
+ /// Encoding a character means converting a unique 32-bits
+ /// code (called the codepoint) in the target encoding, UTF-32.
+ /// For UTF-32, the codepoint is the same as the character value.
+ ///
+ /// \param input Codepoint to encode as UTF-32
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to UTF-32 (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename Out> static Out Encode( Uint32 input, Out output, Uint32 replacement = 0 );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Advance to the next UTF-32 character
+ ///
+ /// This function is trivial for UTF-32, which can store
+ /// every character in a single storage element.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In> static In Next( In begin, In end );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Count the number of characters of a UTF-32 sequence
+ ///
+ /// This function is trivial for UTF-32, which can store
+ /// every character in a single storage element.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In> static std::size_t Count( In begin, In end );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an ANSI characters range to UTF-32
+ ///
+ /// The current global locale will be used by default, unless you
+ /// pass a custom one in the \a locale parameter.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromAnsi( In begin, In end, Out output, const std::locale& locale = std::locale() );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a wide characters range to UTF-32
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out> static Out FromWide( In begin, In end, Out output );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-32
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out> static Out FromLatin1( In begin, In end, Out output );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-32 characters range to ANSI characters
+ ///
+ /// The current global locale will be used by default, unless you
+ /// pass a custom one in the \a locale parameter.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to ANSI (use 0 to skip them)
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToAnsi( In begin, In end, Out output, char replacement = 0,
+ const std::locale& locale = std::locale() );
#ifndef EFSW_NO_WIDECHAR
- ////////////////////////////////////////////////////////////
- /// \brief Convert an UTF-32 characters range to wide characters
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out ToWide(In begin, In end, Out output, wchar_t replacement = 0);
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-32 characters range to wide characters
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToWide( In begin, In end, Out output, wchar_t replacement = 0 );
#endif
- ////////////////////////////////////////////////////////////
- /// \brief Convert an UTF-16 characters range to latin-1 (ISO-5589-1) characters
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out ToLatin1(In begin, In end, Out output, char replacement = 0);
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert a UTF-32 characters range to UTF-8
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out toUtf8(In begin, In end, Out output);
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert a UTF-32 characters range to UTF-16
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out ToUtf16(In begin, In end, Out output);
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert a UTF-32 characters range to UTF-32
- ///
- /// This functions does nothing more than a direct copy;
- /// it is defined only to provide the same interface as other
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-16 characters range to latin-1 (ISO-5589-1) characters
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToLatin1( In begin, In end, Out output, char replacement = 0 );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-32 characters range to UTF-8
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out> static Out toUtf8( In begin, In end, Out output );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-32 characters range to UTF-16
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out> static Out ToUtf16( In begin, In end, Out output );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-32 characters range to UTF-32
+ ///
+ /// This functions does nothing more than a direct copy;
+ /// it is defined only to provide the same interface as other
/// specializations of the efsw::Utf<> template, and allow
- /// generic code to be written on top of it.
- ///
- /// \param begin Iterator pointing to the beginning of the input sequence
- /// \param end Iterator pointing to the end of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename In, typename Out>
- static Out ToUtf32(In begin, In end, Out output);
-
- ////////////////////////////////////////////////////////////
- /// \brief Decode a single ANSI character to UTF-32
- ///
- /// This function does not exist in other specializations
+ /// generic code to be written on top of it.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out> static Out ToUtf32( In begin, In end, Out output );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Decode a single ANSI character to UTF-32
+ ///
+ /// This function does not exist in other specializations
/// of efsw::Utf<>, it is defined for convenience (it is used by
- /// several other conversion functions).
- ///
- /// \param input Input ANSI character
- /// \param locale Locale to use for conversion
- ///
- /// \return Converted character
- ///
- ////////////////////////////////////////////////////////////
- template <typename In>
- static Uint32 DecodeAnsi(In input, const std::locale& locale = std::locale());
-
- ////////////////////////////////////////////////////////////
- /// \brief Decode a single wide character to UTF-32
- ///
- /// This function does not exist in other specializations
+ /// several other conversion functions).
+ ///
+ /// \param input Input ANSI character
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Converted character
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static Uint32 DecodeAnsi( In input, const std::locale& locale = std::locale() );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Decode a single wide character to UTF-32
+ ///
+ /// This function does not exist in other specializations
/// of efsw::Utf<>, it is defined for convenience (it is used by
- /// several other conversion functions).
- ///
- /// \param input Input wide character
- ///
- /// \return Converted character
- ///
- ////////////////////////////////////////////////////////////
- template <typename In>
- static Uint32 DecodeWide(In input);
-
- ////////////////////////////////////////////////////////////
- /// \brief Encode a single UTF-32 character to ANSI
- ///
- /// This function does not exist in other specializations
+ /// several other conversion functions).
+ ///
+ /// \param input Input wide character
+ ///
+ /// \return Converted character
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In> static Uint32 DecodeWide( In input );
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Encode a single UTF-32 character to ANSI
+ ///
+ /// This function does not exist in other specializations
/// of efsw::Utf<>, it is defined for convenience (it is used by
- /// several other conversion functions).
- ///
- /// \param codepoint Iterator pointing to the beginning of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- /// \param replacement Replacement if the input character is not convertible to ANSI (use 0 to skip it)
- /// \param locale Locale to use for conversion
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename Out>
- static Out EncodeAnsi(Uint32 codepoint, Out output, char replacement = 0, const std::locale& locale = std::locale());
+ /// several other conversion functions).
+ ///
+ /// \param codepoint Iterator pointing to the beginning of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement if the input character is not convertible to ANSI (use 0 to
+ /// skip it) \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename Out>
+ static Out EncodeAnsi( Uint32 codepoint, Out output, char replacement = 0,
+ const std::locale& locale = std::locale() );
#ifndef EFSW_NO_WIDECHAR
- ////////////////////////////////////////////////////////////
- /// \brief Encode a single UTF-32 character to wide
- ///
- /// This function does not exist in other specializations
+ ////////////////////////////////////////////////////////////
+ /// \brief Encode a single UTF-32 character to wide
+ ///
+ /// This function does not exist in other specializations
/// of efsw::Utf<>, it is defined for convenience (it is used by
- /// several other conversion functions).
- ///
- /// \param codepoint Iterator pointing to the beginning of the input sequence
- /// \param output Iterator pointing to the beginning of the output sequence
- /// \param replacement Replacement if the input character is not convertible to wide (use 0 to skip it)
- ///
- /// \return Iterator to the end of the output sequence which has been written
- ///
- ////////////////////////////////////////////////////////////
- template <typename Out>
- static Out EncodeWide(Uint32 codepoint, Out output, wchar_t replacement = 0);
+ /// several other conversion functions).
+ ///
+ /// \param codepoint Iterator pointing to the beginning of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement if the input character is not convertible to wide (use 0 to
+ /// skip it)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename Out>
+ static Out EncodeWide( Uint32 codepoint, Out output, wchar_t replacement = 0 );
#endif
};
#include "Utf.inl"
// Make typedefs to get rid of the template syntax
-typedef Utf<8> Utf8;
+typedef Utf<8> Utf8;
typedef Utf<16> Utf16;
typedef Utf<32> Utf32;
-}
+} // namespace efsw
#endif
////////////////////////////////////////////////////////////
diff --git a/dep/efsw/src/efsw/Utf.inl b/dep/efsw/src/efsw/Utf.inl
index db8fd5d61ee..7e3e9d6035a 100644
--- a/dep/efsw/src/efsw/Utf.inl
+++ b/dep/efsw/src/efsw/Utf.inl
@@ -5,667 +5,572 @@
// http://people.w3.org/rishida/scripts/uniview/conversion
////////////////////////////////////////////////////////////
-template <typename In>
-In Utf<8>::Decode(In begin, In end, Uint32& output, Uint32 replacement)
-{
- // Some useful precomputed data
- static const int trailing[256] =
- {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5
- };
- static const Uint32 offsets[6] =
- {
- 0x00000000, 0x00003080, 0x000E2080, 0x03C82080, 0xFA082080, 0x82082080
- };
-
- // Decode the character
- int trailingBytes = trailing[static_cast<Uint8>(*begin)];
- if (begin + trailingBytes < end)
- {
- output = 0;
- switch (trailingBytes)
- {
- case 5 : output += static_cast<Uint8>(*begin++); output <<= 6;
- case 4 : output += static_cast<Uint8>(*begin++); output <<= 6;
- case 3 : output += static_cast<Uint8>(*begin++); output <<= 6;
- case 2 : output += static_cast<Uint8>(*begin++); output <<= 6;
- case 1 : output += static_cast<Uint8>(*begin++); output <<= 6;
- case 0 : output += static_cast<Uint8>(*begin++);
- }
- output -= offsets[trailingBytes];
- }
- else
- {
- // Incomplete character
- begin = end;
- output = replacement;
- }
-
- return begin;
-}
-
-template <typename Out>
-Out Utf<8>::Encode(Uint32 input, Out output, Uint8 replacement)
-{
- // Some useful precomputed data
- static const Uint8 firstBytes[7] =
- {
- 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
- };
-
- // Encode the character
- if ((input > 0x0010FFFF) || ((input >= 0xD800) && (input <= 0xDBFF)))
- {
- // Invalid character
- if (replacement)
- *output++ = replacement;
- }
- else
- {
- // Valid character
-
- // Get the number of bytes to write
- int bytesToWrite = 1;
- if (input < 0x80) bytesToWrite = 1;
- else if (input < 0x800) bytesToWrite = 2;
- else if (input < 0x10000) bytesToWrite = 3;
- else if (input <= 0x0010FFFF) bytesToWrite = 4;
-
- // Extract the bytes to write
- Uint8 bytes[4];
- switch (bytesToWrite)
- {
- case 4 : bytes[3] = static_cast<Uint8>((input | 0x80) & 0xBF); input >>= 6;
- case 3 : bytes[2] = static_cast<Uint8>((input | 0x80) & 0xBF); input >>= 6;
- case 2 : bytes[1] = static_cast<Uint8>((input | 0x80) & 0xBF); input >>= 6;
- case 1 : bytes[0] = static_cast<Uint8> (input | firstBytes[bytesToWrite]);
- }
-
- // Add them to the output
- const Uint8* currentByte = bytes;
- switch (bytesToWrite)
- {
- case 4 : *output++ = *currentByte++;
- case 3 : *output++ = *currentByte++;
- case 2 : *output++ = *currentByte++;
- case 1 : *output++ = *currentByte++;
- }
- }
-
- return output;
-}
-
-template <typename In>
-In Utf<8>::Next(In begin, In end)
-{
- Uint32 codepoint;
- return Decode(begin, end, codepoint);
-}
-
-template <typename In>
-std::size_t Utf<8>::Count(In begin, In end)
-{
- std::size_t length = 0;
- while (begin < end)
- {
- begin = Next(begin, end);
- ++length;
- }
-
- return length;
+template <typename In> In Utf<8>::Decode( In begin, In end, Uint32& output, Uint32 replacement ) {
+ // Some useful precomputed data
+ static const int trailing[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 };
+ static const Uint32 offsets[6] = { 0x00000000, 0x00003080, 0x000E2080,
+ 0x03C82080, 0xFA082080, 0x82082080 };
+
+ // Decode the character
+ int trailingBytes = trailing[static_cast<Uint8>( *begin )];
+ if ( begin + trailingBytes < end ) {
+ output = 0;
+ switch ( trailingBytes ) {
+ case 5:
+ output += static_cast<Uint8>( *begin++ );
+ output <<= 6;
+ case 4:
+ output += static_cast<Uint8>( *begin++ );
+ output <<= 6;
+ case 3:
+ output += static_cast<Uint8>( *begin++ );
+ output <<= 6;
+ case 2:
+ output += static_cast<Uint8>( *begin++ );
+ output <<= 6;
+ case 1:
+ output += static_cast<Uint8>( *begin++ );
+ output <<= 6;
+ case 0:
+ output += static_cast<Uint8>( *begin++ );
+ }
+ output -= offsets[trailingBytes];
+ } else {
+ // Incomplete character
+ begin = end;
+ output = replacement;
+ }
+
+ return begin;
+}
+
+template <typename Out> Out Utf<8>::Encode( Uint32 input, Out output, Uint8 replacement ) {
+ // Some useful precomputed data
+ static const Uint8 firstBytes[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+ // Encode the character
+ if ( ( input > 0x0010FFFF ) || ( ( input >= 0xD800 ) && ( input <= 0xDBFF ) ) ) {
+ // Invalid character
+ if ( replacement )
+ *output++ = replacement;
+ } else {
+ // Valid character
+
+ // Get the number of bytes to write
+ int bytesToWrite = 1;
+ if ( input < 0x80 )
+ bytesToWrite = 1;
+ else if ( input < 0x800 )
+ bytesToWrite = 2;
+ else if ( input < 0x10000 )
+ bytesToWrite = 3;
+ else if ( input <= 0x0010FFFF )
+ bytesToWrite = 4;
+
+ // Extract the bytes to write
+ Uint8 bytes[4];
+ switch ( bytesToWrite ) {
+ case 4:
+ bytes[3] = static_cast<Uint8>( ( input | 0x80 ) & 0xBF );
+ input >>= 6;
+ case 3:
+ bytes[2] = static_cast<Uint8>( ( input | 0x80 ) & 0xBF );
+ input >>= 6;
+ case 2:
+ bytes[1] = static_cast<Uint8>( ( input | 0x80 ) & 0xBF );
+ input >>= 6;
+ case 1:
+ bytes[0] = static_cast<Uint8>( input | firstBytes[bytesToWrite] );
+ }
+
+ // Add them to the output
+ const Uint8* currentByte = bytes;
+ switch ( bytesToWrite ) {
+ case 4:
+ *output++ = *currentByte++;
+ case 3:
+ *output++ = *currentByte++;
+ case 2:
+ *output++ = *currentByte++;
+ case 1:
+ *output++ = *currentByte++;
+ }
+ }
+
+ return output;
+}
+
+template <typename In> In Utf<8>::Next( In begin, In end ) {
+ Uint32 codepoint;
+ return Decode( begin, end, codepoint );
+}
+
+template <typename In> std::size_t Utf<8>::Count( In begin, In end ) {
+ std::size_t length = 0;
+ while ( begin < end ) {
+ begin = Next( begin, end );
+ ++length;
+ }
+
+ return length;
}
template <typename In, typename Out>
-Out Utf<8>::FromAnsi(In begin, In end, Out output, const std::locale& locale)
-{
- while (begin < end)
- {
- Uint32 codepoint = Utf<32>::DecodeAnsi(*begin++, locale);
- output = Encode(codepoint, output);
- }
+Out Utf<8>::FromAnsi( In begin, In end, Out output, const std::locale& locale ) {
+ while ( begin < end ) {
+ Uint32 codepoint = Utf<32>::DecodeAnsi( *begin++, locale );
+ output = Encode( codepoint, output );
+ }
- return output;
+ return output;
}
-template <typename In, typename Out>
-Out Utf<8>::FromWide(In begin, In end, Out output)
-{
- while (begin < end)
- {
- Uint32 codepoint = Utf<32>::DecodeWide(*begin++);
- output = Encode(codepoint, output);
- }
+template <typename In, typename Out> Out Utf<8>::FromWide( In begin, In end, Out output ) {
+ while ( begin < end ) {
+ Uint32 codepoint = Utf<32>::DecodeWide( *begin++ );
+ output = Encode( codepoint, output );
+ }
- return output;
+ return output;
}
-template <typename In, typename Out>
-Out Utf<8>::FromLatin1(In begin, In end, Out output)
-{
- // Latin-1 is directly compatible with Unicode encodings,
- // and can thus be treated as (a sub-range of) UTF-32
- while (begin < end)
- output = Encode(*begin++, output);
+template <typename In, typename Out> Out Utf<8>::FromLatin1( In begin, In end, Out output ) {
+ // Latin-1 is directly compatible with Unicode encodings,
+ // and can thus be treated as (a sub-range of) UTF-32
+ while ( begin < end )
+ output = Encode( *begin++, output );
- return output;
+ return output;
}
template <typename In, typename Out>
-Out Utf<8>::ToAnsi(In begin, In end, Out output, char replacement, const std::locale& locale)
-{
- while (begin < end)
- {
- Uint32 codepoint;
- begin = Decode(begin, end, codepoint);
- output = Utf<32>::EncodeAnsi(codepoint, output, replacement, locale);
- }
+Out Utf<8>::ToAnsi( In begin, In end, Out output, char replacement, const std::locale& locale ) {
+ while ( begin < end ) {
+ Uint32 codepoint;
+ begin = Decode( begin, end, codepoint );
+ output = Utf<32>::EncodeAnsi( codepoint, output, replacement, locale );
+ }
- return output;
+ return output;
}
#ifndef EFSW_NO_WIDECHAR
template <typename In, typename Out>
-Out Utf<8>::ToWide(In begin, In end, Out output, wchar_t replacement)
-{
- while (begin < end)
- {
- Uint32 codepoint;
- begin = Decode(begin, end, codepoint);
- output = Utf<32>::EncodeWide(codepoint, output, replacement);
- }
+Out Utf<8>::ToWide( In begin, In end, Out output, wchar_t replacement ) {
+ while ( begin < end ) {
+ Uint32 codepoint;
+ begin = Decode( begin, end, codepoint );
+ output = Utf<32>::EncodeWide( codepoint, output, replacement );
+ }
- return output;
+ return output;
}
#endif
template <typename In, typename Out>
-Out Utf<8>::ToLatin1(In begin, In end, Out output, char replacement)
-{
- // Latin-1 is directly compatible with Unicode encodings,
- // and can thus be treated as (a sub-range of) UTF-32
- while (begin < end)
- {
- Uint32 codepoint;
- begin = Decode(begin, end, codepoint);
- *output++ = codepoint < 256 ? static_cast<char>(codepoint) : replacement;
- }
-
- return output;
+Out Utf<8>::ToLatin1( In begin, In end, Out output, char replacement ) {
+ // Latin-1 is directly compatible with Unicode encodings,
+ // and can thus be treated as (a sub-range of) UTF-32
+ while ( begin < end ) {
+ Uint32 codepoint;
+ begin = Decode( begin, end, codepoint );
+ *output++ = codepoint < 256 ? static_cast<char>( codepoint ) : replacement;
+ }
+
+ return output;
+}
+
+template <typename In, typename Out> Out Utf<8>::toUtf8( In begin, In end, Out output ) {
+ while ( begin < end )
+ *output++ = *begin++;
+
+ return output;
+}
+
+template <typename In, typename Out> Out Utf<8>::ToUtf16( In begin, In end, Out output ) {
+ while ( begin < end ) {
+ Uint32 codepoint;
+ begin = Decode( begin, end, codepoint );
+ output = Utf<16>::Encode( codepoint, output );
+ }
+
+ return output;
+}
+
+template <typename In, typename Out> Out Utf<8>::ToUtf32( In begin, In end, Out output ) {
+ while ( begin < end ) {
+ Uint32 codepoint;
+ begin = Decode( begin, end, codepoint );
+ *output++ = codepoint;
+ }
+
+ return output;
+}
+
+template <typename In> In Utf<16>::Decode( In begin, In end, Uint32& output, Uint32 replacement ) {
+ Uint16 first = *begin++;
+
+ // If it's a surrogate pair, first convert to a single UTF-32 character
+ if ( ( first >= 0xD800 ) && ( first <= 0xDBFF ) ) {
+ if ( begin < end ) {
+ Uint32 second = *begin++;
+ if ( ( second >= 0xDC00 ) && ( second <= 0xDFFF ) ) {
+ // The second element is valid: convert the two elements to a UTF-32 character
+ output = static_cast<Uint32>( ( ( first - 0xD800 ) << 10 ) + ( second - 0xDC00 ) +
+ 0x0010000 );
+ } else {
+ // Invalid character
+ output = replacement;
+ }
+ } else {
+ // Invalid character
+ begin = end;
+ output = replacement;
+ }
+ } else {
+ // We can make a direct copy
+ output = first;
+ }
+
+ return begin;
+}
+
+template <typename Out> Out Utf<16>::Encode( Uint32 input, Out output, Uint16 replacement ) {
+ if ( input < 0xFFFF ) {
+ // The character can be copied directly, we just need to check if it's in the valid range
+ if ( ( input >= 0xD800 ) && ( input <= 0xDFFF ) ) {
+ // Invalid character (this range is reserved)
+ if ( replacement )
+ *output++ = replacement;
+ } else {
+ // Valid character directly convertible to a single UTF-16 character
+ *output++ = static_cast<Uint16>( input );
+ }
+ } else if ( input > 0x0010FFFF ) {
+ // Invalid character (greater than the maximum unicode value)
+ if ( replacement )
+ *output++ = replacement;
+ } else {
+ // The input character will be converted to two UTF-16 elements
+ input -= 0x0010000;
+ *output++ = static_cast<Uint16>( ( input >> 10 ) + 0xD800 );
+ *output++ = static_cast<Uint16>( ( input & 0x3FFUL ) + 0xDC00 );
+ }
+
+ return output;
+}
+
+template <typename In> In Utf<16>::Next( In begin, In end ) {
+ Uint32 codepoint;
+ return Decode( begin, end, codepoint );
+}
+
+template <typename In> std::size_t Utf<16>::Count( In begin, In end ) {
+ std::size_t length = 0;
+ while ( begin < end ) {
+ begin = Next( begin, end );
+ ++length;
+ }
+
+ return length;
}
template <typename In, typename Out>
-Out Utf<8>::toUtf8(In begin, In end, Out output)
-{
- while (begin < end)
- *output++ = *begin++;
+Out Utf<16>::FromAnsi( In begin, In end, Out output, const std::locale& locale ) {
+ while ( begin < end ) {
+ Uint32 codepoint = Utf<32>::DecodeAnsi( *begin++, locale );
+ output = Encode( codepoint, output );
+ }
- return output;
+ return output;
}
-template <typename In, typename Out>
-Out Utf<8>::ToUtf16(In begin, In end, Out output)
-{
- while (begin < end)
- {
- Uint32 codepoint;
- begin = Decode(begin, end, codepoint);
- output = Utf<16>::Encode(codepoint, output);
- }
-
- return output;
-}
-
-template <typename In, typename Out>
-Out Utf<8>::ToUtf32(In begin, In end, Out output)
-{
- while (begin < end)
- {
- Uint32 codepoint;
- begin = Decode(begin, end, codepoint);
- *output++ = codepoint;
- }
-
- return output;
-}
-
-template <typename In>
-In Utf<16>::Decode(In begin, In end, Uint32& output, Uint32 replacement)
-{
- Uint16 first = *begin++;
-
- // If it's a surrogate pair, first convert to a single UTF-32 character
- if ((first >= 0xD800) && (first <= 0xDBFF))
- {
- if (begin < end)
- {
- Uint32 second = *begin++;
- if ((second >= 0xDC00) && (second <= 0xDFFF))
- {
- // The second element is valid: convert the two elements to a UTF-32 character
- output = static_cast<Uint32>(((first - 0xD800) << 10) + (second - 0xDC00) + 0x0010000);
- }
- else
- {
- // Invalid character
- output = replacement;
- }
- }
- else
- {
- // Invalid character
- begin = end;
- output = replacement;
- }
- }
- else
- {
- // We can make a direct copy
- output = first;
- }
-
- return begin;
-}
-
-template <typename Out>
-Out Utf<16>::Encode(Uint32 input, Out output, Uint16 replacement)
-{
- if (input < 0xFFFF)
- {
- // The character can be copied directly, we just need to check if it's in the valid range
- if ((input >= 0xD800) && (input <= 0xDFFF))
- {
- // Invalid character (this range is reserved)
- if (replacement)
- *output++ = replacement;
- }
- else
- {
- // Valid character directly convertible to a single UTF-16 character
- *output++ = static_cast<Uint16>(input);
- }
- }
- else if (input > 0x0010FFFF)
- {
- // Invalid character (greater than the maximum unicode value)
- if (replacement)
- *output++ = replacement;
- }
- else
- {
- // The input character will be converted to two UTF-16 elements
- input -= 0x0010000;
- *output++ = static_cast<Uint16>((input >> 10) + 0xD800);
- *output++ = static_cast<Uint16>((input & 0x3FFUL) + 0xDC00);
- }
-
- return output;
-}
-
-template <typename In>
-In Utf<16>::Next(In begin, In end)
-{
- Uint32 codepoint;
- return Decode(begin, end, codepoint);
-}
-
-template <typename In>
-std::size_t Utf<16>::Count(In begin, In end)
-{
- std::size_t length = 0;
- while (begin < end)
- {
- begin = Next(begin, end);
- ++length;
- }
-
- return length;
-}
-
-template <typename In, typename Out>
-Out Utf<16>::FromAnsi(In begin, In end, Out output, const std::locale& locale)
-{
- while (begin < end)
- {
- Uint32 codepoint = Utf<32>::DecodeAnsi(*begin++, locale);
- output = Encode(codepoint, output);
- }
-
- return output;
-}
-
-template <typename In, typename Out>
-Out Utf<16>::FromWide(In begin, In end, Out output)
-{
- while (begin < end)
- {
- Uint32 codepoint = Utf<32>::DecodeWide(*begin++);
- output = Encode(codepoint, output);
- }
+template <typename In, typename Out> Out Utf<16>::FromWide( In begin, In end, Out output ) {
+ while ( begin < end ) {
+ Uint32 codepoint = Utf<32>::DecodeWide( *begin++ );
+ output = Encode( codepoint, output );
+ }
- return output;
+ return output;
}
-template <typename In, typename Out>
-Out Utf<16>::FromLatin1(In begin, In end, Out output)
-{
- // Latin-1 is directly compatible with Unicode encodings,
- // and can thus be treated as (a sub-range of) UTF-32
- while (begin < end)
- *output++ = *begin++;
+template <typename In, typename Out> Out Utf<16>::FromLatin1( In begin, In end, Out output ) {
+ // Latin-1 is directly compatible with Unicode encodings,
+ // and can thus be treated as (a sub-range of) UTF-32
+ while ( begin < end )
+ *output++ = *begin++;
- return output;
+ return output;
}
template <typename In, typename Out>
-Out Utf<16>::ToAnsi(In begin, In end, Out output, char replacement, const std::locale& locale)
-{
- while (begin < end)
- {
- Uint32 codepoint;
- begin = Decode(begin, end, codepoint);
- output = Utf<32>::EncodeAnsi(codepoint, output, replacement, locale);
- }
+Out Utf<16>::ToAnsi( In begin, In end, Out output, char replacement, const std::locale& locale ) {
+ while ( begin < end ) {
+ Uint32 codepoint;
+ begin = Decode( begin, end, codepoint );
+ output = Utf<32>::EncodeAnsi( codepoint, output, replacement, locale );
+ }
- return output;
+ return output;
}
#ifndef EFSW_NO_WIDECHAR
template <typename In, typename Out>
-Out Utf<16>::ToWide(In begin, In end, Out output, wchar_t replacement)
-{
- while (begin < end)
- {
- Uint32 codepoint;
- begin = Decode(begin, end, codepoint);
- output = Utf<32>::EncodeWide(codepoint, output, replacement);
- }
+Out Utf<16>::ToWide( In begin, In end, Out output, wchar_t replacement ) {
+ while ( begin < end ) {
+ Uint32 codepoint;
+ begin = Decode( begin, end, codepoint );
+ output = Utf<32>::EncodeWide( codepoint, output, replacement );
+ }
- return output;
+ return output;
}
#endif
template <typename In, typename Out>
-Out Utf<16>::ToLatin1(In begin, In end, Out output, char replacement)
-{
- // Latin-1 is directly compatible with Unicode encodings,
- // and can thus be treated as (a sub-range of) UTF-32
- while (begin < end)
- {
- *output++ = *begin < 256 ? static_cast<char>(*begin) : replacement;
- begin++;
- }
+Out Utf<16>::ToLatin1( In begin, In end, Out output, char replacement ) {
+ // Latin-1 is directly compatible with Unicode encodings,
+ // and can thus be treated as (a sub-range of) UTF-32
+ while ( begin < end ) {
+ *output++ = *begin < 256 ? static_cast<char>( *begin ) : replacement;
+ begin++;
+ }
- return output;
+ return output;
}
-template <typename In, typename Out>
-Out Utf<16>::toUtf8(In begin, In end, Out output)
-{
- while (begin < end)
- {
- Uint32 codepoint;
- begin = Decode(begin, end, codepoint);
- output = Utf<8>::Encode(codepoint, output);
- }
+template <typename In, typename Out> Out Utf<16>::toUtf8( In begin, In end, Out output ) {
+ while ( begin < end ) {
+ Uint32 codepoint;
+ begin = Decode( begin, end, codepoint );
+ output = Utf<8>::Encode( codepoint, output );
+ }
- return output;
+ return output;
}
-template <typename In, typename Out>
-Out Utf<16>::ToUtf16(In begin, In end, Out output)
-{
- while (begin < end)
- *output++ = *begin++;
+template <typename In, typename Out> Out Utf<16>::ToUtf16( In begin, In end, Out output ) {
+ while ( begin < end )
+ *output++ = *begin++;
- return output;
+ return output;
}
-template <typename In, typename Out>
-Out Utf<16>::ToUtf32(In begin, In end, Out output)
-{
- while (begin < end)
- {
- Uint32 codepoint;
- begin = Decode(begin, end, codepoint);
- *output++ = codepoint;
- }
+template <typename In, typename Out> Out Utf<16>::ToUtf32( In begin, In end, Out output ) {
+ while ( begin < end ) {
+ Uint32 codepoint;
+ begin = Decode( begin, end, codepoint );
+ *output++ = codepoint;
+ }
- return output;
+ return output;
}
-template <typename In>
-In Utf<32>::Decode(In begin, In end, Uint32& output, Uint32)
-{
- output = *begin++;
- return begin;
+template <typename In> In Utf<32>::Decode( In begin, In end, Uint32& output, Uint32 ) {
+ output = *begin++;
+ return begin;
}
-template <typename Out>
-Out Utf<32>::Encode(Uint32 input, Out output, Uint32 replacement)
-{
- *output++ = input;
- return output;
+template <typename Out> Out Utf<32>::Encode( Uint32 input, Out output, Uint32 replacement ) {
+ *output++ = input;
+ return output;
}
-template <typename In>
-In Utf<32>::Next(In begin, In end)
-{
- return ++begin;
+template <typename In> In Utf<32>::Next( In begin, In end ) {
+ return ++begin;
}
-template <typename In>
-std::size_t Utf<32>::Count(In begin, In end)
-{
- return begin - end;
+template <typename In> std::size_t Utf<32>::Count( In begin, In end ) {
+ return begin - end;
}
template <typename In, typename Out>
-Out Utf<32>::FromAnsi(In begin, In end, Out output, const std::locale& locale)
-{
- while (begin < end)
- *output++ = DecodeAnsi(*begin++, locale);
+Out Utf<32>::FromAnsi( In begin, In end, Out output, const std::locale& locale ) {
+ while ( begin < end )
+ *output++ = DecodeAnsi( *begin++, locale );
- return output;
+ return output;
}
-template <typename In, typename Out>
-Out Utf<32>::FromWide(In begin, In end, Out output)
-{
- while (begin < end)
- *output++ = DecodeWide(*begin++);
+template <typename In, typename Out> Out Utf<32>::FromWide( In begin, In end, Out output ) {
+ while ( begin < end )
+ *output++ = DecodeWide( *begin++ );
- return output;
+ return output;
}
-template <typename In, typename Out>
-Out Utf<32>::FromLatin1(In begin, In end, Out output)
-{
- // Latin-1 is directly compatible with Unicode encodings,
- // and can thus be treated as (a sub-range of) UTF-32
- while (begin < end)
- *output++ = *begin++;
+template <typename In, typename Out> Out Utf<32>::FromLatin1( In begin, In end, Out output ) {
+ // Latin-1 is directly compatible with Unicode encodings,
+ // and can thus be treated as (a sub-range of) UTF-32
+ while ( begin < end )
+ *output++ = *begin++;
- return output;
+ return output;
}
template <typename In, typename Out>
-Out Utf<32>::ToAnsi(In begin, In end, Out output, char replacement, const std::locale& locale)
-{
- while (begin < end)
- output = EncodeAnsi(*begin++, output, replacement, locale);
+Out Utf<32>::ToAnsi( In begin, In end, Out output, char replacement, const std::locale& locale ) {
+ while ( begin < end )
+ output = EncodeAnsi( *begin++, output, replacement, locale );
- return output;
+ return output;
}
#ifndef EFSW_NO_WIDECHAR
template <typename In, typename Out>
-Out Utf<32>::ToWide(In begin, In end, Out output, wchar_t replacement)
-{
- while (begin < end)
- output = EncodeWide(*begin++, output, replacement);
+Out Utf<32>::ToWide( In begin, In end, Out output, wchar_t replacement ) {
+ while ( begin < end )
+ output = EncodeWide( *begin++, output, replacement );
- return output;
+ return output;
}
#endif
template <typename In, typename Out>
-Out Utf<32>::ToLatin1(In begin, In end, Out output, char replacement)
-{
- // Latin-1 is directly compatible with Unicode encodings,
- // and can thus be treated as (a sub-range of) UTF-32
- while (begin < end)
- {
- *output++ = *begin < 256 ? static_cast<char>(*begin) : replacement;
- begin++;
- }
+Out Utf<32>::ToLatin1( In begin, In end, Out output, char replacement ) {
+ // Latin-1 is directly compatible with Unicode encodings,
+ // and can thus be treated as (a sub-range of) UTF-32
+ while ( begin < end ) {
+ *output++ = *begin < 256 ? static_cast<char>( *begin ) : replacement;
+ begin++;
+ }
- return output;
+ return output;
}
-template <typename In, typename Out>
-Out Utf<32>::toUtf8(In begin, In end, Out output)
-{
- while (begin < end)
- output = Utf<8>::Encode(*begin++, output);
+template <typename In, typename Out> Out Utf<32>::toUtf8( In begin, In end, Out output ) {
+ while ( begin < end )
+ output = Utf<8>::Encode( *begin++, output );
- return output;
+ return output;
}
-template <typename In, typename Out>
-Out Utf<32>::ToUtf16(In begin, In end, Out output)
-{
- while (begin < end)
- output = Utf<16>::Encode(*begin++, output);
+template <typename In, typename Out> Out Utf<32>::ToUtf16( In begin, In end, Out output ) {
+ while ( begin < end )
+ output = Utf<16>::Encode( *begin++, output );
- return output;
+ return output;
}
-template <typename In, typename Out>
-Out Utf<32>::ToUtf32(In begin, In end, Out output)
-{
- while (begin < end)
- *output++ = *begin++;
+template <typename In, typename Out> Out Utf<32>::ToUtf32( In begin, In end, Out output ) {
+ while ( begin < end )
+ *output++ = *begin++;
- return output;
+ return output;
}
-template <typename In>
-Uint32 Utf<32>::DecodeAnsi(In input, const std::locale& locale)
-{
- // On Windows, gcc's standard library (glibc++) has almost
- // no support for Unicode stuff. As a consequence, in this
- // context we can only use the default locale and ignore
- // the one passed as parameter.
+template <typename In> Uint32 Utf<32>::DecodeAnsi( In input, const std::locale& locale ) {
+ // On Windows, gcc's standard library (glibc++) has almost
+ // no support for Unicode stuff. As a consequence, in this
+ // context we can only use the default locale and ignore
+ // the one passed as parameter.
- #if EFSW_PLATFORM == EFSW_PLATFORM_WIN && /* if Windows ... */ \
- (defined(__GLIBCPP__) || defined (__GLIBCXX__)) && /* ... and standard library is glibc++ ... */ \
- !(defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) /* ... and STLPort is not used on top of it */
+#if EFSW_PLATFORM == EFSW_PLATFORM_WIN && /* if Windows ... */ \
+ ( defined( __GLIBCPP__ ) || \
+ defined( __GLIBCXX__ ) ) && /* ... and standard library is glibc++ ... */ \
+ !( defined( __SGI_STL_PORT ) || \
+ defined( _STLPORT_VERSION ) ) /* ... and STLPort is not used on top of it */
- wchar_t character = 0;
- mbtowc(&character, &input, 1);
- return static_cast<Uint32>(character);
+ wchar_t character = 0;
+ mbtowc( &character, &input, 1 );
+ return static_cast<Uint32>( character );
- #else
- // Get the facet of the locale which deals with character conversion
- #ifndef EFSW_NO_WIDECHAR
- const std::ctype<wchar_t>& facet = std::use_facet< std::ctype<wchar_t> >(locale);
- #else
- const std::ctype<char>& facet = std::use_facet< std::ctype<char> >(locale);
- #endif
-
- // Use the facet to convert each character of the input string
- return static_cast<Uint32>(facet.widen(input));
+#else
+// Get the facet of the locale which deals with character conversion
+#ifndef EFSW_NO_WIDECHAR
+ const std::ctype<wchar_t>& facet = std::use_facet<std::ctype<wchar_t>>( locale );
+#else
+ const std::ctype<char>& facet = std::use_facet<std::ctype<char>>( locale );
+#endif
+
+ // Use the facet to convert each character of the input string
+ return static_cast<Uint32>( facet.widen( input ) );
- #endif
+#endif
}
-template <typename In>
-Uint32 Utf<32>::DecodeWide(In input)
-{
- // The encoding of wide characters is not well defined and is left to the system;
- // however we can safely assume that it is UCS-2 on Windows and
- // UCS-4 on Unix systems.
- // In both cases, a simple copy is enough (UCS-2 is a subset of UCS-4,
- // and UCS-4 *is* UTF-32).
+template <typename In> Uint32 Utf<32>::DecodeWide( In input ) {
+ // The encoding of wide characters is not well defined and is left to the system;
+ // however we can safely assume that it is UCS-2 on Windows and
+ // UCS-4 on Unix systems.
+ // In both cases, a simple copy is enough (UCS-2 is a subset of UCS-4,
+ // and UCS-4 *is* UTF-32).
- return input;
+ return input;
}
template <typename Out>
-Out Utf<32>::EncodeAnsi(Uint32 codepoint, Out output, char replacement, const std::locale& locale)
-{
- // On Windows, gcc's standard library (glibc++) has almost
- // no support for Unicode stuff. As a consequence, in this
- // context we can only use the default locale and ignore
- // the one passed as parameter.
-
- #if EFSW_PLATFORM == EFSW_PLATFORM_WIN && /* if Windows ... */ \
- (defined(__GLIBCPP__) || defined (__GLIBCXX__)) && /* ... and standard library is glibc++ ... */ \
- !(defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) /* ... and STLPort is not used on top of it */
-
- char character = 0;
- if (wctomb(&character, static_cast<wchar_t>(codepoint)) >= 0)
- *output++ = character;
- else if (replacement)
- *output++ = replacement;
-
- return output;
-
- #else
- // Get the facet of the locale which deals with character conversion
- #ifndef EFSW_NO_WIDECHAR
- const std::ctype<wchar_t>& facet = std::use_facet< std::ctype<wchar_t> >(locale);
- #else
- const std::ctype<char>& facet = std::use_facet< std::ctype<char> >(locale);
- #endif
+Out Utf<32>::EncodeAnsi( Uint32 codepoint, Out output, char replacement,
+ const std::locale& locale ) {
+ // On Windows, gcc's standard library (glibc++) has almost
+ // no support for Unicode stuff. As a consequence, in this
+ // context we can only use the default locale and ignore
+ // the one passed as parameter.
+
+#if EFSW_PLATFORM == EFSW_PLATFORM_WIN && /* if Windows ... */ \
+ ( defined( __GLIBCPP__ ) || \
+ defined( __GLIBCXX__ ) ) && /* ... and standard library is glibc++ ... */ \
+ !( defined( __SGI_STL_PORT ) || \
+ defined( _STLPORT_VERSION ) ) /* ... and STLPort is not used on top of it */
+
+ char character = 0;
+ if ( wctomb( &character, static_cast<wchar_t>( codepoint ) ) >= 0 )
+ *output++ = character;
+ else if ( replacement )
+ *output++ = replacement;
+
+ return output;
+
+#else
+// Get the facet of the locale which deals with character conversion
+#ifndef EFSW_NO_WIDECHAR
+ const std::ctype<wchar_t>& facet = std::use_facet<std::ctype<wchar_t>>( locale );
+#else
+ const std::ctype<char>& facet = std::use_facet<std::ctype<char>>( locale );
+#endif
- // Use the facet to convert each character of the input string
- *output++ = facet.narrow(static_cast<wchar_t>(codepoint), replacement);
+ // Use the facet to convert each character of the input string
+ *output++ = facet.narrow( static_cast<wchar_t>( codepoint ), replacement );
- return output;
+ return output;
- #endif
+#endif
}
#ifndef EFSW_NO_WIDECHAR
template <typename Out>
-Out Utf<32>::EncodeWide(Uint32 codepoint, Out output, wchar_t replacement)
-{
- // The encoding of wide characters is not well defined and is left to the system;
- // however we can safely assume that it is UCS-2 on Windows and
- // UCS-4 on Unix systems.
- // For UCS-2 we need to check if the source characters fits in (UCS-2 is a subset of UCS-4).
- // For UCS-4 we can do a direct copy (UCS-4 *is* UTF-32).
-
- switch (sizeof(wchar_t))
- {
- case 4:
- {
- *output++ = static_cast<wchar_t>(codepoint);
- break;
- }
-
- default:
- {
- if ((codepoint <= 0xFFFF) && ((codepoint < 0xD800) || (codepoint > 0xDFFF)))
- {
- *output++ = static_cast<wchar_t>(codepoint);
- }
- else if (replacement)
- {
- *output++ = replacement;
- }
- break;
- }
- }
-
- return output;
+Out Utf<32>::EncodeWide( Uint32 codepoint, Out output, wchar_t replacement ) {
+ // The encoding of wide characters is not well defined and is left to the system;
+ // however we can safely assume that it is UCS-2 on Windows and
+ // UCS-4 on Unix systems.
+ // For UCS-2 we need to check if the source characters fits in (UCS-2 is a subset of UCS-4).
+ // For UCS-4 we can do a direct copy (UCS-4 *is* UTF-32).
+
+ switch ( sizeof( wchar_t ) ) {
+ case 4: {
+ *output++ = static_cast<wchar_t>( codepoint );
+ break;
+ }
+
+ default: {
+ if ( ( codepoint <= 0xFFFF ) && ( ( codepoint < 0xD800 ) || ( codepoint > 0xDFFF ) ) ) {
+ *output++ = static_cast<wchar_t>( codepoint );
+ } else if ( replacement ) {
+ *output++ = replacement;
+ }
+ break;
+ }
+ }
+
+ return output;
}
#endif
diff --git a/dep/efsw/src/efsw/Watcher.cpp b/dep/efsw/src/efsw/Watcher.cpp
index d81c84228ad..913ae3c431a 100644
--- a/dep/efsw/src/efsw/Watcher.cpp
+++ b/dep/efsw/src/efsw/Watcher.cpp
@@ -2,20 +2,9 @@
namespace efsw {
-Watcher::Watcher() :
- ID(0),
- Directory(""),
- Listener(NULL),
- Recursive(false)
-{
-}
+Watcher::Watcher() : ID( 0 ), Directory( "" ), Listener( NULL ), Recursive( false ) {}
-Watcher::Watcher( WatchID id, std::string directory, FileWatchListener * listener, bool recursive ) :
- ID( id ),
- Directory( directory ),
- Listener( listener ),
- Recursive( recursive )
-{
-}
+Watcher::Watcher( WatchID id, std::string directory, FileWatchListener* listener, bool recursive ) :
+ ID( id ), Directory( directory ), Listener( listener ), Recursive( recursive ) {}
-}
+} // namespace efsw
diff --git a/dep/efsw/src/efsw/Watcher.hpp b/dep/efsw/src/efsw/Watcher.hpp
index 5a35cb9a2ac..84f0980bc47 100644
--- a/dep/efsw/src/efsw/Watcher.hpp
+++ b/dep/efsw/src/efsw/Watcher.hpp
@@ -7,24 +7,23 @@
namespace efsw {
/** @brief Base Watcher class */
-class Watcher
-{
- public:
- Watcher();
+class Watcher {
+ public:
+ Watcher();
- Watcher( WatchID id, std::string directory, FileWatchListener * listener, bool recursive );
+ Watcher( WatchID id, std::string directory, FileWatchListener* listener, bool recursive );
- virtual ~Watcher() {}
+ virtual ~Watcher() {}
- virtual void watch() {}
+ virtual void watch() {}
- WatchID ID;
- std::string Directory;
- FileWatchListener * Listener;
- bool Recursive;
- std::string OldFileName;
+ WatchID ID;
+ std::string Directory;
+ FileWatchListener* Listener;
+ bool Recursive;
+ std::string OldFileName;
};
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/WatcherFSEvents.cpp b/dep/efsw/src/efsw/WatcherFSEvents.cpp
index a13a743b01e..3621df746b5 100644
--- a/dep/efsw/src/efsw/WatcherFSEvents.cpp
+++ b/dep/efsw/src/efsw/WatcherFSEvents.cpp
@@ -1,39 +1,25 @@
-#include <efsw/WatcherFSEvents.hpp>
-#include <efsw/FileWatcherFSEvents.hpp>
-#include <efsw/FileSystem.hpp>
#include <efsw/Debug.hpp>
+#include <efsw/FileSystem.hpp>
+#include <efsw/FileWatcherFSEvents.hpp>
+#include <efsw/WatcherFSEvents.hpp>
#if EFSW_PLATFORM == EFSW_PLATFORM_FSEVENTS
namespace efsw {
WatcherFSEvents::WatcherFSEvents() :
- Watcher(),
- FWatcher( NULL ),
- FSStream( NULL ),
- WatcherGen( NULL ),
- initializedAsync( false )
-{
-}
+ Watcher(), FWatcher( NULL ), FSStream( NULL ), WatcherGen( NULL ) {}
-WatcherFSEvents::WatcherFSEvents( WatchID id, std::string directory, FileWatchListener * listener, bool recursive, WatcherFSEvents * parent ) :
+WatcherFSEvents::WatcherFSEvents( WatchID id, std::string directory, FileWatchListener* listener,
+ bool recursive, WatcherFSEvents* parent ) :
Watcher( id, directory, listener, recursive ),
FWatcher( NULL ),
FSStream( NULL ),
- WatcherGen( NULL ),
- initializedAsync( false )
-{
-}
-
-WatcherFSEvents::~WatcherFSEvents()
-{
- if ( NULL != FSStream )
- {
- if ( initializedAsync )
- {
- FSEventStreamStop( FSStream );
- }
+ WatcherGen( NULL ) {}
+WatcherFSEvents::~WatcherFSEvents() {
+ if ( NULL != FSStream ) {
+ FSEventStreamStop( FSStream );
FSEventStreamInvalidate( FSStream );
FSEventStreamRelease( FSStream );
}
@@ -41,22 +27,19 @@ WatcherFSEvents::~WatcherFSEvents()
efSAFE_DELETE( WatcherGen );
}
-void WatcherFSEvents::init()
-{
- CFStringRef CFDirectory = CFStringCreateWithCString( NULL, Directory.c_str(), kCFStringEncodingUTF8 );
- CFArrayRef CFDirectoryArray = CFArrayCreate( NULL, (const void **)&CFDirectory, 1, NULL );
-
+void WatcherFSEvents::init() {
+ CFStringRef CFDirectory =
+ CFStringCreateWithCString( NULL, Directory.c_str(), kCFStringEncodingUTF8 );
+ CFArrayRef CFDirectoryArray = CFArrayCreate( NULL, (const void**)&CFDirectory, 1, NULL );
+
Uint32 streamFlags = kFSEventStreamCreateFlagNone;
-
- if ( FileWatcherFSEvents::isGranular() )
- {
- streamFlags = efswFSEventStreamCreateFlagFileEvents;
- }
- else
- {
- WatcherGen = new WatcherGeneric( ID, Directory, Listener, FWatcher, Recursive );
+
+ if ( FileWatcherFSEvents::isGranular() ) {
+ streamFlags = efswFSEventStreamCreateFlagFileEvents | efswFSEventStreamCreateFlagNoDefer;
+ } else {
+ WatcherGen = new WatcherGeneric( ID, Directory, Listener, FWatcher.load(), Recursive );
}
-
+
FSEventStreamContext ctx;
/* Initialize context */
ctx.version = 0;
@@ -65,200 +48,161 @@ void WatcherFSEvents::init()
ctx.release = NULL;
ctx.copyDescription = NULL;
- FSStream = FSEventStreamCreate( kCFAllocatorDefault, &FileWatcherFSEvents::FSEventCallback, &ctx, CFDirectoryArray, kFSEventStreamEventIdSinceNow, 0.25, streamFlags );
+ dispatch_queue_t queue = dispatch_queue_create(NULL, NULL);
- FWatcher->mNeedInit.push_back( this );
+ FSStream =
+ FSEventStreamCreate( kCFAllocatorDefault, &FileWatcherFSEvents::FSEventCallback, &ctx,
+ CFDirectoryArray, kFSEventStreamEventIdSinceNow, 0., streamFlags );
- CFRelease( CFDirectoryArray );
- CFRelease( CFDirectory );
-}
+ FSEventStreamSetDispatchQueue(FSStream, queue);
-void WatcherFSEvents::initAsync()
-{
- FSEventStreamScheduleWithRunLoop( FSStream, FWatcher->mRunLoopRef, kCFRunLoopDefaultMode );
FSEventStreamStart( FSStream );
- initializedAsync = true;
+
+ CFRelease( CFDirectoryArray );
+ CFRelease( CFDirectory );
}
-void WatcherFSEvents::sendFileAction( WatchID watchid, const std::string& dir, const std::string& filename, Action action, std::string oldFilename )
-{
- Listener->handleFileAction( watchid, FileSystem::precomposeFileName( dir ), FileSystem::precomposeFileName( filename ), action, oldFilename );
+void WatcherFSEvents::sendFileAction( WatchID watchid, const std::string& dir,
+ const std::string& filename, Action action,
+ std::string oldFilename ) {
+ Listener->handleFileAction( watchid, FileSystem::precomposeFileName( dir ),
+ FileSystem::precomposeFileName( filename ), action, FileSystem::precomposeFileName( oldFilename ) );
}
-void WatcherFSEvents::handleAddModDel( const Uint32& flags, const std::string& path, std::string& dirPath, std::string& filePath )
-{
- if ( flags & efswFSEventStreamEventFlagItemCreated )
- {
- if ( FileInfo::exists( path ) )
- {
+void WatcherFSEvents::handleAddModDel( const Uint32& flags, const std::string& path,
+ std::string& dirPath, std::string& filePath ) {
+ if ( flags & efswFSEventStreamEventFlagItemCreated ) {
+ if ( FileInfo::exists( path ) ) {
sendFileAction( ID, dirPath, filePath, Actions::Add );
}
}
- if ( flags & efswFSEventsModified )
- {
+ if ( flags & efswFSEventsModified ) {
sendFileAction( ID, dirPath, filePath, Actions::Modified );
}
- if ( flags & efswFSEventStreamEventFlagItemRemoved )
- {
- // Since i don't know the order, at least i try to keep the data consistent with the real state
- if ( !FileInfo::exists( path ) )
- {
+ if ( flags & efswFSEventStreamEventFlagItemRemoved ) {
+ // Since i don't know the order, at least i try to keep the data consistent with the real
+ // state
+ if ( !FileInfo::exists( path ) ) {
sendFileAction( ID, dirPath, filePath, Actions::Delete );
}
}
}
-void WatcherFSEvents::handleActions( std::vector<FSEvent>& events )
-{
+void WatcherFSEvents::handleActions( std::vector<FSEvent>& events ) {
size_t esize = events.size();
- for ( size_t i = 0; i < esize; i++ )
- {
+ for ( size_t i = 0; i < esize; i++ ) {
FSEvent& event = events[i];
- if ( event.Flags & ( kFSEventStreamEventFlagUserDropped |
- kFSEventStreamEventFlagKernelDropped |
- kFSEventStreamEventFlagEventIdsWrapped |
- kFSEventStreamEventFlagHistoryDone |
- kFSEventStreamEventFlagMount |
- kFSEventStreamEventFlagUnmount |
- kFSEventStreamEventFlagRootChanged ) )
- {
+ if ( event.Flags &
+ ( kFSEventStreamEventFlagUserDropped | kFSEventStreamEventFlagKernelDropped |
+ kFSEventStreamEventFlagEventIdsWrapped | kFSEventStreamEventFlagHistoryDone |
+ kFSEventStreamEventFlagMount | kFSEventStreamEventFlagUnmount |
+ kFSEventStreamEventFlagRootChanged ) ) {
continue;
}
- if ( !Recursive )
- {
+ if ( !Recursive ) {
/** In case that is not recursive the watcher, ignore the events from subfolders */
- if ( event.Path.find_last_of( FileSystem::getOSSlash() ) != Directory.size() - 1 )
- {
+ if ( event.Path.find_last_of( FileSystem::getOSSlash() ) != Directory.size() - 1 ) {
continue;
}
}
- if ( FileWatcherFSEvents::isGranular() )
- {
+ if ( FileWatcherFSEvents::isGranular() ) {
std::string dirPath( FileSystem::pathRemoveFileName( event.Path ) );
std::string filePath( FileSystem::fileNameFromPath( event.Path ) );
- if ( event.Flags & ( efswFSEventStreamEventFlagItemCreated |
- efswFSEventStreamEventFlagItemRemoved |
- efswFSEventStreamEventFlagItemRenamed )
- )
- {
- if ( dirPath != Directory )
- {
+ if ( event.Flags &
+ ( efswFSEventStreamEventFlagItemCreated | efswFSEventStreamEventFlagItemRemoved |
+ efswFSEventStreamEventFlagItemRenamed ) ) {
+ if ( dirPath != Directory ) {
DirsChanged.insert( dirPath );
}
}
- // This is a mess. But it's FSEvents faults, because shrinks events from the same file in one single event ( so there's no order for them )
- // For example a file could have been added modified and erased, but i can't know if first was erased and then added and modified, or added, then modified and then erased.
- // I don't know what they were thinking by doing this...
- efDEBUG( "Event in: %s - flags: %ld\n", path.c_str(), event.Flags );
-
- if ( event.Flags & efswFSEventStreamEventFlagItemRenamed )
- {
- if ( ( i + 1 < esize ) &&
- ( events[ i + 1 ].Flags & efswFSEventStreamEventFlagItemRenamed ) &&
- ( events[ i + 1 ].Id == event.Id + 1 )
- )
- {
- FSEvent& nEvent = events[ i + 1 ];
+ // This is a mess. But it's FSEvents faults, because shrinks events from the same file
+ // in one single event ( so there's no order for them ) For example a file could have
+ // been added modified and erased, but i can't know if first was erased and then added
+ // and modified, or added, then modified and then erased. I don't know what they were
+ // thinking by doing this...
+ efDEBUG( "Event in: %s - flags: %ld\n", event.Path.c_str(), event.Flags );
+
+ if ( event.Flags & efswFSEventStreamEventFlagItemRenamed ) {
+ if ( ( i + 1 < esize ) &&
+ ( events[i + 1].Flags & efswFSEventStreamEventFlagItemRenamed ) &&
+ ( events[i + 1].Id == event.Id + 1 ) ) {
+ FSEvent& nEvent = events[i + 1];
std::string newDir( FileSystem::pathRemoveFileName( nEvent.Path ) );
std::string newFilepath( FileSystem::fileNameFromPath( nEvent.Path ) );
- if ( event.Path != nEvent.Path )
- {
- if ( dirPath == newDir )
- {
- if ( !FileInfo::exists( event.Path ) )
- {
- sendFileAction( ID, dirPath, newFilepath, Actions::Moved, filePath );
+ if ( event.Path != nEvent.Path ) {
+ if ( dirPath == newDir ) {
+ if ( !FileInfo::exists( event.Path ) ) {
+ sendFileAction( ID, dirPath, newFilepath, Actions::Moved,
+ filePath );
+ } else {
+ sendFileAction( ID, dirPath, filePath, Actions::Moved,
+ newFilepath );
}
- else
- {
- sendFileAction( ID, dirPath, filePath, Actions::Moved, newFilepath );
- }
- }
- else
- {
+ } else {
sendFileAction( ID, dirPath, filePath, Actions::Delete );
sendFileAction( ID, newDir, newFilepath, Actions::Add );
- if ( nEvent.Flags & efswFSEventsModified )
- {
+ if ( nEvent.Flags & efswFSEventsModified ) {
sendFileAction( ID, newDir, newFilepath, Actions::Modified );
}
}
- }
- else
- {
+ } else {
handleAddModDel( nEvent.Flags, nEvent.Path, dirPath, filePath );
}
- if ( nEvent.Flags & ( efswFSEventStreamEventFlagItemCreated |
- efswFSEventStreamEventFlagItemRemoved |
- efswFSEventStreamEventFlagItemRenamed )
- )
- {
- if ( newDir != Directory )
- {
+ if ( nEvent.Flags & ( efswFSEventStreamEventFlagItemCreated |
+ efswFSEventStreamEventFlagItemRemoved |
+ efswFSEventStreamEventFlagItemRenamed ) ) {
+ if ( newDir != Directory ) {
DirsChanged.insert( newDir );
}
}
// Skip the renamed file
i++;
- }
- else if ( FileInfo::exists( event.Path ) )
- {
+ } else if ( FileInfo::exists( event.Path ) ) {
sendFileAction( ID, dirPath, filePath, Actions::Add );
- if ( event.Flags & efswFSEventsModified )
- {
+ if ( event.Flags & efswFSEventsModified ) {
sendFileAction( ID, dirPath, filePath, Actions::Modified );
}
- }
- else
- {
+ } else {
sendFileAction( ID, dirPath, filePath, Actions::Delete );
}
- }
- else
- {
+ } else {
handleAddModDel( event.Flags, event.Path, dirPath, filePath );
}
- }
- else
- {
+ } else {
efDEBUG( "Directory: %s changed\n", event.Path.c_str() );
DirsChanged.insert( event.Path );
}
}
}
-void WatcherFSEvents::process()
-{
+void WatcherFSEvents::process() {
std::set<std::string>::iterator it = DirsChanged.begin();
- for ( ; it != DirsChanged.end(); it++ )
- {
- if ( !FileWatcherFSEvents::isGranular() )
- {
- WatcherGen->watchDir( (*it) );
- }
- else
- {
- sendFileAction( ID, FileSystem::pathRemoveFileName( (*it) ), FileSystem::fileNameFromPath( (*it) ), Actions::Modified );
+ for ( ; it != DirsChanged.end(); it++ ) {
+ if ( !FileWatcherFSEvents::isGranular() ) {
+ WatcherGen->watchDir( ( *it ) );
+ } else {
+ sendFileAction( ID, FileSystem::pathRemoveFileName( ( *it ) ),
+ FileSystem::fileNameFromPath( ( *it ) ), Actions::Modified );
}
}
DirsChanged.clear();
}
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/WatcherFSEvents.hpp b/dep/efsw/src/efsw/WatcherFSEvents.hpp
index d4fc5c9a8d3..a18c06d40b9 100644
--- a/dep/efsw/src/efsw/WatcherFSEvents.hpp
+++ b/dep/efsw/src/efsw/WatcherFSEvents.hpp
@@ -5,10 +5,10 @@
#if EFSW_PLATFORM == EFSW_PLATFORM_FSEVENTS
-#include <efsw/WatcherGeneric.hpp>
-#include <efsw/FileInfo.hpp>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
+#include <efsw/FileInfo.hpp>
+#include <efsw/WatcherGeneric.hpp>
#include <set>
#include <vector>
@@ -16,54 +16,46 @@ namespace efsw {
class FileWatcherFSEvents;
-class FSEvent
-{
- public:
- FSEvent( std::string path, long flags, Uint64 id ) :
- Path( path ),
- Flags( flags ),
- Id ( id )
- {
- }
-
- std::string Path;
- long Flags;
- Uint64 Id;
+class FSEvent {
+ public:
+ FSEvent( std::string path, long flags, Uint64 id ) : Path( path ), Flags( flags ), Id( id ) {}
+
+ std::string Path;
+ long Flags;
+ Uint64 Id;
};
-class WatcherFSEvents : public Watcher
-{
- public:
- WatcherFSEvents();
-
- WatcherFSEvents( WatchID id, std::string directory, FileWatchListener * listener, bool recursive, WatcherFSEvents * parent = NULL );
-
- ~WatcherFSEvents();
+class WatcherFSEvents : public Watcher {
+ public:
+ WatcherFSEvents();
- void init();
+ WatcherFSEvents( WatchID id, std::string directory, FileWatchListener* listener, bool recursive,
+ WatcherFSEvents* parent = NULL );
- void initAsync();
+ ~WatcherFSEvents();
- void handleActions( std::vector<FSEvent> & events );
+ void init();
- void process();
+ void handleActions( std::vector<FSEvent>& events );
- FileWatcherFSEvents * FWatcher;
+ void process();
- FSEventStreamRef FSStream;
- protected:
- void handleAddModDel( const Uint32 &flags, const std::string &path, std::string &dirPath, std::string &filePath );
+ Atomic<FileWatcherFSEvents*> FWatcher;
+ FSEventStreamRef FSStream;
- WatcherGeneric * WatcherGen;
+ protected:
+ void handleAddModDel( const Uint32& flags, const std::string& path, std::string& dirPath,
+ std::string& filePath );
- bool initializedAsync;
+ WatcherGeneric* WatcherGen;
- std::set<std::string> DirsChanged;
+ std::set<std::string> DirsChanged;
- void sendFileAction( WatchID watchid, const std::string& dir, const std::string& filename, Action action, std::string oldFilename = "" );
+ void sendFileAction( WatchID watchid, const std::string& dir, const std::string& filename,
+ Action action, std::string oldFilename = "" );
};
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/WatcherGeneric.cpp b/dep/efsw/src/efsw/WatcherGeneric.cpp
index 94170d3ce87..a6bb10619be 100644
--- a/dep/efsw/src/efsw/WatcherGeneric.cpp
+++ b/dep/efsw/src/efsw/WatcherGeneric.cpp
@@ -1,15 +1,12 @@
-#include <efsw/WatcherGeneric.hpp>
-#include <efsw/FileSystem.hpp>
#include <efsw/DirWatcherGeneric.hpp>
+#include <efsw/FileSystem.hpp>
+#include <efsw/WatcherGeneric.hpp>
-namespace efsw
-{
+namespace efsw {
-WatcherGeneric::WatcherGeneric( WatchID id, const std::string& directory, FileWatchListener * fwl, FileWatcherImpl * fw, bool recursive ) :
- Watcher( id, directory, fwl, recursive ),
- WatcherImpl( fw ),
- DirWatch( NULL )
-{
+WatcherGeneric::WatcherGeneric( WatchID id, const std::string& directory, FileWatchListener* fwl,
+ FileWatcherImpl* fw, bool recursive ) :
+ Watcher( id, directory, fwl, recursive ), WatcherImpl( fw ), DirWatch( NULL ) {
FileSystem::dirAddSlashAtEnd( Directory );
DirWatch = new DirWatcherGeneric( NULL, this, directory, recursive, false );
@@ -17,24 +14,20 @@ WatcherGeneric::WatcherGeneric( WatchID id, const std::string& directory, FileWa
DirWatch->addChilds( false );
}
-WatcherGeneric::~WatcherGeneric()
-{
+WatcherGeneric::~WatcherGeneric() {
efSAFE_DELETE( DirWatch );
}
-void WatcherGeneric::watch()
-{
+void WatcherGeneric::watch() {
DirWatch->watch();
}
-void WatcherGeneric::watchDir( std::string dir )
-{
+void WatcherGeneric::watchDir( std::string dir ) {
DirWatch->watchDir( dir );
}
-bool WatcherGeneric::pathInWatches( std::string path )
-{
+bool WatcherGeneric::pathInWatches( std::string path ) {
return DirWatch->pathInWatches( path );
}
-}
+} // namespace efsw
diff --git a/dep/efsw/src/efsw/WatcherGeneric.hpp b/dep/efsw/src/efsw/WatcherGeneric.hpp
index 8794e921b40..d11ec20efd5 100644
--- a/dep/efsw/src/efsw/WatcherGeneric.hpp
+++ b/dep/efsw/src/efsw/WatcherGeneric.hpp
@@ -3,28 +3,27 @@
#include <efsw/FileWatcherImpl.hpp>
-namespace efsw
-{
+namespace efsw {
class DirWatcherGeneric;
-class WatcherGeneric : public Watcher
-{
- public:
- FileWatcherImpl * WatcherImpl;
- DirWatcherGeneric * DirWatch;
+class WatcherGeneric : public Watcher {
+ public:
+ FileWatcherImpl* WatcherImpl;
+ DirWatcherGeneric* DirWatch;
- WatcherGeneric( WatchID id, const std::string& directory, FileWatchListener * fwl, FileWatcherImpl * fw, bool recursive );
+ WatcherGeneric( WatchID id, const std::string& directory, FileWatchListener* fwl,
+ FileWatcherImpl* fw, bool recursive );
- ~WatcherGeneric();
+ ~WatcherGeneric();
- void watch();
+ void watch() override;
- void watchDir( std::string dir );
+ void watchDir( std::string dir );
- bool pathInWatches( std::string path );
+ bool pathInWatches( std::string path );
};
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/WatcherInotify.cpp b/dep/efsw/src/efsw/WatcherInotify.cpp
index 741641bf43c..812ddaee44c 100644
--- a/dep/efsw/src/efsw/WatcherInotify.cpp
+++ b/dep/efsw/src/efsw/WatcherInotify.cpp
@@ -2,27 +2,13 @@
namespace efsw {
-WatcherInotify::WatcherInotify() :
- Watcher(),
- Parent( NULL )
-{
-}
-
-WatcherInotify::WatcherInotify( WatchID id, std::string directory, FileWatchListener * listener, bool recursive, WatcherInotify * parent ) :
- Watcher( id, directory, listener, recursive ),
- Parent( parent ),
- DirInfo( directory )
-{
-}
+WatcherInotify::WatcherInotify() : Watcher(), Parent( NULL ) {}
-bool WatcherInotify::inParentTree( WatcherInotify * parent )
-{
- WatcherInotify * tNext = Parent;
+bool WatcherInotify::inParentTree( WatcherInotify* parent ) {
+ WatcherInotify* tNext = Parent;
- while ( NULL != tNext )
- {
- if ( tNext == parent )
- {
+ while ( NULL != tNext ) {
+ if ( tNext == parent ) {
return true;
}
@@ -31,5 +17,5 @@ bool WatcherInotify::inParentTree( WatcherInotify * parent )
return false;
}
-
-}
+
+} // namespace efsw
diff --git a/dep/efsw/src/efsw/WatcherInotify.hpp b/dep/efsw/src/efsw/WatcherInotify.hpp
index 1caf399679b..d43935c5009 100644
--- a/dep/efsw/src/efsw/WatcherInotify.hpp
+++ b/dep/efsw/src/efsw/WatcherInotify.hpp
@@ -1,25 +1,23 @@
-#ifndef EFSW_WATCHERINOTIFY_HPP
+#ifndef EFSW_WATCHERINOTIFY_HPP
#define EFSW_WATCHERINOTIFY_HPP
-#include <efsw/FileWatcherImpl.hpp>
#include <efsw/FileInfo.hpp>
+#include <efsw/FileWatcherImpl.hpp>
namespace efsw {
-class WatcherInotify : public Watcher
-{
- public:
- WatcherInotify();
-
- WatcherInotify( WatchID id, std::string directory, FileWatchListener * listener, bool recursive, WatcherInotify * parent = NULL );
+class WatcherInotify : public Watcher {
+ public:
+ WatcherInotify();
- bool inParentTree( WatcherInotify * parent );
+ bool inParentTree( WatcherInotify* parent );
- WatcherInotify * Parent;
+ WatcherInotify* Parent;
+ WatchID InotifyID;
- FileInfo DirInfo;
+ FileInfo DirInfo;
};
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/WatcherKqueue.cpp b/dep/efsw/src/efsw/WatcherKqueue.cpp
index 8347fb53439..397264162e5 100644
--- a/dep/efsw/src/efsw/WatcherKqueue.cpp
+++ b/dep/efsw/src/efsw/WatcherKqueue.cpp
@@ -2,38 +2,36 @@
#if EFSW_PLATFORM == EFSW_PLATFORM_KQUEUE || EFSW_PLATFORM == EFSW_PLATFORM_FSEVENTS
-#include <sys/stat.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
+#include <dirent.h>
#include <efsw/Debug.hpp>
+#include <efsw/FileSystem.hpp>
+#include <efsw/FileWatcherKqueue.hpp>
#include <efsw/String.hpp>
#include <efsw/System.hpp>
-#include <efsw/FileSystem.hpp>
#include <efsw/WatcherGeneric.hpp>
-#include <efsw/FileWatcherKqueue.hpp>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
-#define KEVENT_RESERVE_VALUE (10)
+#define KEVENT_RESERVE_VALUE ( 10 )
#ifndef O_EVTONLY
-#define O_EVTONLY (O_RDONLY | O_NONBLOCK)
+#define O_EVTONLY ( O_RDONLY | O_NONBLOCK )
#endif
namespace efsw {
-int comparator(const void* ke1, const void* ke2)
-{
- const KEvent * kev1 = reinterpret_cast<const KEvent*>( ke1 );
- const KEvent * kev2 = reinterpret_cast<const KEvent*>( ke2 );
+int comparator( const void* ke1, const void* ke2 ) {
+ const KEvent* kev1 = reinterpret_cast<const KEvent*>( ke1 );
+ const KEvent* kev2 = reinterpret_cast<const KEvent*>( ke2 );
- if ( NULL != kev2->udata )
- {
- FileInfo * fi1 = reinterpret_cast<FileInfo*>( kev1->udata );
- FileInfo * fi2 = reinterpret_cast<FileInfo*>( kev2->udata );
+ if ( NULL != kev2->udata ) {
+ FileInfo* fi1 = reinterpret_cast<FileInfo*>( kev1->udata );
+ FileInfo* fi2 = reinterpret_cast<FileInfo*>( kev2->udata );
return strcmp( fi1->Filepath.c_str(), fi2->Filepath.c_str() );
}
@@ -41,75 +39,68 @@ int comparator(const void* ke1, const void* ke2)
return 1;
}
-WatcherKqueue::WatcherKqueue(WatchID watchid, const std::string& dirname, FileWatchListener* listener, bool recursive, FileWatcherKqueue * watcher, WatcherKqueue * parent ) :
+WatcherKqueue::WatcherKqueue( WatchID watchid, const std::string& dirname,
+ FileWatchListener* listener, bool recursive,
+ FileWatcherKqueue* watcher, WatcherKqueue* parent ) :
Watcher( watchid, dirname, listener, recursive ),
- mLastWatchID(0),
+ mLastWatchID( 0 ),
mChangeListCount( 0 ),
mKqueue( kqueue() ),
mWatcher( watcher ),
mParent( parent ),
mInitOK( true ),
- mErrno(0)
-{
- if ( -1 == mKqueue )
- {
- efDEBUG( "kqueue() returned invalid descriptor for directory %s. File descriptors count: %ld\n", Directory.c_str(), mWatcher->mFileDescriptorCount );
-
+ mErrno( 0 ) {
+ if ( -1 == mKqueue ) {
+ efDEBUG(
+ "kqueue() returned invalid descriptor for directory %s. File descriptors count: %ld\n",
+ Directory.c_str(), mWatcher->mFileDescriptorCount );
+
mInitOK = false;
mErrno = errno;
- }
- else
- {
+ } else {
mWatcher->addFD();
}
}
-WatcherKqueue::~WatcherKqueue()
-{
+WatcherKqueue::~WatcherKqueue() {
// Remove the childs watchers ( sub-folders watches )
removeAll();
- for ( size_t i = 0; i < mChangeListCount; i++ )
- {
- if ( NULL != mChangeList[i].udata )
- {
- FileInfo * fi = reinterpret_cast<FileInfo*>( mChangeList[i].udata );
+ for ( size_t i = 0; i < mChangeListCount; i++ ) {
+ if ( NULL != mChangeList[i].udata ) {
+ FileInfo* fi = reinterpret_cast<FileInfo*>( mChangeList[i].udata );
efSAFE_DELETE( fi );
}
}
close( mKqueue );
-
+
mWatcher->removeFD();
}
-void WatcherKqueue::addAll()
-{
- if ( -1 == mKqueue )
- {
+void WatcherKqueue::addAll() {
+ if ( -1 == mKqueue ) {
return;
}
// scan directory and call addFile(name, false) on each file
FileSystem::dirAddSlashAtEnd( Directory );
- efDEBUG( "addAll(): Added folder: %s\n", Directory.c_str());
+ efDEBUG( "addAll(): Added folder: %s\n", Directory.c_str() );
// add base dir
int fd = open( Directory.c_str(), O_EVTONLY );
-
- if ( -1 == fd )
- {
+
+ if ( -1 == fd ) {
efDEBUG( "addAll(): Couldn't open folder: %s\n", Directory.c_str() );
-
- if ( EACCES != errno )
- {
+
+ if ( EACCES != errno ) {
mInitOK = false;
}
mErrno = errno;
-
+
return;
}
@@ -119,83 +110,66 @@ void WatcherKqueue::addAll()
mChangeList.resize( KEVENT_RESERVE_VALUE );
// Creates the kevent for the folder
- EV_SET(
- &mChangeList[0],
- fd,
- EVFILT_VNODE,
- EV_ADD | EV_ENABLE | EV_ONESHOT,
- NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB | NOTE_RENAME,
- 0,
- 0
- );
+ EV_SET( &mChangeList[0], fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
+ NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB | NOTE_RENAME, 0, 0 );
mWatcher->addFD();
// Get the files and directories from the directory
FileInfoMap files = FileSystem::filesInfoFromPath( Directory );
- for ( FileInfoMap::iterator it = files.begin(); it != files.end(); it++ )
- {
+ for ( FileInfoMap::iterator it = files.begin(); it != files.end(); it++ ) {
FileInfo& fi = it->second;
- if ( fi.isRegularFile() )
- {
+ if ( fi.isRegularFile() ) {
// Add the regular files kevent
- addFile( fi.Filepath , false );
- }
- else if ( Recursive && fi.isDirectory() && fi.isReadable() )
- {
+ addFile( fi.Filepath, false );
+ } else if ( Recursive && fi.isDirectory() && fi.isReadable() ) {
// Create another watcher for the subfolders ( if recursive )
WatchID id = addWatch( fi.Filepath, Listener, Recursive, this );
// If the watcher is not adding the watcher means that the directory was created
- if ( id > 0 && !mWatcher->isAddingWatcher() )
- {
+ if ( id > 0 && !mWatcher->isAddingWatcher() ) {
handleFolderAction( fi.Filepath, Actions::Add );
}
}
}
}
-void WatcherKqueue::removeAll()
-{
+void WatcherKqueue::removeAll() {
efDEBUG( "removeAll(): Removing all child watchers\n" );
- std::list<WatchID> erase;
+ std::vector<WatchID> erase;
- for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); it++ )
- {
+ for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); it++ ) {
efDEBUG( "removeAll(): Removed child watcher %s\n", it->second->Directory.c_str() );
erase.push_back( it->second->ID );
}
- for ( std::list<WatchID>::iterator eit = erase.begin(); eit != erase.end(); eit++ )
- {
+ for ( std::vector<WatchID>::iterator eit = erase.begin(); eit != erase.end(); eit++ ) {
removeWatch( *eit );
}
}
-void WatcherKqueue::addFile(const std::string& name, bool emitEvents)
-{
+void WatcherKqueue::addFile( const std::string& name, bool emitEvents ) {
efDEBUG( "addFile(): Added: %s\n", name.c_str() );
// Open the file to get the file descriptor
int fd = open( name.c_str(), O_EVTONLY );
- if( fd == -1 )
- {
- efDEBUG( "addFile(): Could open file descriptor for %s. File descriptor count: %ld\n", name.c_str(), mWatcher->mFileDescriptorCount );
-
+ if ( fd == -1 ) {
+ efDEBUG( "addFile(): Could open file descriptor for %s. File descriptor count: %ld\n",
+ name.c_str(), mWatcher->mFileDescriptorCount );
+
Errors::Log::createLastError( Errors::FileNotReadable, name );
-
- if ( EACCES != errno )
- {
+
+ if ( EACCES != errno ) {
mInitOK = false;
}
mErrno = errno;
-
+
return;
}
@@ -205,39 +179,31 @@ void WatcherKqueue::addFile(const std::string& name, bool emitEvents)
mChangeListCount++;
if ( mChangeListCount + KEVENT_RESERVE_VALUE > mChangeList.size() &&
- mChangeListCount % KEVENT_RESERVE_VALUE == 0 )
- {
+ mChangeListCount % KEVENT_RESERVE_VALUE == 0 ) {
size_t reserve_size = mChangeList.size() + KEVENT_RESERVE_VALUE;
mChangeList.resize( reserve_size );
- efDEBUG( "addFile(): Reserverd more KEvents space for %s, space reserved %ld, list actual size %ld.\n", Directory.c_str(), reserve_size, mChangeListCount );
+ efDEBUG( "addFile(): Reserverd more KEvents space for %s, space reserved %ld, list actual "
+ "size %ld.\n",
+ Directory.c_str(), reserve_size, mChangeListCount );
}
// create entry
- FileInfo * entry = new FileInfo( name );
+ FileInfo* entry = new FileInfo( name );
// set the event data at the end of the list
- EV_SET(
- &mChangeList[mChangeListCount],
- fd,
- EVFILT_VNODE,
- EV_ADD | EV_ENABLE | EV_ONESHOT,
- NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB | NOTE_RENAME,
- 0,
- (void*)entry
- );
+ EV_SET( &mChangeList[mChangeListCount], fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
+ NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB | NOTE_RENAME, 0, (void*)entry );
// qsort sort the list by name
- qsort(&mChangeList[1], mChangeListCount, sizeof(KEvent), comparator);
+ qsort( &mChangeList[1], mChangeListCount, sizeof( KEvent ), comparator );
// handle action
- if( emitEvents )
- {
- handleAction(name, Actions::Add);
+ if ( emitEvents ) {
+ handleAction( name, Actions::Add );
}
}
-void WatcherKqueue::removeFile( const std::string& name, bool emitEvents )
-{
+void WatcherKqueue::removeFile( const std::string& name, bool emitEvents ) {
efDEBUG( "removeFile(): Trying to remove file: %s\n", name.c_str() );
// bsearch
@@ -249,11 +215,11 @@ void WatcherKqueue::removeFile( const std::string& name, bool emitEvents )
target.udata = &tempEntry;
// Search the kevent
- KEvent * ke = (KEvent*)bsearch(&target, &mChangeList[0], mChangeListCount + 1, sizeof(KEvent), comparator);
+ KEvent* ke = (KEvent*)bsearch( &target, &mChangeList[0], mChangeListCount + 1, sizeof( KEvent ),
+ comparator );
// Trying to remove a non-existing file?
- if( !ke )
- {
+ if ( !ke ) {
Errors::Log::createLastError( Errors::FileNotFound, name );
efDEBUG( "File not removed\n" );
return;
@@ -262,13 +228,12 @@ void WatcherKqueue::removeFile( const std::string& name, bool emitEvents )
efDEBUG( "File removed\n" );
// handle action
- if ( emitEvents )
- {
+ if ( emitEvents ) {
handleAction( name, Actions::Delete );
}
// Delete the user data ( FileInfo ) from the kevent closed
- FileInfo * del = reinterpret_cast<FileInfo*>( ke->udata );
+ FileInfo* del = reinterpret_cast<FileInfo*>( ke->udata );
efSAFE_DELETE( del );
@@ -277,121 +242,104 @@ void WatcherKqueue::removeFile( const std::string& name, bool emitEvents )
mWatcher->removeFD();
- memset(ke, 0, sizeof(KEvent));
+ memset( ke, 0, sizeof( KEvent ) );
// move end to current
- memcpy(ke, &mChangeList[mChangeListCount], sizeof(KEvent));
- memset(&mChangeList[mChangeListCount], 0, sizeof(KEvent));
+ memcpy( ke, &mChangeList[mChangeListCount], sizeof( KEvent ) );
+ memset( &mChangeList[mChangeListCount], 0, sizeof( KEvent ) );
--mChangeListCount;
}
-void WatcherKqueue::rescan()
-{
+void WatcherKqueue::rescan() {
efDEBUG( "rescan(): Rescanning: %s\n", Directory.c_str() );
DirectorySnapshotDiff Diff = mDirSnap.scan();
- if ( Diff.DirChanged )
- {
+ if ( Diff.DirChanged ) {
sendDirChanged();
}
- if ( Diff.changed() )
- {
+ if ( Diff.changed() ) {
FileInfoList::iterator it;
MovedList::iterator mit;
/// Files
- DiffIterator( FilesCreated )
- {
- addFile( (*it).Filepath );
+ DiffIterator( FilesCreated ) {
+ addFile( ( *it ).Filepath );
}
- DiffIterator( FilesModified )
- {
- handleAction( (*it).Filepath, Actions::Modified );
+ DiffIterator( FilesModified ) {
+ handleAction( ( *it ).Filepath, Actions::Modified );
}
- DiffIterator( FilesDeleted )
- {
- removeFile( (*it).Filepath );
+ DiffIterator( FilesDeleted ) {
+ removeFile( ( *it ).Filepath );
}
- DiffMovedIterator( FilesMoved )
- {
- handleAction( (*mit).second.Filepath, Actions::Moved, (*mit).first );
- removeFile( Directory + (*mit).first, false );
- addFile( (*mit).second.Filepath, false );
+ DiffMovedIterator( FilesMoved ) {
+ handleAction( ( *mit ).second.Filepath, Actions::Moved, ( *mit ).first );
+ removeFile( Directory + ( *mit ).first, false );
+ addFile( ( *mit ).second.Filepath, false );
}
/// Directories
- DiffIterator( DirsCreated )
- {
- handleFolderAction( (*it).Filepath, Actions::Add );
- addWatch( (*it).Filepath, Listener, Recursive, this );
+ DiffIterator( DirsCreated ) {
+ handleFolderAction( ( *it ).Filepath, Actions::Add );
+ addWatch( ( *it ).Filepath, Listener, Recursive, this );
}
- DiffIterator( DirsModified )
- {
- handleFolderAction( (*it).Filepath, Actions::Modified );
+ DiffIterator( DirsModified ) {
+ handleFolderAction( ( *it ).Filepath, Actions::Modified );
}
- DiffIterator( DirsDeleted )
- {
- handleFolderAction( (*it).Filepath, Actions::Delete );
+ DiffIterator( DirsDeleted ) {
+ handleFolderAction( ( *it ).Filepath, Actions::Delete );
- Watcher * watch = findWatcher( (*it).Filepath );
+ Watcher* watch = findWatcher( ( *it ).Filepath );
- if ( NULL != watch )
- {
+ if ( NULL != watch ) {
removeWatch( watch->ID );
-
}
}
- DiffMovedIterator( DirsMoved )
- {
- moveDirectory( Directory + (*mit).first, (*mit).second.Filepath );
+ DiffMovedIterator( DirsMoved ) {
+ moveDirectory( Directory + ( *mit ).first, ( *mit ).second.Filepath );
}
}
}
-WatchID WatcherKqueue::watchingDirectory( std::string dir )
-{
- Watcher * watch = findWatcher( dir );
+WatchID WatcherKqueue::watchingDirectory( std::string dir ) {
+ Watcher* watch = findWatcher( dir );
- if ( NULL != watch )
- {
+ if ( NULL != watch ) {
return watch->ID;
}
return Errors::FileNotFound;
}
-void WatcherKqueue::handleAction( const std::string& filename, efsw::Action action, const std::string& oldFilename )
-{
- Listener->handleFileAction( ID, Directory, FileSystem::fileNameFromPath( filename ), action, FileSystem::fileNameFromPath( oldFilename ) );
+void WatcherKqueue::handleAction( const std::string& filename, efsw::Action action,
+ const std::string& oldFilename ) {
+ Listener->handleFileAction( ID, Directory, FileSystem::fileNameFromPath( filename ), action,
+ FileSystem::fileNameFromPath( oldFilename ) );
}
-void WatcherKqueue::handleFolderAction( std::string filename, efsw::Action action , const std::string &oldFilename )
-{
+void WatcherKqueue::handleFolderAction( std::string filename, efsw::Action action,
+ const std::string& oldFilename ) {
FileSystem::dirRemoveSlashAtEnd( filename );
handleAction( filename, action, oldFilename );
}
-void WatcherKqueue::sendDirChanged()
-{
- if ( NULL != mParent )
- {
- Listener->handleFileAction( mParent->ID, mParent->Directory, FileSystem::fileNameFromPath( Directory ), Actions::Modified );
+void WatcherKqueue::sendDirChanged() {
+ if ( NULL != mParent ) {
+ Listener->handleFileAction( mParent->ID, mParent->Directory,
+ FileSystem::fileNameFromPath( Directory ), Actions::Modified );
}
}
-void WatcherKqueue::watch()
-{
- if ( -1 == mKqueue )
- {
+void WatcherKqueue::watch() {
+ if ( -1 == mKqueue ) {
return;
}
@@ -399,89 +347,70 @@ void WatcherKqueue::watch()
KEvent event;
// First iterate the childs, to get the events from the deepest folder, to the watcher childs
- for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); ++it )
- {
+ for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); ++it ) {
it->second->watch();
}
bool needScan = false;
// Then we get the the events of the current folder
- while( ( nev = kevent( mKqueue, &mChangeList[0], mChangeListCount + 1, &event, 1, &mWatcher->mTimeOut ) ) != 0 )
- {
+ while ( ( nev = kevent( mKqueue, &mChangeList[0], mChangeListCount + 1, &event, 1,
+ &mWatcher->mTimeOut ) ) != 0 ) {
// An error ocurred?
- if( nev == -1 )
- {
+ if ( nev == -1 ) {
efDEBUG( "watch(): Error on directory %s\n", Directory.c_str() );
- perror("kevent");
+ perror( "kevent" );
break;
- }
- else
- {
- FileInfo * entry = NULL;
+ } else {
+ FileInfo* entry = NULL;
// If udate == NULL means that it is the fisrt element of the change list, the folder.
// otherwise it is an event of some file inside the folder
- if( ( entry = reinterpret_cast<FileInfo*> ( event.udata ) ) != NULL )
- {
+ if ( ( entry = reinterpret_cast<FileInfo*>( event.udata ) ) != NULL ) {
efDEBUG( "watch(): File: %s ", entry->Filepath.c_str() );
// If the event flag is delete... the file was deleted
- if ( event.fflags & NOTE_DELETE )
- {
+ if ( event.fflags & NOTE_DELETE ) {
efDEBUG( "deleted\n" );
mDirSnap.removeFile( entry->Filepath );
removeFile( entry->Filepath );
- }
- else if ( event.fflags & NOTE_EXTEND ||
- event.fflags & NOTE_WRITE ||
- event.fflags & NOTE_ATTRIB
- )
- {
+ } else if ( event.fflags & NOTE_EXTEND || event.fflags & NOTE_WRITE ||
+ event.fflags & NOTE_ATTRIB ) {
// The file was modified
efDEBUG( "modified\n" );
FileInfo fi( entry->Filepath );
- if ( fi != *entry )
- {
+ if ( fi != *entry ) {
*entry = fi;
mDirSnap.updateFile( entry->Filepath );
handleAction( entry->Filepath, efsw::Actions::Modified );
}
- }
- else if ( event.fflags & NOTE_RENAME )
- {
+ } else if ( event.fflags & NOTE_RENAME ) {
efDEBUG( "moved\n" );
needScan = true;
}
- }
- else
- {
+ } else {
needScan = true;
}
}
}
- if ( needScan )
- {
+ if ( needScan ) {
rescan();
}
}
-Watcher * WatcherKqueue::findWatcher( const std::string path )
-{
+Watcher* WatcherKqueue::findWatcher( const std::string path ) {
WatchMap::iterator it = mWatches.begin();
- for ( ; it != mWatches.end(); it++ )
- {
- if ( it->second->Directory == path )
- {
+ for ( ; it != mWatches.end(); it++ ) {
+ if ( it->second->Directory == path ) {
return it->second;
}
}
@@ -489,28 +418,24 @@ Watcher * WatcherKqueue::findWatcher( const std::string path )
return NULL;
}
-void WatcherKqueue::moveDirectory( std::string oldPath, std::string newPath, bool emitEvents )
-{
+void WatcherKqueue::moveDirectory( std::string oldPath, std::string newPath, bool emitEvents ) {
// Update the directory path if it's a watcher
std::string opath2( oldPath );
FileSystem::dirAddSlashAtEnd( opath2 );
- Watcher * watch = findWatcher( opath2 );
+ Watcher* watch = findWatcher( opath2 );
- if ( NULL != watch )
- {
+ if ( NULL != watch ) {
watch->Directory = opath2;
}
- if ( emitEvents )
- {
+ if ( emitEvents ) {
handleFolderAction( newPath, efsw::Actions::Moved, oldPath );
}
}
-WatchID WatcherKqueue::addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive , WatcherKqueue *parent)
-{
- static long s_fc = 0;
+WatchID WatcherKqueue::addWatch( const std::string& directory, FileWatchListener* watcher,
+ bool recursive, WatcherKqueue* parent ) {
static bool s_ug = false;
std::string dir( directory );
@@ -518,57 +443,42 @@ WatchID WatcherKqueue::addWatch( const std::string& directory, FileWatchListener
FileSystem::dirAddSlashAtEnd( dir );
// This should never happen here
- if( !FileSystem::isDirectory( dir ) )
- {
+ if ( !FileSystem::isDirectory( dir ) ) {
return Errors::Log::createLastError( Errors::FileNotFound, dir );
- }
- else if ( pathInWatches( dir ) || pathInParent( dir ) )
- {
+ } else if ( pathInWatches( dir ) || pathInParent( dir ) ) {
return Errors::Log::createLastError( Errors::FileRepeated, directory );
- }
- else if ( NULL != parent && FileSystem::isRemoteFS( dir ) )
- {
+ } else if ( NULL != parent && FileSystem::isRemoteFS( dir ) ) {
return Errors::Log::createLastError( Errors::FileRemote, dir );
}
std::string curPath;
std::string link( FileSystem::getLinkRealPath( dir, curPath ) );
- if ( "" != link )
- {
+ if ( "" != link ) {
/// Avoid adding symlinks directories if it's now enabled
- if ( NULL != parent && !mWatcher->mFileWatcher->followSymlinks() )
- {
+ if ( NULL != parent && !mWatcher->mFileWatcher->followSymlinks() ) {
return Errors::Log::createLastError( Errors::FileOutOfScope, dir );
}
- if ( pathInWatches( link ) || pathInParent( link ) )
- {
+ if ( pathInWatches( link ) || pathInParent( link ) ) {
return Errors::Log::createLastError( Errors::FileRepeated, link );
- }
- else if ( !mWatcher->linkAllowed( curPath, link ) )
- {
+ } else if ( !mWatcher->linkAllowed( curPath, link ) ) {
return Errors::Log::createLastError( Errors::FileOutOfScope, link );
- }
- else
- {
+ } else {
dir = link;
}
}
- if ( mWatcher->availablesFD() )
- {
- WatcherKqueue* watch = new WatcherKqueue( ++mLastWatchID, dir, watcher, recursive, mWatcher, parent );
+ if ( mWatcher->availablesFD() ) {
+ WatcherKqueue* watch =
+ new WatcherKqueue( ++mLastWatchID, dir, watcher, recursive, mWatcher, parent );
- mWatches.insert(std::make_pair(mLastWatchID, watch));
+ mWatches.insert( std::make_pair( mLastWatchID, watch ) );
watch->addAll();
- s_fc++;
-
// if failed to open the directory... erase the watcher
- if ( !watch->initOK() )
- {
+ if ( !watch->initOK() ) {
int le = watch->lastErrno();
mWatches.erase( watch->ID );
@@ -578,90 +488,78 @@ WatchID WatcherKqueue::addWatch( const std::string& directory, FileWatchListener
mLastWatchID--;
// Probably the folder has too many files, create a generic watcher
- if ( EACCES != le )
- {
- WatcherGeneric * watch = new WatcherGeneric( ++mLastWatchID, dir, watcher, mWatcher, recursive );
+ if ( EACCES != le ) {
+ WatcherGeneric* watch =
+ new WatcherGeneric( ++mLastWatchID, dir, watcher, mWatcher, recursive );
- mWatches.insert(std::make_pair(mLastWatchID, watch));
- }
- else
- {
+ mWatches.insert( std::make_pair( mLastWatchID, watch ) );
+ } else {
return Errors::Log::createLastError( Errors::Unspecified, link );
}
}
- }
- else
- {
- if ( !s_ug )
- {
- efDEBUG( "Started using WatcherGeneric, reached file descriptors limit: %ld. Folders added: %ld\n", mWatcher->mFileDescriptorCount, s_fc );
+ } else {
+ if ( !s_ug ) {
+ efDEBUG( "Started using WatcherGeneric, reached file descriptors limit: %ld.\n",
+ mWatcher->mFileDescriptorCount );
s_ug = true;
}
- WatcherGeneric * watch = new WatcherGeneric( ++mLastWatchID, dir, watcher, mWatcher, recursive );
+ WatcherGeneric* watch =
+ new WatcherGeneric( ++mLastWatchID, dir, watcher, mWatcher, recursive );
- mWatches.insert(std::make_pair(mLastWatchID, watch));
+ mWatches.insert( std::make_pair( mLastWatchID, watch ) );
}
return mLastWatchID;
}
-bool WatcherKqueue::initOK()
-{
+bool WatcherKqueue::initOK() {
return mInitOK;
}
-void WatcherKqueue::removeWatch( WatchID watchid )
-{
- WatchMap::iterator iter = mWatches.find(watchid);
+void WatcherKqueue::removeWatch( WatchID watchid ) {
+ WatchMap::iterator iter = mWatches.find( watchid );
- if(iter == mWatches.end())
+ if ( iter == mWatches.end() )
return;
- Watcher * watch = iter->second;
+ Watcher* watch = iter->second;
- mWatches.erase(iter);
+ mWatches.erase( iter );
efSAFE_DELETE( watch );
}
-bool WatcherKqueue::pathInWatches( const std::string& path )
-{
+bool WatcherKqueue::pathInWatches( const std::string& path ) {
return NULL != findWatcher( path );
}
-bool WatcherKqueue::pathInParent( const std::string &path )
-{
- WatcherKqueue * pNext = mParent;
+bool WatcherKqueue::pathInParent( const std::string& path ) {
+ WatcherKqueue* pNext = mParent;
- while ( NULL != pNext )
- {
- if ( pNext->pathInWatches( path ) )
- {
+ while ( NULL != pNext ) {
+ if ( pNext->pathInWatches( path ) ) {
return true;
}
pNext = pNext->mParent;
}
- if ( mWatcher->pathInWatches( path ) )
- {
+ if ( mWatcher->pathInWatches( path ) ) {
return true;
}
- if ( path == Directory )
- {
+ if ( path == Directory ) {
return true;
}
return false;
}
-int WatcherKqueue::lastErrno()
-{
+int WatcherKqueue::lastErrno() {
return mErrno;
}
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/WatcherKqueue.hpp b/dep/efsw/src/efsw/WatcherKqueue.hpp
index 4babbe73354..75c0f623dd7 100644
--- a/dep/efsw/src/efsw/WatcherKqueue.hpp
+++ b/dep/efsw/src/efsw/WatcherKqueue.hpp
@@ -5,14 +5,13 @@
#if EFSW_PLATFORM == EFSW_PLATFORM_KQUEUE || EFSW_PLATFORM == EFSW_PLATFORM_FSEVENTS
+#include <efsw/DirectorySnapshot.hpp>
#include <map>
-#include <vector>
-#include <sys/types.h>
#include <sys/event.h>
-#include <efsw/DirectorySnapshot.hpp>
+#include <sys/types.h>
+#include <vector>
-namespace efsw
-{
+namespace efsw {
class FileWatcherKqueue;
class WatcherKqueue;
@@ -22,72 +21,76 @@ typedef struct kevent KEvent;
/// type for a map from WatchID to WatcherKqueue pointer
typedef std::map<WatchID, Watcher*> WatchMap;
-class WatcherKqueue : public Watcher
-{
- public:
- WatcherKqueue( WatchID watchid, const std::string& dirname, FileWatchListener* listener, bool recursive, FileWatcherKqueue * watcher, WatcherKqueue * parent = NULL );
+class WatcherKqueue : public Watcher {
+ public:
+ WatcherKqueue( WatchID watchid, const std::string& dirname, FileWatchListener* listener,
+ bool recursive, FileWatcherKqueue* watcher, WatcherKqueue* parent = NULL );
+
+ virtual ~WatcherKqueue();
+
+ void addFile( const std::string& name, bool emitEvents = true );
+
+ void removeFile( const std::string& name, bool emitEvents = true );
+
+ // called when the directory is actually changed
+ // means a file has been added or removed
+ // rescans the watched directory adding/removing files and sending notices
+ void rescan();
- virtual ~WatcherKqueue();
+ void handleAction( const std::string& filename, efsw::Action action,
+ const std::string& oldFilename = "" );
- void addFile( const std::string& name, bool emitEvents = true );
+ void handleFolderAction( std::string filename, efsw::Action action,
+ const std::string& oldFilename = "" );
- void removeFile( const std::string& name, bool emitEvents = true );
+ void addAll();
- // called when the directory is actually changed
- // means a file has been added or removed
- // rescans the watched directory adding/removing files and sending notices
- void rescan();
+ void removeAll();
- void handleAction( const std::string& filename, efsw::Action action, const std::string& oldFilename = "" );
+ WatchID watchingDirectory( std::string dir );
- void handleFolderAction( std::string filename, efsw::Action action, const std::string& oldFilename = "" );
+ void watch() override;
- void addAll();
+ WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive,
+ WatcherKqueue* parent );
- void removeAll();
+ void removeWatch( WatchID watchid );
- WatchID watchingDirectory( std::string dir );
+ bool initOK();
- void watch();
+ int lastErrno();
- WatchID addWatch(const std::string& directory, FileWatchListener* watcher, bool recursive, WatcherKqueue * parent);
+ protected:
+ WatchMap mWatches;
+ int mLastWatchID;
- void removeWatch (WatchID watchid );
-
- bool initOK();
+ // index 0 is always the directory
+ std::vector<KEvent> mChangeList;
+ size_t mChangeListCount;
+ DirectorySnapshot mDirSnap;
- int lastErrno();
- protected:
- WatchMap mWatches;
- int mLastWatchID;
+ /// The descriptor for the kqueue
+ int mKqueue;
- // index 0 is always the directory
- std::vector<KEvent> mChangeList;
- size_t mChangeListCount;
- DirectorySnapshot mDirSnap;
+ FileWatcherKqueue* mWatcher;
- /// The descriptor for the kqueue
- int mKqueue;
+ WatcherKqueue* mParent;
- FileWatcherKqueue * mWatcher;
+ bool mInitOK;
+ int mErrno;
- WatcherKqueue * mParent;
-
- bool mInitOK;
- int mErrno;
+ bool pathInWatches( const std::string& path );
- bool pathInWatches( const std::string& path );
-
- bool pathInParent( const std::string& path );
+ bool pathInParent( const std::string& path );
- Watcher * findWatcher( const std::string path );
+ Watcher* findWatcher( const std::string path );
- void moveDirectory( std::string oldPath, std::string newPath, bool emitEvents = true );
+ void moveDirectory( std::string oldPath, std::string newPath, bool emitEvents = true );
- void sendDirChanged();
+ void sendDirChanged();
};
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/WatcherWin32.cpp b/dep/efsw/src/efsw/WatcherWin32.cpp
index 4d2dc7e064f..ad206e35f71 100644
--- a/dep/efsw/src/efsw/WatcherWin32.cpp
+++ b/dep/efsw/src/efsw/WatcherWin32.cpp
@@ -1,144 +1,130 @@
-#include <efsw/WatcherWin32.hpp>
+#include <efsw/Debug.hpp>
#include <efsw/String.hpp>
+#include <efsw/WatcherWin32.hpp>
#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32
-namespace efsw
-{
+#include <algorithm>
+
+namespace efsw {
/// Unpacks events and passes them to a user defined callback.
-void CALLBACK WatchCallback(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)
-{
- char szFile[MAX_PATH];
- PFILE_NOTIFY_INFORMATION pNotify;
- WatcherStructWin32 * tWatch = (WatcherStructWin32*) lpOverlapped;
- WatcherWin32 * pWatch = tWatch->Watch;
- size_t offset = 0;
+void CALLBACK WatchCallback( DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped ) {
- if (dwNumberOfBytesTransfered == 0)
- {
- RefreshWatch(tWatch); // If dwNumberOfBytesTransfered == 0, it means the buffer overflowed (too many changes between GetOverlappedResults calls). Those events are lost, but at least we can refresh so subsequent changes are seen again.
+ if ( NULL == lpOverlapped ) {
return;
}
- if (dwErrorCode == ERROR_SUCCESS)
- {
- do
- {
- bool skip = false;
+ PFILE_NOTIFY_INFORMATION pNotify;
+ WatcherStructWin32* tWatch = (WatcherStructWin32*)lpOverlapped;
+ WatcherWin32* pWatch = tWatch->Watch;
+ size_t offset = 0;
+
+ if ( dwNumberOfBytesTransfered == 0 ) {
+ if ( nullptr != pWatch && !pWatch->StopNow ) {
+ RefreshWatch( tWatch );
+ } else {
+ return;
+ }
+ }
- pNotify = (PFILE_NOTIFY_INFORMATION) &pWatch->mBuffer[offset];
- offset += pNotify->NextEntryOffset;
+ do {
+ bool skip = false;
- int count = WideCharToMultiByte(CP_UTF8, 0, pNotify->FileName,
- pNotify->FileNameLength / sizeof(WCHAR),
- szFile, MAX_PATH - 1, NULL, NULL);
- szFile[count] = TEXT('\0');
+ pNotify = (PFILE_NOTIFY_INFORMATION)&pWatch->Buffer[offset];
+ offset += pNotify->NextEntryOffset;
+ int count =
+ WideCharToMultiByte( CP_UTF8, 0, pNotify->FileName,
+ pNotify->FileNameLength / sizeof( WCHAR ), NULL, 0, NULL, NULL );
+ if ( count == 0 )
+ continue;
- std::string nfile( szFile );
+ std::string nfile( count, '\0' );
- if ( FILE_ACTION_MODIFIED == pNotify->Action )
- {
- FileInfo fifile( std::string( pWatch->DirName ) + nfile );
+ count = WideCharToMultiByte( CP_UTF8, 0, pNotify->FileName,
+ pNotify->FileNameLength / sizeof( WCHAR ), &nfile[0], count,
+ NULL, NULL );
- if ( pWatch->LastModifiedEvent.file.ModificationTime == fifile.ModificationTime && pWatch->LastModifiedEvent.file.Size == fifile.Size && pWatch->LastModifiedEvent.fileName == nfile )
- {
- skip = true;
- }
+ if ( FILE_ACTION_MODIFIED == pNotify->Action ) {
+ FileInfo fifile( std::string( pWatch->DirName ) + nfile );
- pWatch->LastModifiedEvent.fileName = nfile;
- pWatch->LastModifiedEvent.file = fifile;
+ if ( pWatch->LastModifiedEvent.file.ModificationTime == fifile.ModificationTime &&
+ pWatch->LastModifiedEvent.file.Size == fifile.Size &&
+ pWatch->LastModifiedEvent.fileName == nfile ) {
+ skip = true;
}
- if ( !skip )
- {
- pWatch->Watch->handleAction(pWatch, nfile, pNotify->Action);
- }
- } while (pNotify->NextEntryOffset != 0);
- }
+ pWatch->LastModifiedEvent.fileName = nfile;
+ pWatch->LastModifiedEvent.file = fifile;
+ }
+
+ if ( !skip ) {
+ pWatch->Watch->handleAction( pWatch, nfile, pNotify->Action );
+ }
+ } while ( pNotify->NextEntryOffset != 0 );
- if (!pWatch->StopNow)
- {
- RefreshWatch(tWatch);
+ if ( !pWatch->StopNow ) {
+ RefreshWatch( tWatch );
}
}
/// Refreshes the directory monitoring.
-bool RefreshWatch(WatcherStructWin32* pWatch)
-{
- return ReadDirectoryChangesW(
- pWatch->Watch->DirHandle,
- pWatch->Watch->mBuffer,
- sizeof(pWatch->Watch->mBuffer),
- pWatch->Watch->Recursive,
- pWatch->Watch->NotifyFilter,
- NULL,
- &pWatch->Overlapped,
- NULL
- ) != 0;
+bool RefreshWatch( WatcherStructWin32* pWatch ) {
+ bool bRet = ReadDirectoryChangesW( pWatch->Watch->DirHandle, pWatch->Watch->Buffer.data(),
+ pWatch->Watch->Buffer.size(), pWatch->Watch->Recursive,
+ pWatch->Watch->NotifyFilter, NULL, &pWatch->Overlapped, NULL ) != 0;
+
+ if ( !bRet ) {
+ std::string error = std::to_string( GetLastError() );
+ Errors::Log::createLastError( Errors::WatcherFailed, error );
+ }
+
+ return bRet;
}
/// Stops monitoring a directory.
-void DestroyWatch(WatcherStructWin32* pWatch)
-{
- if (pWatch)
- {
- WatcherWin32 * tWatch = pWatch->Watch;
-
+void DestroyWatch( WatcherStructWin32* pWatch ) {
+ if ( pWatch ) {
+ WatcherWin32* tWatch = pWatch->Watch;
tWatch->StopNow = true;
-
- CancelIoEx(tWatch->DirHandle, &pWatch->Overlapped);
-
- RefreshWatch(pWatch);
- CloseHandle(pWatch->Overlapped.hEvent);
- CloseHandle(pWatch->Watch->DirHandle);
+ CancelIoEx( pWatch->Watch->DirHandle, &pWatch->Overlapped );
+ CloseHandle( pWatch->Watch->DirHandle );
efSAFE_DELETE_ARRAY( pWatch->Watch->DirName );
efSAFE_DELETE( pWatch->Watch );
- HeapFree(GetProcessHeap(), 0, pWatch);
}
}
/// Starts monitoring a directory.
-WatcherStructWin32* CreateWatch(LPCWSTR szDirectory, bool recursive, DWORD NotifyFilter)
-{
- WatcherStructWin32 * tWatch;
- size_t ptrsize = sizeof(*tWatch);
- tWatch = static_cast<WatcherStructWin32*>(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ptrsize));
-
- WatcherWin32 * pWatch = new WatcherWin32();
+WatcherStructWin32* CreateWatch( LPCWSTR szDirectory, bool recursive,
+ DWORD bufferSize, DWORD notifyFilter, HANDLE iocp ) {
+ WatcherStructWin32* tWatch;
+ size_t ptrsize = sizeof( *tWatch );
+ tWatch = static_cast<WatcherStructWin32*>(
+ HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, ptrsize ) );
+
+ WatcherWin32* pWatch = new WatcherWin32(bufferSize);
tWatch->Watch = pWatch;
pWatch->DirHandle = CreateFileW(
- szDirectory,
- GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
- NULL
- );
-
- if (pWatch->DirHandle != INVALID_HANDLE_VALUE)
- {
- tWatch->Overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- pWatch->NotifyFilter = NotifyFilter;
+ szDirectory, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL );
+
+ if ( pWatch->DirHandle != INVALID_HANDLE_VALUE &&
+ CreateIoCompletionPort( pWatch->DirHandle, iocp, 0, 1 ) ) {
+ pWatch->NotifyFilter = notifyFilter;
pWatch->Recursive = recursive;
- if (RefreshWatch(tWatch))
- {
+ if ( RefreshWatch( tWatch ) ) {
return tWatch;
}
- else
- {
- CloseHandle(tWatch->Overlapped.hEvent);
- CloseHandle(pWatch->DirHandle);
- }
}
- HeapFree(GetProcessHeap(), 0, tWatch);
+ CloseHandle( pWatch->DirHandle );
+ efSAFE_DELETE( pWatch->Watch );
+ HeapFree( GetProcessHeap(), 0, tWatch );
return NULL;
}
-}
+} // namespace efsw
- #endif
+#endif
diff --git a/dep/efsw/src/efsw/WatcherWin32.hpp b/dep/efsw/src/efsw/WatcherWin32.hpp
index 3c6d988fbf4..ae050b730df 100644
--- a/dep/efsw/src/efsw/WatcherWin32.hpp
+++ b/dep/efsw/src/efsw/WatcherWin32.hpp
@@ -1,76 +1,73 @@
#ifndef EFSW_WATCHERWIN32_HPP
#define EFSW_WATCHERWIN32_HPP
-#include <efsw/FileWatcherImpl.hpp>
#include <efsw/FileInfo.hpp>
+#include <efsw/FileWatcherImpl.hpp>
+#include <vector>
#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32
#include <windows.h>
#ifdef EFSW_COMPILER_MSVC
- #pragma comment(lib, "comctl32.lib")
- #pragma comment(lib, "user32.lib")
- #pragma comment(lib, "ole32.lib")
+#pragma comment( lib, "comctl32.lib" )
+#pragma comment( lib, "user32.lib" )
+#pragma comment( lib, "ole32.lib" )
- // disable secure warnings
- #pragma warning (disable: 4996)
+// disable secure warnings
+#pragma warning( disable : 4996 )
#endif
-namespace efsw
-{
+namespace efsw {
class WatcherWin32;
/// Internal watch data
-struct WatcherStructWin32
-{
+struct WatcherStructWin32 {
OVERLAPPED Overlapped;
- WatcherWin32 * Watch;
+ WatcherWin32* Watch;
};
-class cLastModifiedEvent
-{
- public:
- cLastModifiedEvent() {}
- FileInfo file;
- std::string fileName;
+struct sLastModifiedEvent {
+ FileInfo file;
+ std::string fileName;
};
-bool RefreshWatch(WatcherStructWin32* pWatch);
+bool RefreshWatch( WatcherStructWin32* pWatch );
-void CALLBACK WatchCallback(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped);
+void CALLBACK WatchCallback( DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped );
-void DestroyWatch(WatcherStructWin32* pWatch);
+void DestroyWatch( WatcherStructWin32* pWatch );
-WatcherStructWin32* CreateWatch(LPCWSTR szDirectory, bool recursive, DWORD NotifyFilter);
+WatcherStructWin32* CreateWatch( LPCWSTR szDirectory, bool recursive,
+ DWORD bufferSize, DWORD notifyFilter, HANDLE iocp );
-class WatcherWin32 : public Watcher
-{
- public:
- WatcherWin32() :
- Struct( NULL ),
- DirHandle( NULL ),
- lParam( 0 ),
- NotifyFilter( 0 ),
- StopNow( false ),
- Watch( NULL ),
- DirName( NULL )
- {
+class WatcherWin32 : public Watcher {
+ public:
+ WatcherWin32(DWORD dwBufferSize) :
+ Struct( NULL ),
+ DirHandle( NULL ),
+ Buffer(),
+ lParam( 0 ),
+ NotifyFilter( 0 ),
+ StopNow( false ),
+ Watch( NULL ),
+ DirName( NULL ) {
+ Buffer.resize(dwBufferSize);
}
- WatcherStructWin32 * Struct;
- HANDLE DirHandle;
- BYTE mBuffer[63 * 1024]; // do NOT make this bigger than 64K because it will fail if the folder being watched is on the network! (see http://msdn.microsoft.com/en-us/library/windows/desktop/aa365465(v=vs.85).aspx)
- LPARAM lParam;
- DWORD NotifyFilter;
- bool StopNow;
- FileWatcherImpl* Watch;
- char* DirName;
- cLastModifiedEvent LastModifiedEvent;
+ WatcherStructWin32* Struct;
+ HANDLE DirHandle;
+ std::vector<BYTE> Buffer;
+ LPARAM lParam;
+ DWORD NotifyFilter;
+ bool StopNow;
+ FileWatcherImpl* Watch;
+ char* DirName;
+ sLastModifiedEvent LastModifiedEvent;
};
-}
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/base.hpp b/dep/efsw/src/efsw/base.hpp
index b5a9687dc74..43abc4fd5e8 100644
--- a/dep/efsw/src/efsw/base.hpp
+++ b/dep/efsw/src/efsw/base.hpp
@@ -1,115 +1,129 @@
#ifndef EFSW_BASE
#define EFSW_BASE
-#include <efsw/sophist.h>
#include <efsw/efsw.hpp>
+#include <efsw/sophist.h>
namespace efsw {
-typedef SOPHIST_int8 Int8;
-typedef SOPHIST_uint8 Uint8;
-typedef SOPHIST_int16 Int16;
-typedef SOPHIST_uint16 Uint16;
-typedef SOPHIST_int32 Int32;
-typedef SOPHIST_uint32 Uint32;
-typedef SOPHIST_int64 Int64;
-typedef SOPHIST_uint64 Uint64;
-
-#define EFSW_OS_WIN 1
-#define EFSW_OS_LINUX 2
-#define EFSW_OS_MACOSX 3
-#define EFSW_OS_BSD 4
-#define EFSW_OS_SOLARIS 5
-#define EFSW_OS_HAIKU 6
-#define EFSW_OS_ANDROID 7
-#define EFSW_OS_IOS 8
-
-#define EFSW_PLATFORM_WIN32 1
-#define EFSW_PLATFORM_INOTIFY 2
-#define EFSW_PLATFORM_KQUEUE 3
-#define EFSW_PLATFORM_FSEVENTS 4
-#define EFSW_PLATFORM_GENERIC 5
-
-#if defined(_WIN32)
- /// Any Windows platform
- #define EFSW_OS EFSW_OS_WIN
- #define EFSW_PLATFORM EFSW_PLATFORM_WIN32
-
- #if ( defined( _MSCVER ) || defined( _MSC_VER ) )
- #define EFSW_COMPILER_MSVC
- #endif
-
- /// Force windows target version above or equal to Windows Server 2008 or Windows Vista
- #if _WIN32_WINNT < 0x600
- #undef _WIN32_WINNT
- #define _WIN32_WINNT 0x600
- #endif
-#elif defined( __FreeBSD__ ) || defined(__OpenBSD__) || defined( __NetBSD__ ) || defined( __DragonFly__ )
- #define EFSW_OS EFSW_OS_BSD
- #define EFSW_PLATFORM EFSW_PLATFORM_KQUEUE
-
-#elif defined( __APPLE_CC__ ) || defined ( __APPLE__ )
- #include <TargetConditionals.h>
-
- #if defined( __IPHONE__ ) || ( defined( TARGET_OS_IPHONE ) && TARGET_OS_IPHONE ) || ( defined( TARGET_IPHONE_SIMULATOR ) && TARGET_IPHONE_SIMULATOR )
- #define EFSW_OS EFSW_OS_IOS
- #define EFSW_PLATFORM EFSW_PLATFORM_KQUEUE
- #else
- #define EFSW_OS EFSW_OS_MACOSX
-
- #if defined(EFSW_FSEVENTS_NOT_SUPPORTED)
- #define EFSW_PLATFORM EFSW_PLATFORM_KQUEUE
- #else
- #define EFSW_PLATFORM EFSW_PLATFORM_FSEVENTS
- #endif
- #endif
-
-#elif defined(__linux__)
- /// This includes Linux and Android
- #ifndef EFSW_KQUEUE
- #define EFSW_PLATFORM EFSW_PLATFORM_INOTIFY
- #else
- /// This is for testing libkqueue, sadly it doesnt work
- #define EFSW_PLATFORM EFSW_PLATFORM_KQUEUE
- #endif
-
- #if defined( __ANDROID__ ) || defined( ANDROID )
- #define EFSW_OS EFSW_OS_ANDROID
- #else
- #define EFSW_OS EFSW_OS_LINUX
- #endif
+typedef SOPHIST_int8 Int8;
+typedef SOPHIST_uint8 Uint8;
+typedef SOPHIST_int16 Int16;
+typedef SOPHIST_uint16 Uint16;
+typedef SOPHIST_int32 Int32;
+typedef SOPHIST_uint32 Uint32;
+typedef SOPHIST_int64 Int64;
+typedef SOPHIST_uint64 Uint64;
+
+#define EFSW_OS_WIN 1
+#define EFSW_OS_LINUX 2
+#define EFSW_OS_MACOSX 3
+#define EFSW_OS_BSD 4
+#define EFSW_OS_SOLARIS 5
+#define EFSW_OS_HAIKU 6
+#define EFSW_OS_ANDROID 7
+#define EFSW_OS_IOS 8
+
+#define EFSW_PLATFORM_WIN32 1
+#define EFSW_PLATFORM_INOTIFY 2
+#define EFSW_PLATFORM_KQUEUE 3
+#define EFSW_PLATFORM_FSEVENTS 4
+#define EFSW_PLATFORM_GENERIC 5
+
+#if defined( _WIN32 )
+/// Any Windows platform
+#define EFSW_OS EFSW_OS_WIN
+#define EFSW_PLATFORM EFSW_PLATFORM_WIN32
+
+#if ( defined( _MSCVER ) || defined( _MSC_VER ) )
+#define EFSW_COMPILER_MSVC
+#endif
+
+/// Force windows target version above or equal to Windows Server 2008 or Windows Vista
+#if _WIN32_WINNT < 0x600
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x600
+#endif
+#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ ) || \
+ defined( __DragonFly__ )
+#define EFSW_OS EFSW_OS_BSD
+#define EFSW_PLATFORM EFSW_PLATFORM_KQUEUE
+
+#elif defined( __APPLE_CC__ ) || defined( __APPLE__ )
+#include <TargetConditionals.h>
+
+#if defined( __IPHONE__ ) || ( defined( TARGET_OS_IPHONE ) && TARGET_OS_IPHONE ) || \
+ ( defined( TARGET_IPHONE_SIMULATOR ) && TARGET_IPHONE_SIMULATOR )
+#define EFSW_OS EFSW_OS_IOS
+#define EFSW_PLATFORM EFSW_PLATFORM_KQUEUE
+#else
+#define EFSW_OS EFSW_OS_MACOSX
+
+#if defined( EFSW_FSEVENTS_NOT_SUPPORTED )
+#define EFSW_PLATFORM EFSW_PLATFORM_KQUEUE
+#else
+#define EFSW_PLATFORM EFSW_PLATFORM_FSEVENTS
+#endif
+#endif
+#elif defined( __linux__ )
+/// This includes Linux and Android
+#ifndef EFSW_KQUEUE
+#define EFSW_PLATFORM EFSW_PLATFORM_INOTIFY
#else
- #if defined( __SVR4 )
- #define EFSW_OS EFSW_OS_SOLARIS
- #elif defined( __HAIKU__ ) || defined( __BEOS__ )
- #define EFSW_OS EFSW_OS_HAIKU
- #endif
-
- /// Everything else
- #define EFSW_PLATFORM EFSW_PLATFORM_GENERIC
+/// This is for testing libkqueue, sadly it doesnt work
+#define EFSW_PLATFORM EFSW_PLATFORM_KQUEUE
+#endif
+
+#if defined( __ANDROID__ ) || defined( ANDROID )
+#define EFSW_OS EFSW_OS_ANDROID
+#else
+#define EFSW_OS EFSW_OS_LINUX
+#endif
+
+#else
+#if defined( __SVR4 )
+#define EFSW_OS EFSW_OS_SOLARIS
+#elif defined( __HAIKU__ ) || defined( __BEOS__ )
+#define EFSW_OS EFSW_OS_HAIKU
+#endif
+
+/// Everything else
+#define EFSW_PLATFORM EFSW_PLATFORM_GENERIC
#endif
#if EFSW_PLATFORM != EFSW_PLATFORM_WIN32
- #define EFSW_PLATFORM_POSIX
+#define EFSW_PLATFORM_POSIX
#endif
#if 1 == SOPHIST_pointer64
- #define EFSW_64BIT
+#define EFSW_64BIT
#else
- #define EFSW_32BIT
+#define EFSW_32BIT
#endif
-#if defined(arm) || defined(__arm__)
- #define EFSW_ARM
+#if defined( arm ) || defined( __arm__ )
+#define EFSW_ARM
#endif
#define efCOMMA ,
-#define efSAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
-#define efSAFE_DELETE_ARRAY(p) { if(p) { delete [] (p); (p)=NULL; } }
-#define efARRAY_SIZE(__array) ( sizeof(__array) / sizeof(__array[0]) )
-
-}
+#define efSAFE_DELETE( p ) \
+ { \
+ if ( p ) { \
+ delete ( p ); \
+ ( p ) = NULL; \
+ } \
+ }
+#define efSAFE_DELETE_ARRAY( p ) \
+ { \
+ if ( p ) { \
+ delete[] ( p ); \
+ ( p ) = NULL; \
+ } \
+ }
+#define efARRAY_SIZE( __array ) ( sizeof( __array ) / sizeof( __array[0] ) )
+
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/platform/platformimpl.hpp b/dep/efsw/src/efsw/platform/platformimpl.hpp
index 86a74eee0c8..54425806985 100644
--- a/dep/efsw/src/efsw/platform/platformimpl.hpp
+++ b/dep/efsw/src/efsw/platform/platformimpl.hpp
@@ -4,17 +4,17 @@
#include <efsw/base.hpp>
#if defined( EFSW_PLATFORM_POSIX )
- #include <efsw/platform/posix/ThreadImpl.hpp>
- #include <efsw/platform/posix/MutexImpl.hpp>
- #include <efsw/platform/posix/SystemImpl.hpp>
- #include <efsw/platform/posix/FileSystemImpl.hpp>
+#include <efsw/platform/posix/ThreadImpl.hpp>
+#include <efsw/platform/posix/MutexImpl.hpp>
+#include <efsw/platform/posix/SystemImpl.hpp>
+#include <efsw/platform/posix/FileSystemImpl.hpp>
#elif EFSW_PLATFORM == EFSW_PLATFORM_WIN32
- #include <efsw/platform/win/ThreadImpl.hpp>
- #include <efsw/platform/win/MutexImpl.hpp>
- #include <efsw/platform/win/SystemImpl.hpp>
- #include <efsw/platform/win/FileSystemImpl.hpp>
+#include <efsw/platform/win/ThreadImpl.hpp>
+#include <efsw/platform/win/MutexImpl.hpp>
+#include <efsw/platform/win/SystemImpl.hpp>
+#include <efsw/platform/win/FileSystemImpl.hpp>
#else
- #error Thread, Mutex, and System not implemented for this platform.
+#error Thread, Mutex, and System not implemented for this platform.
#endif
#endif
diff --git a/dep/efsw/src/efsw/platform/posix/FileSystemImpl.cpp b/dep/efsw/src/efsw/platform/posix/FileSystemImpl.cpp
index 5795d567740..92eeb4768ea 100644
--- a/dep/efsw/src/efsw/platform/posix/FileSystemImpl.cpp
+++ b/dep/efsw/src/efsw/platform/posix/FileSystemImpl.cpp
@@ -2,11 +2,11 @@
#if defined( EFSW_PLATFORM_POSIX )
+#include <cstring>
+#include <dirent.h>
#include <efsw/FileInfo.hpp>
#include <efsw/FileSystem.hpp>
-#include <dirent.h>
#include <unistd.h>
-#include <cstring>
#ifndef _DARWIN_FEATURE_64_BIT_INODE
#define _DARWIN_FEATURE_64_BIT_INODE
@@ -16,15 +16,15 @@
#define _FILE_OFFSET_BITS 64
#endif
-#include <sys/stat.h>
-#include <cstdlib>
#include <climits>
+#include <cstdlib>
+#include <sys/stat.h>
#if EFSW_OS == EFSW_OS_LINUX || EFSW_OS == EFSW_OS_SOLARIS || EFSW_OS == EFSW_OS_ANDROID
#include <sys/vfs.h>
#elif EFSW_OS == EFSW_OS_MACOSX || EFSW_OS == EFSW_OS_BSD || EFSW_OS == EFSW_OS_IOS
-#include <sys/param.h>
#include <sys/mount.h>
+#include <sys/param.h>
#endif
/** Remote file systems codes */
@@ -52,43 +52,15 @@
#define S_MAGIC_VXFS 0xA501FCF5
#if EFSW_OS == EFSW_OS_LINUX
-#include <mntent.h>
#include <cstdio>
+#include <mntent.h>
#endif
namespace efsw { namespace Platform {
#if EFSW_OS == EFSW_OS_LINUX
-#pragma pack(push, 1)
-struct ntfs_super_block
-{
- char jump[3];
- char oem_id[8];
-};
-#pragma pack(pop)
-
-bool isNTFS( std::string device )
-{
- FILE * fd = fopen( device.c_str(), "r" );
-
- ntfs_super_block ns;
-
- if ( fd != NULL )
- {
- fread( &ns, 1, sizeof(ntfs_super_block), fd );
- fclose( fd );
-
- std::string oemId( ns.oem_id );
-
- return oemId.compare(0, 4, "NTFS") == 0;
- }
-
- return false;
-}
-
-std::string findMountPoint( std::string file )
-{
+std::string findMountPoint( std::string file ) {
std::string cwd = FileSystem::getCurrentWorkingDirectory();
struct stat last_stat;
struct stat file_stat;
@@ -108,22 +80,20 @@ std::string findMountPoint( std::string file )
if ( !FileSystem::changeWorkingDirectory( dir ) )
return "";
- if (stat (".", &last_stat) < 0)
+ if ( stat( ".", &last_stat ) < 0 )
return "";
}
- while (true)
- {
+ while ( true ) {
struct stat st;
- if ( stat("..", &st) < 0 )
+ if ( stat( "..", &st ) < 0 )
goto done;
if ( st.st_dev != last_stat.st_dev || st.st_ino == last_stat.st_ino )
break;
- if ( !FileSystem::changeWorkingDirectory("..") )
- {
+ if ( !FileSystem::changeWorkingDirectory( ".." ) ) {
goto done;
}
@@ -139,46 +109,41 @@ done:
return mp;
}
-std::string findDevicePath( const std::string& directory )
-{
- struct mntent *ent;
- FILE *aFile;
+std::string findDevicePath( const std::string& directory ) {
+ struct mntent* ent;
+ FILE* aFile;
- aFile = setmntent("/proc/mounts", "r");
+ aFile = setmntent( "/proc/mounts", "r" );
if ( aFile == NULL )
return "";
- while ( NULL != ( ent = getmntent( aFile ) ) )
- {
+ while ( NULL != ( ent = getmntent( aFile ) ) ) {
std::string dirName( ent->mnt_dir );
- if ( dirName == directory )
- {
+ if ( dirName == directory ) {
std::string fsName( ent->mnt_fsname );
- endmntent(aFile);
+ endmntent( aFile );
return fsName;
}
}
- endmntent(aFile);
+ endmntent( aFile );
return "";
}
-bool isLocalFUSEDirectory( std::string directory )
-{
+bool isLocalFUSEDirectory( std::string directory ) {
efsw::FileSystem::dirRemoveSlashAtEnd( directory );
directory = findMountPoint( directory );
- if ( !directory.empty() )
- {
+ if ( !directory.empty() ) {
std::string devicePath = findDevicePath( directory );
- return ( !devicePath.empty() && isNTFS( devicePath ) );
+ return !devicePath.empty();
}
return false;
@@ -186,102 +151,93 @@ bool isLocalFUSEDirectory( std::string directory )
#endif
-bool FileSystem::changeWorkingDirectory( const std::string & path )
-{
+bool FileSystem::changeWorkingDirectory( const std::string& path ) {
return -1 != chdir( path.c_str() );
}
std::string FileSystem::getCurrentWorkingDirectory() {
char dir[PATH_MAX + 1];
- getcwd( dir, PATH_MAX + 1 );
- return std::string( dir );
+ char* result = getcwd( dir, PATH_MAX + 1 );
+ return result != NULL ? std::string( result ) : std::string();
}
-FileInfoMap FileSystem::filesInfoFromPath( const std::string& path )
-{
+FileInfoMap FileSystem::filesInfoFromPath( const std::string& path ) {
FileInfoMap files;
- DIR *dp;
- struct dirent *dirp;
+ DIR* dp;
+ struct dirent* dirp;
- if( ( dp = opendir( path.c_str() ) ) == NULL)
+ if ( ( dp = opendir( path.c_str() ) ) == NULL )
return files;
- while ( ( dirp = readdir(dp) ) != NULL)
- {
- if ( strcmp( dirp->d_name, ".." ) != 0 && strcmp( dirp->d_name, "." ) != 0 )
- {
+ while ( ( dirp = readdir( dp ) ) != NULL ) {
+ if ( strcmp( dirp->d_name, ".." ) != 0 && strcmp( dirp->d_name, "." ) != 0 ) {
std::string name( dirp->d_name );
std::string fpath( path + name );
- files[ name ] = FileInfo( fpath );
+ files[name] = FileInfo( fpath );
}
}
- closedir(dp);
+ closedir( dp );
return files;
}
-char FileSystem::getOSSlash()
-{
+char FileSystem::getOSSlash() {
return '/';
}
-bool FileSystem::isDirectory( const std::string& path )
-{
+bool FileSystem::isDirectory( const std::string& path ) {
struct stat st;
int res = stat( path.c_str(), &st );
- if ( 0 == res )
- {
- return static_cast<bool>( S_ISDIR(st.st_mode) );
+ if ( 0 == res ) {
+ return static_cast<bool>( S_ISDIR( st.st_mode ) );
}
return false;
}
-bool FileSystem::isRemoteFS( const std::string& directory )
-{
-#if EFSW_OS == EFSW_OS_LINUX || EFSW_OS == EFSW_OS_MACOSX || EFSW_OS == EFSW_OS_BSD || EFSW_OS == EFSW_OS_SOLARIS || EFSW_OS == EFSW_OS_ANDROID || EFSW_OS == EFSW_OS_IOS
+bool FileSystem::isRemoteFS( const std::string& directory ) {
+#if EFSW_OS == EFSW_OS_LINUX || EFSW_OS == EFSW_OS_MACOSX || EFSW_OS == EFSW_OS_BSD || \
+ EFSW_OS == EFSW_OS_SOLARIS || EFSW_OS == EFSW_OS_ANDROID || EFSW_OS == EFSW_OS_IOS
struct statfs statfsbuf;
statfs( directory.c_str(), &statfsbuf );
- switch ( statfsbuf.f_type | 0UL )
- {
+ switch ( statfsbuf.f_type | 0UL ) {
case S_MAGIC_FUSEBLK: /* 0x65735546 remote */
{
- #if EFSW_OS == EFSW_OS_LINUX
+#if EFSW_OS == EFSW_OS_LINUX
return !isLocalFUSEDirectory( directory );
- #endif
+#endif
}
- case S_MAGIC_AFS: /* 0x5346414F remote */
- case S_MAGIC_AUFS: /* 0x61756673 remote */
- case S_MAGIC_CEPH: /* 0x00C36400 remote */
- case S_MAGIC_CIFS: /* 0xFF534D42 remote */
- case S_MAGIC_CODA: /* 0x73757245 remote */
- case S_MAGIC_FHGFS: /* 0x19830326 remote */
+ case S_MAGIC_AFS: /* 0x5346414F remote */
+ case S_MAGIC_AUFS: /* 0x61756673 remote */
+ case S_MAGIC_CEPH: /* 0x00C36400 remote */
+ case S_MAGIC_CIFS: /* 0xFF534D42 remote */
+ case S_MAGIC_CODA: /* 0x73757245 remote */
+ case S_MAGIC_FHGFS: /* 0x19830326 remote */
case S_MAGIC_FUSECTL: /* 0x65735543 remote */
- case S_MAGIC_GFS: /* 0x01161970 remote */
- case S_MAGIC_GPFS: /* 0x47504653 remote */
- case S_MAGIC_KAFS: /* 0x6B414653 remote */
- case S_MAGIC_LUSTRE: /* 0x0BD00BD0 remote */
- case S_MAGIC_NCP: /* 0x564C remote */
- case S_MAGIC_NFS: /* 0x6969 remote */
- case S_MAGIC_NFSD: /* 0x6E667364 remote */
- case S_MAGIC_OCFS2: /* 0x7461636F remote */
- case S_MAGIC_PANFS: /* 0xAAD7AAEA remote */
- case S_MAGIC_PIPEFS: /* 0x50495045 remote */
- case S_MAGIC_SMB: /* 0x517B remote */
- case S_MAGIC_SNFS: /* 0xBEEFDEAD remote */
- case S_MAGIC_VMHGFS: /* 0xBACBACBC remote */
- case S_MAGIC_VXFS: /* 0xA501FCF5 remote */
+ case S_MAGIC_GFS: /* 0x01161970 remote */
+ case S_MAGIC_GPFS: /* 0x47504653 remote */
+ case S_MAGIC_KAFS: /* 0x6B414653 remote */
+ case S_MAGIC_LUSTRE: /* 0x0BD00BD0 remote */
+ case S_MAGIC_NCP: /* 0x564C remote */
+ case S_MAGIC_NFS: /* 0x6969 remote */
+ case S_MAGIC_NFSD: /* 0x6E667364 remote */
+ case S_MAGIC_OCFS2: /* 0x7461636F remote */
+ case S_MAGIC_PANFS: /* 0xAAD7AAEA remote */
+ case S_MAGIC_PIPEFS: /* 0x50495045 remote */
+ case S_MAGIC_SMB: /* 0x517B remote */
+ case S_MAGIC_SNFS: /* 0xBEEFDEAD remote */
+ case S_MAGIC_VMHGFS: /* 0xBACBACBC remote */
+ case S_MAGIC_VXFS: /* 0xA501FCF5 remote */
{
return true;
}
- default:
- {
+ default: {
return false;
}
}
@@ -290,6 +246,6 @@ bool FileSystem::isRemoteFS( const std::string& directory )
return false;
}
-}}
+}} // namespace efsw::Platform
#endif
diff --git a/dep/efsw/src/efsw/platform/posix/FileSystemImpl.hpp b/dep/efsw/src/efsw/platform/posix/FileSystemImpl.hpp
index 7353d81cf3f..0bfba7656f5 100644
--- a/dep/efsw/src/efsw/platform/posix/FileSystemImpl.hpp
+++ b/dep/efsw/src/efsw/platform/posix/FileSystemImpl.hpp
@@ -1,30 +1,29 @@
#ifndef EFSW_FILESYSTEMIMPLPOSIX_HPP
#define EFSW_FILESYSTEMIMPLPOSIX_HPP
-#include <efsw/base.hpp>
#include <efsw/FileInfo.hpp>
+#include <efsw/base.hpp>
#if defined( EFSW_PLATFORM_POSIX )
namespace efsw { namespace Platform {
-class FileSystem
-{
- public:
- static FileInfoMap filesInfoFromPath( const std::string& path );
+class FileSystem {
+ public:
+ static FileInfoMap filesInfoFromPath( const std::string& path );
- static char getOSSlash();
+ static char getOSSlash();
- static bool isDirectory( const std::string& path );
+ static bool isDirectory( const std::string& path );
- static bool isRemoteFS( const std::string& directory );
+ static bool isRemoteFS( const std::string& directory );
- static bool changeWorkingDirectory( const std::string & path );
+ static bool changeWorkingDirectory( const std::string& path );
- static std::string getCurrentWorkingDirectory();
+ static std::string getCurrentWorkingDirectory();
};
-}}
+}} // namespace efsw::Platform
#endif
diff --git a/dep/efsw/src/efsw/platform/posix/MutexImpl.cpp b/dep/efsw/src/efsw/platform/posix/MutexImpl.cpp
index 6f2af5abc61..2233798284c 100644
--- a/dep/efsw/src/efsw/platform/posix/MutexImpl.cpp
+++ b/dep/efsw/src/efsw/platform/posix/MutexImpl.cpp
@@ -4,29 +4,25 @@
namespace efsw { namespace Platform {
-MutexImpl::MutexImpl()
-{
+MutexImpl::MutexImpl() {
pthread_mutexattr_t attributes;
- pthread_mutexattr_init(&attributes);
- pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&mMutex, &attributes);
+ pthread_mutexattr_init( &attributes );
+ pthread_mutexattr_settype( &attributes, PTHREAD_MUTEX_RECURSIVE );
+ pthread_mutex_init( &mMutex, &attributes );
}
-MutexImpl::~MutexImpl()
-{
- pthread_mutex_destroy(&mMutex);
+MutexImpl::~MutexImpl() {
+ pthread_mutex_destroy( &mMutex );
}
-void MutexImpl::lock()
-{
- pthread_mutex_lock(&mMutex);
+void MutexImpl::lock() {
+ pthread_mutex_lock( &mMutex );
}
-void MutexImpl::unlock()
-{
- pthread_mutex_unlock(&mMutex);
+void MutexImpl::unlock() {
+ pthread_mutex_unlock( &mMutex );
}
-}}
+}} // namespace efsw::Platform
#endif
diff --git a/dep/efsw/src/efsw/platform/posix/MutexImpl.hpp b/dep/efsw/src/efsw/platform/posix/MutexImpl.hpp
index d51eecb16aa..a33d827966f 100644
--- a/dep/efsw/src/efsw/platform/posix/MutexImpl.hpp
+++ b/dep/efsw/src/efsw/platform/posix/MutexImpl.hpp
@@ -9,23 +9,22 @@
namespace efsw { namespace Platform {
-class MutexImpl
-{
- public:
- MutexImpl();
+class MutexImpl {
+ public:
+ MutexImpl();
- ~MutexImpl();
+ ~MutexImpl();
- void lock();
+ void lock();
- void unlock();
- private:
- pthread_mutex_t mMutex;
+ void unlock();
+
+ private:
+ pthread_mutex_t mMutex;
};
-}}
+}} // namespace efsw::Platform
#endif
#endif
-
diff --git a/dep/efsw/src/efsw/platform/posix/SystemImpl.cpp b/dep/efsw/src/efsw/platform/posix/SystemImpl.cpp
index 22e37095afd..37d4120ef1e 100644
--- a/dep/efsw/src/efsw/platform/posix/SystemImpl.cpp
+++ b/dep/efsw/src/efsw/platform/posix/SystemImpl.cpp
@@ -3,32 +3,31 @@
#if defined( EFSW_PLATFORM_POSIX )
#include <cstdio>
-#include <pthread.h>
-#include <sys/time.h>
#include <limits.h>
+#include <pthread.h>
#include <sys/resource.h>
+#include <sys/time.h>
-#include <efsw/FileSystem.hpp>
#include <efsw/Debug.hpp>
+#include <efsw/FileSystem.hpp>
#if EFSW_OS == EFSW_OS_MACOSX
- #include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CoreFoundation.h>
#elif EFSW_OS == EFSW_OS_LINUX || EFSW_OS == EFSW_OS_ANDROID
- #include <libgen.h>
- #include <unistd.h>
+#include <libgen.h>
+#include <unistd.h>
#elif EFSW_OS == EFSW_OS_HAIKU
- #include <kernel/OS.h>
- #include <kernel/image.h>
+#include <kernel/OS.h>
+#include <kernel/image.h>
#elif EFSW_OS == EFSW_OS_SOLARIS
- #include <stdlib.h>
+#include <stdlib.h>
#elif EFSW_OS == EFSW_OS_BSD
- #include <sys/sysctl.h>
+#include <sys/sysctl.h>
#endif
namespace efsw { namespace Platform {
-void System::sleep( const unsigned long& ms )
-{
+void System::sleep( const unsigned long& ms ) {
// usleep( static_cast<unsigned long>( ms * 1000 ) );
// usleep is not reliable enough (it might block the
@@ -42,47 +41,44 @@ void System::sleep( const unsigned long& ms )
// get the current time
timeval tv;
- gettimeofday(&tv, NULL);
+ gettimeofday( &tv, NULL );
// construct the time limit (current time + time to wait)
timespec ti;
- ti.tv_nsec = (tv.tv_usec + (usecs % 1000000)) * 1000;
- ti.tv_sec = tv.tv_sec + (usecs / 1000000) + (ti.tv_nsec / 1000000000);
+ ti.tv_nsec = ( tv.tv_usec + ( usecs % 1000000 ) ) * 1000;
+ ti.tv_sec = tv.tv_sec + ( usecs / 1000000 ) + ( ti.tv_nsec / 1000000000 );
ti.tv_nsec %= 1000000000;
// create a mutex and thread condition
pthread_mutex_t mutex;
- pthread_mutex_init(&mutex, 0);
+ pthread_mutex_init( &mutex, 0 );
pthread_cond_t condition;
- pthread_cond_init(&condition, 0);
+ pthread_cond_init( &condition, 0 );
// wait...
- pthread_mutex_lock(&mutex);
- pthread_cond_timedwait(&condition, &mutex, &ti);
- pthread_mutex_unlock(&mutex);
+ pthread_mutex_lock( &mutex );
+ pthread_cond_timedwait( &condition, &mutex, &ti );
+ pthread_mutex_unlock( &mutex );
// destroy the mutex and condition
- pthread_cond_destroy(&condition);
+ pthread_cond_destroy( &condition );
}
-std::string System::getProcessPath()
-{
+std::string System::getProcessPath() {
#if EFSW_OS == EFSW_OS_MACOSX
char exe_file[FILENAME_MAX + 1];
CFBundleRef mainBundle = CFBundleGetMainBundle();
- if (mainBundle)
- {
- CFURLRef mainURL = CFBundleCopyBundleURL(mainBundle);
+ if ( mainBundle ) {
+ CFURLRef mainURL = CFBundleCopyBundleURL( mainBundle );
- if (mainURL)
- {
- int ok = CFURLGetFileSystemRepresentation ( mainURL, (Boolean) true, (UInt8*)exe_file, FILENAME_MAX );
+ if ( mainURL ) {
+ int ok = CFURLGetFileSystemRepresentation( mainURL, ( Boolean ) true, (UInt8*)exe_file,
+ FILENAME_MAX );
- if (ok)
- {
- return std::string(exe_file) + "/";
+ if ( ok ) {
+ return std::string( exe_file ) + "/";
}
}
}
@@ -93,14 +89,11 @@ std::string System::getProcessPath()
int size;
- size = readlink("/proc/self/exe", exe_file, FILENAME_MAX);
+ size = readlink( "/proc/self/exe", exe_file, FILENAME_MAX );
- if (size < 0)
- {
- return std::string( "./" );
- }
- else
- {
+ if ( size < 0 ) {
+ return std::string( "./" );
+ } else {
exe_file[size] = '\0';
return std::string( dirname( exe_file ) ) + "/";
}
@@ -112,8 +105,8 @@ std::string System::getProcessPath()
mib[2] = KERN_PROC_PATHNAME;
mib[3] = -1;
char buf[1024];
- size_t cb = sizeof(buf);
- sysctl(mib, 4, buf, &cb, NULL, 0);
+ size_t cb = sizeof( buf );
+ sysctl( mib, 4, buf, &cb, NULL, 0 );
return FileSystem::pathRemoveFileName( std::string( buf ) );
@@ -124,8 +117,7 @@ std::string System::getProcessPath()
image_info info;
int32 cookie = 0;
- while ( B_OK == get_next_image_info( 0, &cookie, &info ) )
- {
+ while ( B_OK == get_next_image_info( 0, &cookie, &info ) ) {
if ( info.type == B_APP_IMAGE )
break;
}
@@ -136,18 +128,16 @@ std::string System::getProcessPath()
return "/sdcard/";
#else
- #warning getProcessPath() not implemented on this platform. ( will return "./" )
+#warning getProcessPath() not implemented on this platform. ( will return "./" )
return "./";
#endif
}
-void System::maxFD()
-{
+void System::maxFD() {
static bool maxed = false;
- if ( !maxed )
- {
+ if ( !maxed ) {
struct rlimit limit;
getrlimit( RLIMIT_NOFILE, &limit );
limit.rlim_cur = limit.rlim_max;
@@ -161,12 +151,10 @@ void System::maxFD()
}
}
-Uint64 System::getMaxFD()
-{
+Uint64 System::getMaxFD() {
static rlim_t max_fd = 0;
- if ( max_fd == 0 )
- {
+ if ( max_fd == 0 ) {
struct rlimit limit;
getrlimit( RLIMIT_NOFILE, &limit );
max_fd = limit.rlim_cur;
@@ -175,6 +163,6 @@ Uint64 System::getMaxFD()
return max_fd;
}
-}}
+}} // namespace efsw::Platform
#endif
diff --git a/dep/efsw/src/efsw/platform/posix/SystemImpl.hpp b/dep/efsw/src/efsw/platform/posix/SystemImpl.hpp
index 34734104467..9322b06c800 100644
--- a/dep/efsw/src/efsw/platform/posix/SystemImpl.hpp
+++ b/dep/efsw/src/efsw/platform/posix/SystemImpl.hpp
@@ -7,19 +7,18 @@
namespace efsw { namespace Platform {
-class System
-{
- public:
- static void sleep( const unsigned long& ms );
+class System {
+ public:
+ static void sleep( const unsigned long& ms );
- static std::string getProcessPath();
+ static std::string getProcessPath();
- static void maxFD();
+ static void maxFD();
- static Uint64 getMaxFD();
+ static Uint64 getMaxFD();
};
-}}
+}} // namespace efsw::Platform
#endif
diff --git a/dep/efsw/src/efsw/platform/posix/ThreadImpl.cpp b/dep/efsw/src/efsw/platform/posix/ThreadImpl.cpp
index 2d3671db9b8..0f96bca7e55 100644
--- a/dep/efsw/src/efsw/platform/posix/ThreadImpl.cpp
+++ b/dep/efsw/src/efsw/platform/posix/ThreadImpl.cpp
@@ -1,61 +1,55 @@
-#include <efsw/platform/posix/ThreadImpl.hpp>
#include <efsw/Thread.hpp>
+#include <efsw/platform/posix/ThreadImpl.hpp>
#if defined( EFSW_PLATFORM_POSIX )
#include <cassert>
-#include <iostream>
#include <efsw/Debug.hpp>
+#include <iostream>
namespace efsw { namespace Platform {
-ThreadImpl::ThreadImpl( Thread * owner ) :
- mIsActive(false)
-{
+ThreadImpl::ThreadImpl( efsw::Thread* owner ) : mIsActive( false ) {
mIsActive = pthread_create( &mThread, NULL, &ThreadImpl::entryPoint, owner ) == 0;
- if ( !mIsActive )
- {
+ if ( !mIsActive ) {
efDEBUG( "Failed to create thread\n" );
}
}
-void ThreadImpl::wait()
-{
+ThreadImpl::~ThreadImpl() {
+ terminate();
+}
+
+void ThreadImpl::wait() {
// Wait for the thread to finish, no timeout
- if ( mIsActive )
- {
+ if ( mIsActive ) {
assert( pthread_equal( pthread_self(), mThread ) == 0 );
- pthread_join( mThread, NULL );
-
- mIsActive = false; // Reset the thread state
+ mIsActive = pthread_join( mThread, NULL ) != 0;
}
}
-void ThreadImpl::terminate()
-{
- if ( mIsActive )
- {
- #if !defined( __ANDROID__ ) && !defined( ANDROID )
- pthread_cancel( mThread );
- #else
- pthread_kill( mThread , SIGUSR1 );
- #endif
+void ThreadImpl::terminate() {
+ if ( mIsActive ) {
+#if !defined( __ANDROID__ ) && !defined( ANDROID )
+ pthread_cancel( mThread );
+#else
+ pthread_kill( mThread, SIGUSR1 );
+#endif
mIsActive = false;
}
}
-void * ThreadImpl::entryPoint( void * userData )
-{
- // The Thread instance is stored in the user data
- Thread * owner = static_cast<Thread*>( userData );
+void* ThreadImpl::entryPoint( void* userData ) {
+// Tell the thread to handle cancel requests immediatly
+#ifdef PTHREAD_CANCEL_ASYNCHRONOUS
+ pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL );
+#endif
- // Tell the thread to handle cancel requests immediatly
- #ifdef PTHREAD_CANCEL_ASYNCHRONOUS
- pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL );
- #endif
+ // The Thread instance is stored in the user data
+ Thread* owner = static_cast<Thread*>( userData );
// Forward to the owner
owner->run();
@@ -63,6 +57,6 @@ void * ThreadImpl::entryPoint( void * userData )
return NULL;
}
-}}
+}} // namespace efsw::Platform
#endif
diff --git a/dep/efsw/src/efsw/platform/posix/ThreadImpl.hpp b/dep/efsw/src/efsw/platform/posix/ThreadImpl.hpp
index be6dc1b3e58..2e02f9ac89d 100644
--- a/dep/efsw/src/efsw/platform/posix/ThreadImpl.hpp
+++ b/dep/efsw/src/efsw/platform/posix/ThreadImpl.hpp
@@ -5,6 +5,7 @@
#if defined( EFSW_PLATFORM_POSIX )
+#include <efsw/Atomic.hpp>
#include <pthread.h>
namespace efsw {
@@ -13,22 +14,25 @@ class Thread;
namespace Platform {
-class ThreadImpl
-{
- public:
- ThreadImpl( Thread * owner );
-
- void wait();
-
- void terminate();
- protected:
- static void * entryPoint( void* userData );
-
- pthread_t mThread;
- bool mIsActive;
+class ThreadImpl {
+ public:
+ explicit ThreadImpl( efsw::Thread* owner );
+
+ ~ThreadImpl();
+
+ void wait();
+
+ void terminate();
+
+ protected:
+ static void* entryPoint( void* userData );
+
+ pthread_t mThread;
+ Atomic<bool> mIsActive;
};
-}}
+} // namespace Platform
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/efsw/platform/win/FileSystemImpl.cpp b/dep/efsw/src/efsw/platform/win/FileSystemImpl.cpp
index cf27eb7a0f6..2b875139e8b 100644
--- a/dep/efsw/src/efsw/platform/win/FileSystemImpl.cpp
+++ b/dep/efsw/src/efsw/platform/win/FileSystemImpl.cpp
@@ -4,7 +4,7 @@
#include <climits>
#ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
@@ -16,31 +16,30 @@
namespace efsw { namespace Platform {
-bool FileSystem::changeWorkingDirectory( const std::string & path )
-{
+bool FileSystem::changeWorkingDirectory( const std::string& path ) {
int res;
#ifdef EFSW_COMPILER_MSVC
- #ifdef UNICODE
+#ifdef UNICODE
res = _wchdir( String::fromUtf8( path.c_str() ).toWideString().c_str() );
- #else
+#else
res = _chdir( String::fromUtf8( path.c_str() ).toAnsiString().c_str() );
- #endif
+#endif
#else
res = chdir( path.c_str() );
#endif
return -1 != res;
}
-std::string FileSystem::getCurrentWorkingDirectory()
-{
+std::string FileSystem::getCurrentWorkingDirectory() {
#ifdef EFSW_COMPILER_MSVC
- #if defined( UNICODE ) AND !defined( EFSW_NO_WIDECHAR )
+#if defined( UNICODE ) && !defined( EFSW_NO_WIDECHAR )
wchar_t dir[_MAX_PATH];
return ( 0 != GetCurrentDirectoryW( _MAX_PATH, dir ) ) ? String( dir ).toUtf8() : std::string();
- #else
+#else
char dir[_MAX_PATH];
- return ( 0 != GetCurrentDirectory( _MAX_PATH, dir ) ) ? String( dir, std::locale() ).toUtf8() : std::string();
- #endif
+ return ( 0 != GetCurrentDirectory( _MAX_PATH, dir ) ) ? String( dir, std::locale() ).toUtf8()
+ : std::string();
+#endif
#else
char dir[PATH_MAX + 1];
getcwd( dir, PATH_MAX + 1 );
@@ -48,42 +47,34 @@ std::string FileSystem::getCurrentWorkingDirectory()
#endif
}
-FileInfoMap FileSystem::filesInfoFromPath( const std::string& path )
-{
+FileInfoMap FileSystem::filesInfoFromPath( const std::string& path ) {
FileInfoMap files;
String tpath( path );
- if ( tpath[ tpath.size() - 1 ] == '/' || tpath[ tpath.size() - 1 ] == '\\' )
- {
+ if ( tpath[tpath.size() - 1] == '/' || tpath[tpath.size() - 1] == '\\' ) {
tpath += "*";
- }
- else
- {
+ } else {
tpath += "\\*";
}
WIN32_FIND_DATAW findFileData;
HANDLE hFind = FindFirstFileW( (LPCWSTR)tpath.toWideString().c_str(), &findFileData );
- if( hFind != INVALID_HANDLE_VALUE )
- {
+ if ( hFind != INVALID_HANDLE_VALUE ) {
std::string name( String( findFileData.cFileName ).toUtf8() );
std::string fpath( path + name );
- if ( name != "." && name != ".." )
- {
- files[ name ] = FileInfo( fpath );
+ if ( name != "." && name != ".." ) {
+ files[name] = FileInfo( fpath );
}
- while( FindNextFileW( hFind, &findFileData ) )
- {
+ while ( FindNextFileW( hFind, &findFileData ) ) {
name = String( findFileData.cFileName ).toUtf8();
fpath = path + name;
- if ( name != "." && name != ".." )
- {
- files[ name ] = FileInfo( fpath );
+ if ( name != "." && name != ".." ) {
+ files[name] = FileInfo( fpath );
}
}
@@ -93,32 +84,28 @@ FileInfoMap FileSystem::filesInfoFromPath( const std::string& path )
return files;
}
-char FileSystem::getOSSlash()
-{
+char FileSystem::getOSSlash() {
return '\\';
}
-bool FileSystem::isDirectory( const std::string& path )
-{
- return 0 != ( GetFileAttributesW( String( path ).toWideString().c_str() ) & FILE_ATTRIBUTE_DIRECTORY );
+bool FileSystem::isDirectory( const std::string& path ) {
+ DWORD attrs = GetFileAttributesW( String( path ).toWideString().c_str() );
+ return attrs != INVALID_FILE_ATTRIBUTES && ( attrs & FILE_ATTRIBUTE_DIRECTORY ) != 0;
}
-bool FileSystem::isRemoteFS( const std::string& directory )
-{
- if ((directory[0] == '\\' || directory[0] == '/') &&
- (directory[1] == '\\' || directory[1] == '/'))
- {
+bool FileSystem::isRemoteFS( const std::string& directory ) {
+ if ( ( directory[0] == '\\' || directory[0] == '/' ) &&
+ ( directory[1] == '\\' || directory[1] == '/' ) ) {
return true;
}
- if ( directory.size() >= 3 )
- {
+ if ( directory.size() >= 3 ) {
return 4 == GetDriveTypeA( directory.substr( 0, 3 ).c_str() );
}
return false;
}
-}}
+}} // namespace efsw::Platform
#endif
diff --git a/dep/efsw/src/efsw/platform/win/FileSystemImpl.hpp b/dep/efsw/src/efsw/platform/win/FileSystemImpl.hpp
index 8f6c5ad1837..e952efcee62 100644
--- a/dep/efsw/src/efsw/platform/win/FileSystemImpl.hpp
+++ b/dep/efsw/src/efsw/platform/win/FileSystemImpl.hpp
@@ -1,31 +1,30 @@
#ifndef EFSW_FILESYSTEMIMPLWIN_HPP
#define EFSW_FILESYSTEMIMPLWIN_HPP
-#include <efsw/base.hpp>
-#include <efsw/String.hpp>
#include <efsw/FileInfo.hpp>
+#include <efsw/String.hpp>
+#include <efsw/base.hpp>
#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32
namespace efsw { namespace Platform {
-class FileSystem
-{
- public:
- static FileInfoMap filesInfoFromPath( const std::string& path );
+class FileSystem {
+ public:
+ static FileInfoMap filesInfoFromPath( const std::string& path );
- static char getOSSlash();
+ static char getOSSlash();
- static bool isDirectory( const std::string& path );
+ static bool isDirectory( const std::string& path );
- static bool isRemoteFS( const std::string& directory );
+ static bool isRemoteFS( const std::string& directory );
- static bool changeWorkingDirectory( const std::string & path );
+ static bool changeWorkingDirectory( const std::string& path );
- static std::string getCurrentWorkingDirectory();
+ static std::string getCurrentWorkingDirectory();
};
-}}
+}} // namespace efsw::Platform
#endif
diff --git a/dep/efsw/src/efsw/platform/win/MutexImpl.cpp b/dep/efsw/src/efsw/platform/win/MutexImpl.cpp
index 0c8c36d8b39..62b7f836e51 100644
--- a/dep/efsw/src/efsw/platform/win/MutexImpl.cpp
+++ b/dep/efsw/src/efsw/platform/win/MutexImpl.cpp
@@ -4,26 +4,22 @@
namespace efsw { namespace Platform {
-MutexImpl::MutexImpl()
-{
- InitializeCriticalSection(&mMutex);
+MutexImpl::MutexImpl() {
+ InitializeCriticalSection( &mMutex );
}
-MutexImpl::~MutexImpl()
-{
- DeleteCriticalSection(&mMutex);
+MutexImpl::~MutexImpl() {
+ DeleteCriticalSection( &mMutex );
}
-void MutexImpl::lock()
-{
- EnterCriticalSection(&mMutex);
+void MutexImpl::lock() {
+ EnterCriticalSection( &mMutex );
}
-void MutexImpl::unlock()
-{
- LeaveCriticalSection(&mMutex);
+void MutexImpl::unlock() {
+ LeaveCriticalSection( &mMutex );
}
-}}
+}} // namespace efsw::Platform
#endif
diff --git a/dep/efsw/src/efsw/platform/win/MutexImpl.hpp b/dep/efsw/src/efsw/platform/win/MutexImpl.hpp
index da1e20c5fa9..7b064920f81 100644
--- a/dep/efsw/src/efsw/platform/win/MutexImpl.hpp
+++ b/dep/efsw/src/efsw/platform/win/MutexImpl.hpp
@@ -6,29 +6,28 @@
#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32
#ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
namespace efsw { namespace Platform {
-class MutexImpl
-{
- public:
- MutexImpl();
+class MutexImpl {
+ public:
+ MutexImpl();
- ~MutexImpl();
+ ~MutexImpl();
- void lock();
+ void lock();
- void unlock();
- private:
- CRITICAL_SECTION mMutex;
+ void unlock();
+
+ private:
+ CRITICAL_SECTION mMutex;
};
-}}
+}} // namespace efsw::Platform
#endif
#endif
-
diff --git a/dep/efsw/src/efsw/platform/win/SystemImpl.cpp b/dep/efsw/src/efsw/platform/win/SystemImpl.cpp
index ddbe1e5c45c..d1f2b21a87c 100644
--- a/dep/efsw/src/efsw/platform/win/SystemImpl.cpp
+++ b/dep/efsw/src/efsw/platform/win/SystemImpl.cpp
@@ -1,23 +1,21 @@
-#include <efsw/platform/win/SystemImpl.hpp>
#include <efsw/String.hpp>
+#include <efsw/platform/win/SystemImpl.hpp>
#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32
#ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
#endif
-#include <windows.h>
#include <cstdlib>
+#include <windows.h>
namespace efsw { namespace Platform {
-void System::sleep( const unsigned long& ms )
-{
+void System::sleep( const unsigned long& ms ) {
::Sleep( ms );
}
-std::string System::getProcessPath()
-{
+std::string System::getProcessPath() {
// Get path to executable:
WCHAR szDrive[_MAX_DRIVE];
WCHAR szDir[_MAX_DIR];
@@ -25,26 +23,24 @@ std::string System::getProcessPath()
WCHAR szExt[_MAX_DIR];
std::wstring dllName( _MAX_DIR, 0 );
- GetModuleFileNameW(0, &dllName[0], _MAX_PATH);
+ GetModuleFileNameW( 0, &dllName[0], _MAX_PATH );
- #ifdef EFSW_COMPILER_MSVC
- _wsplitpath_s( dllName.c_str(), szDrive, _MAX_DRIVE, szDir, _MAX_DIR, szFilename, _MAX_DIR, szExt, _MAX_DIR );
- #else
- _wsplitpath( dllName.c_str(), szDrive, szDir, szFilename, szExt);
- #endif
+#ifdef EFSW_COMPILER_MSVC
+ _wsplitpath_s( dllName.c_str(), szDrive, _MAX_DRIVE, szDir, _MAX_DIR, szFilename, _MAX_DIR,
+ szExt, _MAX_DIR );
+#else
+ _wsplitpath( dllName.c_str(), szDrive, szDir, szFilename, szExt );
+#endif
return String( szDrive ).toUtf8() + String( szDir ).toUtf8();
}
-void System::maxFD()
-{
-}
+void System::maxFD() {}
-Uint64 System::getMaxFD()
-{ // Number of ReadDirectory per thread
+Uint64 System::getMaxFD() { // Number of ReadDirectory per thread
return 60;
}
-}}
+}} // namespace efsw::Platform
#endif
diff --git a/dep/efsw/src/efsw/platform/win/SystemImpl.hpp b/dep/efsw/src/efsw/platform/win/SystemImpl.hpp
index 2f785e3565c..99b486756bd 100644
--- a/dep/efsw/src/efsw/platform/win/SystemImpl.hpp
+++ b/dep/efsw/src/efsw/platform/win/SystemImpl.hpp
@@ -7,19 +7,18 @@
namespace efsw { namespace Platform {
-class System
-{
- public:
- static void sleep( const unsigned long& ms );
+class System {
+ public:
+ static void sleep( const unsigned long& ms );
- static std::string getProcessPath();
+ static std::string getProcessPath();
- static void maxFD();
+ static void maxFD();
- static Uint64 getMaxFD();
+ static Uint64 getMaxFD();
};
-}}
+}} // namespace efsw::Platform
#endif
diff --git a/dep/efsw/src/efsw/platform/win/ThreadImpl.cpp b/dep/efsw/src/efsw/platform/win/ThreadImpl.cpp
index 48c9456adab..463934c9009 100644
--- a/dep/efsw/src/efsw/platform/win/ThreadImpl.cpp
+++ b/dep/efsw/src/efsw/platform/win/ThreadImpl.cpp
@@ -1,6 +1,6 @@
-#include <efsw/platform/win/ThreadImpl.hpp>
-#include <efsw/Thread.hpp>
#include <assert.h>
+#include <efsw/Thread.hpp>
+#include <efsw/platform/win/ThreadImpl.hpp>
#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32
@@ -8,57 +8,49 @@
namespace efsw { namespace Platform {
-ThreadImpl::ThreadImpl( Thread *owner )
-{
- mThread = reinterpret_cast<HANDLE>( _beginthreadex( NULL, 0, &ThreadImpl::entryPoint, owner, 0, &mThreadId ) );
+ThreadImpl::ThreadImpl( efsw::Thread* owner ) {
+ mThread = reinterpret_cast<HANDLE>(
+ _beginthreadex( NULL, 0, &ThreadImpl::entryPoint, owner, 0, &mThreadId ) );
- if ( !mThread )
- {
+ if ( !mThread ) {
efDEBUG( "Failed to create thread\n" );
}
}
-ThreadImpl::~ThreadImpl()
-{
- if ( mThread )
- {
+ThreadImpl::~ThreadImpl() {
+ if ( mThread ) {
CloseHandle( mThread );
}
}
-void ThreadImpl::wait()
-{
+void ThreadImpl::wait() {
// Wait for the thread to finish, no timeout
- if ( mThread )
- {
+ if ( mThread ) {
assert( mThreadId != GetCurrentThreadId() ); // A thread cannot wait for itself!
WaitForSingleObject( mThread, INFINITE );
}
}
-void ThreadImpl::terminate()
-{
- if ( mThread )
- {
+void ThreadImpl::terminate() {
+ if ( mThread ) {
TerminateThread( mThread, 0 );
}
}
-unsigned int __stdcall ThreadImpl::entryPoint( void * userData )
-{
+unsigned int __stdcall ThreadImpl::entryPoint( void* userData ) {
// The Thread instance is stored in the user data
- Thread * owner = static_cast<Thread*>( userData );
+ Thread* owner = static_cast<Thread*>( userData );
// Forward to the owner
owner->run();
// Optional, but it is cleaner
- _endthreadex(0);
+ _endthreadex( 0 );
return 0;
}
-}}
+}} // namespace efsw::Platform
#endif
diff --git a/dep/efsw/src/efsw/platform/win/ThreadImpl.hpp b/dep/efsw/src/efsw/platform/win/ThreadImpl.hpp
index 45e4505897a..455f24c2783 100644
--- a/dep/efsw/src/efsw/platform/win/ThreadImpl.hpp
+++ b/dep/efsw/src/efsw/platform/win/ThreadImpl.hpp
@@ -6,10 +6,10 @@
#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32
#ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
#endif
-#include <windows.h>
#include <process.h>
+#include <windows.h>
namespace efsw {
@@ -17,24 +17,25 @@ class Thread;
namespace Platform {
-class ThreadImpl
-{
- public:
- ThreadImpl( Thread * owner );
-
- ~ThreadImpl();
-
- void wait();
-
- void terminate();
- protected:
- static unsigned int __stdcall entryPoint(void* userData);
-
- HANDLE mThread;
- unsigned int mThreadId;
+class ThreadImpl {
+ public:
+ explicit ThreadImpl( efsw::Thread* owner );
+
+ ~ThreadImpl();
+
+ void wait();
+
+ void terminate();
+
+ protected:
+ static unsigned int __stdcall entryPoint( void* userData );
+
+ HANDLE mThread;
+ unsigned int mThreadId;
};
-}}
+} // namespace Platform
+} // namespace efsw
#endif
diff --git a/dep/efsw/src/test/efsw-test.c b/dep/efsw/src/test/efsw-test.c
new file mode 100644
index 00000000000..54a3e21bba5
--- /dev/null
+++ b/dep/efsw/src/test/efsw-test.c
@@ -0,0 +1,164 @@
+#include <efsw/efsw.h>
+
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <time.h>
+
+#ifdef _WIN32
+ #include <Windows.h>
+#else
+ #include <unistd.h>
+#endif
+
+const char PATH_SEPARATOR =
+#ifdef _WIN32
+ '\\';
+#else
+ '/';
+#endif
+
+bool STOP = false;
+
+void sigend( int sig ) {
+ printf( "Bye bye" );
+ STOP = true;
+}
+
+void sleepMsecs( int msecs ) {
+#ifdef _WIN32
+ Sleep( msecs );
+#else
+ sleep( msecs );
+#endif
+}
+
+const char * getActionName( enum efsw_action action ) {
+ switch ( action ) {
+ case EFSW_ADD:
+ return "Add";
+ case EFSW_MODIFIED:
+ return "Modified";
+ case EFSW_DELETE:
+ return "Delete";
+ case EFSW_MOVED:
+ return "Moved";
+ default:
+ return "Bad Action";
+ }
+}
+
+void handleFileAction( efsw_watcher watcher, efsw_watchid watchid,
+ const char* dir, const char* filename,
+ enum efsw_action action, const char* oldFilename,
+ void* param ) {
+ if ( strlen( oldFilename ) == 0 ) {
+ printf( "Watch ID %ld DIR (%s) FILE (%s) has event %s\n",
+ watchid, dir, filename, getActionName( action ));
+ } else {
+ printf( "Watch ID %ld DIR (%s) FILE (from file %s to %s) has event %s\n",
+ watchid, dir, oldFilename, filename, getActionName( action ));
+ }
+}
+
+efsw_watchid handleWatchID( efsw_watchid watchid ) {
+ switch ( watchid ) {
+ case EFSW_NOTFOUND:
+ case EFSW_REPEATED:
+ case EFSW_OUTOFSCOPE:
+ case EFSW_REMOTE:
+ case EFSW_WATCHER_FAILED:
+ case EFSW_UNSPECIFIED: {
+ printf( "%s\n", efsw_getlasterror() );
+ break;
+ }
+ default: {
+ printf( "Added WatchID: %ld\n", watchid );
+ }
+ }
+
+ return watchid;
+}
+
+int main( int argc, char** argv ) {
+ signal( SIGABRT, sigend );
+ signal( SIGINT, sigend );
+ signal( SIGTERM, sigend );
+
+ printf("Press ^C to exit demo\n");
+
+ bool commonTest = true;
+ bool useGeneric = false;
+ char *path = 0;
+
+ if ( argc >= 2 ) {
+ path = argv[1];
+
+ struct stat s;
+ if( stat(path,&s) == 0 && (s.st_mode & S_IFDIR) == S_IFDIR ) {
+ commonTest = false;
+ }
+
+ if ( argc >= 3 ) {
+ if ( strcmp( argv[2], "true" ) == 0 ) {
+ useGeneric = true;
+ }
+ }
+ }
+
+ /// create the file watcher object
+ efsw_watcher fileWatcher = efsw_create( useGeneric );
+ efsw_follow_symlinks( fileWatcher, false );
+ efsw_allow_outofscopelinks( fileWatcher, false );
+
+ if ( commonTest ) {
+ char cwd[256];
+ getcwd( cwd, sizeof(cwd) );
+ printf( "CurPath: %s\n", cwd );
+
+ /// starts watching
+ efsw_watch( fileWatcher );
+
+ /// add a watch to the system
+ char path1[256];
+ sprintf(path1, "%s%ctest", cwd, PATH_SEPARATOR );
+ handleWatchID( efsw_addwatch_withoptions( fileWatcher, path1, handleFileAction, true, 0, 0, 0 ) );
+
+ /// adds another watch after started watching...
+ sleepMsecs( 100 );
+
+ char path2[256];
+ sprintf(path2, "%s%ctest2", cwd, PATH_SEPARATOR );
+ efsw_watchid watchID = handleWatchID(
+ efsw_addwatch_withoptions( fileWatcher, path2, handleFileAction, true, 0, 0, 0 ) );
+
+ /// delete the watch
+ if ( watchID > 0 ) {
+ sleepMsecs( 1000 );
+ efsw_removewatch_byid( fileWatcher, watchID );
+ }
+ } else {
+ if ( efsw_addwatch( fileWatcher, path, handleFileAction, true, 0 ) > 0 ) {
+ efsw_watch( fileWatcher );
+
+ printf( "Watching directory: %s\n", path );
+
+ if ( useGeneric ) {
+ printf( "Using generic backend watcher\n" );
+ }
+ } else {
+ printf( "Error trying to watch directory: %s\n", path );
+ printf( "%s\n", efsw_getlasterror() );
+ }
+ }
+
+ while ( !STOP ) {
+ sleepMsecs( 100 );
+ }
+
+ efsw_release( fileWatcher );
+
+ return 0;
+}
diff --git a/dep/efsw/src/test/efsw-test.cpp b/dep/efsw/src/test/efsw-test.cpp
index a49e3414fcc..d51d68d7599 100644
--- a/dep/efsw/src/test/efsw-test.cpp
+++ b/dep/efsw/src/test/efsw-test.cpp
@@ -1,56 +1,59 @@
-#include <efsw/efsw.hpp>
-#include <efsw/System.hpp>
#include <efsw/FileSystem.hpp>
-#include <signal.h>
+#include <efsw/System.hpp>
+#include <efsw/efsw.hpp>
#include <iostream>
+#include <signal.h>
bool STOP = false;
-void sigend(int signal)
-{
+void sigend( int ) {
std::cout << std::endl << "Bye bye" << std::endl;
STOP = true;
}
/// Processes a file action
-class UpdateListener : public efsw::FileWatchListener
-{
- public:
- UpdateListener() {}
-
- std::string getActionName( efsw::Action action )
- {
- switch ( action )
- {
- case efsw::Actions::Add: return "Add";
- case efsw::Actions::Modified: return "Modified";
- case efsw::Actions::Delete: return "Delete";
- case efsw::Actions::Moved: return "Moved";
- default: return "Bad Action";
- }
+class UpdateListener : public efsw::FileWatchListener {
+ public:
+ UpdateListener() {}
+
+ std::string getActionName( efsw::Action action ) {
+ switch ( action ) {
+ case efsw::Actions::Add:
+ return "Add";
+ case efsw::Actions::Modified:
+ return "Modified";
+ case efsw::Actions::Delete:
+ return "Delete";
+ case efsw::Actions::Moved:
+ return "Moved";
+ default:
+ return "Bad Action";
}
+ }
- void handleFileAction( efsw::WatchID watchid, const std::string& dir, const std::string& filename, efsw::Action action, std::string oldFilename = "" )
- {
- std::cout << "DIR (" << dir + ") FILE (" + ( oldFilename.empty() ? "" : "from file " + oldFilename + " to " ) + filename + ") has event " << getActionName( action ) << std::endl;
- }
+ void handleFileAction( efsw::WatchID watchid, const std::string& dir,
+ const std::string& filename, efsw::Action action,
+ std::string oldFilename = "" ) override {
+ std::cout << "Watch ID " << watchid << " DIR ("
+ << dir + ") FILE (" +
+ ( oldFilename.empty() ? "" : "from file " + oldFilename + " to " ) +
+ filename + ") has event "
+ << getActionName( action ) << std::endl;
+ }
};
-efsw::WatchID handleWatchID( efsw::WatchID watchid )
-{
- switch ( watchid )
- {
+efsw::WatchID handleWatchID( efsw::WatchID watchid ) {
+ switch ( watchid ) {
case efsw::Errors::FileNotFound:
case efsw::Errors::FileRepeated:
case efsw::Errors::FileOutOfScope:
case efsw::Errors::FileRemote:
- case efsw::Errors::Unspecified:
- {
+ case efsw::Errors::WatcherFailed:
+ case efsw::Errors::Unspecified: {
std::cout << efsw::Errors::Log::getLastErrorLog().c_str() << std::endl;
break;
}
- default:
- {
+ default: {
std::cout << "Added WatchID: " << watchid << std::endl;
}
}
@@ -58,11 +61,10 @@ efsw::WatchID handleWatchID( efsw::WatchID watchid )
return watchid;
}
-int main(int argc, char **argv)
-{
- signal( SIGABRT , sigend );
- signal( SIGINT , sigend );
- signal( SIGTERM , sigend );
+int main( int argc, char** argv ) {
+ signal( SIGABRT, sigend );
+ signal( SIGINT, sigend );
+ signal( SIGTERM, sigend );
std::cout << "Press ^C to exit demo" << std::endl;
@@ -70,25 +72,21 @@ int main(int argc, char **argv)
bool useGeneric = false;
std::string path;
- if ( argc >= 2 )
- {
+ if ( argc >= 2 ) {
path = std::string( argv[1] );
- if ( efsw::FileSystem::isDirectory( path ) )
- {
- commonTest = false;
+ if ( efsw::FileSystem::isDirectory( path ) ) {
+ commonTest = false;
}
- if ( argc >= 3 )
- {
- if ( std::string( argv[2] ) == "true" )
- {
+ if ( argc >= 3 ) {
+ if ( std::string( argv[2] ) == "true" ) {
useGeneric = true;
}
}
}
- UpdateListener * ul = new UpdateListener();
+ UpdateListener* ul = new UpdateListener();
/// create the file watcher object
efsw::FileWatcher fileWatcher( useGeneric );
@@ -96,54 +94,44 @@ int main(int argc, char **argv)
fileWatcher.followSymlinks( false );
fileWatcher.allowOutOfScopeLinks( false );
- if ( commonTest )
- {
+ if ( commonTest ) {
std::string CurPath( efsw::System::getProcessPath() );
std::cout << "CurPath: " << CurPath.c_str() << std::endl;
+ /// starts watching
+ fileWatcher.watch();
+
/// add a watch to the system
handleWatchID( fileWatcher.addWatch( CurPath + "test", ul, true ) );
- /// starts watching
- fileWatcher.watch();
-
/// adds another watch after started watching...
efsw::System::sleep( 100 );
- efsw::WatchID watchID = handleWatchID( fileWatcher.addWatch( CurPath + "test2", ul, true ) );
+ efsw::WatchID watchID =
+ handleWatchID( fileWatcher.addWatch( CurPath + "test2", ul, true ) );
/// delete the watch
- if ( watchID > 0 )
- {
+ if ( watchID > 0 ) {
efsw::System::sleep( 1000 );
fileWatcher.removeWatch( watchID );
}
- }
- else
- {
- efsw::WatchID err;
-
- if ( ( err = fileWatcher.addWatch( path, ul, true ) ) > 0 )
- {
+ } else {
+ if ( fileWatcher.addWatch( path, ul, true ) > 0 ) {
fileWatcher.watch();
std::cout << "Watching directory: " << path.c_str() << std::endl;
- if ( useGeneric )
- {
+ if ( useGeneric ) {
std::cout << "Using generic backend watcher" << std::endl;
}
- }
- else
- {
+ } else {
std::cout << "Error trying to watch directory: " << path.c_str() << std::endl;
std::cout << efsw::Errors::Log::getLastErrorLog().c_str() << std::endl;
}
}
- while( !STOP )
- {
+ while ( !STOP ) {
efsw::System::sleep( 100 );
}