diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..0beb23f9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "src/3rdParty/efsw"] + path = src/3rdParty/efsw + url = https://github.com/SpartanJ/efsw diff --git a/CMakeLists.txt b/CMakeLists.txt index 613019e5..00c2f223 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,8 @@ -cmake_minimum_required(VERSION 3.10) -project(yue CXX) +cmake_minimum_required(VERSION 3.13) +project(yue LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) set(LUA_LIBDIR ${LUA_INCDIR}/../lib ${LUA_INCDIR}/../../lib) set(LUA_INCLUDE_DIR "${LUA_INCDIR}") @@ -50,129 +53,47 @@ message(STATUS "Lua: " ${LUA}) message(STATUS "Lua include: " ${LUA_INCLUDE_DIR}) message(STATUS "Lua library: ${LUA_LIBRARIES}") -enable_language(CXX) +set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) + include_directories(src src/3rdParty ${LUA_INCLUDE_DIR}) -add_definitions(-std=c++17 -O3 -fPIC) if (APPLE) add_compile_options(-Wno-deprecated-declarations) endif () -add_library(libyue MODULE +add_library(yue-common STATIC src/yuescript/ast.cpp src/yuescript/parser.cpp src/yuescript/yue_ast.cpp src/yuescript/yue_parser.cpp src/yuescript/yue_compiler.cpp +) + +target_link_libraries(yue-common PUBLIC ${LUA_LIBRARIES}) + +add_library(libyue MODULE src/yuescript/yuescript.cpp ) set_target_properties(libyue PROPERTIES PREFIX "") set_target_properties(libyue PROPERTIES OUTPUT_NAME "yue") -target_link_libraries(libyue ${LUA_LIBRARIES}) +target_link_libraries(libyue PRIVATE yue-common) + +add_subdirectory(src/3rdParty/efsw) add_executable(yue - src/yuescript/ast.cpp - src/yuescript/parser.cpp - src/yuescript/yue_ast.cpp - src/yuescript/yue_parser.cpp - src/yuescript/yue_compiler.cpp src/yuescript/yuescript.cpp src/yue.cpp ) -target_sources(yue PRIVATE - src/3rdParty/efsw/Debug.cpp - src/3rdParty/efsw/DirectorySnapshot.cpp - src/3rdParty/efsw/DirectorySnapshotDiff.cpp - src/3rdParty/efsw/DirWatcherGeneric.cpp - src/3rdParty/efsw/FileInfo.cpp - src/3rdParty/efsw/FileSystem.cpp - src/3rdParty/efsw/FileWatcher.cpp - src/3rdParty/efsw/FileWatcherCWrapper.cpp - src/3rdParty/efsw/FileWatcherGeneric.cpp - src/3rdParty/efsw/FileWatcherImpl.cpp - src/3rdParty/efsw/Log.cpp - src/3rdParty/efsw/Mutex.cpp - src/3rdParty/efsw/String.cpp - src/3rdParty/efsw/System.cpp - src/3rdParty/efsw/Thread.cpp - src/3rdParty/efsw/Watcher.cpp - src/3rdParty/efsw/WatcherGeneric.cpp -) - -if (WIN32) - target_sources(yue PRIVATE - src/3rdParty/efsw/platform/win/FileSystemImpl.cpp - src/3rdParty/efsw/platform/win/MutexImpl.cpp - src/3rdParty/efsw/platform/win/SystemImpl.cpp - src/3rdParty/efsw/platform/win/ThreadImpl.cpp - ) -else () - target_sources(yue PRIVATE - src/3rdParty/efsw/platform/posix/FileSystemImpl.cpp - src/3rdParty/efsw/platform/posix/MutexImpl.cpp - src/3rdParty/efsw/platform/posix/SystemImpl.cpp - src/3rdParty/efsw/platform/posix/ThreadImpl.cpp - ) -endif() - -if (APPLE) - target_sources(yue PRIVATE - src/3rdParty/efsw/FileWatcherFSEvents.cpp - src/3rdParty/efsw/FileWatcherKqueue.cpp - src/3rdParty/efsw/WatcherFSEvents.cpp - src/3rdParty/efsw/WatcherKqueue.cpp - ) - - if (NOT CMAKE_SYSTEM_VERSION GREATER 9) - target_compile_definitions(yue PRIVATE EFSW_FSEVENTS_NOT_SUPPORTED) - endif() -elseif (WIN32) - target_sources(yue PRIVATE - src/3rdParty/efsw/FileWatcherWin32.cpp - src/3rdParty/efsw/WatcherWin32.cpp - ) -elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - target_sources(yue PRIVATE - src/3rdParty/efsw/FileWatcherInotify.cpp - src/3rdParty/efsw/WatcherInotify.cpp - ) - - if (NOT EXISTS "/usr/include/sys/inotify.h" AND NOT EXISTS "/usr/local/include/sys/inotify.h") - target_compile_definitions(yue PRIVATE EFSW_INOTIFY_NOSYS) - endif() -elseif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") - target_sources(yue PRIVATE - src/3rdParty/efsw/FileWatcherKqueue.cpp - src/3rdParty/efsw/WatcherKqueue.cpp - ) -endif() - -if (MSVC) - target_compile_definitions(yue PRIVATE _SCL_SECURE_NO_WARNINGS) -else () - target_compile_options(yue PRIVATE -Wall -Wno-long-long -fPIC) -endif() +target_link_libraries(yue PRIVATE efsw-static yue-common) if (${CMAKE_BUILD_TYPE} MATCHES "Debug") target_compile_definitions(yue PRIVATE DEBUG) elseif (${CMAKE_BUILD_TYPE} MATCHES "Release") target_compile_definitions(yue PRIVATE NDEBUG) endif() - -find_package(Threads REQUIRED) -if (APPLE) - set(MAC_LIBS "-framework CoreFoundation" "-framework CoreServices") - target_link_libraries(yue PRIVATE ${LUA_LIBRARIES} ${MAC_LIBS} Threads::Threads) -elseif (NOT (${CMAKE_SYSTEM_NAME} MATCHES "Haiku") AND NOT WIN32) - target_link_libraries(yue PRIVATE ${LUA_LIBRARIES} Threads::Threads) -else () - target_link_libraries(yue PRIVATE ${LUA_LIBRARIES}) -endif() - if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") target_link_options(yue PRIVATE -lstdc++fs -ldl) endif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") install(CODE "") - diff --git a/src/3rdParty/efsw b/src/3rdParty/efsw new file mode 160000 index 00000000..ad4ac905 --- /dev/null +++ b/src/3rdParty/efsw @@ -0,0 +1 @@ +Subproject commit ad4ac9056402940bd41df38597d6046674b1c4a1 diff --git a/src/3rdParty/efsw/Atomic.hpp b/src/3rdParty/efsw/Atomic.hpp deleted file mode 100644 index 9015c600..00000000 --- a/src/3rdParty/efsw/Atomic.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef EFSW_ATOMIC_BOOL_HPP -#define EFSW_ATOMIC_BOOL_HPP - -#include - -#include - -namespace efsw { - -template 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 set_; -}; - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/Debug.cpp b/src/3rdParty/efsw/Debug.cpp deleted file mode 100644 index 18cfd315..00000000 --- a/src/3rdParty/efsw/Debug.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include -#include - -#ifdef EFSW_COMPILER_MSVC -#define WIN32_LEAN_AND_MEAN -#include -#include -#endif - -#include -#include -#include - -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 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 - - va_end( args ); - -#ifdef EFSW_COMPILER_MSVC - OutputDebugStringA( buf ); -#else - std::cout << buf; -#endif -} - -void efPRINTC( unsigned int cond, const char* format, ... ) { - if ( 0 == cond ) - return; - - 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 - - va_end( args ); - -#ifdef EFSW_COMPILER_MSVC - OutputDebugStringA( buf ); -#else - std::cout << buf; -#endif -} - -#endif - -} // namespace efsw diff --git a/src/3rdParty/efsw/Debug.hpp b/src/3rdParty/efsw/Debug.hpp deleted file mode 100644 index fefaec4d..00000000 --- a/src/3rdParty/efsw/Debug.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef EFSW_DEBUG_HPP -#define EFSW_DEBUG_HPP - -#include - -namespace efsw { - -#ifdef DEBUG - -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 ); \ - } - -void efPRINT( const char* format, ... ); -void efPRINTC( unsigned int cond, const char* format, ... ); - -#else - -#define efASSERT( expr ) -#define efASSERTM( expr, msg ) - -#ifndef EFSW_COMPILER_MSVC -#define efPRINT( format, args... ) \ - {} -#define efPRINTC( cond, format, args... ) \ - {} -#else -#define efPRINT -#define efPRINTC -#endif - -#endif - -#ifdef EFSW_VERBOSE -#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 - -#endif - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/DirWatcherGeneric.cpp b/src/3rdParty/efsw/DirWatcherGeneric.cpp deleted file mode 100644 index 8b6bc8a9..00000000 --- a/src/3rdParty/efsw/DirWatcherGeneric.cpp +++ /dev/null @@ -1,388 +0,0 @@ -#include -#include -#include -#include - -namespace efsw { - -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 ) { - DirSnap.scan(); - } else { - DirectorySnapshotDiff Diff = DirSnap.scan(); - - if ( Diff.changed() ) { - FileInfoList::iterator it; - - DiffIterator( FilesCreated ) { - handleAction( ( *it ).Filepath, Actions::Add ); - } - } - } -} - -DirWatcherGeneric::~DirWatcherGeneric() { - /// If the directory was deleted mark the files as deleted - if ( Deleted ) { - DirectorySnapshotDiff Diff = DirSnap.scan(); - - if ( !DirSnap.exists() ) { - FileInfoList::iterator it; - - DiffIterator( FilesDeleted ) { - handleAction( ( *it ).Filepath, Actions::Delete ); - } - - DiffIterator( DirsDeleted ) { - handleAction( ( *it ).Filepath, Actions::Delete ); - } - } - } - - DirWatchMap::iterator it = Directories.begin(); - - for ( ; it != Directories.end(); ++it ) { - if ( Deleted ) { - /// If the directory was deleted, mark the flag for file deletion - it->second->Deleted = true; - } - - efSAFE_DELETE( it->second ); - } -} - -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() ) ) ) { - /// Get the real directory - if ( NULL != Parent ) { - std::string parentPath( Parent->DirSnap.DirectoryInfo.Filepath ); - FileSystem::dirAddSlashAtEnd( parentPath ); - FileSystem::dirAddSlashAtEnd( directory ); - - dir = parentPath + directory; - } else { - efDEBUG( "resetDirectory(): Parent is NULL. Fatal error." ); - } - } - } - - 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::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 ) ) { - /// 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 ) { - /// Avoid adding symlinks directories if it's now enabled - 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 ) ) { - continue; - } else { - dir = link; - } - } else { - if ( Watch->pathInWatches( dir ) || Watch->WatcherImpl->pathInWatches( dir ) ) { - continue; - } - } - - if ( reportNewFiles ) { - handleAction( dir, Actions::Add ); - } - - Directories[dir] = - new DirWatcherGeneric( this, Watch, dir, Recursive, reportNewFiles ); - - Directories[dir]->addChilds( reportNewFiles ); - } - } - } -} - -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 ( Diff.changed() ) { - FileInfoList::iterator it; - MovedList::iterator mit; - - /// Files - DiffIterator( FilesCreated ) { - handleAction( ( *it ).Filepath, Actions::Add ); - } - - DiffIterator( FilesModified ) { - handleAction( ( *it ).Filepath, Actions::Modified ); - } - - DiffIterator( FilesDeleted ) { - handleAction( ( *it ).Filepath, Actions::Delete ); - } - - DiffMovedIterator( FilesMoved ) { - handleAction( ( *mit ).second.Filepath, Actions::Moved, ( *mit ).first ); - } - - /// Directories - DiffIterator( DirsCreated ) { - createDirectory( ( *it ).Filepath ); - } - - DiffIterator( DirsModified ) { - handleAction( ( *it ).Filepath, Actions::Modified ); - } - - 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 ); - } - } - - /// Process the subdirectories looking for changes - 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 ); - - if ( NULL != watcher ) { - watcher->watch( true ); - } -} - -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() ) ); - - if ( dir.size() >= DirSnap.DirectoryInfo.Filepath.size() ) { - dir = dir.substr( DirSnap.DirectoryInfo.Filepath.size() - 1 ); - } - - if ( dir.size() == 1 ) { - efASSERT( dir[0] == FileSystem::getOSSlash() ); - return this; - } - - size_t level = 0; - std::vector dirv = String::split( dir, FileSystem::getOSSlash(), false ); - - DirWatcherGeneric* watcher = this; - - while ( level < dirv.size() ) { - // search the dir level in the current watcher - DirWatchMap::iterator it = watcher->Directories.find( dirv[level] ); - - // found? continue with the next level - if ( it != watcher->Directories.end() ) { - watcher = it->second; - - level++; - } else { - // couldn't found the folder level? - // directory not watched - return NULL; - } - } - - return watcher; -} - -DirWatcherGeneric* DirWatcherGeneric::findDirWatcher( std::string dir ) { - if ( DirSnap.DirectoryInfo.Filepath == dir ) { - return this; - } else { - DirWatcherGeneric* watcher = NULL; - - for ( DirWatchMap::iterator it = Directories.begin(); it != Directories.end(); ++it ) { - watcher = it->second->findDirWatcher( dir ); - - if ( NULL != watcher ) { - return watcher; - } - } - } - - return NULL; -} - -DirWatcherGeneric* DirWatcherGeneric::createDirectory( std::string newdir ) { - FileSystem::dirRemoveSlashAtEnd( newdir ); - newdir = FileSystem::fileNameFromPath( newdir ); - - DirWatcherGeneric* dw = NULL; - - /// Check if the directory is a symbolic link - 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 ) ) { - return NULL; - } - - std::string curPath; - std::string link( FileSystem::getLinkRealPath( dir, curPath ) ); - bool skip = false; - - if ( "" != link ) { - /// Avoid adding symlinks directories if it's now enabled - 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 ) ) { - skip = true; - } else { - dir = link; - } - } else { - if ( Watch->pathInWatches( dir ) || Watch->WatcherImpl->pathInWatches( dir ) ) { - skip = true; - } - } - - 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; - } - - return dw; -} - -void DirWatcherGeneric::removeDirectory( std::string dir ) { - FileSystem::dirRemoveSlashAtEnd( dir ); - dir = FileSystem::fileNameFromPath( dir ); - - DirWatcherGeneric* dw = NULL; - DirWatchMap::iterator dit; - - /// Folder deleted - - /// Search the folder, it should exists - dit = Directories.find( dir ); - - if ( dit != Directories.end() ) { - dw = dit->second; - - /// Flag it as deleted so it fire the event for every file inside deleted - dw->Deleted = true; - - /// Delete the DirWatcherGeneric - efSAFE_DELETE( dw ); - - /// Remove the directory from the map - Directories.erase( dit->first ); - } -} - -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; - DirWatchMap::iterator dit; - - /// Directory existed? - dit = Directories.find( oldDir ); - - if ( dit != Directories.end() ) { - dw = dit->second; - - /// Remove the directory from the map - Directories.erase( dit->first ); - - Directories[newDir] = dw; - - dw->resetDirectory( newDir ); - } -} - -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; - } - } - - return false; -} - -} // namespace efsw diff --git a/src/3rdParty/efsw/DirWatcherGeneric.hpp b/src/3rdParty/efsw/DirWatcherGeneric.hpp deleted file mode 100644 index ca52de7f..00000000 --- a/src/3rdParty/efsw/DirWatcherGeneric.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef EFSW_DIRWATCHERGENERIC_HPP -#define EFSW_DIRWATCHERGENERIC_HPP - -#include -#include -#include -#include - -namespace efsw { - -class DirWatcherGeneric { - public: - typedef std::map DirWatchMap; - - 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(); - - void watch( bool reportOwnChange = false ); - - void watchDir( std::string& dir ); - - static bool isDir( const std::string& directory ); - - bool pathInWatches( std::string path ); - - void addChilds( bool reportNewFiles = true ); - - DirWatcherGeneric* findDirWatcher( std::string dir ); - - DirWatcherGeneric* findDirWatcherFast( std::string dir ); - - protected: - bool Deleted; - - DirWatcherGeneric* createDirectory( std::string newdir ); - - void removeDirectory( std::string dir ); - - void moveDirectory( std::string oldDir, std::string newDir ); - - void resetDirectory( std::string directory ); - - void handleAction( const std::string& filename, unsigned long action, - std::string oldFilename = "" ); -}; - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/DirectorySnapshot.cpp b/src/3rdParty/efsw/DirectorySnapshot.cpp deleted file mode 100644 index f78475f5..00000000 --- a/src/3rdParty/efsw/DirectorySnapshot.cpp +++ /dev/null @@ -1,212 +0,0 @@ -#include -#include - -namespace efsw { - -DirectorySnapshot::DirectorySnapshot() {} - -DirectorySnapshot::DirectorySnapshot( std::string directory ) { - init( directory ); -} - -DirectorySnapshot::~DirectorySnapshot() {} - -void DirectorySnapshot::init( std::string directory ) { - setDirectoryInfo( directory ); - initFiles(); -} - -bool DirectorySnapshot::exists() { - return DirectoryInfo.exists(); -} - -void DirectorySnapshot::deleteAll( DirectorySnapshotDiff& Diff ) { - FileInfo fi; - - for ( FileInfoMap::iterator it = Files.begin(); it != Files.end(); it++ ) { - fi = it->second; - - if ( fi.isDirectory() ) { - Diff.DirsDeleted.push_back( fi ); - } else { - Diff.FilesDeleted.push_back( fi ); - } - } - - Files.clear(); -} - -void DirectorySnapshot::setDirectoryInfo( std::string directory ) { - DirectoryInfo = FileInfo( directory ); -} - -void DirectorySnapshot::initFiles() { - Files = FileSystem::filesInfoFromPath( DirectoryInfo.Filepath ); - - FileInfoMap::iterator it = Files.begin(); - std::vector eraseFiles; - - /// Remove all non regular files and non directories - for ( ; it != Files.end(); it++ ) { - if ( !it->second.isRegularFile() && !it->second.isDirectory() ) { - eraseFiles.push_back( it->first ); - } - } - - for ( std::vector::iterator eit = eraseFiles.begin(); eit != eraseFiles.end(); - eit++ ) { - Files.erase( *eit ); - } -} - -DirectorySnapshotDiff DirectorySnapshot::scan() { - DirectorySnapshotDiff Diff; - - Diff.clear(); - - FileInfo curFI( DirectoryInfo.Filepath ); - - Diff.DirChanged = DirectoryInfo != curFI; - - if ( Diff.DirChanged ) { - DirectoryInfo = curFI; - } - - /// If the directory was erased, create the events for files and directories deletion - if ( !curFI.exists() ) { - deleteAll( Diff ); - - return Diff; - } - - FileInfoMap files = FileSystem::filesInfoFromPath( DirectoryInfo.Filepath ); - - if ( files.empty() && Files.empty() ) { - return Diff; - } - - FileInfo fi; - FileInfoMap FilesCpy; - FileInfoMap::iterator it; - FileInfoMap::iterator fiIt; - - if ( Diff.DirChanged ) { - FilesCpy = Files; - } - - for ( it = files.begin(); it != files.end(); it++ ) { - fi = it->second; - - /// File existed before? - fiIt = Files.find( it->first ); - - if ( fiIt != Files.end() ) { - /// Erase from the file list copy - FilesCpy.erase( it->first ); - - /// File changed? - if ( ( *fiIt ).second != fi ) { - /// Update the new file info - Files[it->first] = fi; - - /// handle modified event - if ( fi.isDirectory() ) { - Diff.DirsModified.push_back( fi ); - } else { - Diff.FilesModified.push_back( fi ); - } - } - } - /// Only add regular files or directories - else if ( fi.isRegularFile() || fi.isDirectory() ) { - /// New file found - Files[it->first] = fi; - - FileInfoMap::iterator fit; - std::string oldFile = ""; - - /// Check if the same inode already existed - if ( ( fit = nodeInFiles( fi ) ) != Files.end() ) { - oldFile = fit->first; - - /// Avoid firing a Delete event - FilesCpy.erase( fit->first ); - - /// Delete the old file name - Files.erase( fit->first ); - - if ( fi.isDirectory() ) { - Diff.DirsMoved.push_back( std::make_pair( oldFile, fi ) ); - } else { - Diff.FilesMoved.push_back( std::make_pair( oldFile, fi ) ); - } - } else { - if ( fi.isDirectory() ) { - Diff.DirsCreated.push_back( fi ); - } else { - Diff.FilesCreated.push_back( fi ); - } - } - } - } - - if ( !Diff.DirChanged ) { - return Diff; - } - - /// The files or directories that remains were deleted - for ( it = FilesCpy.begin(); it != FilesCpy.end(); it++ ) { - fi = it->second; - - if ( fi.isDirectory() ) { - Diff.DirsDeleted.push_back( fi ); - } else { - Diff.FilesDeleted.push_back( fi ); - } - - /// Remove the file or directory from the list of files - Files.erase( it->first ); - } - - return Diff; -} - -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 ) { - return it; - } - } - } - - return Files.end(); -} - -void DirectorySnapshot::addFile( std::string path ) { - std::string name( FileSystem::fileNameFromPath( path ) ); - Files[name] = FileInfo( path ); -} - -void DirectorySnapshot::removeFile( std::string path ) { - std::string name( FileSystem::fileNameFromPath( path ) ); - - FileInfoMap::iterator it = Files.find( name ); - - if ( Files.end() != it ) { - Files.erase( it ); - } -} - -void DirectorySnapshot::moveFile( std::string oldPath, std::string newPath ) { - removeFile( oldPath ); - addFile( newPath ); -} - -void DirectorySnapshot::updateFile( std::string path ) { - addFile( path ); -} - -} // namespace efsw diff --git a/src/3rdParty/efsw/DirectorySnapshot.hpp b/src/3rdParty/efsw/DirectorySnapshot.hpp deleted file mode 100644 index 0e605429..00000000 --- a/src/3rdParty/efsw/DirectorySnapshot.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef EFSW_DIRECTORYSNAPSHOT_HPP -#define EFSW_DIRECTORYSNAPSHOT_HPP - -#include - -namespace efsw { - -class DirectorySnapshot { - public: - FileInfo DirectoryInfo; - FileInfoMap Files; - - void setDirectoryInfo( std::string directory ); - - DirectorySnapshot(); - - DirectorySnapshot( std::string directory ); - - ~DirectorySnapshot(); - - void init( std::string directory ); - - bool exists(); - - DirectorySnapshotDiff scan(); - - FileInfoMap::iterator nodeInFiles( FileInfo& fi ); - - void addFile( std::string path ); - - void removeFile( std::string path ); - - void moveFile( std::string oldPath, std::string newPath ); - - void updateFile( std::string path ); - - protected: - void initFiles(); - - void deleteAll( DirectorySnapshotDiff& Diff ); -}; - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/DirectorySnapshotDiff.cpp b/src/3rdParty/efsw/DirectorySnapshotDiff.cpp deleted file mode 100644 index 37ee507f..00000000 --- a/src/3rdParty/efsw/DirectorySnapshotDiff.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include - -namespace efsw { - -void DirectorySnapshotDiff::clear() { - FilesCreated.clear(); - FilesModified.clear(); - FilesMoved.clear(); - FilesDeleted.clear(); - DirsCreated.clear(); - DirsModified.clear(); - DirsMoved.clear(); - DirsDeleted.clear(); -} - -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/src/3rdParty/efsw/DirectorySnapshotDiff.hpp b/src/3rdParty/efsw/DirectorySnapshotDiff.hpp deleted file mode 100644 index 26a29ec4..00000000 --- a/src/3rdParty/efsw/DirectorySnapshotDiff.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef EFSW_DIRECTORYSNAPSHOTDIFF_HPP -#define EFSW_DIRECTORYSNAPSHOTDIFF_HPP - -#include - -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(); -}; - -#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++ ) - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/FileInfo.cpp b/src/3rdParty/efsw/FileInfo.cpp deleted file mode 100644 index 707f617f..00000000 --- a/src/3rdParty/efsw/FileInfo.cpp +++ /dev/null @@ -1,240 +0,0 @@ -#include -#include -#include - -#ifndef _DARWIN_FEATURE_64_BIT_INODE -#define _DARWIN_FEATURE_64_BIT_INODE -#endif - -#ifndef _FILE_OFFSET_BITS -#define _FILE_OFFSET_BITS 64 -#endif - -#include - -#include -#include - -#ifdef EFSW_COMPILER_MSVC -#ifndef S_ISDIR -#define S_ISDIR( f ) ( (f)&_S_IFDIR ) -#endif - -#ifndef S_ISREG -#define S_ISREG( f ) ( (f)&_S_IFREG ) -#endif - -#ifndef S_ISRDBL -#define S_ISRDBL( f ) ( (f)&_S_IREAD ) -#endif -#else -#include - -#ifndef S_ISRDBL -#define S_ISRDBL( f ) ( (f)&S_IRUSR ) -#endif -#endif - -namespace efsw { - -bool FileInfo::exists( const std::string& filePath ) { - FileInfo fi( filePath ); - return fi.exists(); -} - -bool FileInfo::isLink( const std::string& filePath ) { - FileInfo fi( filePath, true ); - return fi.isLink(); -} - -bool FileInfo::inodeSupported() { -#if EFSW_PLATFORM != EFSW_PLATFORM_WIN32 - return true; -#else - return false; -#endif -} - -FileInfo::FileInfo() : - 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 ) { - getInfo(); -} - -FileInfo::FileInfo( const std::string& filepath, bool linkInfo ) : - Filepath( filepath ), - ModificationTime( 0 ), - OwnerId( 0 ), - GroupId( 0 ), - Permissions( 0 ), - Inode( 0 ) { - if ( linkInfo ) { - getRealInfo(); - } else { - getInfo(); - } -} - -void FileInfo::getInfo() { -#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32 - if ( Filepath.size() == 3 && Filepath[1] == ':' && Filepath[2] == FileSystem::getOSSlash() ) { - Filepath += FileSystem::getOSSlash(); - } -#endif - - /// 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 ) { - FileSystem::dirRemoveSlashAtEnd( Filepath ); - } - -#if EFSW_PLATFORM != EFSW_PLATFORM_WIN32 - struct stat st; - int res = stat( Filepath.c_str(), &st ); -#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; - } - - if ( slashAtEnd ) { - FileSystem::dirAddSlashAtEnd( Filepath ); - } -} - -void FileInfo::getRealInfo() { - bool slashAtEnd = FileSystem::slashAtEnd( Filepath ); - - if ( slashAtEnd ) { - FileSystem::dirRemoveSlashAtEnd( Filepath ); - } - -#if EFSW_PLATFORM != EFSW_PLATFORM_WIN32 - struct stat st; - int res = lstat( Filepath.c_str(), &st ); -#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; - } - - 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::isDirectory() const { - return 0 != S_ISDIR( Permissions ); -} - -bool FileInfo::isRegularFile() const { - return 0 != S_ISREG( Permissions ); -} - -bool FileInfo::isReadable() const { -#if EFSW_PLATFORM != EFSW_PLATFORM_WIN32 - static bool isRoot = getuid() == 0; - return isRoot || 0 != S_ISRDBL( Permissions ); -#else - return 0 != S_ISRDBL( Permissions ); -#endif -} - -bool FileInfo::isLink() const { -#if EFSW_PLATFORM != EFSW_PLATFORM_WIN32 - return S_ISLNK( Permissions ); -#else - return false; -#endif -} - -std::string FileInfo::linksTo() { -#if EFSW_PLATFORM != EFSW_PLATFORM_WIN32 - if ( isLink() ) { - char* ch = realpath( Filepath.c_str(), NULL ); - - if ( NULL != ch ) { - std::string tstr( ch ); - - free( ch ); - - return tstr; - } - } -#endif - return std::string( "" ); -} - -bool FileInfo::exists() { - bool slashAtEnd = FileSystem::slashAtEnd( Filepath ); - - if ( slashAtEnd ) { - FileSystem::dirRemoveSlashAtEnd( Filepath ); - } - -#if EFSW_PLATFORM != EFSW_PLATFORM_WIN32 - struct stat st; - int res = stat( Filepath.c_str(), &st ); -#else - struct _stat st; - int res = _wstat( String::fromUtf8( Filepath ).toWideString().c_str(), &st ); -#endif - - 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; - return *this; -} - -bool FileInfo::sameInode( const FileInfo& Other ) const { - return inodeSupported() && Inode == Other.Inode; -} - -bool FileInfo::operator!=( const FileInfo& Other ) const { - return !( *this == Other ); -} - -} // namespace efsw diff --git a/src/3rdParty/efsw/FileInfo.hpp b/src/3rdParty/efsw/FileInfo.hpp deleted file mode 100644 index 1b55c352..00000000 --- a/src/3rdParty/efsw/FileInfo.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef EFSW_FILEINFO_HPP -#define EFSW_FILEINFO_HPP - -#include -#include -#include -#include - -namespace efsw { - -class FileInfo { - public: - static bool exists( const std::string& filePath ); - - static bool isLink( const std::string& filePath ); - - static bool inodeSupported(); - - FileInfo(); - - FileInfo( const std::string& filepath ); - - FileInfo( const std::string& filepath, bool linkInfo ); - - FileInfo(const FileInfo&) = default; - - bool operator==( const FileInfo& Other ) const; - - bool operator!=( const FileInfo& Other ) const; - - FileInfo& operator=( const FileInfo& Other ); - - bool isDirectory() const; - - bool isRegularFile() const; - - bool isReadable() const; - - bool sameInode( const FileInfo& Other ) const; - - bool isLink() const; - - std::string linksTo(); - - bool exists(); - - void getInfo(); - - void getRealInfo(); - - std::string Filepath; - Uint64 ModificationTime; - Uint64 Size; - Uint32 OwnerId; - Uint32 GroupId; - Uint32 Permissions; - Uint64 Inode; -}; - -typedef std::map FileInfoMap; -typedef std::vector FileInfoList; -typedef std::vector> MovedList; - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/FileSystem.cpp b/src/3rdParty/efsw/FileSystem.cpp deleted file mode 100644 index 1ed346ca..00000000 --- a/src/3rdParty/efsw/FileSystem.cpp +++ /dev/null @@ -1,161 +0,0 @@ -#include -#include -#include -#include - -#if EFSW_OS == EFSW_OS_MACOSX -#include -#endif - -#if EFSW_OS == EFSW_OS_WIN -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#endif - -namespace efsw { - -bool FileSystem::isDirectory( const std::string& path ) { - return Platform::FileSystem::isDirectory( path ); -} - -FileInfoMap FileSystem::filesInfoFromPath( std::string path ) { - dirAddSlashAtEnd( path ); - - return Platform::FileSystem::filesInfoFromPath( path ); -} - -char FileSystem::getOSSlash() { - return Platform::FileSystem::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() ) { - dir.push_back( 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 ) { - dirRemoveSlashAtEnd( filepath ); - - size_t pos = filepath.find_last_of( getOSSlash() ); - - if ( pos != std::string::npos ) { - return filepath.substr( pos + 1 ); - } - - return filepath; -} - -std::string FileSystem::pathRemoveFileName( std::string filepath ) { - dirRemoveSlashAtEnd( filepath ); - - size_t pos = filepath.find_last_of( getOSSlash() ); - - if ( pos != std::string::npos ) { - return filepath.substr( 0, pos + 1 ); - } - - return filepath; -} - -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() ) { - /// get the real path of the link - std::string link( fi.linksTo() ); - - /// get the current path of the directory without the link dir path - curPath = FileSystem::pathRemoveFileName( dir ); - - /// ensure that ends with the os directory slash - FileSystem::dirAddSlashAtEnd( link ); - - return link; - } - - /// if it's not a link return nothing - return ""; -} - -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 ); - - 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(); - } - - 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 ) { - return Platform::FileSystem::isRemoteFS( directory ); -} - -bool FileSystem::changeWorkingDirectory( const std::string& directory ) { - return Platform::FileSystem::changeWorkingDirectory( directory ); -} - -std::string FileSystem::getCurrentWorkingDirectory() { - return Platform::FileSystem::getCurrentWorkingDirectory(); -} - -std::string FileSystem::getRealPath( const std::string& path ) { - std::string realPath; -#if defined( EFSW_PLATFORM_POSIX ) - char dir[PATH_MAX]; - realpath( path.c_str(), &dir[0] ); - realPath = std::string( dir ); -#elif EFSW_OS == EFSW_OS_WIN - wchar_t dir[_MAX_PATH + 1]; - GetFullPathNameW( String::fromUtf8( path ).toWideString().c_str(), _MAX_PATH, &dir[0], - nullptr ); - realPath = String( dir ).toUtf8(); -#else -#warning FileSystem::getRealPath() not implemented on this platform. -#endif - return realPath; -} - -} // namespace efsw diff --git a/src/3rdParty/efsw/FileSystem.hpp b/src/3rdParty/efsw/FileSystem.hpp deleted file mode 100644 index 1d66ece4..00000000 --- a/src/3rdParty/efsw/FileSystem.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef EFSW_FILESYSTEM_HPP -#define EFSW_FILESYSTEM_HPP - -#include -#include - -namespace efsw { - -class FileSystem { - public: - static bool isDirectory( const std::string& path ); - - static FileInfoMap filesInfoFromPath( std::string path ); - - static char getOSSlash(); - - static bool slashAtEnd( std::string& dir ); - - static void dirAddSlashAtEnd( std::string& dir ); - - static void dirRemoveSlashAtEnd( std::string& dir ); - - static std::string fileNameFromPath( std::string filepath ); - - static std::string pathRemoveFileName( std::string filepath ); - - static std::string getLinkRealPath( std::string dir, std::string& curPath ); - - static std::string precomposeFileName( const std::string& name ); - - static bool isRemoteFS( const std::string& directory ); - - static bool changeWorkingDirectory( const std::string& path ); - - static std::string getCurrentWorkingDirectory(); - - static std::string getRealPath( const std::string& path ); - -}; - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/FileWatcher.cpp b/src/3rdParty/efsw/FileWatcher.cpp deleted file mode 100644 index f45b2434..00000000 --- a/src/3rdParty/efsw/FileWatcher.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include -#include -#include -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32 -#include -#define FILEWATCHER_IMPL FileWatcherWin32 -#define BACKEND_NAME "Win32" -#elif EFSW_PLATFORM == EFSW_PLATFORM_INOTIFY -#include -#define FILEWATCHER_IMPL FileWatcherInotify -#define BACKEND_NAME "Inotify" -#elif EFSW_PLATFORM == EFSW_PLATFORM_KQUEUE -#include -#define FILEWATCHER_IMPL FileWatcherKqueue -#define BACKEND_NAME "Kqueue" -#elif EFSW_PLATFORM == EFSW_PLATFORM_FSEVENTS -#include -#define FILEWATCHER_IMPL FileWatcherFSEvents -#define BACKEND_NAME "FSEvents" -#else -#define FILEWATCHER_IMPL FileWatcherGeneric -#define BACKEND_NAME "Generic" -#endif - -#include - -namespace efsw { - -FileWatcher::FileWatcher() : mFollowSymlinks( false ), mOutOfScopeLinks( false ) { - efDEBUG( "Using backend: %s\n", BACKEND_NAME ); - - mImpl = new FILEWATCHER_IMPL( this ); - - if ( !mImpl->initOK() ) { - efSAFE_DELETE( mImpl ); - - efDEBUG( "Falled back to backend: %s\n", BACKEND_NAME ); - - mImpl = new FileWatcherGeneric( this ); - } -} - -FileWatcher::FileWatcher( bool useGenericFileWatcher ) : - mFollowSymlinks( false ), mOutOfScopeLinks( false ) { - if ( useGenericFileWatcher ) { - efDEBUG( "Using backend: Generic\n" ); - - mImpl = new FileWatcherGeneric( this ); - } else { - efDEBUG( "Using backend: %s\n", BACKEND_NAME ); - - mImpl = new FILEWATCHER_IMPL( this ); - - if ( !mImpl->initOK() ) { - efSAFE_DELETE( mImpl ); - - efDEBUG( "Falled back to backend: %s\n", BACKEND_NAME ); - - mImpl = new FileWatcherGeneric( this ); - } - } -} - -FileWatcher::~FileWatcher() { - efSAFE_DELETE( mImpl ); -} - -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 ) { - return addWatch( directory, watcher, recursive, {} ); -} - -WatchID FileWatcher::addWatch( const std::string& directory, FileWatchListener* watcher, - bool recursive, const std::vector& 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( WatchID watchid ) { - mImpl->removeWatch( watchid ); -} - -void FileWatcher::watch() { - mImpl->watch(); -} - -std::vector FileWatcher::directories() { - return mImpl->directories(); -} - -void FileWatcher::followSymlinks( bool follow ) { - mFollowSymlinks = follow; -} - -const bool& FileWatcher::followSymlinks() const { - return mFollowSymlinks; -} - -void FileWatcher::allowOutOfScopeLinks( bool allow ) { - mOutOfScopeLinks = allow; -} - -const bool& FileWatcher::allowOutOfScopeLinks() const { - return mOutOfScopeLinks; -} - -} // namespace efsw diff --git a/src/3rdParty/efsw/FileWatcherCWrapper.cpp b/src/3rdParty/efsw/FileWatcherCWrapper.cpp deleted file mode 100644 index 8712d6e0..00000000 --- a/src/3rdParty/efsw/FileWatcherCWrapper.cpp +++ /dev/null @@ -1,131 +0,0 @@ -#include -#include -#include - -#define TOBOOL( i ) ( ( i ) == 0 ? false : true ) - -/*************************************************************************************************/ -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 ); - } -}; - -/************************************************************************************************* - * globals - */ -static std::vector g_callbacks; - -Watcher_CAPI* find_callback( efsw_watcher watcher, efsw_pfn_fileaction_callback fn, void* param ) { - for ( std::vector::iterator i = g_callbacks.begin(); i != g_callbacks.end(); - ++i ) { - Watcher_CAPI* callback = *i; - - if ( callback->mFn == fn && callback->mWatcher == watcher && callback->mParam == param ) - return *i; - } - - return NULL; -} - -Watcher_CAPI* remove_callback( efsw_watcher watcher ) { - std::vector::iterator i = g_callbacks.begin(); - - while ( i != g_callbacks.end() ) { - Watcher_CAPI* callback = *i; - - if ( callback->mWatcher == watcher ) - i = g_callbacks.erase( i ); - else - ++i; - } - - return NULL; -} - -/*************************************************************************************************/ -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 ); - delete (efsw::FileWatcher*)watcher; -} - -const char* efsw_getlasterror() { - static std::string log_str; - log_str = efsw::Errors::Log::getLastErrorLog(); - return log_str.c_str(); -} - -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, param ); - - if ( callback == NULL ) { - callback = new Watcher_CAPI( watcher, callback_fn, param ); - g_callbacks.push_back( callback ); - } - - std::vector watcher_options{}; - for ( int i = 0; i < options_number; i++ ) { - efsw_watcher_option* option = &options[i]; - watcher_options.emplace_back( efsw::WatcherOption{ - static_cast(option->option), option->value } ); - } - - return ( (efsw::FileWatcher*)watcher ) - ->addWatch( std::string( directory ), callback, TOBOOL( recursive ), watcher_options ); -} - -void efsw_removewatch( efsw_watcher watcher, const char* directory ) { - ( (efsw::FileWatcher*)watcher )->removeWatch( std::string( directory ) ); -} - -void efsw_removewatch_byid( efsw_watcher watcher, efsw_watchid watchid ) { - ( (efsw::FileWatcher*)watcher )->removeWatch( watchid ); -} - -void efsw_watch( efsw_watcher watcher ) { - ( (efsw::FileWatcher*)watcher )->watch(); -} - -void efsw_follow_symlinks( efsw_watcher watcher, int enable ) { - ( (efsw::FileWatcher*)watcher )->followSymlinks( TOBOOL( enable ) ); -} - -int efsw_follow_symlinks_isenabled( efsw_watcher watcher ) { - return (int)( (efsw::FileWatcher*)watcher )->followSymlinks(); -} - -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/src/3rdParty/efsw/FileWatcherFSEvents.cpp b/src/3rdParty/efsw/FileWatcherFSEvents.cpp deleted file mode 100644 index 70ec2b18..00000000 --- a/src/3rdParty/efsw/FileWatcherFSEvents.cpp +++ /dev/null @@ -1,248 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_FSEVENTS - -#include - -namespace efsw { - -int getOSXReleaseNumber() { - static int osxR = -1; - - 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 ) { - release = release.substr( 0, pos ); - } - - int rel = 0; - - if ( String::fromString( rel, release ) ) { - osxR = rel; - } - } - } - - return osxR; -} - -bool FileWatcherFSEvents::isGranular() { - return getOSXReleaseNumber() >= 11; -} - -static std::string convertCFStringToStdString( CFStringRef cfString ) { - // Try to get the C string pointer directly - const char* cStr = CFStringGetCStringPtr( cfString, kCFStringEncodingUTF8 ); - - if ( cStr ) { - // If the pointer is valid, directly return a std::string from it - return std::string( cStr ); - } else { - // If not, manually convert it - CFIndex length = CFStringGetLength( cfString ); - CFIndex maxSize = CFStringGetMaximumSizeForEncoding( length, kCFStringEncodingUTF8 ) + - 1; // +1 for null terminator - - char* buffer = new char[maxSize]; - - if ( CFStringGetCString( cfString, buffer, maxSize, kCFStringEncodingUTF8 ) ) { - std::string result( buffer ); - delete[] buffer; - return result; - } else { - delete[] buffer; - return ""; - } - } -} - -void FileWatcherFSEvents::FSEventCallback( ConstFSEventStreamRef /*streamRef*/, void* userData, - size_t numEvents, void* eventPaths, - const FSEventStreamEventFlags eventFlags[], - const FSEventStreamEventId eventIds[] ) { - WatcherFSEvents* watcher = static_cast( userData ); - - std::vector events; - events.reserve( numEvents ); - - for ( size_t i = 0; i < numEvents; i++ ) { - if ( isGranular() ) { - CFDictionaryRef pathInfoDict = - static_cast( CFArrayGetValueAtIndex( (CFArrayRef)eventPaths, i ) ); - CFStringRef path = static_cast( - CFDictionaryGetValue( pathInfoDict, kFSEventStreamEventExtendedDataPathKey ) ); - CFNumberRef cfInode = static_cast( - CFDictionaryGetValue( pathInfoDict, kFSEventStreamEventExtendedFileIDKey ) ); - - if ( cfInode ) { - unsigned long inode = 0; - CFNumberGetValue( cfInode, kCFNumberLongType, &inode ); - events.push_back( FSEvent( convertCFStringToStdString( path ), (long)eventFlags[i], - (Uint64)eventIds[i], inode ) ); - } - } else { - events.push_back( FSEvent( std::string( ( (char**)eventPaths )[i] ), - (long)eventFlags[i], (Uint64)eventIds[i] ) ); - } - } - - watcher->handleActions( events ); - - watcher->process(); - - efDEBUG( "\n" ); -} - -FileWatcherFSEvents::FileWatcherFSEvents( FileWatcher* parent ) : - FileWatcherImpl( parent ), mLastWatchID( 0 ) { - mInitOK = true; - - watch(); -} - -FileWatcherFSEvents::~FileWatcherFSEvents() { - mInitOK = false; - - mWatchCond.notify_all(); - - WatchMap::iterator iter = mWatches.begin(); - - for ( ; iter != mWatches.end(); ++iter ) { - WatcherFSEvents* watch = iter->second; - - efSAFE_DELETE( watch ); - } -} - -WatchID FileWatcherFSEvents::addWatch( const std::string& directory, FileWatchListener* watcher, - bool recursive, const std::vector& options ) { - std::string dir( FileSystem::getRealPath( directory ) ); - - FileInfo fi( dir ); - - if ( !fi.isDirectory() ) { - return Errors::Log::createLastError( Errors::FileNotFound, dir ); - } else if ( !fi.isReadable() ) { - return Errors::Log::createLastError( Errors::FileNotReadable, dir ); - } - - FileSystem::dirAddSlashAtEnd( dir ); - - if ( pathInWatches( dir ) ) { - return Errors::Log::createLastError( Errors::FileRepeated, directory ); - } - - /// Check if the directory is a symbolic link - std::string curPath; - std::string link( FileSystem::getLinkRealPath( dir, curPath ) ); - - 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 ) ) { - return Errors::Log::createLastError( Errors::FileRepeated, directory ); - } else if ( !linkAllowed( curPath, link ) ) { - return Errors::Log::createLastError( Errors::FileOutOfScope, dir ); - } else { - dir = link; - } - } - - mLastWatchID++; - - WatcherFSEvents* pWatch = new WatcherFSEvents(); - pWatch->Listener = watcher; - pWatch->ID = mLastWatchID; - pWatch->Directory = dir; - pWatch->Recursive = recursive; - pWatch->FWatcher = this; - pWatch->ModifiedFlags = - getOptionValue( options, Option::MacModifiedFilter, efswFSEventsModified ); - pWatch->SanitizeEvents = getOptionValue( options, Option::MacSanitizeEvents, 0 ) != 0; - - pWatch->init(); - - { - Lock lock( mWatchesLock ); - mWatches.insert( std::make_pair( mLastWatchID, pWatch ) ); - } - - mWatchCond.notify_all(); - return pWatch->ID; -} - -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 ) { - removeWatch( iter->second->ID ); - return; - } - } -} - -void FileWatcherFSEvents::removeWatch( WatchID watchid ) { - Lock lock( mWatchesLock ); - - WatchMap::iterator iter = mWatches.find( watchid ); - - if ( iter == mWatches.end() ) - return; - - WatcherFSEvents* watch = iter->second; - - mWatches.erase( iter ); - - efDEBUG( "Removed watch %s\n", watch->Directory.c_str() ); - - efSAFE_DELETE( watch ); -} - -void FileWatcherFSEvents::watch() {} - -void FileWatcherFSEvents::handleAction( Watcher* /*watch*/, const std::string& /*filename*/, - unsigned long /*action*/, std::string /*oldFilename*/ ) { - /// Not used -} - -std::vector FileWatcherFSEvents::directories() { - std::vector dirs; - - Lock lock( mWatchesLock ); - - 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 ) { - return true; - } - } - - return false; -} - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/FileWatcherFSEvents.hpp b/src/3rdParty/efsw/FileWatcherFSEvents.hpp deleted file mode 100644 index daa538cc..00000000 --- a/src/3rdParty/efsw/FileWatcherFSEvents.hpp +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef EFSW_FILEWATCHERFSEVENTS_HPP -#define EFSW_FILEWATCHERFSEVENTS_HPP - -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_FSEVENTS - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace efsw { - -/// Implementation for Win32 based on ReadDirectoryChangesW. -/// @class FileWatcherFSEvents -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 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 &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 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 - -#endif diff --git a/src/3rdParty/efsw/FileWatcherGeneric.cpp b/src/3rdParty/efsw/FileWatcherGeneric.cpp deleted file mode 100644 index 3f3c52e4..00000000 --- a/src/3rdParty/efsw/FileWatcherGeneric.cpp +++ /dev/null @@ -1,158 +0,0 @@ -#include -#include -#include -#include - -namespace efsw { - -FileWatcherGeneric::FileWatcherGeneric( FileWatcher* parent ) : - FileWatcherImpl( parent ), mThread( NULL ), mLastWatchID( 0 ) { - mInitOK = true; - mIsGeneric = true; -} - -FileWatcherGeneric::~FileWatcherGeneric() { - mInitOK = false; - - efSAFE_DELETE( mThread ); - - /// Delete the watches - WatchList::iterator it = mWatches.begin(); - - for ( ; it != mWatches.end(); ++it ) { - efSAFE_DELETE( ( *it ) ); - } -} - -WatchID FileWatcherGeneric::addWatch( const std::string& directory, FileWatchListener* watcher, - bool recursive, const std::vector& options ) { - std::string dir( directory ); - - FileSystem::dirAddSlashAtEnd( dir ); - - FileInfo fi( dir ); - - if ( !fi.isDirectory() ) { - return Errors::Log::createLastError( Errors::FileNotFound, dir ); - } else if ( !fi.isReadable() ) { - return Errors::Log::createLastError( Errors::FileNotReadable, 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 ) ) { - return Errors::Log::createLastError( Errors::FileRepeated, dir ); - } else if ( !linkAllowed( curPath, link ) ) { - return Errors::Log::createLastError( Errors::FileOutOfScope, dir ); - } else { - dir = link; - } - } - - mLastWatchID++; - - WatcherGeneric* pWatch = new WatcherGeneric( mLastWatchID, dir, watcher, this, recursive ); - - Lock lock( mWatchesLock ); - mWatches.push_back( pWatch ); - - return pWatch->ID; -} - -void FileWatcherGeneric::removeWatch( const std::string& directory ) { - WatchList::iterator it = mWatches.begin(); - - for ( ; it != mWatches.end(); ++it ) { - if ( ( *it )->Directory == directory ) { - WatcherGeneric* watch = ( *it ); - - Lock lock( mWatchesLock ); - - mWatches.erase( it ); - - efSAFE_DELETE( watch ); - - return; - } - } -} - -void FileWatcherGeneric::removeWatch( WatchID watchid ) { - WatchList::iterator it = mWatches.begin(); - - for ( ; it != mWatches.end(); ++it ) { - if ( ( *it )->ID == watchid ) { - WatcherGeneric* watch = ( *it ); - - Lock lock( mWatchesLock ); - - mWatches.erase( it ); - - efSAFE_DELETE( watch ); - - return; - } - } -} - -void FileWatcherGeneric::watch() { - if ( NULL == mThread ) { - mThread = new Thread( &FileWatcherGeneric::run, this ); - mThread->launch(); - } -} - -void FileWatcherGeneric::run() { - do { - { - Lock lock( mWatchesLock ); - - WatchList::iterator it = mWatches.begin(); - - for ( ; it != mWatches.end(); ++it ) { - ( *it )->watch(); - } - } - - if ( mInitOK ) - System::sleep( 1000 ); - } while ( mInitOK ); -} - -void FileWatcherGeneric::handleAction( Watcher*, const std::string&, unsigned long, std::string ) { - /// Not used -} - -std::vector FileWatcherGeneric::directories() { - std::vector dirs; - - Lock lock( mWatchesLock ); - - dirs.reserve( mWatches.size() ); - - WatchList::iterator it = mWatches.begin(); - - for ( ; it != mWatches.end(); ++it ) { - dirs.push_back( ( *it )->Directory ); - } - - return dirs; -} - -bool FileWatcherGeneric::pathInWatches( const std::string& path ) { - WatchList::iterator it = mWatches.begin(); - - for ( ; it != mWatches.end(); ++it ) { - if ( ( *it )->Directory == path || ( *it )->pathInWatches( path ) ) { - return true; - } - } - - return false; -} - -} // namespace efsw diff --git a/src/3rdParty/efsw/FileWatcherGeneric.hpp b/src/3rdParty/efsw/FileWatcherGeneric.hpp deleted file mode 100644 index 47f7e047..00000000 --- a/src/3rdParty/efsw/FileWatcherGeneric.hpp +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef EFSW_FILEWATCHERGENERIC_HPP -#define EFSW_FILEWATCHERGENERIC_HPP - -#include -#include -#include -#include - -namespace efsw { - -/// Implementation for Generic File Watcher. -/// @class FileWatcherGeneric -class FileWatcherGeneric : public FileWatcherImpl { - public: - typedef std::vector WatchList; - - FileWatcherGeneric( FileWatcher* parent ); - - virtual ~FileWatcherGeneric(); - - /// Add a directory watch - /// On error returns WatchID with Error type. - WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive, - const std::vector &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 directories() override; - - protected: - Thread* mThread; - - /// The last watchid - WatchID mLastWatchID; - - /// Map of WatchID to WatchStruct pointers - WatchList mWatches; - - Mutex mWatchesLock; - - bool pathInWatches( const std::string& path ) override; - - private: - void run(); -}; - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/FileWatcherImpl.cpp b/src/3rdParty/efsw/FileWatcherImpl.cpp deleted file mode 100644 index bf69a452..00000000 --- a/src/3rdParty/efsw/FileWatcherImpl.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include -#include -#include - -namespace efsw { - -FileWatcherImpl::FileWatcherImpl( FileWatcher* parent ) : - mFileWatcher( parent ), mInitOK( false ), mIsGeneric( false ) { - System::maxFD(); -} - -FileWatcherImpl::~FileWatcherImpl() {} - -bool FileWatcherImpl::initOK() { - return static_cast( mInitOK ); -} - -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& 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/src/3rdParty/efsw/FileWatcherImpl.hpp b/src/3rdParty/efsw/FileWatcherImpl.hpp deleted file mode 100644 index a6ec4720..00000000 --- a/src/3rdParty/efsw/FileWatcherImpl.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef EFSW_FILEWATCHERIMPL_HPP -#define EFSW_FILEWATCHERIMPL_HPP - -#include -#include -#include -#include -#include -#include - -namespace efsw { - -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& options = {} ) = 0; - - /// Remove a directory watch. This is a brute force lazy search O(nlogn). - virtual void removeWatch( const std::string& directory ) = 0; - - /// Remove a directory watch. This is a map lookup O(logn). - virtual void removeWatch( WatchID watchid ) = 0; - - /// Updates the watcher. Must be called often. - virtual void watch() = 0; - - /// Handles the action - virtual void handleAction( Watcher* watch, const std::string& filename, unsigned long action, - std::string oldFilename = "" ) = 0; - - /// @return Returns a list of the directories that are being watched - virtual std::vector directories() = 0; - - /// @return true if the backend init successfully - virtual bool initOK(); - - /// @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 ); - - /// Search if a directory already exists in the watches - virtual bool pathInWatches( const std::string& path ) = 0; - - protected: - friend class FileWatcher; - friend class DirWatcherGeneric; - - FileWatcher* mFileWatcher; - Atomic mInitOK; - bool mIsGeneric; - - int getOptionValue( const std::vector& options, Option option, - int defaultValue ); -}; - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/FileWatcherInotify.cpp b/src/3rdParty/efsw/FileWatcherInotify.cpp deleted file mode 100644 index 1ec3d481..00000000 --- a/src/3rdParty/efsw/FileWatcherInotify.cpp +++ /dev/null @@ -1,575 +0,0 @@ -#include -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_INOTIFY - -#include -#include -#include -#include -#include -#include - -#ifdef EFSW_INOTIFY_NOSYS -#include -#else -#include -#endif - -#include -#include -#include -#include -#include - -#define BUFF_SIZE ( ( sizeof( struct inotify_event ) + FILENAME_MAX ) * 1024 ) - -namespace efsw { - -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 { - mInitOK = true; - } -} - -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 ) { - efSAFE_DELETE( iter->second ); - } - - mWatches.clear(); - - if ( mFD != -1 ) { - close( mFD ); - mFD = -1; - } -} - -WatchID FileWatcherInotify::addWatch( const std::string& directory, FileWatchListener* watcher, - bool recursive, const std::vector& options ) { - if ( !mInitOK ) - return Errors::Log::createLastError( Errors::Unspecified, directory ); - Lock initLock( mInitLock ); - bool syntheticEvents = getOptionValue( options, Options::LinuxProduceSyntheticEvents, 0 ) != 0; - return addWatch( directory, watcher, recursive, syntheticEvents, NULL ); -} - -WatchID FileWatcherInotify::addWatch( const std::string& directory, FileWatchListener* watcher, - bool recursive, bool syntheticEvents, - WatcherInotify* parent, bool fromInternalEvent ) { - std::string dir( directory ); - - FileSystem::dirAddSlashAtEnd( dir ); - - FileInfo fi( dir ); - - if ( !fi.isDirectory() ) { - return Errors::Log::createLastError( Errors::FileNotFound, dir ); - } else if ( !fi.isReadable() ) { - return Errors::Log::createLastError( Errors::FileNotReadable, dir ); - } else if ( pathInWatches( dir ) ) { - return Errors::Log::createLastError( Errors::FileRepeated, directory ); - } else if ( NULL != parent && FileSystem::isRemoteFS( dir ) ) { - return Errors::Log::createLastError( Errors::FileRemote, dir ); - } - - /// Check if the directory is a symbolic link - std::string curPath; - std::string link( FileSystem::getLinkRealPath( dir, curPath ) ); - - if ( "" != link ) { - /// Avoid adding symlinks directories if it's now enabled - 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 ) ) { - return Errors::Log::createLastError( Errors::FileRepeated, directory ); - } else if ( !linkAllowed( curPath, link ) ) { - return Errors::Log::createLastError( Errors::FileOutOfScope, dir ); - } 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 ); - - if ( wd < 0 ) { - if ( errno == ENOENT ) { - return Errors::Log::createLastError( Errors::FileNotFound, dir ); - } 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 = 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 ) ); - mWatchesRef[pWatch->Directory] = wd; - } - - if ( NULL == pWatch->Parent ) { - Lock l( mRealWatchesLock ); - mRealWatches[pWatch->InotifyID] = pWatch; - } - - if ( pWatch->Recursive ) { - std::map files = FileSystem::filesInfoFromPath( pWatch->Directory ); - std::map::iterator it = files.begin(); - - for ( ; it != files.end(); ++it ) { - if ( !mInitOK ) - break; - - const FileInfo& cfi = it->second; - - if ( cfi.isDirectory() && cfi.isReadable() ) { - addWatch( cfi.Filepath, watcher, recursive, syntheticEvents, pWatch ); - } - } - - if ( fromInternalEvent && parent != NULL && syntheticEvents ) { - for ( const auto& file : files ) { - if ( file.second.isRegularFile() ) { - pWatch->Listener->handleFileAction( - pWatch->ID, pWatch->Directory, - FileSystem::fileNameFromPath( file.second.Filepath ), Actions::Add ); - } - } - } - } - - return wd; -} - -void FileWatcherInotify::removeWatchLocked( WatchID watchid ) { - WatchMap::iterator iter = mWatches.find( watchid ); - if ( iter == mWatches.end() ) - return; - - WatcherInotify* watch = iter->second; - - for ( std::vector>::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::vector eraseWatches; - - for ( ; it != mWatches.end(); ++it ) - if ( it->second != watch && it->second->inParentTree( watch ) ) - eraseWatches.push_back( it->second->InotifyID ); - - for ( std::vector::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->InotifyID ); - - if ( eraseit != mRealWatches.end() ) { - mRealWatches.erase( eraseit ); - } - } - - int err = inotify_rm_watch( mFD, watchid ); - - 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 ) { - if ( !mInitOK ) - return; - Lock initLock( mInitLock ); - Lock lock( mWatchesLock ); - Lock l( mRealWatchesLock ); - - std::unordered_map::iterator ref = mWatchesRef.find( directory ); - if ( ref == mWatchesRef.end() ) - return; - - removeWatchLocked( ref->second ); -} - -void FileWatcherInotify::removeWatch( WatchID watchid ) { - if ( !mInitOK ) - return; - Lock initLock( mInitLock ); - Lock lock( mWatchesLock ); - removeWatchLocked( watchid ); -} - -void FileWatcherInotify::watch() { - if ( NULL == mThread ) { - mThread = new Thread( &FileWatcherInotify::run, this ); - mThread->launch(); - } -} - -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; - if ( watcher->Directory == watcherPath ) - return watcher; - } - - return NULL; -} - -void FileWatcherInotify::run() { - char* buff = new char[BUFF_SIZE]; - memset( buff, 0, BUFF_SIZE ); - WatchMap::iterator wit; - - 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 ); - timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = 100000; - - if ( select( FD_SETSIZE, &rfds, NULL, NULL, &timeout ) > 0 ) { - ssize_t len; - - len = read( mFD, buff, BUFF_SIZE ); - - if ( len != -1 ) { - ssize_t i = 0; - - while ( i < len ) { - struct inotify_event* pevent = (struct inotify_event*)&buff[i]; - - { - { - Lock lock( mWatchesLock ); - - wit = mWatches.find( pevent->wd ); - } - - 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 ) ); - } - - 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; - } - } - } 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 ) ); - } - - currentMoveFrom = NULL; - currentMoveCookie = -1; - } - - if ( !mMovedOutsideWatches.empty() ) { - // We need to make a copy since the element mMovedOutsideWatches could be modified - // during the iteration. - std::vector> movedOutsideWatches( - mMovedOutsideWatches ); - - /// In case that the IN_MOVED_TO is never fired means that the file was moved to other - /// folder - for ( std::vector>::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>::iterator itm = - mMovedOutsideWatches.begin(); - mMovedOutsideWatches.end() != itm; ++itm ) { - if ( itm->first == it->first ) { - found = true; - break; - } - } - if ( !found ) - continue; - } - - Watcher* watch = ( *it ).first; - const std::string& oldFileName = ( *it ).second; - - /// Check if the file move was a folder already being watched - std::vector eraseWatches; - - { - Lock lock( mWatchesLock ); - - for ( ; wit != mWatches.end(); ++wit ) { - Watcher* oldWatch = wit->second; - - if ( oldWatch != watch && - -1 != String::strStartsWith( watch->Directory + oldFileName + "/", - oldWatch->Directory ) ) { - eraseWatches.push_back( oldWatch ); - } - } - } - - /// 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::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 ); - - delete[] buff; -} - -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 ) ) { - bool found = false; - - { - 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 ) { - WatcherInotify* iWatch = static_cast( watch ); - addWatch( fpath, watch->Listener, watch->Recursive, iWatch->syntheticEvents, - static_cast( watch ), true ); - } - } -} - -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 ); - - 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 ); - } - - if ( watch->Recursive && FileSystem::isDirectory( fpath ) ) { - /// Update the new directory path - std::string opath( watch->Directory + watch->OldFileName ); - FileSystem::dirAddSlashAtEnd( opath ); - FileSystem::dirAddSlashAtEnd( fpath ); - - Lock lock( mWatchesLock ); - - 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 ) { - watch->Listener->handleFileAction( watch->ID, watch->Directory, filename, Actions::Add ); - - checkForNewWatcher( watch, fpath ); - } else if ( IN_MOVED_FROM & action ) { - watch->OldFileName = filename; - } 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 ) { - 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::vector FileWatcherInotify::directories() { - std::vector dirs; - - 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 ) { - 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/src/3rdParty/efsw/FileWatcherInotify.hpp b/src/3rdParty/efsw/FileWatcherInotify.hpp deleted file mode 100644 index 26d2c0b2..00000000 --- a/src/3rdParty/efsw/FileWatcherInotify.hpp +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef EFSW_FILEWATCHERLINUX_HPP -#define EFSW_FILEWATCHERLINUX_HPP - -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_INOTIFY - -#include -#include -#include -#include - -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 WatchMap; - - FileWatcherInotify( FileWatcher* parent ); - - virtual ~FileWatcherInotify(); - - /// Add a directory watch - /// On error returns WatchID with Error type. - WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive, - const std::vector& 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 directories() override; - - protected: - /// Map of WatchID to WatchStruct pointers - WatchMap mWatches; - - /// User added watches - WatchMap mRealWatches; - - std::unordered_map mWatchesRef; - - /// inotify file descriptor - int mFD; - - Thread* mThread; - - Mutex mWatchesLock; - Mutex mRealWatchesLock; - Mutex mInitLock; - bool mIsTakingAction; - std::vector> mMovedOutsideWatches; - - WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive, - bool syntheticEvents, WatcherInotify* parent = NULL, - bool fromInternalEvent = false ); - - bool pathInWatches( const std::string& path ) override; - - private: - void run(); - - void removeWatchLocked( WatchID watchid ); - - void checkForNewWatcher( Watcher* watch, std::string fpath ); - - Watcher* watcherContainsDirectory( std::string dir ); -}; - -} // namespace efsw - -#endif - -#endif diff --git a/src/3rdParty/efsw/FileWatcherKqueue.cpp b/src/3rdParty/efsw/FileWatcherKqueue.cpp deleted file mode 100644 index ad03036a..00000000 --- a/src/3rdParty/efsw/FileWatcherKqueue.cpp +++ /dev/null @@ -1,229 +0,0 @@ -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_KQUEUE || EFSW_PLATFORM == EFSW_PLATFORM_FSEVENTS - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace efsw { - -FileWatcherKqueue::FileWatcherKqueue( FileWatcher* parent ) : - FileWatcherImpl( parent ), - mLastWatchID( 0 ), - mThread( NULL ), - mFileDescriptorCount( 1 ), - mAddingWatcher( false ) { - mTimeOut.tv_sec = 0; - mTimeOut.tv_nsec = 0; - mInitOK = true; -} - -FileWatcherKqueue::~FileWatcherKqueue() { - WatchMap::iterator iter = mWatches.begin(); - - for ( ; iter != mWatches.end(); ++iter ) { - efSAFE_DELETE( iter->second ); - } - - mWatches.clear(); - - mInitOK = false; - - efSAFE_DELETE( mThread ); -} - -WatchID FileWatcherKqueue::addWatch( const std::string& directory, FileWatchListener* watcher, - bool recursive, const std::vector& /*options*/ ) { - static bool s_ug = false; - - std::string dir( directory ); - - FileSystem::dirAddSlashAtEnd( dir ); - - FileInfo fi( dir ); - - if ( !fi.isDirectory() ) { - return Errors::Log::createLastError( Errors::FileNotFound, dir ); - } else if ( !fi.isReadable() ) { - return Errors::Log::createLastError( Errors::FileNotReadable, 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 ) ) { - return Errors::Log::createLastError( Errors::FileRepeated, directory ); - } else if ( !linkAllowed( curPath, link ) ) { - return Errors::Log::createLastError( Errors::FileOutOfScope, dir ); - } else { - dir = link; - } - } - - /// 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 ); - - { - Lock lock( mWatchesLock ); - mWatches.insert( std::make_pair( mLastWatchID, watch ) ); - } - - watch->addAll(); - - // if failed to open the directory... erase the watcher - if ( !watch->initOK() ) { - int le = watch->lastErrno(); - - mWatches.erase( watch->ID ); - - efSAFE_DELETE( watch ); - - mLastWatchID--; - - // Probably the folder has too many files, create a generic watcher - if ( EACCES != le ) { - WatcherGeneric* genericWatch = - new WatcherGeneric( ++mLastWatchID, dir, watcher, this, recursive ); - - Lock lock( mWatchesLock ); - 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 ); - s_ug = true; - } - - WatcherGeneric* watch = new WatcherGeneric( ++mLastWatchID, dir, watcher, this, recursive ); - - Lock lock( mWatchesLock ); - mWatches.insert( std::make_pair( mLastWatchID, watch ) ); - } - - return mLastWatchID; -} - -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 ); - return; - } - } -} - -void FileWatcherKqueue::removeWatch( WatchID watchid ) { - Lock lock( mWatchesLock ); - - WatchMap::iterator iter = mWatches.find( watchid ); - - if ( iter == mWatches.end() ) - return; - - Watcher* watch = iter->second; - - mWatches.erase( iter ); - - efSAFE_DELETE( watch ); -} - -bool FileWatcherKqueue::isAddingWatcher() const { - return mAddingWatcher; -} - -void FileWatcherKqueue::watch() { - if ( NULL == mThread ) { - mThread = new Thread( &FileWatcherKqueue::run, this ); - mThread->launch(); - } -} - -void FileWatcherKqueue::run() { - do { - { - Lock lock( mWatchesLock ); - - for ( WatchMap::iterator it = mWatches.begin(); it != mWatches.end(); ++it ) { - it->second->watch(); - } - } - - System::sleep( 500 ); - } while ( mInitOK ); -} - -void FileWatcherKqueue::handleAction( Watcher* /*watch*/, const std::string& /*filename*/, - unsigned long /*action*/, std::string /*oldFilename*/ ) {} - -std::vector FileWatcherKqueue::directories() { - std::vector dirs; - - Lock lock( mWatchesLock ); - - dirs.reserve( mWatches.size() ); - - WatchMap::iterator it = mWatches.begin(); - - for ( ; it != mWatches.end(); ++it ) { - dirs.push_back( it->second->Directory ); - } - - return dirs; -} - -bool FileWatcherKqueue::pathInWatches( const std::string& path ) { - WatchMap::iterator it = mWatches.begin(); - - for ( ; it != mWatches.end(); ++it ) { - if ( it->second->Directory == path ) { - return true; - } - } - - return false; -} - -void FileWatcherKqueue::addFD() { - mFileDescriptorCount++; -} - -void FileWatcherKqueue::removeFD() { - mFileDescriptorCount--; -} - -bool FileWatcherKqueue::availablesFD() { - return mFileDescriptorCount <= (Int64)System::getMaxFD() - 500; -} - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/FileWatcherKqueue.hpp b/src/3rdParty/efsw/FileWatcherKqueue.hpp deleted file mode 100644 index ff5327b2..00000000 --- a/src/3rdParty/efsw/FileWatcherKqueue.hpp +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef EFSW_FILEWATCHEROSX_HPP -#define EFSW_FILEWATCHEROSX_HPP - -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_KQUEUE || EFSW_PLATFORM == EFSW_PLATFORM_FSEVENTS - -#include - -namespace efsw { - -/// Implementation for OSX based on kqueue. -/// @class FileWatcherKqueue -class FileWatcherKqueue : public FileWatcherImpl { - friend class WatcherKqueue; - - public: - FileWatcherKqueue( FileWatcher* parent ); - - virtual ~FileWatcherKqueue(); - - /// Add a directory watch - /// On error returns WatchID with Error type. - WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive, - const std::vector &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 directories() override; - - protected: - /// Map of WatchID to WatchStruct pointers - WatchMap mWatches; - - /// time out data - struct timespec mTimeOut; - - /// WatchID allocator - int mLastWatchID; - - Thread* mThread; - - Mutex mWatchesLock; - - std::vector mRemoveList; - - long mFileDescriptorCount; - - bool mAddingWatcher; - - bool isAddingWatcher() const; - - bool pathInWatches( const std::string& path ) override; - - void addFD(); - - void removeFD(); - - bool availablesFD(); - - private: - void run(); -}; - -} // namespace efsw - -#endif - -#endif diff --git a/src/3rdParty/efsw/FileWatcherWin32.cpp b/src/3rdParty/efsw/FileWatcherWin32.cpp deleted file mode 100644 index 19b71d78..00000000 --- a/src/3rdParty/efsw/FileWatcherWin32.cpp +++ /dev/null @@ -1,267 +0,0 @@ -#include -#include -#include -#include -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32 - -namespace efsw { - -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() { - mInitOK = false; - - if ( mIOCP && mIOCP != INVALID_HANDLE_VALUE ) { - PostQueuedCompletionStatus( mIOCP, 0, reinterpret_cast( this ), NULL ); - } - - efSAFE_DELETE( mThread ); - - removeAllWatches(); - - if ( mIOCP ) - CloseHandle( mIOCP ); -} - -WatchID FileWatcherWin32::addWatch( const std::string& directory, FileWatchListener* watcher, - bool recursive, const std::vector &options ) { - std::string dir( directory ); - - FileInfo fi( dir ); - - if ( !fi.isDirectory() ) { - return Errors::Log::createLastError( Errors::FileNotFound, dir ); - } else if ( !fi.isReadable() ) { - return Errors::Log::createLastError( Errors::FileNotReadable, dir ); - } - - FileSystem::dirAddSlashAtEnd( dir ); - - Lock lock( mWatchesLock ); - - if ( pathInWatches( dir ) ) { - return Errors::Log::createLastError( Errors::FileRepeated, dir ); - } - - WatchID watchid = ++mLastWatchID; - - DWORD bufferSize = static_cast( getOptionValue(options, Option::WinBufferSize, 63 * 1024) ); - DWORD notifyFilter = static_cast( 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) ); - - WatcherStructWin32* watch = CreateWatch( String::fromUtf8( dir ).toWideString().c_str(), - recursive, bufferSize, notifyFilter, mIOCP ); - - if ( NULL == watch ) { - return Errors::Log::createLastError( Errors::FileNotFound, dir ); - } - - // Add the handle to the handles vector - 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() ); - - mWatches.insert( watch ); - - return watchid; -} - -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 ); - break; - } - } -} - -void FileWatcherWin32::removeWatch( WatchID watchid ) { - Lock lock( mWatchesLock ); - - Watches::iterator iter = mWatches.begin(); - - for ( ; iter != mWatches.end(); ++iter ) { - // Find the watch ID - if ( ( *iter )->Watch->ID == watchid ) { - removeWatch( *iter ); - return; - } - } -} - -void FileWatcherWin32::removeWatch( WatcherStructWin32* watch ) { - Lock lock( mWatchesLock ); - - DestroyWatch( watch ); - mWatches.erase( watch ); -} - -void FileWatcherWin32::watch() { - if ( NULL == mThread ) { - mThread = new Thread( &FileWatcherWin32::run, this ); - mThread->launch(); - } -} - -void FileWatcherWin32::removeAllWatches() { - Lock lock( mWatchesLock ); - - Watches::iterator iter = mWatches.begin(); - - for ( ; iter != mWatches.end(); ++iter ) { - DestroyWatch( ( *iter ) ); - } - - mWatches.clear(); -} - -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( this ) ) { - break; - } else { - Lock lock( mWatchesLock ); - if (mWatches.find( (WatcherStructWin32*)ov ) != mWatches.end()) - WatchCallback( numOfBytes, ov ); - } - } - } else { - System::sleep( 10 ); - } - } while ( mInitOK ); - - removeAllWatches(); -} - -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; - - break; - } - } - } - - std::string folderPath( static_cast( watch )->DirName ); - std::string realFilename = filename; - std::size_t sepPos = filename.find_last_of( "/\\" ); - std::string oldFolderPath = - static_cast( 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( 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( watch )->DirName ); - std::string realFilename = filename; - std::size_t sepPos = filename.find_last_of( "/\\" ); - - if ( sepPos != std::string::npos ) { - folderPath += filename.substr( 0, sepPos + 1 < filename.size() ? sepPos + 1 : sepPos ); - realFilename = filename.substr( sepPos + 1 ); - } - - FileSystem::dirAddSlashAtEnd( folderPath ); - - watch->Listener->handleFileAction( watch->ID, folderPath, realFilename, fwAction ); -} - -std::vector FileWatcherWin32::directories() { - std::vector dirs; - - Lock lock( mWatchesLock ); - - 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 ) { - Lock lock( mWatchesLock ); - - for ( Watches::iterator it = mWatches.begin(); it != mWatches.end(); ++it ) { - if ( ( *it )->Watch->DirName == path ) { - return true; - } - } - - return false; -} - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/FileWatcherWin32.hpp b/src/3rdParty/efsw/FileWatcherWin32.hpp deleted file mode 100644 index 3016aac3..00000000 --- a/src/3rdParty/efsw/FileWatcherWin32.hpp +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef EFSW_FILEWATCHERWIN32_HPP -#define EFSW_FILEWATCHERWIN32_HPP - -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32 - -#include -#include -#include -#include - -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::unordered_set Watches; - - FileWatcherWin32( FileWatcher* parent ); - - virtual ~FileWatcherWin32(); - - /// Add a directory watch - /// On error returns WatchID with Error type. - WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive, - const std::vector &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 directories() override; - - protected: - HANDLE mIOCP; - Watches mWatches; - - /// The last watchid - WatchID mLastWatchID; - Thread* mThread; - Mutex mWatchesLock; - - bool pathInWatches( const std::string& path ) override; - - /// Remove all directory watches. - void removeAllWatches(); - - void removeWatch( WatcherStructWin32* watch ); - - private: - void run(); -}; - -} // namespace efsw - -#endif - -#endif diff --git a/src/3rdParty/efsw/LICENSE b/src/3rdParty/efsw/LICENSE deleted file mode 100644 index 37f354a1..00000000 --- a/src/3rdParty/efsw/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -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 -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -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. diff --git a/src/3rdParty/efsw/Lock.hpp b/src/3rdParty/efsw/Lock.hpp deleted file mode 100644 index e8c522ab..00000000 --- a/src/3rdParty/efsw/Lock.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef EFSW_LOCK_HPP -#define EFSW_LOCK_HPP - -#include - -namespace efsw { - -/** Simple mutex class */ -class Lock { - public: - explicit Lock( Mutex& mutex ) : mMutex( mutex ) { mMutex.lock(); } - - ~Lock() { mMutex.unlock(); } - - private: - Mutex& mMutex; -}; - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/Log.cpp b/src/3rdParty/efsw/Log.cpp deleted file mode 100644 index 6f32df7c..00000000 --- a/src/3rdParty/efsw/Log.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include - -namespace efsw { namespace Errors { - -static std::string LastError = ""; -static Error LastErrorCode = NoError; - -std::string Log::getLastErrorLog() { - return LastError; -} - -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; - } - - efDEBUG( "%s\n", LastError.c_str() ); - return err; -} - -}} // namespace efsw::Errors diff --git a/src/3rdParty/efsw/Mutex.cpp b/src/3rdParty/efsw/Mutex.cpp deleted file mode 100644 index c961db18..00000000 --- a/src/3rdParty/efsw/Mutex.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include - -namespace efsw { - -Mutex::Mutex() : mMutexImpl( new Platform::MutexImpl() ) {} - -Mutex::~Mutex() { - efSAFE_DELETE( mMutexImpl ); -} - -void Mutex::lock() { - mMutexImpl->lock(); -} - -void Mutex::unlock() { - mMutexImpl->unlock(); -} - -} // namespace efsw diff --git a/src/3rdParty/efsw/Mutex.hpp b/src/3rdParty/efsw/Mutex.hpp deleted file mode 100644 index d98ad17c..00000000 --- a/src/3rdParty/efsw/Mutex.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef EFSW_MUTEX_HPP -#define EFSW_MUTEX_HPP - -#include - -namespace efsw { - -namespace Platform { -class MutexImpl; -} - -/** Simple mutex class */ -class Mutex { - public: - Mutex(); - - ~Mutex(); - - /** Lock the mutex */ - void lock(); - - /** Unlock the mutex */ - void unlock(); - - private: - Platform::MutexImpl* mMutexImpl; -}; - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/String.cpp b/src/3rdParty/efsw/String.cpp deleted file mode 100644 index e3ba68f3..00000000 --- a/src/3rdParty/efsw/String.cpp +++ /dev/null @@ -1,669 +0,0 @@ -#include -#include -#include - -namespace efsw { - -const std::size_t String::InvalidPos = StringType::npos; - -std::vector String::split( const std::string& str, const char& splitchar, - const bool& pushEmptyString ) { - std::vector 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 ); - tmpstr = ""; - } - } else { - tmpstr += str[i]; - } - } - - if ( tmpstr.size() ) { - tmp.push_back( tmpstr ); - } - - return tmp; -} - -std::vector String::split( const String& str, const Uint32& splitchar, - const bool& pushEmptyString ) { - std::vector tmp; - String tmpstr; - - for ( size_t i = 0; i < str.size(); i++ ) { - if ( str[i] == splitchar ) { - if ( pushEmptyString || tmpstr.size() ) { - tmp.push_back( tmpstr ); - tmpstr = ""; - } - } else { - tmpstr += str[i]; - } - } - - 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(); - - if ( str.size() >= size ) { - for ( std::size_t i = 0; i < size; i++ ) { - if ( start[i] == str[i] ) { - pos = (int)i; - } else { - pos = -1; - break; - } - } - } - - return pos; -} - -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] ) { - pos = (int)i; - } else { - pos = -1; - break; - } - } - } - - return pos; -} - -String::String() {} - -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 ); -} -#endif - -String::String( StringBaseType utf32Char ) { - mString += utf32Char; -} - -String::String( const char* uf8String ) { - if ( uf8String ) { - std::size_t length = strlen( uf8String ); - - if ( length > 0 ) { - mString.reserve( length + 1 ); - - Utf8::ToUtf32( uf8String, uf8String + length, std::back_inserter( mString ) ); - } - } -} - -String::String( const std::string& utf8String ) { - mString.reserve( utf8String.length() + 1 ); - - 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 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 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 ) - mString = utf32String; -} - -String::String( const StringType& utf32String ) : mString( utf32String ) {} - -String::String( const String& str ) : mString( str.mString ) {} - -String String::fromUtf8( const std::string& utf8String ) { - String::StringType utf32; - - utf32.reserve( utf8String.length() + 1 ); - - Utf8::ToUtf32( utf8String.begin(), utf8String.end(), std::back_inserter( utf32 ) ); - - return String( utf32 ); -} - -String::operator std::string() const { - return toAnsiString(); -} - -std::string String::toAnsiString( const std::locale& locale ) const { - // Prepare the output string - std::string output; - output.reserve( mString.length() + 1 ); - - // Convert - Utf32::ToAnsi( mString.begin(), mString.end(), std::back_inserter( output ), 0, locale ); - - return output; -} - -#ifndef EFSW_NO_WIDECHAR -std::wstring String::toWideString() const { - // Prepare the output string - std::wstring output; - output.reserve( mString.length() + 1 ); - - // Convert - Utf32::ToWide( mString.begin(), mString.end(), std::back_inserter( output ), 0 ); - - return output; -} -#endif - -std::string String::toUtf8() const { - // Prepare the output string - std::string output; - output.reserve( mString.length() + 1 ); - - // Convert - Utf32::toUtf8( mString.begin(), mString.end(), std::back_inserter( output ) ); - - return output; -} - -String& String::operator=( const String& right ) { - mString = right.mString; - return *this; -} - -String& String::operator=( const StringBaseType& right ) { - mString = right; - return *this; -} - -String& String::operator+=( const String& right ) { - mString += right.mString; - return *this; -} - -String& String::operator+=( const StringBaseType& right ) { - mString += right; - return *this; -} - -String::StringBaseType String::operator[]( std::size_t index ) const { - return mString[index]; -} - -String::StringBaseType& String::operator[]( std::size_t index ) { - return mString[index]; -} - -String::StringBaseType String::at( std::size_t index ) const { - return mString.at( index ); -} - -void String::push_back( StringBaseType c ) { - mString.push_back( c ); -} - -void String::swap( String& str ) { - mString.swap( str.mString ); -} - -void String::clear() { - mString.clear(); -} - -std::size_t String::size() const { - return mString.size(); -} - -std::size_t String::length() const { - return mString.length(); -} - -bool String::empty() const { - return mString.empty(); -} - -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 ); - return *this; -} - -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 tmp( s ); - - mString.insert( pos1, tmp.data(), n ); - - return *this; -} - -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 tmp( s ); - - mString.insert( pos1, tmp.data() ); - - return *this; -} - -String::Iterator String::insert( Iterator p, char c ) { - return mString.insert( p, c ); -} - -void String::insert( Iterator p, size_t n, char c ) { - mString.insert( p, n, c ); -} - -const String::StringBaseType* String::c_str() const { - return mString.c_str(); -} - -const String::StringBaseType* String::data() const { - return mString.data(); -} - -String::Iterator String::begin() { - return mString.begin(); -} - -String::ConstIterator String::begin() const { - return mString.begin(); -} - -String::Iterator String::end() { - return mString.end(); -} - -String::ConstIterator String::end() const { - return mString.end(); -} - -String::ReverseIterator String::rbegin() { - return mString.rbegin(); -} - -String::ConstReverseIterator String::rbegin() const { - return mString.rbegin(); -} - -String::ReverseIterator String::rend() { - return mString.rend(); -} - -String::ConstReverseIterator String::rend() const { - return mString.rend(); -} - -void String::resize( std::size_t n, StringBaseType c ) { - mString.resize( n, c ); -} - -void String::resize( std::size_t n ) { - mString.resize( n ); -} - -std::size_t String::max_size() const { - return mString.max_size(); -} - -void String::reserve( size_t res_arg ) { - mString.reserve( res_arg ); -} - -std::size_t String::capacity() const { - return mString.capacity(); -} - -String& String::assign( const String& str ) { - mString.assign( str.mString ); - return *this; -} - -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 tmp( s ); - - mString.assign( tmp.mString ); - - return *this; -} - -String& String::assign( const char* s ) { - String tmp( s ); - - mString.assign( tmp.mString ); - - return *this; -} - -String& String::assign( size_t n, char c ) { - mString.assign( n, c ); - - return *this; -} - -String& String::append( const String& str ) { - mString.append( str.mString ); - - return *this; -} - -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 tmp( s ); - - mString.append( tmp.mString ); - - return *this; -} - -String& String::append( const char* s ) { - String tmp( s ); - - mString.append( tmp.mString ); - - return *this; -} - -String& String::append( size_t n, char c ) { - mString.append( n, c ); - - return *this; -} - -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 ) { - mString.replace( pos1, n1, str.mString ); - - return *this; -} - -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 ) { - 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 tmp( s ); - - mString.replace( pos1, n1, tmp.data(), n2 ); - - return *this; -} - -String& String::replace( Iterator i1, Iterator i2, const char* s, size_t n2 ) { - String tmp( s ); - - mString.replace( i1, i2, tmp.data(), n2 ); - - return *this; -} - -String& String::replace( size_t pos1, size_t n1, const char* s ) { - String tmp( s ); - - mString.replace( pos1, n1, tmp.mString ); - - return *this; -} - -String& String::replace( Iterator i1, Iterator i2, const char* s ) { - String tmp( s ); - - mString.replace( i1, i2, tmp.mString ); - - return *this; -} - -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 ) { - mString.replace( i1, i2, n2, (StringBaseType)c ); - - return *this; -} - -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 { - return find( String( s ), pos ); -} - -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 { - return mString.find( (StringBaseType)c, pos ); -} - -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 { - return rfind( String( s ), pos ); -} - -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 { - return mString.rfind( c, pos ); -} - -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 { - return String( mString.substr( pos, n ) ); -} - -int String::compare( const String& str ) const { - return mString.compare( str.mString ); -} - -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 { - return mString.compare( pos1, n1, str.mString ); -} - -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 { - 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 { - return compare( pos1, n1, String( s ), 0, n2 ); -} - -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 { - return find_first_of( String( s ), pos ); -} - -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 { - return mString.find_first_of( c, pos ); -} - -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 { - return find_last_of( String( s ), pos ); -} - -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 { - return mString.find_last_of( c, pos ); -} - -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 { - return find_first_not_of( String( s ), pos ); -} - -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 { - return mString.find_first_not_of( c, pos ); -} - -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 { - return find_last_not_of( String( s ), pos ); -} - -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 { - return mString.find_last_not_of( c, pos ); -} - -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.mString < right.mString; -} - -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 ); -} - -String operator+( const String& left, const String& right ) { - String string = left; - string += right; - - return string; -} - -} // namespace efsw diff --git a/src/3rdParty/efsw/String.hpp b/src/3rdParty/efsw/String.hpp deleted file mode 100644 index b42b9453..00000000 --- a/src/3rdParty/efsw/String.hpp +++ /dev/null @@ -1,630 +0,0 @@ -/** 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. - **/ - -#ifndef EFSW_STRING_HPP -#define EFSW_STRING_HPP - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace efsw { - -/** @brief Utility string class that automatically handles conversions between types and encodings - * **/ -class String { - public: - typedef char32_t StringBaseType; - typedef std::basic_string 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 static std::string toStr( const T& i ) { - std::ostringstream ss; - ss << i; - return ss.str(); - } - - /** Converts from a string to type */ - template - 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 - 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(); - } - - /** Split a string and hold it on a vector */ - static std::vector split( const std::string& str, const char& splitchar, - const bool& pushEmptyString = false ); - - /** Split a string and hold it on a vector */ - static std::vector 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 - ** @param str The string to compare - ** @return -1 if the substring is no in str, otherwise the size of the substring - */ - static int strStartsWith( const std::string& start, const std::string& str ); - - static int strStartsWith( const String& start, const String& str ); - - /** @brief Construct from an UTF-8 string to UTF-32 according - ** @param uf8String UTF-8 string to convert - **/ - static String fromUtf8( const std::string& utf8String ); - - /** @brief Default constructor - ** This constructor creates an empty string. - **/ - String(); - - /** @brief Construct from a single ANSI character and a locale - ** The source character is converted to UTF-32 according - ** to the given locale. If you want to use the current global - ** locale, rather use the other constructor. - ** @param ansiChar ANSI character to convert - ** @param locale Locale to use for conversion - **/ - String( char ansiChar, const std::locale& locale = std::locale() ); - -#ifndef EFSW_NO_WIDECHAR - /** @brief Construct from single wide character - ** @param wideChar Wide character to convert - **/ - String( wchar_t wideChar ); -#endif - - /** @brief Construct from single UTF-32 character - ** @param utf32Char UTF-32 character to convert - **/ - String( StringBaseType utf32Char ); - - /** @brief Construct from an from a null-terminated C-style UTF-8 string to UTF-32 - ** @param uf8String UTF-8 string to convert - **/ - String( const char* uf8String ); - - /** @brief Construct from an UTF-8 string to UTF-32 according - ** @param uf8String UTF-8 string to convert - **/ - String( const std::string& utf8String ); - - /** @brief Construct from a null-terminated C-style ANSI string and a locale - ** The source string is converted to UTF-32 according - ** to the given locale. If you want to use the current global - ** locale, rather use the other constructor. - ** @param ansiString ANSI string to convert - ** @param locale Locale to use for conversion - **/ - String( const char* ansiString, const std::locale& locale ); - - /** @brief Construct from an ANSI string and a locale - ** The source string is converted to UTF-32 according - ** to the given locale. If you want to use the current global - ** locale, rather use the other constructor. - ** @param ansiString ANSI string to convert - ** @param locale Locale to use for conversion - **/ - String( const std::string& ansiString, const std::locale& locale ); - -#ifndef EFSW_NO_WIDECHAR - /** @brief Construct from null-terminated C-style wide string - ** @param wideString Wide string to convert - **/ - String( const wchar_t* wideString ); - - /** @brief Construct from a wide string - ** @param wideString Wide string to convert - **/ - String( const std::wstring& wideString ); -#endif - - /** @brief Construct from a null-terminated C-style UTF-32 string - ** @param utf32String UTF-32 string to assign - **/ - String( const StringBaseType* utf32String ); - - /** @brief Construct from an UTF-32 string - ** @param utf32String UTF-32 string to assign - **/ - String( const StringType& utf32String ); - - /** @brief Copy constructor - ** @param str Instance to copy - **/ - String( const String& str ); - - /** @brief Implicit cast operator to std::string (ANSI string) - ** The current global locale is used for conversion. If you - ** want to explicitely specify a locale, see toAnsiString. - ** Characters that do not fit in the target encoding are - ** discarded from the returned string. - ** This operator is defined for convenience, and is equivalent - ** to calling toAnsiString(). - ** @return Converted ANSI string - ** @see toAnsiString, operator String - **/ - operator std::string() const; - - /** @brief Convert the unicode string to an ANSI string - ** The UTF-32 string is converted to an ANSI string in - ** the encoding defined by \a locale. If you want to use - ** the current global locale, see the other overload - ** of toAnsiString. - ** Characters that do not fit in the target encoding are - ** discarded from the returned string. - ** @param locale Locale to use for conversion - ** @return Converted ANSI string - ** @see toWideString, operator std::string - **/ - std::string toAnsiString( const std::locale& locale = std::locale() ) const; - -#ifndef EFSW_NO_WIDECHAR - /** @brief Convert the unicode string to a wide string - ** Characters that do not fit in the target encoding are - ** discarded from the returned string. - ** @return Converted wide string - ** @see toAnsiString, operator String - **/ - std::wstring toWideString() const; -#endif - - std::string toUtf8() const; - - /** @brief Overload of assignment operator - ** @param right Instance to assign - ** @return Reference to self - **/ - String& operator=( const String& 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 StringBaseType& right ); - - /** @brief Overload of [] operator to access a character by its position - ** This function provides read-only access to characters. - ** Note: this function doesn't throw if \a index is out of range. - ** @param index Index of the character to get - ** @return Character at position \a index - **/ - 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. - ** Note: this function doesn't throw if \a index is out of range. - ** @param index Index of the character to get - ** @return Reference to the character at position \a 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. - ** @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 - **/ - void clear(); - - /** @brief Get the size of the string - ** @return Number of characters in the string - ** @see empty - **/ - std::size_t size() const; - - /** @see size() */ - std::size_t length() const; - - /** @brief Check whether the string is empty or not - ** @return True if the string is empty (i.e. contains no character) - ** @see clear, size - **/ - bool empty() const; - - /** @brief Erase one or more characters from the string - ** This function removes a sequence of \a count characters - ** starting from \a position. - ** @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 ); - - /** @brief Insert one or more characters into the string - ** This function inserts the characters of \a str - ** into the string, starting from \a position. - ** @param position Position of insertion - ** @param str Characters to insert - **/ - 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 ); - - String& insert( std::size_t pos1, size_t n, char c ); - - Iterator insert( Iterator p, char c ); - - void insert( Iterator p, std::size_t n, char c ); - - template - void insert( Iterator p, InputIterator first, InputIterator last ) { - mString.insert( p, first, last ); - } - - /** @brief Find a sequence of one or more characters in the string - ** This function searches for the characters of \a str - ** into the string, starting from \a start. - ** @param str Characters to find - ** @param start Where to begin searching - ** @return Position of \a str in the string, or String::InvalidPos if not found - **/ - 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 = 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 - ** null-terminated C-style representation of the string. - ** The returned pointer is temporary and is meant only for - ** immediate use, thus it is not recommended to store it. - ** @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. - ** @return Pointer to an internal array containing the same content as the string. - **/ - const StringBaseType* data() const; - - /** @brief Return an iterator to the beginning of the string - ** @return Read-write iterator to the beginning of the string characters - ** @see end - **/ - Iterator begin(); - - /** @brief Return an iterator to the beginning of the string - ** @return Read-only iterator to the beginning of the string characters - ** @see end - **/ - ConstIterator begin() const; - - /** @brief Return an iterator to the beginning of the string - ** The end iterator refers to 1 position past the last character; - ** thus it represents an invalid character and should never be - ** accessed. - ** @return Read-write iterator to the end of the string characters - ** @see begin - **/ - Iterator end(); - - /** @brief Return an iterator to the beginning of the string - ** The end iterator refers to 1 position past the last character; - ** thus it represents an invalid character and should never be - ** accessed. - ** @return Read-only iterator to the end of the string characters - ** @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 - **/ - ReverseIterator rbegin(); - - /** @brief Return an reverse iterator to the beginning of the string - ** @return Read-only reverse iterator to the beginning of the string characters - ** @see end - **/ - ConstReverseIterator rbegin() const; - - /** @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 - ** accessed. - ** @return Read-write reverse iterator to the end of the string characters - ** @see begin - **/ - 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 - ** accessed. - ** @return Read-only reverse iterator to the end of the string characters - ** @see begin - **/ - ConstReverseIterator rend() const; - - /** @brief Resize String */ - void resize( std::size_t n, StringBaseType c ); - - /** @brief Resize String */ - 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 ); - - /** @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 ); - - String& assign( const String& str, std::size_t pos, std::size_t n ); - - String& assign( const char* s, std::size_t n ); - - String& assign( const char* s ); - - String& assign( std::size_t n, char c ); - - template String& assign( InputIterator first, InputIterator last ) { - mString.assign( first, last ); - return *this; - } - - String& append( const String& str ); - - 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 ); - - String& append( std::size_t n, char c ); - - String& append( std::size_t n, StringBaseType c ); - - template 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( 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 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( 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( Iterator i1, Iterator i2, std::size_t n2, char c ); - - template - 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 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( char c, std::size_t pos = 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; - - int compare( const String& str ) 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 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 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 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( 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 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( 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 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( 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 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( 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 ); - - StringType mString; ///< Internal string of UTF-32 characters -}; - -/** @relates String -** @brief Overload of == operator to compare two UTF-32 strings -** @param left Left operand (a string) -** @param right Right operand (a string) -** @return True if both strings are equal -**/ -bool operator==( const String& left, const String& right ); - -/** @relates String -** @brief Overload of != operator to compare two UTF-32 strings -** @param left Left operand (a string) -** @param right Right operand (a string) -** @return True if both strings are different -**/ -bool operator!=( const String& left, const String& right ); - -/** @relates String -** @brief Overload of < operator to compare two UTF-32 strings -** @param left Left operand (a string) -** @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 ); - -/** @relates String -** @brief Overload of > operator to compare two UTF-32 strings -** @param left Left operand (a string) -** @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 ); - -/** @relates String -** @brief Overload of <= operator to compare two UTF-32 strings -** @param left Left operand (a string) -** @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 ); - -/** @relates String -** @brief Overload of >= operator to compare two UTF-32 strings -** @param left Left operand (a string) -** @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 ); - -/** @relates String -** @brief Overload of binary + operator to concatenate two strings -** @param left Left operand (a string) -** @param right Right operand (a string) -** @return Concatenated string -**/ -String operator+( const String& left, const String& right ); - -} // namespace efsw - -#endif - -/** @class efsw::String -** @ingroup system -** efsw::String is a utility string class defined mainly for -** convenience. It is a Unicode string (implemented using -** UTF-32), thus it can store any character in the world -** (european, chinese, arabic, hebrew, etc.). -** It automatically handles conversions from/to ANSI and -** wide strings, so that you can work with standard string -** classes and still be compatible with functions taking a -** efsw::String. -** @code -** efsw::String s; -** std::string s1 = s; // automatically converted to ANSI string -** String s2 = s; // automatically converted to wide string -** s = "hello"; // automatically converted from ANSI string -** s = L"hello"; // automatically converted from wide string -** s += 'a'; // automatically converted from ANSI string -** s += L'a'; // automatically converted from wide string -** @endcode -** Conversions involving ANSI strings use the default user locale. However -** it is possible to use a custom locale if necessary: -** @code -** std::locale locale; -** efsw::String s; -** ... -** std::string s1 = s.toAnsiString(locale); -** s = efsw::String("hello", locale); -** @endcode -** -** efsw::String defines the most important functions of the -** standard std::string class: removing, random access, iterating, -** appending, comparing, etc. However it is a simple class -** provided for convenience, and you may have to consider using -** a more optimized class if your program requires complex string -** handling. The automatic conversion functions will then take -** care of converting your string to efsw::String whenever EE -** requires it. -** -** Please note that EE also defines a low-level, generic -** interface for Unicode handling, see the efsw::Utf classes. -** -** All credits to Laurent Gomila, i just modified and expanded a little bit the implementation. -**/ diff --git a/src/3rdParty/efsw/System.cpp b/src/3rdParty/efsw/System.cpp deleted file mode 100644 index ba68bf4a..00000000 --- a/src/3rdParty/efsw/System.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include - -namespace efsw { - -void System::sleep( const unsigned long& ms ) { - Platform::System::sleep( ms ); -} - -std::string System::getProcessPath() { - return Platform::System::getProcessPath(); -} - -void System::maxFD() { - Platform::System::maxFD(); -} - -Uint64 System::getMaxFD() { - return Platform::System::getMaxFD(); -} - -} // namespace efsw diff --git a/src/3rdParty/efsw/System.hpp b/src/3rdParty/efsw/System.hpp deleted file mode 100644 index 498e1211..00000000 --- a/src/3rdParty/efsw/System.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef EFSW_SYSTEM_HPP -#define EFSW_SYSTEM_HPP - -#include - -namespace efsw { - -class System { - public: - /// Sleep for x milliseconds - static void sleep( const unsigned long& ms ); - - /// @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(); - - /// @return The number of supported file descriptors for the process - static Uint64 getMaxFD(); -}; - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/Thread.cpp b/src/3rdParty/efsw/Thread.cpp deleted file mode 100644 index cfa88b48..00000000 --- a/src/3rdParty/efsw/Thread.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include - -namespace efsw { - -Thread::Thread() : mThreadImpl( NULL ), mEntryPoint( NULL ) {} - -Thread::~Thread() { - wait(); - - efSAFE_DELETE( mEntryPoint ); -} - -void Thread::launch() { - wait(); - - mThreadImpl = new Platform::ThreadImpl( this ); -} - -void Thread::wait() { - if ( mThreadImpl ) { - mThreadImpl->wait(); - - efSAFE_DELETE( mThreadImpl ); - } -} - -void Thread::terminate() { - if ( mThreadImpl ) { - mThreadImpl->terminate(); - - efSAFE_DELETE( mThreadImpl ); - } -} - -void Thread::run() { - if ( mEntryPoint ) - mEntryPoint->run(); -} - -} // namespace efsw diff --git a/src/3rdParty/efsw/Thread.hpp b/src/3rdParty/efsw/Thread.hpp deleted file mode 100644 index b60373c2..00000000 --- a/src/3rdParty/efsw/Thread.hpp +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef EFSW_THREAD_HPP -#define EFSW_THREAD_HPP - -#include - -namespace efsw { - -namespace Platform { -class ThreadImpl; -} -namespace Private { -struct ThreadFunc; -} - -/** @brief Thread manager class */ -class Thread { - public: - typedef void ( *FuncType )( void* ); - - template Thread( F function ); - - template Thread( F function, A argument ); - - template Thread( void ( C::*function )(), C* object ); - - virtual ~Thread(); - - /** Launch the thread */ - virtual void launch(); - - /** Wait the thread until end */ - void wait(); - - /** Terminate the thread */ - void terminate(); - - protected: - Thread(); - - 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 { - virtual ~ThreadFunc() {} - virtual void run() = 0; -}; - -// Specialization using a functor (including free functions) with no argument -template 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 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 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 -Thread::Thread( F functor ) : - mThreadImpl( NULL ), mEntryPoint( new Private::ThreadFunctor( functor ) ) {} - -template -Thread::Thread( F function, A argument ) : - mThreadImpl( NULL ), - mEntryPoint( new Private::ThreadFunctorWithArg( function, argument ) ) {} - -template -Thread::Thread( void ( C::*function )(), C* object ) : - mThreadImpl( NULL ), mEntryPoint( new Private::ThreadMemberFunc( function, object ) ) {} - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/Utf.hpp b/src/3rdParty/efsw/Utf.hpp deleted file mode 100644 index 1b042cda..00000000 --- a/src/3rdParty/efsw/Utf.hpp +++ /dev/null @@ -1,721 +0,0 @@ -/** 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. - * */ - -#ifndef EFSW_UTF_HPP -#define EFSW_UTF_HPP - -//////////////////////////////////////////////////////////// -// Headers -//////////////////////////////////////////////////////////// -#include -#include -#include -#include - -namespace efsw { - -template 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 - 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 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 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 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 - 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 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 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 - 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 - 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 - 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 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 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 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 - 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 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 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 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 - 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 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 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 - 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 - 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 - 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 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 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 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 - 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 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 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 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 - 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 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 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 - 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 - 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 - 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 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 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 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 - 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 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 - 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 - /// 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 - 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<16> Utf16; -typedef Utf<32> Utf32; - -} // namespace efsw -#endif - -//////////////////////////////////////////////////////////// -/// \class efsw::Utf -/// \ingroup system -/// -/// Utility class providing generic functions for UTF conversions. -/// -/// efsw::Utf is a low-level, generic interface for counting, iterating, -/// encoding and decoding Unicode characters and strings. It is able -/// to handle ANSI, wide, UTF-8, UTF-16 and UTF-32 encodings. -/// -/// efsw::Utf functions are all static, these classes are not meant to -/// be instanciated. All the functions are template, so that you -/// can use any character / string type for a given encoding. -/// -/// It has 3 specializations: -/// \li efsw::Utf<8> (typedef'd to efsw::Utf8) -/// \li efsw::Utf<16> (typedef'd to efsw::Utf16) -/// \li efsw::Utf<32> (typedef'd to efsw::Utf32) -/// -//////////////////////////////////////////////////////////// diff --git a/src/3rdParty/efsw/Utf.inl b/src/3rdParty/efsw/Utf.inl deleted file mode 100644 index 5c9d7a38..00000000 --- a/src/3rdParty/efsw/Utf.inl +++ /dev/null @@ -1,576 +0,0 @@ -// References : -// http://www.unicode.org/ -// http://www.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.c -// http://www.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.h -// http://people.w3.org/rishida/scripts/uniview/conversion -//////////////////////////////////////////////////////////// - -template 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( *begin )]; - if ( begin + trailingBytes < end ) { - output = 0; - switch ( trailingBytes ) { - case 5: - output += static_cast( *begin++ ); - output <<= 6; - case 4: - output += static_cast( *begin++ ); - output <<= 6; - case 3: - output += static_cast( *begin++ ); - output <<= 6; - case 2: - output += static_cast( *begin++ ); - output <<= 6; - case 1: - output += static_cast( *begin++ ); - output <<= 6; - case 0: - output += static_cast( *begin++ ); - } - output -= offsets[trailingBytes]; - } else { - // Incomplete character - begin = end; - output = replacement; - } - - return begin; -} - -template 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( ( input | 0x80 ) & 0xBF ); - input >>= 6; - case 3: - bytes[2] = static_cast( ( input | 0x80 ) & 0xBF ); - input >>= 6; - case 2: - bytes[1] = static_cast( ( input | 0x80 ) & 0xBF ); - input >>= 6; - case 1: - bytes[0] = static_cast( 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 In Utf<8>::Next( In begin, In end ) { - Uint32 codepoint; - return Decode( begin, end, codepoint ); -} - -template 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 -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; -} - -template 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; -} - -template 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; -} - -template -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; -} - -#ifndef EFSW_NO_WIDECHAR -template -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; -} -#endif - -template -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( codepoint ) : replacement; - } - - return output; -} - -template Out Utf<8>::toUtf8( In begin, In end, Out output ) { - while ( begin < end ) - *output++ = *begin++; - - return output; -} - -template 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 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 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( ( ( 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 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( 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( ( input >> 10 ) + 0xD800 ); - *output++ = static_cast( ( input & 0x3FFUL ) + 0xDC00 ); - } - - return output; -} - -template In Utf<16>::Next( In begin, In end ) { - Uint32 codepoint; - return Decode( begin, end, codepoint ); -} - -template 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 -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 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; -} - -template 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; -} - -template -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; -} - -#ifndef EFSW_NO_WIDECHAR -template -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; -} -#endif - -template -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( *begin ) : replacement; - begin++; - } - - return output; -} - -template 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; -} - -template Out Utf<16>::ToUtf16( In begin, In end, Out output ) { - while ( begin < end ) - *output++ = *begin++; - - return output; -} - -template Out Utf<16>::ToUtf32( In begin, In end, Out output ) { - while ( begin < end ) { - Uint32 codepoint; - begin = Decode( begin, end, codepoint ); - *output++ = codepoint; - } - - return output; -} - -template In Utf<32>::Decode( In begin, In /*end*/, Uint32& output, Uint32 ) { - output = *begin++; - return begin; -} - -template Out Utf<32>::Encode( Uint32 input, Out output, Uint32 /*replacement*/ ) { - *output++ = input; - return output; -} - -template In Utf<32>::Next( In begin, In /*end*/ ) { - return ++begin; -} - -template std::size_t Utf<32>::Count( In begin, In end ) { - return begin - end; -} - -template -Out Utf<32>::FromAnsi( In begin, In end, Out output, const std::locale& locale ) { - while ( begin < end ) - *output++ = DecodeAnsi( *begin++, locale ); - - return output; -} - -template Out Utf<32>::FromWide( In begin, In end, Out output ) { - while ( begin < end ) - *output++ = DecodeWide( *begin++ ); - - return output; -} - -template 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; -} - -template -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; -} - -#ifndef EFSW_NO_WIDECHAR -template -Out Utf<32>::ToWide( In begin, In end, Out output, wchar_t replacement ) { - while ( begin < end ) - output = EncodeWide( *begin++, output, replacement ); - - return output; -} -#endif - -template -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( *begin ) : replacement; - begin++; - } - - return output; -} - -template Out Utf<32>::toUtf8( In begin, In end, Out output ) { - while ( begin < end ) - output = Utf<8>::Encode( *begin++, output ); - - return output; -} - -template Out Utf<32>::ToUtf16( In begin, In end, Out output ) { - while ( begin < end ) - output = Utf<16>::Encode( *begin++, output ); - - return output; -} - -template Out Utf<32>::ToUtf32( In begin, In end, Out output ) { - while ( begin < end ) - *output++ = *begin++; - - return output; -} - -template 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 */ - - wchar_t character = 0; - mbtowc( &character, &input, 1 ); - return static_cast( character ); - -#else -// Get the facet of the locale which deals with character conversion -#ifndef EFSW_NO_WIDECHAR - const std::ctype& facet = std::use_facet>( locale ); -#else - const std::ctype& facet = std::use_facet>( locale ); -#endif - - // Use the facet to convert each character of the input string - return static_cast( facet.widen( input ) ); - -#endif -} - -template 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; -} - -template -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( 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& facet = std::use_facet>( locale ); -#else - const std::ctype& facet = std::use_facet>( locale ); -#endif - - // Use the facet to convert each character of the input string - *output++ = facet.narrow( static_cast( codepoint ), replacement ); - - return output; - -#endif -} - -#ifndef EFSW_NO_WIDECHAR -template -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( codepoint ); - break; - } - - default: { - if ( ( codepoint <= 0xFFFF ) && ( ( codepoint < 0xD800 ) || ( codepoint > 0xDFFF ) ) ) { - *output++ = static_cast( codepoint ); - } else if ( replacement ) { - *output++ = replacement; - } - break; - } - } - - return output; -} -#endif diff --git a/src/3rdParty/efsw/Watcher.cpp b/src/3rdParty/efsw/Watcher.cpp deleted file mode 100644 index 913ae3c4..00000000 --- a/src/3rdParty/efsw/Watcher.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include - -namespace efsw { - -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 ) {} - -} // namespace efsw diff --git a/src/3rdParty/efsw/Watcher.hpp b/src/3rdParty/efsw/Watcher.hpp deleted file mode 100644 index 84f0980b..00000000 --- a/src/3rdParty/efsw/Watcher.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef EFSW_WATCHERIMPL_HPP -#define EFSW_WATCHERIMPL_HPP - -#include -#include - -namespace efsw { - -/** @brief Base Watcher class */ -class Watcher { - public: - Watcher(); - - Watcher( WatchID id, std::string directory, FileWatchListener* listener, bool recursive ); - - virtual ~Watcher() {} - - virtual void watch() {} - - WatchID ID; - std::string Directory; - FileWatchListener* Listener; - bool Recursive; - std::string OldFileName; -}; - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/WatcherFSEvents.cpp b/src/3rdParty/efsw/WatcherFSEvents.cpp deleted file mode 100644 index f9633741..00000000 --- a/src/3rdParty/efsw/WatcherFSEvents.cpp +++ /dev/null @@ -1,208 +0,0 @@ -#include -#include -#include -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_FSEVENTS - -namespace efsw { - -WatcherFSEvents::WatcherFSEvents() : - Watcher(), FWatcher( NULL ), FSStream( NULL ), WatcherGen( NULL ) {} - -WatcherFSEvents::~WatcherFSEvents() { - if ( NULL != FSStream ) { - FSEventStreamStop( FSStream ); - FSEventStreamInvalidate( FSStream ); - FSEventStreamRelease( FSStream ); - } - - efSAFE_DELETE( WatcherGen ); -} - -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 | efswFSEventStreamCreateFlagNoDefer | - efswFSEventStreamCreateFlagUseExtendedData | - efswFSEventStreamCreateFlagUseCFTypes; - } else { - WatcherGen = new WatcherGeneric( ID, Directory, Listener, FWatcher.load(), Recursive ); - } - - FSEventStreamContext ctx; - /* Initialize context */ - ctx.version = 0; - ctx.info = this; - ctx.retain = NULL; - ctx.release = NULL; - ctx.copyDescription = NULL; - - dispatch_queue_t queue = dispatch_queue_create( NULL, NULL ); - - FSStream = - FSEventStreamCreate( kCFAllocatorDefault, &FileWatcherFSEvents::FSEventCallback, &ctx, - CFDirectoryArray, kFSEventStreamEventIdSinceNow, 0., streamFlags ); - - FSEventStreamSetDispatchQueue( FSStream, queue ); - - FSEventStreamStart( FSStream ); - - 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, - FileSystem::precomposeFileName( oldFilename ) ); -} - -void WatcherFSEvents::handleAddModDel( const Uint32& flags, const std::string& path, - std::string& dirPath, std::string& filePath, Uint64 inode ) { - if ( ( flags & efswFSEventStreamEventFlagItemCreated ) && FileInfo::exists( path ) && - ( !SanitizeEvents || FilesAdded.find( inode ) != FilesAdded.end() ) ) { - sendFileAction( ID, dirPath, filePath, Actions::Add ); - - if ( SanitizeEvents ) - FilesAdded.insert( inode ); - } - - if ( flags & ModifiedFlags ) { - sendFileAction( ID, dirPath, filePath, Actions::Modified ); - } - - if ( ( flags & efswFSEventStreamEventFlagItemRemoved ) && !FileInfo::exists( path ) ) { - // Since i don't know the order, at least i try to keep the data consistent with the real - // state - sendFileAction( ID, dirPath, filePath, Actions::Delete ); - - if ( SanitizeEvents ) - FilesAdded.erase( inode ); - } -} - -void WatcherFSEvents::handleActions( std::vector& events ) { - size_t esize = events.size(); - - for ( size_t i = 0; i < esize; i++ ) { - FSEvent& event = events[i]; - - if ( event.Flags & - ( kFSEventStreamEventFlagUserDropped | kFSEventStreamEventFlagKernelDropped | - kFSEventStreamEventFlagEventIdsWrapped | kFSEventStreamEventFlagHistoryDone | - kFSEventStreamEventFlagMount | kFSEventStreamEventFlagUnmount | - kFSEventStreamEventFlagRootChanged ) ) { - continue; - } - - 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 ) { - continue; - } - } - - 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 ) { - 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: 0x%x\n", event.Path.c_str(), event.Flags ); - - if ( event.Flags & efswFSEventStreamEventFlagItemRenamed ) { - if ( ( i + 1 < esize ) && - ( events[i + 1].Flags & efswFSEventStreamEventFlagItemRenamed ) && - ( events[i + 1].inode == event.inode ) ) { - 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 ) || - 0 == strcasecmp( event.Path.c_str(), nEvent.Path.c_str() ) ) { - sendFileAction( ID, dirPath, newFilepath, Actions::Moved, - filePath ); - } else { - sendFileAction( ID, dirPath, filePath, Actions::Moved, - newFilepath ); - } - } else { - sendFileAction( ID, dirPath, filePath, Actions::Delete ); - sendFileAction( ID, newDir, newFilepath, Actions::Add ); - - if ( nEvent.Flags & ModifiedFlags ) { - sendFileAction( ID, newDir, newFilepath, Actions::Modified ); - } - } - } else { - handleAddModDel( nEvent.Flags, nEvent.Path, dirPath, filePath, event.inode ); - } - - if ( nEvent.Flags & ( efswFSEventStreamEventFlagItemCreated | - efswFSEventStreamEventFlagItemRemoved | - efswFSEventStreamEventFlagItemRenamed ) ) { - if ( newDir != Directory ) { - DirsChanged.insert( newDir ); - } - } - - // Skip the renamed file - i++; - } else if ( FileInfo::exists( event.Path ) ) { - sendFileAction( ID, dirPath, filePath, Actions::Add ); - - if ( event.Flags & ModifiedFlags ) { - sendFileAction( ID, dirPath, filePath, Actions::Modified ); - } - } else { - sendFileAction( ID, dirPath, filePath, Actions::Delete ); - } - } else { - handleAddModDel( event.Flags, event.Path, dirPath, filePath, event.inode ); - } - } else { - efDEBUG( "Directory: %s changed\n", event.Path.c_str() ); - DirsChanged.insert( event.Path ); - } - } -} - -void WatcherFSEvents::process() { - std::unordered_set::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 ); - } - } - - DirsChanged.clear(); -} - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/WatcherFSEvents.hpp b/src/3rdParty/efsw/WatcherFSEvents.hpp deleted file mode 100644 index f05b0940..00000000 --- a/src/3rdParty/efsw/WatcherFSEvents.hpp +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef EFSW_WATCHERINOTIFY_HPP -#define EFSW_WATCHERINOTIFY_HPP - -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_FSEVENTS - -#include -#include -#include -#include -#include -#include - -namespace efsw { - -/* OSX < 10.7 has no file events */ -/* So i declare the events constants */ -enum FSEventEvents { - efswFSEventStreamCreateFlagUseCFTypes = 0x00000001, - efswFSEventStreamCreateFlagNoDefer = 0x00000002, - efswFSEventStreamCreateFlagFileEvents = 0x00000010, - efswFSEventStreamCreateFlagUseExtendedData = 0x00000040, - 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 -}; - -class FileWatcherFSEvents; - -class FSEvent { - public: - FSEvent( std::string path, long flags, Uint64 id, Uint64 inode = 0 ) : - Path( path ), Flags( flags ), Id( id ), inode( inode ) {} - - std::string Path; - long Flags{ 0 }; - Uint64 Id{ 0 }; - Uint64 inode{ 0 }; -}; - -class WatcherFSEvents : public Watcher { - public: - WatcherFSEvents(); - - ~WatcherFSEvents(); - - void init(); - - void handleActions( std::vector& events ); - - void process(); - - Atomic FWatcher; - FSEventStreamRef FSStream; - Uint64 ModifiedFlags{ efswFSEventsModified }; - bool SanitizeEvents{ false }; - - protected: - void handleAddModDel( const Uint32& flags, const std::string& path, std::string& dirPath, - std::string& filePath, Uint64 inode ); - - WatcherGeneric* WatcherGen; - - std::unordered_set DirsChanged; - std::unordered_set FilesAdded; - - void sendFileAction( WatchID watchid, const std::string& dir, const std::string& filename, - Action action, std::string oldFilename = "" ); -}; - -} // namespace efsw - -#endif - -#endif diff --git a/src/3rdParty/efsw/WatcherGeneric.cpp b/src/3rdParty/efsw/WatcherGeneric.cpp deleted file mode 100644 index a6bb1061..00000000 --- a/src/3rdParty/efsw/WatcherGeneric.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include -#include - -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 ) { - FileSystem::dirAddSlashAtEnd( Directory ); - - DirWatch = new DirWatcherGeneric( NULL, this, directory, recursive, false ); - - DirWatch->addChilds( false ); -} - -WatcherGeneric::~WatcherGeneric() { - efSAFE_DELETE( DirWatch ); -} - -void WatcherGeneric::watch() { - DirWatch->watch(); -} - -void WatcherGeneric::watchDir( std::string dir ) { - DirWatch->watchDir( dir ); -} - -bool WatcherGeneric::pathInWatches( std::string path ) { - return DirWatch->pathInWatches( path ); -} - -} // namespace efsw diff --git a/src/3rdParty/efsw/WatcherGeneric.hpp b/src/3rdParty/efsw/WatcherGeneric.hpp deleted file mode 100644 index d11ec20e..00000000 --- a/src/3rdParty/efsw/WatcherGeneric.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef EFSW_WATCHERGENERIC_HPP -#define EFSW_WATCHERGENERIC_HPP - -#include - -namespace efsw { - -class DirWatcherGeneric; - -class WatcherGeneric : public Watcher { - public: - FileWatcherImpl* WatcherImpl; - DirWatcherGeneric* DirWatch; - - WatcherGeneric( WatchID id, const std::string& directory, FileWatchListener* fwl, - FileWatcherImpl* fw, bool recursive ); - - ~WatcherGeneric(); - - void watch() override; - - void watchDir( std::string dir ); - - bool pathInWatches( std::string path ); -}; - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/WatcherInotify.cpp b/src/3rdParty/efsw/WatcherInotify.cpp deleted file mode 100644 index 812ddaee..00000000 --- a/src/3rdParty/efsw/WatcherInotify.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include - -namespace efsw { - -WatcherInotify::WatcherInotify() : Watcher(), Parent( NULL ) {} - -bool WatcherInotify::inParentTree( WatcherInotify* parent ) { - WatcherInotify* tNext = Parent; - - while ( NULL != tNext ) { - if ( tNext == parent ) { - return true; - } - - tNext = tNext->Parent; - } - - return false; -} - -} // namespace efsw diff --git a/src/3rdParty/efsw/WatcherInotify.hpp b/src/3rdParty/efsw/WatcherInotify.hpp deleted file mode 100644 index ec55ed0e..00000000 --- a/src/3rdParty/efsw/WatcherInotify.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef EFSW_WATCHERINOTIFY_HPP -#define EFSW_WATCHERINOTIFY_HPP - -#include -#include - -namespace efsw { - -class WatcherInotify : public Watcher { - public: - WatcherInotify(); - - bool inParentTree( WatcherInotify* parent ); - - WatcherInotify* Parent; - WatchID InotifyID; - - FileInfo DirInfo; - bool syntheticEvents{ false }; -}; - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/WatcherKqueue.cpp b/src/3rdParty/efsw/WatcherKqueue.cpp deleted file mode 100644 index 424b9890..00000000 --- a/src/3rdParty/efsw/WatcherKqueue.cpp +++ /dev/null @@ -1,566 +0,0 @@ -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_KQUEUE || EFSW_PLATFORM == EFSW_PLATFORM_FSEVENTS - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define KEVENT_RESERVE_VALUE ( 10 ) - -#ifndef O_EVTONLY -#define O_EVTONLY ( O_RDONLY | O_NONBLOCK ) -#endif - -namespace efsw { - -int comparator( const void* ke1, const void* ke2 ) { - const KEvent* kev1 = reinterpret_cast( ke1 ); - const KEvent* kev2 = reinterpret_cast( ke2 ); - - if ( NULL != kev2->udata ) { - FileInfo* fi1 = reinterpret_cast( kev1->udata ); - FileInfo* fi2 = reinterpret_cast( kev2->udata ); - - return strcmp( fi1->Filepath.c_str(), fi2->Filepath.c_str() ); - } - - return 1; -} - -WatcherKqueue::WatcherKqueue( WatchID watchid, const std::string& dirname, - FileWatchListener* listener, bool recursive, - FileWatcherKqueue* watcher, WatcherKqueue* parent ) : - Watcher( watchid, dirname, listener, recursive ), - 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 ); - - mInitOK = false; - mErrno = errno; - } else { - mWatcher->addFD(); - } -} - -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( mChangeList[i].udata ); - - efSAFE_DELETE( fi ); - } - } - - close( mKqueue ); - - mWatcher->removeFD(); -} - -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() ); - - // add base dir - int fd = open( Directory.c_str(), O_EVTONLY ); - - if ( -1 == fd ) { - efDEBUG( "addAll(): Couldn't open folder: %s\n", Directory.c_str() ); - - if ( EACCES != errno ) { - mInitOK = false; - } - - mErrno = errno; - - return; - } - - mDirSnap.setDirectoryInfo( Directory ); - mDirSnap.scan(); - - 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 ); - - 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++ ) { - FileInfo& fi = it->second; - - if ( fi.isRegularFile() ) { - // Add the regular files kevent - 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() ) { - handleFolderAction( fi.Filepath, Actions::Add ); - } - } - } -} - -void WatcherKqueue::removeAll() { - efDEBUG( "removeAll(): Removing all child watchers\n" ); - - std::vector erase; - - 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::vector::iterator eit = erase.begin(); eit != erase.end(); eit++ ) { - removeWatch( *eit ); - } -} - -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 ); - - Errors::Log::createLastError( Errors::FileNotReadable, name ); - - if ( EACCES != errno ) { - mInitOK = false; - } - - mErrno = errno; - - return; - } - - mWatcher->addFD(); - - // increase the file kevent file count - mChangeListCount++; - - if ( mChangeListCount + KEVENT_RESERVE_VALUE > mChangeList.size() && - 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 ); - } - - // create entry - 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 ); - - // qsort sort the list by name - qsort( &mChangeList[1], mChangeListCount, sizeof( KEvent ), comparator ); - - // handle action - if ( emitEvents ) { - handleAction( name, Actions::Add ); - } -} - -void WatcherKqueue::removeFile( const std::string& name, bool emitEvents ) { - efDEBUG( "removeFile(): Trying to remove file: %s\n", name.c_str() ); - - // bsearch - KEvent target; - - // Create a temporary file info to search the kevent ( searching the directory ) - FileInfo tempEntry( name ); - - target.udata = &tempEntry; - - // Search the kevent - KEvent* ke = (KEvent*)bsearch( &target, &mChangeList[0], mChangeListCount + 1, sizeof( KEvent ), - comparator ); - - // Trying to remove a non-existing file? - if ( !ke ) { - Errors::Log::createLastError( Errors::FileNotFound, name ); - efDEBUG( "File not removed\n" ); - return; - } - - efDEBUG( "File removed\n" ); - - // handle action - if ( emitEvents ) { - handleAction( name, Actions::Delete ); - } - - // Delete the user data ( FileInfo ) from the kevent closed - FileInfo* del = reinterpret_cast( ke->udata ); - - efSAFE_DELETE( del ); - - // close the file descriptor from the kevent - close( ke->ident ); - - mWatcher->removeFD(); - - memset( ke, 0, sizeof( KEvent ) ); - - // move end to current - memcpy( ke, &mChangeList[mChangeListCount], sizeof( KEvent ) ); - memset( &mChangeList[mChangeListCount], 0, sizeof( KEvent ) ); - --mChangeListCount; -} - -void WatcherKqueue::rescan() { - efDEBUG( "rescan(): Rescanning: %s\n", Directory.c_str() ); - - DirectorySnapshotDiff Diff = mDirSnap.scan(); - - if ( Diff.DirChanged ) { - sendDirChanged(); - } - - if ( Diff.changed() ) { - FileInfoList::iterator it; - MovedList::iterator mit; - - /// Files - DiffIterator( FilesCreated ) { - addFile( ( *it ).Filepath ); - } - - DiffIterator( FilesModified ) { - handleAction( ( *it ).Filepath, Actions::Modified ); - } - - 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 ); - } - - /// Directories - DiffIterator( DirsCreated ) { - handleFolderAction( ( *it ).Filepath, Actions::Add ); - addWatch( ( *it ).Filepath, Listener, Recursive, this ); - } - - DiffIterator( DirsModified ) { - handleFolderAction( ( *it ).Filepath, Actions::Modified ); - } - - DiffIterator( DirsDeleted ) { - handleFolderAction( ( *it ).Filepath, Actions::Delete ); - - Watcher* watch = findWatcher( ( *it ).Filepath ); - - if ( NULL != watch ) { - removeWatch( watch->ID ); - } - } - - DiffMovedIterator( DirsMoved ) { - moveDirectory( Directory + ( *mit ).first, ( *mit ).second.Filepath ); - } - } -} - -WatchID WatcherKqueue::watchingDirectory( std::string dir ) { - Watcher* watch = findWatcher( dir ); - - 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::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::watch() { - if ( -1 == mKqueue ) { - return; - } - - int nev = 0; - 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 ) { - it->second->watch(); - } - - bool needScan = false; - - // Then we get the the events of the current folder - while ( !mChangeList.empty() && - ( nev = kevent( mKqueue, mChangeList.data(), mChangeListCount + 1, &event, 1, - &mWatcher->mTimeOut ) ) != 0 ) { - // An error ocurred? - if ( nev == -1 ) { - efDEBUG( "watch(): Error on directory %s\n", Directory.c_str() ); - perror( "kevent" ); - break; - } 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( 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 ) { - efDEBUG( "deleted\n" ); - - mDirSnap.removeFile( entry->Filepath ); - - removeFile( entry->Filepath ); - } 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 ) { - *entry = fi; - - mDirSnap.updateFile( entry->Filepath ); - - handleAction( entry->Filepath, efsw::Actions::Modified ); - } - } else if ( event.fflags & NOTE_RENAME ) { - efDEBUG( "moved\n" ); - - needScan = true; - } - } else { - needScan = true; - } - } - } - - if ( needScan ) { - rescan(); - } -} - -Watcher* WatcherKqueue::findWatcher( const std::string path ) { - WatchMap::iterator it = mWatches.begin(); - - for ( ; it != mWatches.end(); it++ ) { - if ( it->second->Directory == path ) { - return it->second; - } - } - - return NULL; -} - -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 ); - - if ( NULL != watch ) { - watch->Directory = opath2; - } - - if ( emitEvents ) { - handleFolderAction( newPath, efsw::Actions::Moved, oldPath ); - } -} - -WatchID WatcherKqueue::addWatch( const std::string& directory, FileWatchListener* watcher, - bool recursive, WatcherKqueue* parent ) { - static bool s_ug = false; - - std::string dir( directory ); - - FileSystem::dirAddSlashAtEnd( dir ); - - // This should never happen here - if ( !FileSystem::isDirectory( dir ) ) { - return Errors::Log::createLastError( Errors::FileNotFound, dir ); - } else if ( pathInWatches( dir ) || pathInParent( dir ) ) { - return Errors::Log::createLastError( Errors::FileRepeated, directory ); - } 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 ) { - /// Avoid adding symlinks directories if it's now enabled - if ( NULL != parent && !mWatcher->mFileWatcher->followSymlinks() ) { - return Errors::Log::createLastError( Errors::FileOutOfScope, dir ); - } - - if ( pathInWatches( link ) || pathInParent( link ) ) { - return Errors::Log::createLastError( Errors::FileRepeated, link ); - } else if ( !mWatcher->linkAllowed( curPath, link ) ) { - return Errors::Log::createLastError( Errors::FileOutOfScope, link ); - } else { - dir = link; - } - } - - if ( mWatcher->availablesFD() ) { - WatcherKqueue* watch = - new WatcherKqueue( ++mLastWatchID, dir, watcher, recursive, mWatcher, parent ); - - mWatches.insert( std::make_pair( mLastWatchID, watch ) ); - - watch->addAll(); - - // if failed to open the directory... erase the watcher - if ( !watch->initOK() ) { - int le = watch->lastErrno(); - - mWatches.erase( watch->ID ); - - efSAFE_DELETE( watch ); - - mLastWatchID--; - - // Probably the folder has too many files, create a generic watcher - if ( EACCES != le ) { - WatcherGeneric* watch = - new WatcherGeneric( ++mLastWatchID, dir, watcher, mWatcher, recursive ); - - 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.\n", - mWatcher->mFileDescriptorCount ); - s_ug = true; - } - - WatcherGeneric* watch = - new WatcherGeneric( ++mLastWatchID, dir, watcher, mWatcher, recursive ); - - mWatches.insert( std::make_pair( mLastWatchID, watch ) ); - } - - return mLastWatchID; -} - -bool WatcherKqueue::initOK() { - return mInitOK; -} - -void WatcherKqueue::removeWatch( WatchID watchid ) { - WatchMap::iterator iter = mWatches.find( watchid ); - - if ( iter == mWatches.end() ) - return; - - Watcher* watch = iter->second; - - mWatches.erase( iter ); - - efSAFE_DELETE( watch ); -} - -bool WatcherKqueue::pathInWatches( const std::string& path ) { - return NULL != findWatcher( path ); -} - -bool WatcherKqueue::pathInParent( const std::string& path ) { - WatcherKqueue* pNext = mParent; - - while ( NULL != pNext ) { - if ( pNext->pathInWatches( path ) ) { - return true; - } - - pNext = pNext->mParent; - } - - if ( mWatcher->pathInWatches( path ) ) { - return true; - } - - if ( path == Directory ) { - return true; - } - - return false; -} - -int WatcherKqueue::lastErrno() { - return mErrno; -} - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/WatcherKqueue.hpp b/src/3rdParty/efsw/WatcherKqueue.hpp deleted file mode 100644 index 75c0f623..00000000 --- a/src/3rdParty/efsw/WatcherKqueue.hpp +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef EFSW_WATCHEROSX_HPP -#define EFSW_WATCHEROSX_HPP - -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_KQUEUE || EFSW_PLATFORM == EFSW_PLATFORM_FSEVENTS - -#include -#include -#include -#include -#include - -namespace efsw { - -class FileWatcherKqueue; -class WatcherKqueue; - -typedef struct kevent KEvent; - -/// type for a map from WatchID to WatcherKqueue pointer -typedef std::map WatchMap; - -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(); - - void handleAction( const std::string& filename, efsw::Action action, - const std::string& oldFilename = "" ); - - void handleFolderAction( std::string filename, efsw::Action action, - const std::string& oldFilename = "" ); - - void addAll(); - - void removeAll(); - - WatchID watchingDirectory( std::string dir ); - - void watch() override; - - WatchID addWatch( const std::string& directory, FileWatchListener* watcher, bool recursive, - WatcherKqueue* parent ); - - void removeWatch( WatchID watchid ); - - bool initOK(); - - int lastErrno(); - - protected: - WatchMap mWatches; - int mLastWatchID; - - // index 0 is always the directory - std::vector mChangeList; - size_t mChangeListCount; - DirectorySnapshot mDirSnap; - - /// The descriptor for the kqueue - int mKqueue; - - FileWatcherKqueue* mWatcher; - - WatcherKqueue* mParent; - - bool mInitOK; - int mErrno; - - bool pathInWatches( const std::string& path ); - - bool pathInParent( const std::string& path ); - - Watcher* findWatcher( const std::string path ); - - void moveDirectory( std::string oldPath, std::string newPath, bool emitEvents = true ); - - void sendDirChanged(); -}; - -} // namespace efsw - -#endif - -#endif diff --git a/src/3rdParty/efsw/WatcherWin32.cpp b/src/3rdParty/efsw/WatcherWin32.cpp deleted file mode 100644 index 712419eb..00000000 --- a/src/3rdParty/efsw/WatcherWin32.cpp +++ /dev/null @@ -1,263 +0,0 @@ -#include -#include -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32 - -#include - -namespace efsw { - -struct EFSW_FILE_NOTIFY_EXTENDED_INFORMATION_EX { - DWORD NextEntryOffset; - DWORD Action; - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastModificationTime; - LARGE_INTEGER LastChangeTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER AllocatedLength; - LARGE_INTEGER FileSize; - DWORD FileAttributes; - DWORD ReparsePointTag; - LARGE_INTEGER FileId; - LARGE_INTEGER ParentFileId; - DWORD FileNameLength; - WCHAR FileName[1]; -}; - -typedef EFSW_FILE_NOTIFY_EXTENDED_INFORMATION_EX* EFSW_PFILE_NOTIFY_EXTENDED_INFORMATION_EX; - -typedef BOOL( WINAPI* EFSW_LPREADDIRECTORYCHANGESEXW )( HANDLE hDirectory, LPVOID lpBuffer, - DWORD nBufferLength, BOOL bWatchSubtree, - DWORD dwNotifyFilter, LPDWORD lpBytesReturned, - LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, - DWORD ReadDirectoryNotifyInformationClass ); - -static EFSW_LPREADDIRECTORYCHANGESEXW pReadDirectoryChangesExW = NULL; - -#define EFSW_ReadDirectoryNotifyExtendedInformation 2 - -static void initReadDirectoryChangesEx() { - static bool hasInit = false; - if ( !hasInit ) { - hasInit = true; - - HMODULE hModule = GetModuleHandleW( L"Kernel32.dll" ); - if ( !hModule ) - return; - - pReadDirectoryChangesExW = - (EFSW_LPREADDIRECTORYCHANGESEXW)GetProcAddress( hModule, "ReadDirectoryChangesExW" ); - } -} - -void WatchCallbackOld( WatcherWin32* pWatch ) { - PFILE_NOTIFY_INFORMATION pNotify; - size_t offset = 0; - do { - bool skip = false; - - 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( count, '\0' ); - - count = WideCharToMultiByte( CP_UTF8, 0, pNotify->FileName, - pNotify->FileNameLength / sizeof( WCHAR ), &nfile[0], count, - NULL, NULL ); - - if ( FILE_ACTION_MODIFIED == pNotify->Action ) { - FileInfo fifile( std::string( pWatch->DirName ) + nfile ); - - if ( pWatch->LastModifiedEvent.file.ModificationTime == fifile.ModificationTime && - pWatch->LastModifiedEvent.file.Size == fifile.Size && - pWatch->LastModifiedEvent.fileName == nfile ) { - skip = true; - } - - pWatch->LastModifiedEvent.fileName = nfile; - pWatch->LastModifiedEvent.file = fifile; - } - - if ( !skip ) { - pWatch->Watch->handleAction( pWatch, nfile, pNotify->Action ); - } - } while ( pNotify->NextEntryOffset != 0 ); -} - -void WatchCallbackEx( WatcherWin32* pWatch ) { - EFSW_PFILE_NOTIFY_EXTENDED_INFORMATION_EX pNotify; - size_t offset = 0; - do { - bool skip = false; - - pNotify = (EFSW_PFILE_NOTIFY_EXTENDED_INFORMATION_EX)&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( count, '\0' ); - - count = WideCharToMultiByte( CP_UTF8, 0, pNotify->FileName, - pNotify->FileNameLength / sizeof( WCHAR ), &nfile[0], count, - NULL, NULL ); - - if ( FILE_ACTION_MODIFIED == pNotify->Action ) { - FileInfo fifile( std::string( pWatch->DirName ) + nfile ); - - if ( pWatch->LastModifiedEvent.file.ModificationTime == fifile.ModificationTime && - pWatch->LastModifiedEvent.file.Size == fifile.Size && - pWatch->LastModifiedEvent.fileName == nfile ) { - skip = true; - } - - pWatch->LastModifiedEvent.fileName = nfile; - pWatch->LastModifiedEvent.file = fifile; - } else if ( FILE_ACTION_RENAMED_OLD_NAME == pNotify->Action ) { - pWatch->OldFiles.emplace_back( nfile, pNotify->FileId ); - skip = true; - } else if ( FILE_ACTION_RENAMED_NEW_NAME == pNotify->Action ) { - std::string oldFile; - LARGE_INTEGER oldFileId{}; - - for ( auto it = pWatch->OldFiles.begin(); it != pWatch->OldFiles.end(); ++it ) { - if ( it->second.QuadPart == pNotify->FileId.QuadPart ) { - oldFile = it->first; - oldFileId = it->second; - it = pWatch->OldFiles.erase( it ); - break; - } - } - - if ( oldFile.empty() ) { - pWatch->Watch->handleAction( pWatch, nfile, FILE_ACTION_ADDED ); - skip = true; - } else { - pWatch->Watch->handleAction( pWatch, oldFile, FILE_ACTION_RENAMED_OLD_NAME ); - } - } - - if ( !skip ) { - pWatch->Watch->handleAction( pWatch, nfile, pNotify->Action ); - } - } while ( pNotify->NextEntryOffset != 0 ); -} - -/// Unpacks events and passes them to a user defined callback. -void CALLBACK WatchCallback( DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped ) { - if ( NULL == lpOverlapped ) { - return; - } - - WatcherStructWin32* tWatch = (WatcherStructWin32*)lpOverlapped; - WatcherWin32* pWatch = tWatch->Watch; - - if ( dwNumberOfBytesTransfered == 0 ) { - if ( nullptr != pWatch && !pWatch->StopNow ) { - RefreshWatch( tWatch ); - } else { - return; - } - } - - // Fork watch depending on the Windows API supported - if ( pWatch->Extended ) { - WatchCallbackEx( pWatch ); - } else { - WatchCallbackOld( pWatch ); - } - - if ( !pWatch->StopNow ) { - RefreshWatch( tWatch ); - } -} - -/// Refreshes the directory monitoring. -RefreshResult RefreshWatch( WatcherStructWin32* pWatch ) { - initReadDirectoryChangesEx(); - - bool bRet = false; - RefreshResult ret = RefreshResult::Failed; - pWatch->Watch->Extended = false; - - if ( pReadDirectoryChangesExW ) { - bRet = pReadDirectoryChangesExW( pWatch->Watch->DirHandle, pWatch->Watch->Buffer.data(), - (DWORD)pWatch->Watch->Buffer.size(), pWatch->Watch->Recursive, - pWatch->Watch->NotifyFilter, NULL, &pWatch->Overlapped, - NULL, EFSW_ReadDirectoryNotifyExtendedInformation ) != 0; - if ( bRet ) { - ret = RefreshResult::SucessEx; - pWatch->Watch->Extended = true; - } - } - - if ( !bRet ) { - bRet = ReadDirectoryChangesW( pWatch->Watch->DirHandle, pWatch->Watch->Buffer.data(), - (DWORD)pWatch->Watch->Buffer.size(), pWatch->Watch->Recursive, - pWatch->Watch->NotifyFilter, NULL, &pWatch->Overlapped, - NULL ) != 0; - - if ( bRet ) - ret = RefreshResult::Success; - } - - if ( !bRet ) { - std::string error = std::to_string( GetLastError() ); - Errors::Log::createLastError( Errors::WatcherFailed, error ); - } - - return ret; -} - -/// Stops monitoring a directory. -void DestroyWatch( WatcherStructWin32* pWatch ) { - if ( pWatch ) { - WatcherWin32* tWatch = pWatch->Watch; - tWatch->StopNow = true; - CancelIoEx( pWatch->Watch->DirHandle, &pWatch->Overlapped ); - CloseHandle( pWatch->Watch->DirHandle ); - efSAFE_DELETE_ARRAY( pWatch->Watch->DirName ); - efSAFE_DELETE( pWatch->Watch ); - efSAFE_DELETE( pWatch ); - } -} - -/// Starts monitoring a directory. -WatcherStructWin32* CreateWatch( LPCWSTR szDirectory, bool recursive, - DWORD bufferSize, DWORD notifyFilter, HANDLE iocp ) { - WatcherStructWin32* tWatch = new WatcherStructWin32(); - WatcherWin32* pWatch = new WatcherWin32(bufferSize); - if (tWatch) - 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 && - CreateIoCompletionPort( pWatch->DirHandle, iocp, 0, 1 ) ) { - pWatch->NotifyFilter = notifyFilter; - pWatch->Recursive = recursive; - - if ( RefreshResult::Failed != RefreshWatch( tWatch ) ) { - return tWatch; - } - } - - CloseHandle( pWatch->DirHandle ); - efSAFE_DELETE( pWatch->Watch ); - efSAFE_DELETE( tWatch ); - return NULL; -} - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/WatcherWin32.hpp b/src/3rdParty/efsw/WatcherWin32.hpp deleted file mode 100644 index ea1e8e45..00000000 --- a/src/3rdParty/efsw/WatcherWin32.hpp +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef EFSW_WATCHERWIN32_HPP -#define EFSW_WATCHERWIN32_HPP - -#include -#include -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32 - -#include - -#ifdef EFSW_COMPILER_MSVC -#pragma comment( lib, "comctl32.lib" ) -#pragma comment( lib, "user32.lib" ) -#pragma comment( lib, "ole32.lib" ) - -// disable secure warnings -#pragma warning( disable : 4996 ) -#endif - -namespace efsw { - -class WatcherWin32; - -enum RefreshResult { Failed, Success, SucessEx }; - -/// Internal watch data -struct WatcherStructWin32 { - OVERLAPPED Overlapped; - WatcherWin32* Watch; -}; - -struct sLastModifiedEvent { - FileInfo file; - std::string fileName; -}; - -RefreshResult RefreshWatch( WatcherStructWin32* pWatch ); - -void CALLBACK WatchCallback( DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped ); - -void DestroyWatch( WatcherStructWin32* pWatch ); - -WatcherStructWin32* CreateWatch( LPCWSTR szDirectory, bool recursive, - DWORD bufferSize, DWORD notifyFilter, HANDLE iocp ); - -class WatcherWin32 : public Watcher { - public: - WatcherWin32(DWORD dwBufferSize) : - Struct( NULL ), - DirHandle( NULL ), - Buffer(), - lParam( 0 ), - NotifyFilter( 0 ), - StopNow( false ), - Extended( false ), - Watch( NULL ), - DirName( NULL ) { - Buffer.resize(dwBufferSize); - } - - WatcherStructWin32* Struct; - HANDLE DirHandle; - std::vector Buffer; - LPARAM lParam; - DWORD NotifyFilter; - bool StopNow; - bool Extended; - FileWatcherImpl* Watch; - char* DirName; - sLastModifiedEvent LastModifiedEvent; - std::vector> OldFiles; -}; - -} // namespace efsw - -#endif - -#endif diff --git a/src/3rdParty/efsw/base.hpp b/src/3rdParty/efsw/base.hpp deleted file mode 100644 index 43abc4fd..00000000 --- a/src/3rdParty/efsw/base.hpp +++ /dev/null @@ -1,129 +0,0 @@ -#ifndef EFSW_BASE -#define EFSW_BASE - -#include -#include - -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 - -#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 - -#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 -#endif - -#if 1 == SOPHIST_pointer64 -#define EFSW_64BIT -#else -#define EFSW_32BIT -#endif - -#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] ) ) - -} // namespace efsw - -#endif diff --git a/src/3rdParty/efsw/efsw.h b/src/3rdParty/efsw/efsw.h deleted file mode 100644 index 30cf5957..00000000 --- a/src/3rdParty/efsw/efsw.h +++ /dev/null @@ -1,194 +0,0 @@ -/** - @author Sepul Sepehr Taghdisian - - Copyright (c) 2024 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 - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - 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. -*/ -/** This is the C API wrapper of EFSW */ -#ifndef ESFW_H -#define ESFW_H - -#ifdef __cplusplus -extern "C" { -#endif - -#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 -#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 -#endif - -/// Type for a watch id -typedef long efsw_watchid; - -/// Type for watcher -typedef void* efsw_watcher; - -enum efsw_action { - EFSW_ADD = 1, /// Sent when a file is created or renamed - EFSW_DELETE = 2, /// Sent when a file is deleted or renamed - EFSW_MODIFIED = 3, /// Sent when a file is modified - EFSW_MOVED = 4 /// Sent when a file is moved -}; - -enum efsw_error { - EFSW_NOTFOUND = -1, - EFSW_REPEATED = -2, - EFSW_OUTOFSCOPE = -3, - EFSW_NOTREADABLE = -4, - EFSW_REMOTE = -5, - 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, - /// For macOS (FSEvents backend), per default all modified event types are capture but we might - // only be interested in a subset; the value of the option should be set to a set of bitwise - // from: - // kFSEventStreamEventFlagItemFinderInfoMod - // kFSEventStreamEventFlagItemModified - // kFSEventStreamEventFlagItemInodeMetaMod - // Default configuration will set the 3 flags - EFSW_OPT_MAC_MODIFIED_FILTER = 3, - /// macOS sometimes informs incorrect or old file states that may confuse the consumer - /// The events sanitizer will try to sanitize incorrectly reported events in favor of reducing - /// the number of events reported. This will have an small performance and memory impact as a - /// consequence. - EFSW_OPT_MAC_SANITIZE_EVENTS = 4, - /// Linux does not support natively recursive watchers. This means that when using recursive - /// watches efsw registers new watchers for each directory. If new file are created between - /// the time efsw takes to register the new directory those events might be missed. To avoid - /// missing new file notifications efsw will trigger synthetic new file events for existing - /// files in the new directroy watched. This might have the unintended consequence of sending - /// duplicated created events due to the system also emitting this event. - LINUX_PRODUCE_SYNTHETIC_EVENTS = 5, -}; - -/// Basic interface for listening for file events. -typedef void ( *efsw_pfn_fileaction_callback )( efsw_watcher watcher, efsw_watchid watchid, - const char* dir, const char* filename, - enum efsw_action action, const char* old_filename, - 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 - */ -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 ); - -/// Retrieve last error occured by file-watcher -EFSW_API const char* efsw_getlasterror(); - -/// 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 ); - -/// Remove a directory watch. This is a map lookup O(logn). -void EFSW_API efsw_removewatch_byid( efsw_watcher watcher, efsw_watchid watchid ); - -/// Starts watching ( in other thread ) -void EFSW_API efsw_watch( efsw_watcher watcher ); - -/** - * Allow recursive watchers to follow symbolic links to other directories - * followSymlinks is disabled by default - */ -void EFSW_API efsw_follow_symlinks( efsw_watcher watcher, int enable ); - -/** @return If can follow symbolic links to directorioes */ -int EFSW_API efsw_follow_symlinks_isenabled( efsw_watcher watcher ); - -/** - * 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 EFSW_API efsw_allow_outofscopelinks( efsw_watcher watcher, int allow ); - -/// @return Returns if out of scope links are allowed -int EFSW_API efsw_outofscopelinks_isallowed( efsw_watcher watcher ); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/3rdParty/efsw/efsw.hpp b/src/3rdParty/efsw/efsw.hpp deleted file mode 100644 index 11a5dec1..00000000 --- a/src/3rdParty/efsw/efsw.hpp +++ /dev/null @@ -1,261 +0,0 @@ -/** - @author Martín Lucas Golini - - Copyright (c) 2024 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 - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - 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. -*/ - -#ifndef ESFW_HPP -#define ESFW_HPP - -#include -#include - -#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 -#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 { - -/// Type for a watch id -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 -}; -} -typedef Actions::Action Action; - -/// Errors log namespace -namespace Errors { - -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(); - - /// @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 ); -}; - -} // 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, - /// For macOS (FSEvents backend), per default all modified event types are capture but we might - /// only be interested in a subset; the value of the option should be set to a set of bitwise - /// from: - /// kFSEventStreamEventFlagItemFinderInfoMod - /// kFSEventStreamEventFlagItemModified - /// kFSEventStreamEventFlagItemInodeMetaMod - /// Default configuration will set the 3 flags - MacModifiedFilter = 3, - /// macOS sometimes informs incorrect or old file states that may confuse the consumer - /// The events sanitizer will try to sanitize incorrectly reported events in favor of reducing - /// the number of events reported. This will have an small performance and memory impact as a - /// consequence. - MacSanitizeEvents = 4, - /// Linux does not support natively recursive watchers. This means that when using recursive - /// watches efsw registers new watchers for each directory. If new file are created between - /// the time efsw takes to register the new directory those events might be missed. To avoid - /// missing new file notifications efsw will trigger synthetic created file events for existing - /// files in the new directroy watched. This might have the unintended consequence of sending - /// duplicated created events due to the system also emitting this event. - LinuxProduceSyntheticEvents = 5, -}; -} -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 ); - - /// 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& 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 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: - 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/src/3rdParty/efsw/inotify-nosys.h b/src/3rdParty/efsw/inotify-nosys.h deleted file mode 100644 index be1e627d..00000000 --- a/src/3rdParty/efsw/inotify-nosys.h +++ /dev/null @@ -1,164 +0,0 @@ -#ifndef _LINUX_INOTIFY_H -#define _LINUX_INOTIFY_H - -#include -#include -#include - -/* - * struct inotify_event - structure read from the inotify device for each event - * - * When you are watching a directory, you will receive the filename for events - * such as IN_CREATE, IN_DELETE, IN_OPEN, IN_CLOSE, ..., relative to the wd. - */ -struct inotify_event { - int wd; /* watch descriptor */ - uint32_t mask; /* watch mask */ - uint32_t cookie; /* cookie to synchronize two events */ - uint32_t len; /* length (including nulls) of name */ - char name __flexarr; /* stub for possible name */ -}; - -/* the following are legal, implemented events that user-space can watch for */ -#define IN_ACCESS 0x00000001 /* File was accessed */ -#define IN_MODIFY 0x00000002 /* File was modified */ -#define IN_ATTRIB 0x00000004 /* Metadata changed */ -#define IN_CLOSE_WRITE 0x00000008 /* Writtable file was closed */ -#define IN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */ -#define IN_OPEN 0x00000020 /* File was opened */ -#define IN_MOVED_FROM 0x00000040 /* File was moved from X */ -#define IN_MOVED_TO 0x00000080 /* File was moved to Y */ -#define IN_CREATE 0x00000100 /* Subfile was created */ -#define IN_DELETE 0x00000200 /* Subfile was deleted */ -#define IN_DELETE_SELF 0x00000400 /* Self was deleted */ -#define IN_MOVE_SELF 0x00000800 /* Self was moved */ - -/* the following are legal events. they are sent as needed to any watch */ -#define IN_UNMOUNT 0x00002000 /* Backing fs was unmounted */ -#define IN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */ -#define IN_IGNORED 0x00008000 /* File was ignored */ - -/* helper events */ -#define IN_CLOSE (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) /* close */ -#define IN_MOVE (IN_MOVED_FROM | IN_MOVED_TO) /* moves */ - -/* special flags */ -#define IN_ONLYDIR 0x01000000 /* only watch the path if it is a directory */ -#define IN_DONT_FOLLOW 0x02000000 /* don't follow a sym link */ -#define IN_MASK_ADD 0x20000000 /* add to the mask of an already existing watch */ -#define IN_ISDIR 0x40000000 /* event occurred against dir */ -#define IN_ONESHOT 0x80000000 /* only send event once */ - -/* - * All of the events - we build the list by hand so that we can add flags in - * the future and not break backward compatibility. Apps will get only the - * events that they originally wanted. Be sure to add new events here! - */ -#define IN_ALL_EVENTS (IN_ACCESS | IN_MODIFY | IN_ATTRIB | IN_CLOSE_WRITE | \ - IN_CLOSE_NOWRITE | IN_OPEN | IN_MOVED_FROM | \ - IN_MOVED_TO | IN_DELETE | IN_CREATE | IN_DELETE_SELF | \ - IN_MOVE_SELF) - -#if defined (__alpha__) -# define __NR_inotify_init 444 -# define __NR_inotify_add_watch 445 -# define __NR_inotify_rm_watch 446 - -#elif defined (__arm__) -# define __NR_inotify_init (__NR_SYSCALL_BASE+316) -# define __NR_inotify_add_watch (__NR_SYSCALL_BASE+317) -# define __NR_inotify_rm_watch (__NR_SYSCALL_BASE+318) - -#elif defined (__aarch64__) -# define __NR_inotify_init 1043 -# define __NR_inotify_add_watch 27 -# define __NR_inotify_rm_watch 28 - -#elif defined (__frv__) -# define __NR_inotify_init 291 -# define __NR_inotify_add_watch 292 -# define __NR_inotify_rm_watch 293 - -#elif defined(__i386__) -# define __NR_inotify_init 291 -# define __NR_inotify_add_watch 292 -# define __NR_inotify_rm_watch 293 - -#elif defined (__ia64__) -# define __NR_inotify_init 1277 -# define __NR_inotify_add_watch 1278 -# define __NR_inotify_rm_watch 1279 - -#elif defined (__mips__) -# if _MIPS_SIM == _MIPS_SIM_ABI32 -# define __NR_inotify_init (__NR_Linux + 284) -# define __NR_inotify_add_watch (__NR_Linux + 285) -# define __NR_inotify_rm_watch (__NR_Linux + 286) -# endif -# if _MIPS_SIM == _MIPS_SIM_ABI64 -# define __NR_inotify_init (__NR_Linux + 243) -# define __NR_inotify_add_watch (__NR_Linux + 243) -# define __NR_inotify_rm_watch (__NR_Linux + 243) -# endif -# if _MIPS_SIM == _MIPS_SIM_NABI32 -# define __NR_inotify_init (__NR_Linux + 247) -# define __NR_inotify_add_watch (__NR_Linux + 248) -# define __NR_inotify_rm_watch (__NR_Linux + 249) -# endif - -#elif defined(__parisc__) -# define __NR_inotify_init (__NR_Linux + 269) -# define __NR_inotify_add_watch (__NR_Linux + 270) -# define __NR_inotify_rm_watch (__NR_Linux + 271) - -#elif defined(__powerpc__) || defined(__powerpc64__) -# define __NR_inotify_init 275 -# define __NR_inotify_add_watch 276 -# define __NR_inotify_rm_watch 277 - -#elif defined (__s390__) -# define __NR_inotify_init 284 -# define __NR_inotify_add_watch 285 -# define __NR_inotify_rm_watch 286 - -#elif defined (__sh__) -# define __NR_inotify_init 290 -# define __NR_inotify_add_watch 291 -# define __NR_inotify_rm_watch 292 - -#elif defined (__sh64__) -# define __NR_inotify_init 318 -# define __NR_inotify_add_watch 319 -# define __NR_inotify_rm_watch 320 - -#elif defined (__sparc__) || defined (__sparc64__) -# define __NR_inotify_init 151 -# define __NR_inotify_add_watch 152 -# define __NR_inotify_rm_watch 156 - -#elif defined(__x86_64__) -# define __NR_inotify_init 253 -# define __NR_inotify_add_watch 254 -# define __NR_inotify_rm_watch 255 - -#else -# error "Unsupported architecture!" -#endif - -static inline int inotify_init (void) -{ - return syscall (__NR_inotify_init); -} - -static inline int inotify_add_watch (int fd, const char *name, uint32_t mask) -{ - return syscall (__NR_inotify_add_watch, fd, name, mask); -} - -static inline int inotify_rm_watch (int fd, uint32_t wd) -{ - return syscall (__NR_inotify_rm_watch, fd, wd); -} - - -#endif /* _LINUX_INOTIFY_H */ diff --git a/src/3rdParty/efsw/platform/platformimpl.hpp b/src/3rdParty/efsw/platform/platformimpl.hpp deleted file mode 100644 index 54425806..00000000 --- a/src/3rdParty/efsw/platform/platformimpl.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef EFSW_PLATFORMIMPL_HPP -#define EFSW_PLATFORMIMPL_HPP - -#include - -#if defined( EFSW_PLATFORM_POSIX ) -#include -#include -#include -#include -#elif EFSW_PLATFORM == EFSW_PLATFORM_WIN32 -#include -#include -#include -#include -#else -#error Thread, Mutex, and System not implemented for this platform. -#endif - -#endif diff --git a/src/3rdParty/efsw/platform/posix/FileSystemImpl.cpp b/src/3rdParty/efsw/platform/posix/FileSystemImpl.cpp deleted file mode 100644 index 92eeb476..00000000 --- a/src/3rdParty/efsw/platform/posix/FileSystemImpl.cpp +++ /dev/null @@ -1,251 +0,0 @@ -#include - -#if defined( EFSW_PLATFORM_POSIX ) - -#include -#include -#include -#include -#include - -#ifndef _DARWIN_FEATURE_64_BIT_INODE -#define _DARWIN_FEATURE_64_BIT_INODE -#endif - -#ifndef _FILE_OFFSET_BITS -#define _FILE_OFFSET_BITS 64 -#endif - -#include -#include -#include - -#if EFSW_OS == EFSW_OS_LINUX || EFSW_OS == EFSW_OS_SOLARIS || EFSW_OS == EFSW_OS_ANDROID -#include -#elif EFSW_OS == EFSW_OS_MACOSX || EFSW_OS == EFSW_OS_BSD || EFSW_OS == EFSW_OS_IOS -#include -#include -#endif - -/** Remote file systems codes */ -#define S_MAGIC_AFS 0x5346414F -#define S_MAGIC_AUFS 0x61756673 -#define S_MAGIC_CEPH 0x00C36400 -#define S_MAGIC_CIFS 0xFF534D42 -#define S_MAGIC_CODA 0x73757245 -#define S_MAGIC_FHGFS 0x19830326 -#define S_MAGIC_FUSEBLK 0x65735546 -#define S_MAGIC_FUSECTL 0x65735543 -#define S_MAGIC_GFS 0x01161970 -#define S_MAGIC_GPFS 0x47504653 -#define S_MAGIC_KAFS 0x6B414653 -#define S_MAGIC_LUSTRE 0x0BD00BD0 -#define S_MAGIC_NCP 0x564C -#define S_MAGIC_NFS 0x6969 -#define S_MAGIC_NFSD 0x6E667364 -#define S_MAGIC_OCFS2 0x7461636F -#define S_MAGIC_PANFS 0xAAD7AAEA -#define S_MAGIC_PIPEFS 0x50495045 -#define S_MAGIC_SMB 0x517B -#define S_MAGIC_SNFS 0xBEEFDEAD -#define S_MAGIC_VMHGFS 0xBACBACBC -#define S_MAGIC_VXFS 0xA501FCF5 - -#if EFSW_OS == EFSW_OS_LINUX -#include -#include -#endif - -namespace efsw { namespace Platform { - -#if EFSW_OS == EFSW_OS_LINUX - -std::string findMountPoint( std::string file ) { - std::string cwd = FileSystem::getCurrentWorkingDirectory(); - struct stat last_stat; - struct stat file_stat; - - stat( file.c_str(), &file_stat ); - - std::string mp; - - if ( efsw::FileSystem::isDirectory( file ) ) { - last_stat = file_stat; - - if ( !FileSystem::changeWorkingDirectory( file ) ) - return ""; - } else { - std::string dir = efsw::FileSystem::pathRemoveFileName( file ); - - if ( !FileSystem::changeWorkingDirectory( dir ) ) - return ""; - - if ( stat( ".", &last_stat ) < 0 ) - return ""; - } - - while ( true ) { - struct stat st; - - 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( ".." ) ) { - goto done; - } - - last_stat = st; - } - - /* Finally reached a mount point, see what it's called. */ - mp = FileSystem::getCurrentWorkingDirectory(); - -done: - FileSystem::changeWorkingDirectory( cwd ); - - return mp; -} - -std::string findDevicePath( const std::string& directory ) { - struct mntent* ent; - FILE* aFile; - - aFile = setmntent( "/proc/mounts", "r" ); - - if ( aFile == NULL ) - return ""; - - while ( NULL != ( ent = getmntent( aFile ) ) ) { - std::string dirName( ent->mnt_dir ); - - if ( dirName == directory ) { - std::string fsName( ent->mnt_fsname ); - - endmntent( aFile ); - - return fsName; - } - } - - endmntent( aFile ); - - return ""; -} - -bool isLocalFUSEDirectory( std::string directory ) { - efsw::FileSystem::dirRemoveSlashAtEnd( directory ); - - directory = findMountPoint( directory ); - - if ( !directory.empty() ) { - std::string devicePath = findDevicePath( directory ); - - return !devicePath.empty(); - } - - return false; -} - -#endif - -bool FileSystem::changeWorkingDirectory( const std::string& path ) { - return -1 != chdir( path.c_str() ); -} - -std::string FileSystem::getCurrentWorkingDirectory() { - char dir[PATH_MAX + 1]; - char* result = getcwd( dir, PATH_MAX + 1 ); - return result != NULL ? std::string( result ) : std::string(); -} - -FileInfoMap FileSystem::filesInfoFromPath( const std::string& path ) { - FileInfoMap files; - - DIR* dp; - struct dirent* dirp; - - 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 ) { - std::string name( dirp->d_name ); - std::string fpath( path + name ); - - files[name] = FileInfo( fpath ); - } - } - - closedir( dp ); - - return files; -} - -char FileSystem::getOSSlash() { - return '/'; -} - -bool FileSystem::isDirectory( const std::string& path ) { - struct stat st; - int res = stat( path.c_str(), &st ); - - if ( 0 == res ) { - return static_cast( 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 - struct statfs statfsbuf; - - statfs( directory.c_str(), &statfsbuf ); - - switch ( statfsbuf.f_type | 0UL ) { - case S_MAGIC_FUSEBLK: /* 0x65735546 remote */ - { -#if EFSW_OS == EFSW_OS_LINUX - return !isLocalFUSEDirectory( directory ); -#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_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 */ - { - return true; - } - default: { - return false; - } - } -#endif - - return false; -} - -}} // namespace efsw::Platform - -#endif diff --git a/src/3rdParty/efsw/platform/posix/FileSystemImpl.hpp b/src/3rdParty/efsw/platform/posix/FileSystemImpl.hpp deleted file mode 100644 index 0bfba765..00000000 --- a/src/3rdParty/efsw/platform/posix/FileSystemImpl.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef EFSW_FILESYSTEMIMPLPOSIX_HPP -#define EFSW_FILESYSTEMIMPLPOSIX_HPP - -#include -#include - -#if defined( EFSW_PLATFORM_POSIX ) - -namespace efsw { namespace Platform { - -class FileSystem { - public: - static FileInfoMap filesInfoFromPath( const std::string& path ); - - static char getOSSlash(); - - static bool isDirectory( const std::string& path ); - - static bool isRemoteFS( const std::string& directory ); - - static bool changeWorkingDirectory( const std::string& path ); - - static std::string getCurrentWorkingDirectory(); -}; - -}} // namespace efsw::Platform - -#endif - -#endif diff --git a/src/3rdParty/efsw/platform/posix/MutexImpl.cpp b/src/3rdParty/efsw/platform/posix/MutexImpl.cpp deleted file mode 100644 index 22337982..00000000 --- a/src/3rdParty/efsw/platform/posix/MutexImpl.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include - -#if defined( EFSW_PLATFORM_POSIX ) - -namespace efsw { namespace Platform { - -MutexImpl::MutexImpl() { - pthread_mutexattr_t attributes; - pthread_mutexattr_init( &attributes ); - pthread_mutexattr_settype( &attributes, PTHREAD_MUTEX_RECURSIVE ); - pthread_mutex_init( &mMutex, &attributes ); -} - -MutexImpl::~MutexImpl() { - pthread_mutex_destroy( &mMutex ); -} - -void MutexImpl::lock() { - pthread_mutex_lock( &mMutex ); -} - -void MutexImpl::unlock() { - pthread_mutex_unlock( &mMutex ); -} - -}} // namespace efsw::Platform - -#endif diff --git a/src/3rdParty/efsw/platform/posix/MutexImpl.hpp b/src/3rdParty/efsw/platform/posix/MutexImpl.hpp deleted file mode 100644 index a33d8279..00000000 --- a/src/3rdParty/efsw/platform/posix/MutexImpl.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef EFSW_MUTEXIMPLPOSIX_HPP -#define EFSW_MUTEXIMPLPOSIX_HPP - -#include - -#if defined( EFSW_PLATFORM_POSIX ) - -#include - -namespace efsw { namespace Platform { - -class MutexImpl { - public: - MutexImpl(); - - ~MutexImpl(); - - void lock(); - - void unlock(); - - private: - pthread_mutex_t mMutex; -}; - -}} // namespace efsw::Platform - -#endif - -#endif diff --git a/src/3rdParty/efsw/platform/posix/SystemImpl.cpp b/src/3rdParty/efsw/platform/posix/SystemImpl.cpp deleted file mode 100644 index 37d4120e..00000000 --- a/src/3rdParty/efsw/platform/posix/SystemImpl.cpp +++ /dev/null @@ -1,168 +0,0 @@ -#include - -#if defined( EFSW_PLATFORM_POSIX ) - -#include -#include -#include -#include -#include - -#include -#include - -#if EFSW_OS == EFSW_OS_MACOSX -#include -#elif EFSW_OS == EFSW_OS_LINUX || EFSW_OS == EFSW_OS_ANDROID -#include -#include -#elif EFSW_OS == EFSW_OS_HAIKU -#include -#include -#elif EFSW_OS == EFSW_OS_SOLARIS -#include -#elif EFSW_OS == EFSW_OS_BSD -#include -#endif - -namespace efsw { namespace Platform { - -void System::sleep( const unsigned long& ms ) { - // usleep( static_cast( ms * 1000 ) ); - - // usleep is not reliable enough (it might block the - // whole process instead of just the current thread) - // so we must use pthread_cond_timedwait instead - - // this implementation is inspired from Qt - // and taken from SFML - - unsigned long long usecs = ms * 1000; - - // get the current time - timeval tv; - 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 %= 1000000000; - - // create a mutex and thread condition - pthread_mutex_t mutex; - pthread_mutex_init( &mutex, 0 ); - pthread_cond_t condition; - pthread_cond_init( &condition, 0 ); - - // wait... - pthread_mutex_lock( &mutex ); - pthread_cond_timedwait( &condition, &mutex, &ti ); - pthread_mutex_unlock( &mutex ); - - // destroy the mutex and condition - pthread_cond_destroy( &condition ); -} - -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 ( mainURL ) { - int ok = CFURLGetFileSystemRepresentation( mainURL, ( Boolean ) true, (UInt8*)exe_file, - FILENAME_MAX ); - - if ( ok ) { - return std::string( exe_file ) + "/"; - } - } - } - - return "./"; -#elif EFSW_OS == EFSW_OS_LINUX - char exe_file[FILENAME_MAX + 1]; - - int size; - - size = readlink( "/proc/self/exe", exe_file, FILENAME_MAX ); - - if ( size < 0 ) { - return std::string( "./" ); - } else { - exe_file[size] = '\0'; - return std::string( dirname( exe_file ) ) + "/"; - } - -#elif EFSW_OS == EFSW_OS_BSD - int mib[4]; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PATHNAME; - mib[3] = -1; - char buf[1024]; - size_t cb = sizeof( buf ); - sysctl( mib, 4, buf, &cb, NULL, 0 ); - - return FileSystem::pathRemoveFileName( std::string( buf ) ); - -#elif EFSW_OS == EFSW_OS_SOLARIS - return FileSystem::pathRemoveFileName( std::string( getexecname() ) ); - -#elif EFSW_OS == EFSW_OS_HAIKU - image_info info; - int32 cookie = 0; - - while ( B_OK == get_next_image_info( 0, &cookie, &info ) ) { - if ( info.type == B_APP_IMAGE ) - break; - } - - return FileSystem::pathRemoveFileName( std::string( info.name ) ); - -#elif EFSW_OS == EFSW_OS_ANDROID - return "/sdcard/"; - -#else -#warning getProcessPath() not implemented on this platform. ( will return "./" ) - return "./"; - -#endif -} - -void System::maxFD() { - static bool maxed = false; - - if ( !maxed ) { - struct rlimit limit; - getrlimit( RLIMIT_NOFILE, &limit ); - limit.rlim_cur = limit.rlim_max; - setrlimit( RLIMIT_NOFILE, &limit ); - - getrlimit( RLIMIT_NOFILE, &limit ); - - efDEBUG( "File descriptor limit %ld\n", limit.rlim_cur ); - - maxed = true; - } -} - -Uint64 System::getMaxFD() { - static rlim_t max_fd = 0; - - if ( max_fd == 0 ) { - struct rlimit limit; - getrlimit( RLIMIT_NOFILE, &limit ); - max_fd = limit.rlim_cur; - } - - return max_fd; -} - -}} // namespace efsw::Platform - -#endif diff --git a/src/3rdParty/efsw/platform/posix/SystemImpl.hpp b/src/3rdParty/efsw/platform/posix/SystemImpl.hpp deleted file mode 100644 index 9322b06c..00000000 --- a/src/3rdParty/efsw/platform/posix/SystemImpl.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef EFSW_SYSTEMIMPLPOSIX_HPP -#define EFSW_SYSTEMIMPLPOSIX_HPP - -#include - -#if defined( EFSW_PLATFORM_POSIX ) - -namespace efsw { namespace Platform { - -class System { - public: - static void sleep( const unsigned long& ms ); - - static std::string getProcessPath(); - - static void maxFD(); - - static Uint64 getMaxFD(); -}; - -}} // namespace efsw::Platform - -#endif - -#endif diff --git a/src/3rdParty/efsw/platform/posix/ThreadImpl.cpp b/src/3rdParty/efsw/platform/posix/ThreadImpl.cpp deleted file mode 100644 index 772fbc9b..00000000 --- a/src/3rdParty/efsw/platform/posix/ThreadImpl.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include - -#if defined( EFSW_PLATFORM_POSIX ) - -#include -#include - -namespace efsw { namespace Platform { - -ThreadImpl::ThreadImpl( efsw::Thread* owner ) : mIsActive( false ) { - mIsActive = pthread_create( &mThread, NULL, &ThreadImpl::entryPoint, owner ) == 0; - - if ( !mIsActive ) { - efDEBUG( "Failed to create thread\n" ); - } -} - -ThreadImpl::~ThreadImpl() { - terminate(); -} - -void ThreadImpl::wait() { - // Wait for the thread to finish, no timeout - if ( mIsActive ) { - assert( pthread_equal( pthread_self(), mThread ) == 0 ); - - 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 - - mIsActive = false; - } -} - -void* ThreadImpl::entryPoint( void* userData ) { -// 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( userData ); - - // Forward to the owner - owner->run(); - - return NULL; -} - -}} // namespace efsw::Platform - -#endif diff --git a/src/3rdParty/efsw/platform/posix/ThreadImpl.hpp b/src/3rdParty/efsw/platform/posix/ThreadImpl.hpp deleted file mode 100644 index 2e02f9ac..00000000 --- a/src/3rdParty/efsw/platform/posix/ThreadImpl.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef EFSW_THREADIMPLPOSIX_HPP -#define EFSW_THREADIMPLPOSIX_HPP - -#include - -#if defined( EFSW_PLATFORM_POSIX ) - -#include -#include - -namespace efsw { - -class Thread; - -namespace Platform { - -class ThreadImpl { - public: - explicit ThreadImpl( efsw::Thread* owner ); - - ~ThreadImpl(); - - void wait(); - - void terminate(); - - protected: - static void* entryPoint( void* userData ); - - pthread_t mThread; - Atomic mIsActive; -}; - -} // namespace Platform -} // namespace efsw - -#endif - -#endif diff --git a/src/3rdParty/efsw/platform/win/FileSystemImpl.cpp b/src/3rdParty/efsw/platform/win/FileSystemImpl.cpp deleted file mode 100644 index 2b875139..00000000 --- a/src/3rdParty/efsw/platform/win/FileSystemImpl.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32 - -#include -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include - -#ifndef EFSW_COMPILER_MSVC -#include -#else -#include -#endif - -namespace efsw { namespace Platform { - -bool FileSystem::changeWorkingDirectory( const std::string& path ) { - int res; -#ifdef EFSW_COMPILER_MSVC -#ifdef UNICODE - res = _wchdir( String::fromUtf8( path.c_str() ).toWideString().c_str() ); -#else - res = _chdir( String::fromUtf8( path.c_str() ).toAnsiString().c_str() ); -#endif -#else - res = chdir( path.c_str() ); -#endif - return -1 != res; -} - -std::string FileSystem::getCurrentWorkingDirectory() { -#ifdef EFSW_COMPILER_MSVC -#if defined( UNICODE ) && !defined( EFSW_NO_WIDECHAR ) - wchar_t dir[_MAX_PATH]; - return ( 0 != GetCurrentDirectoryW( _MAX_PATH, dir ) ) ? String( dir ).toUtf8() : std::string(); -#else - char dir[_MAX_PATH]; - 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 ); - return std::string( dir ); -#endif -} - -FileInfoMap FileSystem::filesInfoFromPath( const std::string& path ) { - FileInfoMap files; - - String tpath( path ); - - if ( tpath[tpath.size() - 1] == '/' || tpath[tpath.size() - 1] == '\\' ) { - tpath += "*"; - } else { - tpath += "\\*"; - } - - WIN32_FIND_DATAW findFileData; - HANDLE hFind = FindFirstFileW( (LPCWSTR)tpath.toWideString().c_str(), &findFileData ); - - if ( hFind != INVALID_HANDLE_VALUE ) { - std::string name( String( findFileData.cFileName ).toUtf8() ); - std::string fpath( path + name ); - - if ( name != "." && name != ".." ) { - files[name] = FileInfo( fpath ); - } - - while ( FindNextFileW( hFind, &findFileData ) ) { - name = String( findFileData.cFileName ).toUtf8(); - fpath = path + name; - - if ( name != "." && name != ".." ) { - files[name] = FileInfo( fpath ); - } - } - - FindClose( hFind ); - } - - return files; -} - -char FileSystem::getOSSlash() { - return '\\'; -} - -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] == '/' ) ) { - return true; - } - - if ( directory.size() >= 3 ) { - return 4 == GetDriveTypeA( directory.substr( 0, 3 ).c_str() ); - } - - return false; -} - -}} // namespace efsw::Platform - -#endif diff --git a/src/3rdParty/efsw/platform/win/FileSystemImpl.hpp b/src/3rdParty/efsw/platform/win/FileSystemImpl.hpp deleted file mode 100644 index e952efce..00000000 --- a/src/3rdParty/efsw/platform/win/FileSystemImpl.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef EFSW_FILESYSTEMIMPLWIN_HPP -#define EFSW_FILESYSTEMIMPLWIN_HPP - -#include -#include -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32 - -namespace efsw { namespace Platform { - -class FileSystem { - public: - static FileInfoMap filesInfoFromPath( const std::string& path ); - - static char getOSSlash(); - - static bool isDirectory( const std::string& path ); - - static bool isRemoteFS( const std::string& directory ); - - static bool changeWorkingDirectory( const std::string& path ); - - static std::string getCurrentWorkingDirectory(); -}; - -}} // namespace efsw::Platform - -#endif - -#endif diff --git a/src/3rdParty/efsw/platform/win/MutexImpl.cpp b/src/3rdParty/efsw/platform/win/MutexImpl.cpp deleted file mode 100644 index 62b7f836..00000000 --- a/src/3rdParty/efsw/platform/win/MutexImpl.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32 - -namespace efsw { namespace Platform { - -MutexImpl::MutexImpl() { - InitializeCriticalSection( &mMutex ); -} - -MutexImpl::~MutexImpl() { - DeleteCriticalSection( &mMutex ); -} - -void MutexImpl::lock() { - EnterCriticalSection( &mMutex ); -} - -void MutexImpl::unlock() { - LeaveCriticalSection( &mMutex ); -} - -}} // namespace efsw::Platform - -#endif diff --git a/src/3rdParty/efsw/platform/win/MutexImpl.hpp b/src/3rdParty/efsw/platform/win/MutexImpl.hpp deleted file mode 100644 index 7b064920..00000000 --- a/src/3rdParty/efsw/platform/win/MutexImpl.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef EFSW_MUTEXIMPLWIN_HPP -#define EFSW_MUTEXIMPLWIN_HPP - -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32 - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include - -namespace efsw { namespace Platform { - -class MutexImpl { - public: - MutexImpl(); - - ~MutexImpl(); - - void lock(); - - void unlock(); - - private: - CRITICAL_SECTION mMutex; -}; - -}} // namespace efsw::Platform - -#endif - -#endif diff --git a/src/3rdParty/efsw/platform/win/SystemImpl.cpp b/src/3rdParty/efsw/platform/win/SystemImpl.cpp deleted file mode 100644 index d1f2b21a..00000000 --- a/src/3rdParty/efsw/platform/win/SystemImpl.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32 - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#include - -namespace efsw { namespace Platform { - -void System::sleep( const unsigned long& ms ) { - ::Sleep( ms ); -} - -std::string System::getProcessPath() { - // Get path to executable: - WCHAR szDrive[_MAX_DRIVE]; - WCHAR szDir[_MAX_DIR]; - WCHAR szFilename[_MAX_DIR]; - WCHAR szExt[_MAX_DIR]; - std::wstring dllName( _MAX_DIR, 0 ); - - 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 - - return String( szDrive ).toUtf8() + String( szDir ).toUtf8(); -} - -void System::maxFD() {} - -Uint64 System::getMaxFD() { // Number of ReadDirectory per thread - return 60; -} - -}} // namespace efsw::Platform - -#endif diff --git a/src/3rdParty/efsw/platform/win/SystemImpl.hpp b/src/3rdParty/efsw/platform/win/SystemImpl.hpp deleted file mode 100644 index 99b48675..00000000 --- a/src/3rdParty/efsw/platform/win/SystemImpl.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef EFSW_SYSTEMIMPLWIN_HPP -#define EFSW_SYSTEMIMPLWIN_HPP - -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32 - -namespace efsw { namespace Platform { - -class System { - public: - static void sleep( const unsigned long& ms ); - - static std::string getProcessPath(); - - static void maxFD(); - - static Uint64 getMaxFD(); -}; - -}} // namespace efsw::Platform - -#endif - -#endif diff --git a/src/3rdParty/efsw/platform/win/ThreadImpl.cpp b/src/3rdParty/efsw/platform/win/ThreadImpl.cpp deleted file mode 100644 index 463934c9..00000000 --- a/src/3rdParty/efsw/platform/win/ThreadImpl.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32 - -#include - -namespace efsw { namespace Platform { - -ThreadImpl::ThreadImpl( efsw::Thread* owner ) { - mThread = reinterpret_cast( - _beginthreadex( NULL, 0, &ThreadImpl::entryPoint, owner, 0, &mThreadId ) ); - - if ( !mThread ) { - efDEBUG( "Failed to create thread\n" ); - } -} - -ThreadImpl::~ThreadImpl() { - if ( mThread ) { - CloseHandle( mThread ); - } -} - -void ThreadImpl::wait() { - // Wait for the thread to finish, no timeout - if ( mThread ) { - assert( mThreadId != GetCurrentThreadId() ); // A thread cannot wait for itself! - - WaitForSingleObject( mThread, INFINITE ); - } -} - -void ThreadImpl::terminate() { - if ( mThread ) { - TerminateThread( mThread, 0 ); - } -} - -unsigned int __stdcall ThreadImpl::entryPoint( void* userData ) { - // The Thread instance is stored in the user data - Thread* owner = static_cast( userData ); - - // Forward to the owner - owner->run(); - - // Optional, but it is cleaner - _endthreadex( 0 ); - - return 0; -} - -}} // namespace efsw::Platform - -#endif diff --git a/src/3rdParty/efsw/platform/win/ThreadImpl.hpp b/src/3rdParty/efsw/platform/win/ThreadImpl.hpp deleted file mode 100644 index 455f24c2..00000000 --- a/src/3rdParty/efsw/platform/win/ThreadImpl.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef EFSW_THREADIMPLWIN_HPP -#define EFSW_THREADIMPLWIN_HPP - -#include - -#if EFSW_PLATFORM == EFSW_PLATFORM_WIN32 - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#include - -namespace efsw { - -class Thread; - -namespace Platform { - -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 - -#endif diff --git a/src/3rdParty/efsw/sophist.h b/src/3rdParty/efsw/sophist.h deleted file mode 100644 index 82e5c362..00000000 --- a/src/3rdParty/efsw/sophist.h +++ /dev/null @@ -1,147 +0,0 @@ -/* sophist.h - 0.3 - public domain - Sean Barrett 2010 -** Knowledge drawn from Brian Hook's posh.h and http://predef.sourceforge.net -** Sophist provides portable types; you typedef/#define them to your own names -** -** defines: -** - SOPHIST_endian - either SOPHIST_little_endian or SOPHIST_big_endian -** - SOPHIST_has_64 - either 0 or 1; if 0, int64 types aren't defined -** - SOPHIST_pointer64 - either 0 or 1; if 1, pointer is 64-bit -** -** - SOPHIST_intptr, SOPHIST_uintptr - integer same size as pointer -** - SOPHIST_int8, SOPHIST_uint8, SOPHIST_int16, SOPHIST_uint16 -** - SOPHIST_int32, SOPHIST_uint32, SOPHIST_int64, SOPHIST_uint64 -** - SOPHIST_int64_constant(number) - macros for creating 64-bit -** - SOPHIST_uint64_constant(number) integer constants -** - SOPHIST_printf_format64 - string for printf format for int64 -*/ - -#ifndef __INCLUDE_SOPHIST_H__ -#define __INCLUDE_SOPHIST_H__ - -#define SOPHIST_compiletime_assert(name,val) \ - typedef int SOPHIST__assert##name[(val) ? 1 : -1] - -/* define a couple synthetic rules to make code more readable */ -#if (defined(__sparc__) || defined(__sparc)) && \ - (defined(__arch64__) || defined(__sparcv9) || defined(__sparc_v9__)) - #define SOPHIST_sparc64 -#endif - -#if (defined(linux) || defined(__linux__)) && \ - (defined(__alpha)||defined(__alpha__)||defined(__x86_64__)||defined(_M_X64)) - #define SOPHIST_linux64 -#endif - -/* basic types */ -typedef signed char SOPHIST_int8; -typedef unsigned char SOPHIST_uint8; - -typedef signed short SOPHIST_int16; -typedef unsigned short SOPHIST_uint16; - -#ifdef __palmos__ - typedef signed long SOPHIST_int32; - typedef unsigned long SOPHIST_uint32; -#else - typedef signed int SOPHIST_int32; - typedef unsigned int SOPHIST_uint32; -#endif - -#ifndef SOPHIST_NO_64 - #if defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__) \ - || (defined(__alpha) && defined(__DECC)) - - typedef signed __int64 SOPHIST_int64; - typedef unsigned __int64 SOPHIST_uint64; - #define SOPHIST_has_64 1 - #define SOPHIST_int64_constant(x) (x##i64) - #define SOPHIST_uint64_constant(x) (x##ui64) - #define SOPHIST_printf_format64 "I64" - - #elif defined(__LP64__) || defined(__powerpc64__) || defined(SOPHIST_sparc64) - - typedef signed long SOPHIST_int64; - typedef unsigned long SOPHIST_uint64; - - #define SOPHIST_has_64 1 - #define SOPHIST_int64_constant(x) ((SOPHIST_int64) x) - #define SOPHIST_uint64_constant(x) ((SOPHIST_uint64) x) - #define SOPHIST_printf_format64 "l" - - #elif defined(_LONG_LONG) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) \ - || defined(__GNUC__) || defined(__MWERKS__) || defined(__APPLE_CC__) \ - || defined(sgi) || defined (__sgi) || defined(__sgi__) \ - || defined(_CRAYC) - - typedef signed long long SOPHIST_int64; - typedef unsigned long long SOPHIST_uint64; - - #define SOPHIST_has_64 1 - #define SOPHIST_int64_constant(x) (x##LL) - #define SOPHIST_uint64_constant(x) (x##ULL) - #define SOPHIST_printf_format64 "ll" - #endif -#endif - -#ifndef SOPHIST_has_64 -#define SOPHIST_has_64 0 -#endif - -SOPHIST_compiletime_assert( int8 , sizeof(SOPHIST_int8 ) == 1); -SOPHIST_compiletime_assert(uint16, sizeof(SOPHIST_int16) == 2); -SOPHIST_compiletime_assert( int32, sizeof(SOPHIST_int32 ) == 4); -SOPHIST_compiletime_assert(uint32, sizeof(SOPHIST_uint32) == 4); - -#if SOPHIST_has_64 - SOPHIST_compiletime_assert( int64, sizeof(SOPHIST_int64 ) == 8); - SOPHIST_compiletime_assert(uint64, sizeof(SOPHIST_uint64) == 8); -#endif - -/* determine whether pointers are 64-bit */ - -#if defined(SOPHIST_linux64) || defined(SOPHIST_sparc64) \ - || defined(__osf__) || (defined(_WIN64) && !defined(_XBOX)) \ - || defined(__64BIT__) \ - || defined(__LP64) || defined(__LP64__) || defined(_LP64) \ - || defined(_ADDR64) || defined(_CRAYC) \ - - #define SOPHIST_pointer64 1 - - SOPHIST_compiletime_assert(pointer64, sizeof(void*) == 8); - - typedef SOPHIST_int64 SOPHIST_intptr; - typedef SOPHIST_uint64 SOPHIST_uintptr; -#else - - #define SOPHIST_pointer64 0 - - SOPHIST_compiletime_assert(pointer64, sizeof(void*) <= 4); - - /* do we care about pointers that are only 16-bit? */ - typedef SOPHIST_int32 SOPHIST_intptr; - typedef SOPHIST_uint32 SOPHIST_uintptr; - -#endif - -SOPHIST_compiletime_assert(intptr, sizeof(SOPHIST_intptr) == sizeof(char *)); - -/* enumerate known little endian cases; fallback to big-endian */ - -#define SOPHIST_little_endian 1 -#define SOPHIST_big_endian 2 - -#if defined(__386__) || defined(i386) || defined(__i386__) \ - || defined(__X86) || defined(_M_IX86) \ - || defined(_M_X64) || defined(__x86_64__) \ - || defined(alpha) || defined(__alpha) || defined(__alpha__) \ - || defined(_M_ALPHA) \ - || defined(ARM) || defined(_ARM) || defined(__arm__) \ - || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) \ - || defined(_WIN32_WCE) || defined(__NT__) \ - || defined(__MIPSEL__) - #define SOPHIST_endian SOPHIST_little_endian -#else - #define SOPHIST_endian SOPHIST_big_endian -#endif - -#endif /* __INCLUDE_SOPHIST_H__ */