#include <efsw/FileWatcherGeneric.hpp>
|
#include <efsw/FileSystem.hpp>
|
#include <efsw/System.hpp>
|
#include <efsw/Lock.hpp>
|
|
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)
|
{
|
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::list<std::string> FileWatcherGeneric::directories()
|
{
|
std::list<std::string> dirs;
|
|
Lock lock( mWatchesLock );
|
|
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;
|
}
|
|
}
|