Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+31
@@ -0,0 +1,31 @@
|
||||
SET(xdr_dh_SRCS
|
||||
XDR_DirHandler.cpp
|
||||
XDR_DirHandler_ifc.cpp
|
||||
)
|
||||
SET(xdr_dh_HDRS
|
||||
XDR_DirHandler.h
|
||||
XDR_DirHandler_ifc.h
|
||||
)
|
||||
IF(WIN32)
|
||||
LIST(APPEND xdr_dh_SRCS
|
||||
XDR_DirHandler_win.cpp
|
||||
)
|
||||
LIST(APPEND xdr_dh_HDRS
|
||||
XDR_DirHandler_win.h
|
||||
)
|
||||
ELSE(WIN32)
|
||||
LIST(APPEND xdr_dh_SRCS
|
||||
XDR_DirHandler_linux.cpp
|
||||
)
|
||||
LIST(APPEND xdr_dh_HDRS
|
||||
XDR_DirHandler_linux.h
|
||||
)
|
||||
ENDIF(WIN32)
|
||||
NGL_ADD_LIBRARY(AAR SV xdr_qthandler_dir SHARED ${xdr_dh_SRCS} ${xdr_dh_HDRS})
|
||||
NGL_TARGET_LINK_LIBRARIES(xdr_qthandler_dir
|
||||
PRIVATE
|
||||
NGLLogger
|
||||
PUBLIC
|
||||
Qt5::Core
|
||||
)
|
||||
NGL_INSTALL_TARGET(xdr_qthandler_dir)
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Scan directory for new XDR files
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include "XDR_DirHandler.h"
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QThread>
|
||||
|
||||
#ifdef WIN32
|
||||
#include "XDR_DirHandler_win.h"
|
||||
#else
|
||||
#include "XDR_DirHandler_linux.h"
|
||||
#endif
|
||||
|
||||
XDR_DirHandler::XDR_DirHandler(const QString &dirToWatch, bool startWatching, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_workerThread(new QThread)
|
||||
, m_workerObject(nullptr)
|
||||
, m_startWatching(startWatching)
|
||||
, m_dirToWatch(dirToWatch)
|
||||
{
|
||||
#ifdef WIN32
|
||||
m_workerObject = new XDR_DirHandlerWin(dirToWatch);
|
||||
#else
|
||||
m_workerObject = new XDR_DirHandlerLinux(dirToWatch);
|
||||
#endif
|
||||
m_workerThread->start();
|
||||
m_workerObject->moveToThread(m_workerThread);
|
||||
connect(m_workerObject, &XDR_DirHandlerIfc::newTelegramArrived,
|
||||
this, &XDR_DirHandler::newTelegramArrived);
|
||||
connect(m_workerThread, &QThread::finished,
|
||||
m_workerObject, &XDR_DirHandlerIfc::deleteLater);
|
||||
if (startWatching)
|
||||
QTimer::singleShot(0, m_workerObject, &XDR_DirHandlerIfc::startWatching);
|
||||
}
|
||||
|
||||
XDR_DirHandler::~XDR_DirHandler()
|
||||
{
|
||||
m_workerThread->requestInterruption();
|
||||
m_workerThread->quit();
|
||||
if (!m_workerThread->wait(10000))
|
||||
m_workerThread->terminate();
|
||||
delete m_workerThread;
|
||||
}
|
||||
|
||||
void XDR_DirHandler::startWatching()
|
||||
{
|
||||
if (!m_startWatching)
|
||||
{
|
||||
QTimer::singleShot(0, m_workerObject, &XDR_DirHandlerIfc::startWatching);
|
||||
m_startWatching = true;
|
||||
}
|
||||
}
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Scan directory for new XDR files
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QString>
|
||||
|
||||
#ifndef XDR_QTHANDLER_DIR_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define XDR_QTHANDLER_DIR_EXPORT
|
||||
# else
|
||||
# ifdef MAKE_XDR_QTHANDLER_DIR_LIB
|
||||
# define XDR_QTHANDLER_DIR_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define XDR_QTHANDLER_DIR_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
class XDR_DirHandlerIfc;
|
||||
class XDR_QTHANDLER_DIR_EXPORT XDR_DirHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
XDR_DirHandler(const QString &dirToWatch, bool startWatching = true, QObject *parent = nullptr);
|
||||
~XDR_DirHandler();
|
||||
|
||||
void startWatching();
|
||||
QString dirToWatch() const { return m_dirToWatch; }
|
||||
|
||||
protected Q_SLOTS:
|
||||
virtual void newTelegramArrived(const QString &fullPath) = 0;
|
||||
private:
|
||||
QThread *m_workerThread;
|
||||
XDR_DirHandlerIfc *m_workerObject;
|
||||
bool m_startWatching;
|
||||
QString m_dirToWatch;
|
||||
};
|
||||
|
||||
class XDR_QTHANDLER_DIR_EXPORT XDR_DirHandler_emit : public XDR_DirHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
XDR_DirHandler_emit(const QString &dirToWatch, QObject *parent = nullptr)
|
||||
: XDR_DirHandler(dirToWatch, true, parent)
|
||||
{}
|
||||
~XDR_DirHandler_emit()
|
||||
{}
|
||||
protected:
|
||||
virtual void newTelegramArrived(const QString &fullPath)
|
||||
{
|
||||
emit newTelegram(fullPath);
|
||||
}
|
||||
|
||||
Q_SIGNALS:
|
||||
void newTelegram(const QString &fullPath);
|
||||
};
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Scan directory for new XDR files - internal interfacefor OS abstraction
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include "XDR_DirHandler_ifc.h"
|
||||
|
||||
XDR_DirHandlerIfc::XDR_DirHandlerIfc(const QString &dirToWatch, QObject *parent)
|
||||
: QObject(parent)
|
||||
, mDirToWatchBA(dirToWatch.toLocal8Bit())
|
||||
, mDirToWatch(dirToWatch)
|
||||
{
|
||||
if (!mDirToWatch.endsWith(QLatin1Char('/')))
|
||||
mDirToWatch += QLatin1Char('/');
|
||||
if (!mDirToWatchBA.endsWith('/'))
|
||||
mDirToWatchBA += '/';
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Scan directory for new XDR files - internal interfacefor OS abstraction
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
|
||||
class XDR_DirHandlerIfc : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
XDR_DirHandlerIfc(const QString &dirToWatch, QObject *parent = nullptr);
|
||||
|
||||
public Q_SLOTS:
|
||||
virtual void startWatching() = 0;
|
||||
Q_SIGNALS:
|
||||
void newTelegramArrived(const QString &fullPath);
|
||||
protected:
|
||||
QByteArray mDirToWatchBA;
|
||||
QString mDirToWatch;
|
||||
};
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
/**
|
||||
* Scan directory for new XDR files - windows specific implementation
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include "XDR_DirHandler_linux.h"
|
||||
|
||||
#include <QMap>
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
#include <QVarLengthArray>
|
||||
|
||||
#include <poll.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void XDR_DirHandlerLinux::startWatching()
|
||||
{
|
||||
onScanDirectory();
|
||||
startEPoll();
|
||||
}
|
||||
|
||||
void XDR_DirHandlerLinux::onScanDirectory()
|
||||
{
|
||||
QByteArray nameBA;
|
||||
nameBA.reserve(128);
|
||||
|
||||
QVarLengthArray<char, 512> tmpFilename;
|
||||
const int tmpFilenameOffset = mDirToWatchBA.size();
|
||||
tmpFilename.clear();
|
||||
tmpFilename.append(mDirToWatchBA.data(), mDirToWatchBA.size());
|
||||
|
||||
// Verzeichnis oeffnen
|
||||
DIR *dirp = opendir(mDirToWatchBA.constData());
|
||||
|
||||
if(!dirp)
|
||||
return;
|
||||
|
||||
// Schleife ueber alle Files
|
||||
dirent* entry;
|
||||
while ((entry = readdir(dirp)) != nullptr) {
|
||||
const char *name = entry->d_name;
|
||||
// skip directories
|
||||
size_t len = strlen(name);
|
||||
// skip "."
|
||||
if( len == 1 && name[0] == '.' )
|
||||
continue;
|
||||
// skip ".."
|
||||
if( len == 2 && name[0] == '.' && name[1] == '.' )
|
||||
continue;
|
||||
|
||||
if(len > 4) {
|
||||
size_t pos = len - 4;
|
||||
if( name[pos] == '.' &&
|
||||
tolower(name[pos+1]) == 't' &&
|
||||
tolower(name[pos+2]) == 'm' &&
|
||||
tolower(name[pos+3]) == 'p')
|
||||
continue;
|
||||
}
|
||||
|
||||
// ist es ein Verzeichnis?
|
||||
struct stat st;
|
||||
tmpFilename.resize(tmpFilenameOffset);
|
||||
tmpFilename.append(name, len);
|
||||
tmpFilename.append('\0');
|
||||
int res = stat(tmpFilename.constData(), &st);
|
||||
if (res || S_ISDIR(st.st_mode) ) {
|
||||
// Unterverzeichnis
|
||||
continue;
|
||||
}
|
||||
|
||||
// einfuegen
|
||||
nameBA.clear();
|
||||
nameBA.append(name, len);
|
||||
m_newFilesMap.insert(nameBA, 1);
|
||||
}
|
||||
closedir(dirp);
|
||||
|
||||
// map is sorted by key, we don't care about value
|
||||
QMap<QByteArray, int>::ConstIterator it = m_newFilesMap.constBegin();
|
||||
QMap<QByteArray, int>::ConstIterator end = m_newFilesMap.constEnd();
|
||||
for( ; it != end; ++it)
|
||||
{
|
||||
emit newTelegramArrived(mDirToWatch + QString::fromLocal8Bit(it.key()));
|
||||
}
|
||||
QTimer::singleShot(5000, this, &XDR_DirHandlerLinux::clearNewFilesMap);
|
||||
}
|
||||
|
||||
void XDR_DirHandlerLinux::clearNewFilesMap()
|
||||
{
|
||||
m_newFilesMap.clear();
|
||||
}
|
||||
|
||||
#if 0
|
||||
// fuer debug-Zwecke
|
||||
static void /* Display information from inotify_event structure */
|
||||
displayInotifyEvent(const inotify_event *i)
|
||||
{
|
||||
printf(" wd =%2d; ", i->wd);
|
||||
if (i->cookie > 0)
|
||||
printf("cookie =%4d; ", i->cookie);
|
||||
|
||||
printf("mask = ");
|
||||
if (i->mask & IN_ACCESS) printf("IN_ACCESS ");
|
||||
if (i->mask & IN_ATTRIB) printf("IN_ATTRIB ");
|
||||
if (i->mask & IN_CLOSE_NOWRITE) printf("IN_CLOSE_NOWRITE ");
|
||||
if (i->mask & IN_CLOSE_WRITE) printf("IN_CLOSE_WRITE ");
|
||||
if (i->mask & IN_CREATE) printf("IN_CREATE ");
|
||||
if (i->mask & IN_DELETE) printf("IN_DELETE ");
|
||||
if (i->mask & IN_DELETE_SELF) printf("IN_DELETE_SELF ");
|
||||
if (i->mask & IN_IGNORED) printf("IN_IGNORED ");
|
||||
if (i->mask & IN_ISDIR) printf("IN_ISDIR ");
|
||||
if (i->mask & IN_MODIFY) printf("IN_MODIFY ");
|
||||
if (i->mask & IN_MOVE_SELF) printf("IN_MOVE_SELF ");
|
||||
if (i->mask & IN_MOVED_FROM) printf("IN_MOVED_FROM ");
|
||||
if (i->mask & IN_MOVED_TO) printf("IN_MOVED_TO ");
|
||||
if (i->mask & IN_OPEN) printf("IN_OPEN ");
|
||||
if (i->mask & IN_Q_OVERFLOW) printf("IN_Q_OVERFLOW ");
|
||||
if (i->mask & IN_UNMOUNT) printf("IN_UNMOUNT ");
|
||||
printf("\n");
|
||||
|
||||
if (i->len > 0)
|
||||
printf(" name = %s\n", i->name);
|
||||
}
|
||||
#endif
|
||||
|
||||
void XDR_DirHandlerLinux::startEPoll()
|
||||
{
|
||||
int inotifyFd = inotify_init();
|
||||
if (inotifyFd != -1) {
|
||||
// Entweder wenn foo.tmp nach foo verschoben wird oder
|
||||
// wenn eine Datei geschlossen wird (inklusive Schreibvorgang vorher)
|
||||
// d.h. wir würden das umbenennen von foo.tmp nach foo gar nicht mehr benoetigen
|
||||
int wd = inotify_add_watch(inotifyFd, mDirToWatchBA.constData(), IN_MOVED_TO|IN_CLOSE_WRITE);
|
||||
if (wd != -1) {
|
||||
Q_FOREVER {
|
||||
if (QThread::currentThread()->isInterruptionRequested())
|
||||
break;
|
||||
struct pollfd fds[1];
|
||||
memset(fds, 0, sizeof(fds));
|
||||
fds[0].fd = inotifyFd;
|
||||
fds[0].events = POLLIN | POLLPRI;
|
||||
constexpr int timeout_msecs = 5;
|
||||
int ret = poll(fds, 1, timeout_msecs);
|
||||
if (ret > 0) {
|
||||
static const int BUF_LEN = (10 * (sizeof(struct inotify_event) + NAME_MAX + 1));
|
||||
char buf[BUF_LEN] __attribute__ ((aligned(8)));
|
||||
int numRead = read(inotifyFd, buf, BUF_LEN);
|
||||
if(numRead <= 0)
|
||||
break;
|
||||
|
||||
for (const char *p = buf; p < buf + numRead; ) {
|
||||
const inotify_event *event = reinterpret_cast<const inotify_event *>(p);
|
||||
//displayInotifyEvent(event);
|
||||
handleInotifyEvents(event);
|
||||
|
||||
p += sizeof(struct inotify_event) + event->len;
|
||||
}
|
||||
}
|
||||
}
|
||||
close(wd);
|
||||
}
|
||||
close(inotifyFd);
|
||||
}
|
||||
}
|
||||
|
||||
void XDR_DirHandlerLinux::handleInotifyEvents(const inotify_event *entry)
|
||||
{
|
||||
// wir gehen davon aus, dass wir nur IN_CLOSE_WRITE und IN_MOVED_TO
|
||||
// bekommen so wie wir es auch aboniert haben.
|
||||
|
||||
// skip directories
|
||||
if((entry->mask & IN_ISDIR) == IN_ISDIR)
|
||||
return;
|
||||
|
||||
const char *name = entry->name;
|
||||
const size_t len = strlen(name); // entry->len contains the length including \0 and padding bytes!
|
||||
if (len > 4) {
|
||||
size_t pos = len - 4;
|
||||
if( name[pos] == '.' &&
|
||||
tolower(name[pos+1]) == 't' &&
|
||||
tolower(name[pos+2]) == 'm' &&
|
||||
tolower(name[pos+3]) == 'p') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_newFilesMap.isEmpty()) {
|
||||
if (m_newFilesMap.contains(QByteArray::fromRawData(name, len)))
|
||||
return;
|
||||
}
|
||||
|
||||
emit newTelegramArrived(mDirToWatch + QString::fromLocal8Bit(name));
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Scan directory for new XDR files - windows specific implementation
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "XDR_DirHandler_ifc.h"
|
||||
#include <QMap>
|
||||
|
||||
struct inotify_event;
|
||||
|
||||
class XDR_DirHandlerLinux final : public XDR_DirHandlerIfc
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using XDR_DirHandlerIfc::XDR_DirHandlerIfc;
|
||||
private Q_SLOTS:
|
||||
void onScanDirectory();
|
||||
void startWatching();
|
||||
void startEPoll();
|
||||
void clearNewFilesMap();
|
||||
private:
|
||||
void handleInotifyEvents(const inotify_event *entry);
|
||||
private:
|
||||
QMap<QByteArray, int> m_newFilesMap; // fuer initiales lesen
|
||||
};
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Scan directory for new XDR files - windows specific implementation
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include "XDR_DirHandler_win.h"
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QVarLengthArray>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
void XDR_DirHandlerWin::startWatching()
|
||||
{
|
||||
onScanDirectory();
|
||||
}
|
||||
|
||||
void XDR_DirHandlerWin::onScanDirectory()
|
||||
{
|
||||
QString lastFilename = mLastFilename;
|
||||
QMap<QString, int> newFilesMap;
|
||||
|
||||
// Verzeichnis oeffnen
|
||||
WIN32_FIND_DATA findData;
|
||||
HANDLE dirp = FindFirstFile(reinterpret_cast<LPCWSTR>(mDirToWatch.utf16()), &findData);
|
||||
|
||||
while(dirp != INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
|
||||
// Schleife ueber alle Files
|
||||
do {
|
||||
// skip directories
|
||||
if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
if (FindNextFile(dirp, &findData) == 0)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
const TCHAR *name = findData.cFileName;
|
||||
const size_t len = wcslen(name);
|
||||
if(len > 4) {
|
||||
size_t pos = len - 4;
|
||||
if( name[pos] == '.' &&
|
||||
_totlower(name[pos+1]) == 't' &&
|
||||
_totlower(name[pos+2]) == 'm' &&
|
||||
_totlower(name[pos+3]) == 'p')
|
||||
continue;
|
||||
}
|
||||
|
||||
// hatten wir schon ?
|
||||
const QString nameStr = QString::fromUtf16(reinterpret_cast<const ushort*>(name), len);
|
||||
if ( mLastFilename.size() && nameStr <= mLastFilename )
|
||||
continue;
|
||||
if (nameStr > lastFilename)
|
||||
lastFilename = nameStr;
|
||||
|
||||
// einfuegen
|
||||
newFilesMap.insert(nameStr, 1);
|
||||
} while (FindNextFile(dirp, &findData) != 0);
|
||||
FindClose(dirp);
|
||||
mLastFilename = lastFilename;
|
||||
|
||||
// map is sorted by key, we don't care about value
|
||||
QMap<QString, int>::ConstIterator it = newFilesMap.constBegin();
|
||||
QMap<QString, int>::ConstIterator end = newFilesMap.constEnd();
|
||||
for( ; it != end; ++it)
|
||||
emit newTelegramArrived(mDirToWatch + it.key());
|
||||
|
||||
// Alle 200 msec lesen
|
||||
QTimer::singleShot(200, this, &XDR_DirHandlerWin::onScanDirectory);
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Scan directory for new XDR files - windows specific implementation
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "XDR_DirHandler_ifc.h"
|
||||
|
||||
class XDR_DirHandlerWin : public XDR_DirHandlerIfc
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using XDR_DirHandlerIfc::XDR_DirHandlerIfc;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onScanDirectory();
|
||||
void startWatching();
|
||||
private:
|
||||
QString mLastFilename;
|
||||
};
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Export definitions
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#ifndef XDR_QTHANDLER_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define XDR_QTHANDLER_EXPORT
|
||||
# else
|
||||
# if defined(MAKE_XDR_QTHANDLER_LIB)
|
||||
# define XDR_QTHANDLER_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define XDR_QTHANDLER_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
Reference in new issue
Block a user