Adds q2 repos to migrate

This commit is contained in:
torsten committed 2026-07-14 12:07:36 +02:00
1 parent ad1f62c4ee
commit 17f1c61c9e
991 files changed
+178451

No files matched your search

+17
View File
@@ -0,0 +1,17 @@
#
# $Id$
# $HeadURL$
# $Author$
#
ADD_SUBDIRECTORY(ngldb)
ADD_SUBDIRECTORY(tcpserver)
ADD_SUBDIRECTORY(QtSingleApplication)
ADD_SUBDIRECTORY(WMS_Interface)
ADD_SUBDIRECTORY(nglapplication)
ADD_SUBDIRECTORY(nglcompression)
ADD_SUBDIRECTORY(nglsettings)
ADD_SUBDIRECTORY(ngltranslator)
ADD_SUBDIRECTORY(ngltools)
ADD_SUBDIRECTORY(nglwidgets)
ADD_SUBDIRECTORY(NGLLogger)
+50
View File
@@ -0,0 +1,50 @@
FIND_PACKAGE(Log4Qt REQUIRED)
# Sourcen
SET(NGLLogger_SRCS
MurmurHash2.cpp
MurmurHash2.h
INGLLogger.h
NGLLogger_export.h
NGLLoggerBootstrap.cpp
NGLLoggerBootstrap.h
NGLLogger.cpp
NGLLogger.h
)
# Header
SET(NGLLogger_HDRS
)
# Make sure NGLLogger.h compiles ..
ADD_DEFINITIONS(-DBUILDING_NGLLOGGER)
NGL_ADD_LIBRARY(ALL NGLLogger SHARED ${NGLLogger_SRCS} ${NGLLogger_HDRS})
NGL_TARGET_INCLUDE_DIRECTORIES(NGLLogger
INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(NGLLogger
PRIVATE
Log4Qt::log4qt
PUBLIC
Qt5::Core
)
NGL_INSTALL_TARGET(NGLLogger)
#
# test_ngllogger
#
IF(BUILD_TESTING AND TARGET NGLLogger)
ADD_EXECUTABLE(test_ngllogger test_ngllogger.cpp)
TARGET_LINK_LIBRARIES(test_ngllogger NGLLogger)
TARGET_LINK_LIBRARIES(test_ngllogger
Log4Qt::log4qt
ngltools
)
ADD_TEST(NAME test_ngllogger COMMAND $<TARGET_FILE:test_ngllogger>)
ENDIF(BUILD_TESTING AND TARGET NGLLogger)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/log4cxx.props ${CMAKE_BINARY_DIR}/log4cxx.props COPYONLY)
+306
View File
@@ -0,0 +1,306 @@
#pragma once
#include <string>
#include <sstream>
#include <QString>
#include <QPointF>
#include <QSize>
#include <QRect>
#include <QRectF>
#include <QList>
#include "NGLLogger_export.h"
namespace NGL
{
class INGLLogger;
enum class LogLevel
{
Undefined = 0,
Trace = 64,
Debug = 96,
Info = 128,
Warning = 150,
Error = 182,
Fatal = 214,
};
class LogStreamHelper
{
public:
inline LogStreamHelper(INGLLogger &logger, LogLevel level, const char *const file, int line, const char *const function)
: m_logger(logger)
, m_level(level)
, m_line(line)
, m_file(file)
, m_func(function)
{}
inline ~LogStreamHelper();
template<typename T>
inline LogStreamHelper &operator<<(const T &val);
private:
std::ostringstream m_buffer;
NGL::INGLLogger &m_logger;
const LogLevel m_level;
const int m_line;
const char *const m_file;
const char *const m_func;
};
class INGLLogger
{
public:
INGLLogger(const INGLLogger &) = delete;
INGLLogger &operator=(const INGLLogger &) = delete;
INGLLogger() = default;
virtual ~INGLLogger() = default;
using String = std::string;
virtual INGLLogger &getNGLLogger(const char *fullqualifiedname) = 0;
virtual INGLLogger &getNGLLogger(const std::string &fullqualifiedname) = 0;
virtual bool isTraceEnabled() const = 0;
virtual bool isDebugEnabled() const = 0;
virtual bool isInfoEnabled() const = 0;
virtual bool isWarningEnabled() const = 0;
virtual bool isErrorEnabled() const = 0;
virtual bool isFatalEnabled() const = 0;
virtual bool isLevelEnabled(LogLevel level) const = 0;
virtual void log(LogLevel level, const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
virtual void logTrace(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
virtual void logDebug(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
virtual void logInfo(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
virtual void logWarning(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
virtual void logError(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
virtual void logFatal(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) = 0;
virtual void logStartup(const char *file, int line, const char *function = nullptr) = 0;
virtual void logShutdown(const char *file, int line, const char *function = nullptr) = 0;
virtual std::string getLoggerName() const = 0;
virtual void setNoSpace(bool bNoSpace) = 0;
virtual bool noSpace() const = 0;
};
inline LogStreamHelper::~LogStreamHelper()
{
m_logger.log(m_level, m_buffer.str(), m_file, m_line, m_func);
}
template<typename T>
inline LogStreamHelper &LogStreamHelper::operator<<(const T &val)
{
m_buffer << val;
if (!m_logger.noSpace())
m_buffer << " ";
return *this;
}
}
inline std::ostream &operator<<(std::ostream &stream, const QByteArray &str)
{
stream << std::string(str.data(), str.size());
return stream;
}
inline std::ostream &operator<<(std::ostream &stream,
const QPointF &value)
{
stream << "QPointF(" << QString::number(value.x(), 'f', 6).toStdString() << "#" << QString::number(value.y(), 'f', 6).toStdString() << ")";
return stream;
}
inline std::ostream &operator<< (std::ostream &stream,
const QPoint &value)
{
stream << "QPoint(" << value.x() << "#" << value.y() << ")";
return stream;
}
inline std::ostream &operator<< (std::ostream &stream,
const QSize &value)
{
stream << "QSize(w=" << value.width() << ";h=" << value.height() << ")";
return stream;
}
inline std::ostream &operator<< (std::ostream &stream,
const QSizeF &value)
{
stream << "QSize(w="
<< QString::number(value.width(), 'f', 6).toStdString() << ";h="
<< QString::number(value.height(), 'f', 6).toStdString()
<< ")";
return stream;
}
inline std::ostream &operator<< (std::ostream &stream,
const QRect &value)
{
stream << "QRect(center=" << value.center()
<< " w=" << value.width()
<< ";h=" << value.height()
<< " bottomLeft=" << value.bottomLeft()
<< " topRight=" << value.topRight()
<< ")";
return stream;
}
inline std::ostream &operator<< (std::ostream &stream,
const QRectF &value)
{
stream << "QRectF(center=" << value.center()
<< " w=" << QString::number(value.width(), 'f', 3).toStdString()
<< ";h=" << QString::number(value.height(), 'f', 3).toStdString()
<< " bottomLeft=" << value.bottomLeft()
<< " topRight=" << value.topRight()
<< ")";
return stream;
}
inline std::ostream &operator<< (std::ostream &stream,
const QList<int> &value)
{
stream << "QList<int>(" << value.size() << "): ";
for (int i : value)
stream << i << ";";
return stream;
}
inline std::ostream &operator<< (std::ostream &stream,
const QList<QPointF> &value)
{
stream << "QList<QPointF>(" << value.size() << "): ";
for (const QPointF &item : value)
stream << item << ";";
return stream;
}
inline std::ostream &operator<<(std::ostream &stream, const QString &str)
{
return stream << str.toUtf8();
}
namespace NGL
{
namespace NGLLoggerHelper
{
NGLLOGGER_EXPORT void hexDumpHelper(NGL::INGLLogger &logger,
NGL::LogLevel level,
const void *a_data,
const unsigned int a_size);
inline void hexDumpHelper(NGL::INGLLogger &logger,
NGL::LogLevel level,
const QByteArray &data)
{
return hexDumpHelper(logger, level, data.data(), data.size());
}
}
NGLLOGGER_EXPORT NGL::INGLLogger& getMemoryLogger();
NGLLOGGER_EXPORT std::string getMemoryData();
}
#define LOGFUNCTION Q_FUNC_INFO
#define NOTICE_LOG(logger) \
NGL::LogStreamHelper(logger, NGL::LogLevel::Info, __FILE__,__LINE__, Q_FUNC_INFO)
#ifdef LTS_DEBUG
#define TRACE_LOG(logger) \
for (bool log_level_enabled = (logger).isTraceEnabled(); log_level_enabled; log_level_enabled = false) \
NGL::LogStreamHelper(logger, NGL::LogLevel::Trace, __FILE__,__LINE__, Q_FUNC_INFO)
#else
#define TRACE_LOG(logger) \
for ( ; false; ) \
NGL::LogStreamHelper(logger, NGL::LogLevel::Trace, __FILE__,__LINE__, Q_FUNC_INFO)
#endif
#define DEBUG_LOG(logger) \
for (bool log_level_enabled = (logger).isDebugEnabled(); log_level_enabled; log_level_enabled = false) \
NGL::LogStreamHelper(logger, NGL::LogLevel::Debug, __FILE__,__LINE__, Q_FUNC_INFO)
#define INFO_LOG(logger) \
for (bool log_level_enabled = (logger).isInfoEnabled(); log_level_enabled; log_level_enabled = false) \
NGL::LogStreamHelper(logger, NGL::LogLevel::Info, __FILE__,__LINE__, Q_FUNC_INFO)
#define WARNING_LOG(logger) \
for (bool log_level_enabled = (logger).isWarningEnabled(); log_level_enabled; log_level_enabled = false) \
NGL::LogStreamHelper(logger, NGL::LogLevel::Warning, __FILE__,__LINE__, Q_FUNC_INFO)
#define ERROR_LOG(logger) \
for (bool log_level_enabled = (logger).isErrorEnabled(); log_level_enabled; log_level_enabled = false) \
NGL::LogStreamHelper(logger, NGL::LogLevel::Error, __FILE__,__LINE__, Q_FUNC_INFO)
#define FATAL_LOG(logger) \
for (bool log_level_enabled = (logger).isFatalEnabled(); log_level_enabled; log_level_enabled = false) \
NGL::LogStreamHelper(logger, NGL::LogLevel::Fatal, __FILE__,__LINE__, Q_FUNC_INFO)
#define STARTUP_LOG(logger) { (logger).logStartup(__FILE__, __LINE__, Q_FUNC_INFO); }
#define SHUTDOWN_LOG(logger) { (logger).logShutdown(__FILE__, __LINE__, Q_FUNC_INFO); }
#define MEMORY_LOG() \
for (bool log_level_enabled = (NGL::getMemoryLogger()).isInfoEnabled(); log_level_enabled; log_level_enabled = false) \
NGL::LogStreamHelper(NGL::getMemoryLogger(), NGL::LogLevel::Info, __FILE__,__LINE__, Q_FUNC_INFO) << NGL::getMemoryData()
+77
View File
@@ -0,0 +1,77 @@
#include "MurmurHash2.h"
#include <QtCore/qcompilerdetection.h>
namespace NGL
{
unsigned int MurmurHash2 ( const void * key, int len, unsigned int seed )
{
const unsigned int m = 0x5bd1e995;
const int r = 24;
unsigned int h = seed ^ len;
const unsigned char * data = (const unsigned char *)key;
while(len >= 4)
{
unsigned int k = *(reinterpret_cast<const unsigned int *>(data));
k *= m;
k ^= k >> r;
k *= m;
h *= m;
h ^= k;
data += 4;
len -= 4;
}
switch(len)
{
case 3: h ^= data[2] << 16;
Q_FALLTHROUGH();
case 2: h ^= data[1] << 8;
Q_FALLTHROUGH();
case 1: h ^= data[0];
h *= m;
};
h ^= h >> 13;
h *= m;
h ^= h >> 15;
return h;
}
}
+9
View File
@@ -0,0 +1,9 @@
#pragma once
namespace NGL
{
unsigned int MurmurHash2 ( const void * key, int len, unsigned int seed = 0 );
}
+446
View File
@@ -0,0 +1,446 @@
#include "NGLLogger.h"
#include "MurmurHash2.h"
#include <cstdlib>
#include <iostream>
#include <log4qt/logger.h>
#include <log4qt/logmanager.h>
#include <log4qt/loggerrepository.h>
#include <log4qt/propertyconfigurator.h>
#include <log4qt/rollingfileappender.h>
#include <log4qt/helpers/configuratorhelper.h>
#include <log4qt/helpers/properties.h>
#include <log4qt/helpers/factory.h>
#include <mutex>
#include <unordered_map>
#include <QCoreApplication>
#include <QFileInfo>
namespace NGL
{
void LtsRollingFileAppender::setLtsLogfileName(const QString &ltsLogfileName)
{
m_ltsLogfileName = ltsLogfileName;
}
void LtsRollingFileAppender::activateOptions()
{
if (!m_ltsLogfileName.isEmpty())
setFile(m_ltsLogfileName);
Log4Qt::RollingFileAppender::activateOptions();
}
QString LtsRollingFileAppender::m_ltsLogfileName;
static Log4Qt::Appender *createLtsRollingFileAppender()
{
auto ret = new LtsRollingFileAppender;
ret->setAppendFile(true);
return ret;
}
class CleanupHelper final
{
public:
CleanupHelper() = default;
~CleanupHelper();
std::mutex &getLoggerMapMutex();
std::unordered_map<unsigned int, NGL::NGLLogger *> m_loggermap;
protected:
std::mutex m_loggermapmutex;
};
NGL::NGLLogger *NGL::NGLLogger::rootlogger_ptr = nullptr;
NGL::CleanupHelper NGL::NGLLogger::s_cleanup;
CleanupHelper::~CleanupHelper()
{
std::lock_guard<std::mutex> lock(m_loggermapmutex);
for (auto it : m_loggermap)
delete it.second;
m_loggermap.clear();
delete NGL::NGLLogger::rootlogger_ptr;
NGL::NGLLogger::rootlogger_ptr = nullptr;
}
std::mutex &CleanupHelper::getLoggerMapMutex()
{
return m_loggermapmutex;
}
}
NGL::NGLLogger::NGLLogger(const std::string &fullqualifiedname)
: name(fullqualifiedname)
, currentLevel(LogLevel::Undefined)
, m_bNoSpace(true)
{
if (!fullqualifiedname.empty())
{
logger_ptr = Log4Qt::LogManager::loggerRepository()->logger(QString::fromStdString(name));
s_cleanup.m_loggermap[MurmurHash2(fullqualifiedname.c_str(), fullqualifiedname.size())] = this;
}
else
{
logger_ptr = Log4Qt::LogManager::loggerRepository()->rootLogger();
}
configChanged();
}
NGL::INGLLogger &NGL::NGLLogger::getNGLLogger(const char *fullqualifiedname)
{
std::lock_guard<std::mutex> lock(s_cleanup.getLoggerMapMutex());
auto it = s_cleanup.m_loggermap.find(MurmurHash2(fullqualifiedname, strlen(fullqualifiedname)));
if (it != s_cleanup.m_loggermap.end())
return *(*it).second;
return *(new NGLLogger(fullqualifiedname));
}
NGL::INGLLogger &NGL::NGLLogger::getNGLLogger(const std::string &fullqualifiedname)
{
std::lock_guard<std::mutex> lock(s_cleanup.getLoggerMapMutex());
auto it = s_cleanup.m_loggermap.find(MurmurHash2(fullqualifiedname.c_str(), fullqualifiedname.size()));
if (it != s_cleanup.m_loggermap.end())
return *(*it).second;
return *(new NGLLogger(fullqualifiedname));
}
void NGL::NGLLogger::log(LogLevel level, const INGLLogger::String &message, const char *file, int line, const char *function)
{
logger_ptr->logWithLocation(static_cast<Log4Qt::Level::Value>(level), file, line, function, QString::fromStdString(message));
}
void NGL::NGLLogger::logTrace(const INGLLogger::String &message, const char *file, int line, const char *function)
{
if (currentLevel >= LogLevel::Trace)
log(LogLevel::Trace, message, file, line, function);
}
void NGL::NGLLogger::logDebug(const INGLLogger::String &message, const char *file, int line, const char *function)
{
if (currentLevel >= LogLevel::Debug)
log(LogLevel::Debug, message, file, line, function);
}
void NGL::NGLLogger::logInfo(const INGLLogger::String &message, const char *file, int line, const char *function)
{
if (currentLevel >= LogLevel::Info)
log(LogLevel::Info, message, file, line, function);
}
void NGL::NGLLogger::logWarning(const INGLLogger::String &message, const char *file, int line, const char *function)
{
if (currentLevel >= LogLevel::Warning)
log(LogLevel::Warning, message, file, line, function);
}
void NGL::NGLLogger::logError(const INGLLogger::String &message, const char *file, int line, const char *function)
{
if (currentLevel >= LogLevel::Error)
log(LogLevel::Error, message, file, line, function);
}
void NGL::NGLLogger::logFatal(const INGLLogger::String &message, const char *file, int line, const char *function)
{
log(LogLevel::Fatal, message, file, line, function);
}
#ifndef LTS_VERSION_MAJOR
#define LTS_VERSION_MAJOR "undefined"
#endif
#ifndef LTS_VERSION_MINOR
#define LTS_VERSION_MINOR "undefined"
#endif
#ifndef LTS_VERSION_PATCH
#define LTS_VERSION_PATCH "undefined"
#endif
#ifndef LTS_VERSION_DATE
#define LTS_VERSION_DATE "undefined"
#endif
#ifndef JENKINS_BUILD_NUMBER
#define JENKINS_BUILD_NUMBER "unknown"
#endif
static const char ver_major[] = LTS_VERSION_MAJOR;
static const char ver_minor[] = LTS_VERSION_MINOR;
static const char ver_patch[] = LTS_VERSION_PATCH;
static const char ver_date[] = LTS_VERSION_DATE;
static const char ver_jenkins[] = JENKINS_BUILD_NUMBER;
void NGL::NGLLogger::logStartup(const char *file, int line, const char *function)
{
log(LogLevel::Info, QStringLiteral("Application is started (%1.%2-%3 rev%4 from %5)")
.arg(QString::fromLatin1(ver_major),
QString::fromLatin1(ver_minor),
QString::fromLatin1(ver_jenkins),
QString::fromLatin1(ver_patch),
QString::fromLatin1(ver_date)).toUtf8().constData(), file, line, function);
}
void NGL::NGLLogger::logShutdown(const char *file, int line, const char *function)
{
log(LogLevel::Info, QStringLiteral("Application is shut down (%1.%2-%3 rev%4 from %5)")
.arg(QString::fromLatin1(ver_major),
QString::fromLatin1(ver_minor),
QString::fromLatin1(ver_jenkins),
QString::fromLatin1(ver_patch),
QString::fromLatin1(ver_date)).toUtf8().constData(), file, line, function);
}
NGL::NGLLogger &NGL::NGLLogger::getNGLRootLogger()
{
if (!rootlogger_ptr) throw NotCreatedError();
return *rootlogger_ptr;
}
static QString findConfigFile(const QString &configfilename)
{
if (configfilename.isEmpty())
return QString();
QFileInfo fi(configfilename);
if (fi.isFile() && fi.isReadable())
return fi.absoluteFilePath();
QString p = QCoreApplication::applicationDirPath() + QLatin1Char('/') + configfilename;
fi.setFile(p);
if (fi.isFile() && fi.isReadable())
return fi.absoluteFilePath();
return QString();
}
NGL::NGLLogger &NGL::NGLLogger::createNGLRootLogger(const QString &configfilename,
bool ignorealreadycreated,
const QString &logOutputName,
bool quiet)
{
if (rootlogger_ptr)
{
if (!ignorealreadycreated) throw AlreadyCreatedError();
}
else
{
Log4Qt::Factory::registerAppender("Lts::RollingFileAppender", createLtsRollingFileAppender);
LtsRollingFileAppender::setLtsLogfileName(logOutputName);
rootlogger_ptr = new NGLLogger(std::string());
const QString filename = findConfigFile(configfilename);
if (!filename.isEmpty())
{
Log4Qt::PropertyConfigurator::configureAndWatch(filename);
QObject::connect(Log4Qt::ConfiguratorHelper::instance(), &Log4Qt::ConfiguratorHelper::configurationFileChanged,
[]() { configurationFileChanged(); });
const auto l = Log4Qt::ConfiguratorHelper::instance()->configureError();
for (const auto &t : l)
std::cerr << t.message().toUtf8().data() << std::endl;
if (!l.isEmpty())
exit(-1);
}
else
{
if (!quiet)
std::cerr << "Could not find log4cxx configuration file " << configfilename << std::endl
<< "Using default logging to stdout" << std::endl;
Log4Qt::Properties props;
props.setProperty(QLatin1String("log4j.rootLogger"),
QLatin1String("WARN, stdout"));
props.setProperty(QLatin1String("log4j.appender.stdout"),
QLatin1String("org.apache.log4j.ConsoleAppender"));
props.setProperty(QLatin1String("log4j.appender.stdout.layout"),
QLatin1String("org.apache.log4j.PatternLayout"));
props.setProperty(QLatin1String("log4j.appender.stdout.layout.ConversionPattern"),
QLatin1String("%d %-5p %c |#| %m (%.50F:%L) %n"));
Log4Qt::PropertyConfigurator::configure(props);
}
rootlogger_ptr->configChanged();
}
return *rootlogger_ptr;
}
void NGL::NGLLogger::configurationFileChanged()
{
for (auto ptr : s_cleanup.m_loggermap)
ptr.second->configChanged();
}
void NGL::NGLLogger::configChanged()
{
if (logger_ptr->isTraceEnabled())
currentLevel = LogLevel::Trace;
else if (logger_ptr->isDebugEnabled())
currentLevel = LogLevel::Debug;
else if (logger_ptr->isInfoEnabled())
currentLevel = LogLevel::Info;
else if (logger_ptr->isWarnEnabled())
currentLevel = LogLevel::Warning;
else if (logger_ptr->isErrorEnabled())
currentLevel = LogLevel::Error;
else
currentLevel = LogLevel::Fatal;
}
namespace NGL
{
namespace NGLLoggerHelper
{
void hexDumpHelper(NGL::INGLLogger &logger, NGL::LogLevel level,
const void *a_data, const unsigned int a_size)
{
if (!logger.isLevelEnabled(level) || !a_data)
return;
unsigned char *data = (unsigned char *)a_data;
QByteArray baBuf;
for (unsigned int i = 0; i < a_size; i++)
{
if (0 == (i % 8))
baBuf = QByteArray::number(i, 16).rightJustified(8, '0').toUpper();
baBuf += " " + QByteArray::number(data[i], 16).rightJustified(2, '0').toUpper();
if (7 == (i % 8))
logger.log(level, baBuf.constData(), __FILE__, __LINE__);
}
if (a_size % 8)
logger.log(level, baBuf.constData(), __FILE__, __LINE__);
}
}
NGL::INGLLogger& getMemoryLogger()
{
try
{
return NGLLogger::getNGLRootLogger().getNGLLogger("memorystate");
}
catch (const std::exception &ex)
{
fprintf(stderr, "Error retrieving logger: %s", ex.what());
abort();
}
}
int parseLine(char* line){
int i = strlen(line);
const char* p = line;
while (*p <'0' || *p > '9') p++;
line[i-3] = '\0';
i = atoi(p);
return i;
}
int getMemoryValue()
{
FILE* file = fopen("/proc/self/status", "r");
int result = -1;
char line[128];
while (fgets(line, 128, file) != NULL){
if (strncmp(line, "VmRSS:", 6) == 0){
result = parseLine(line);
break;
}
}
fclose(file);
return result;
}
std::string getMemoryData()
{
return QStringLiteral("VmRSS: %1 kB #").arg(QString::number(getMemoryValue())).toStdString();
}
}
+94
View File
@@ -0,0 +1,94 @@
#pragma once
#ifndef BUILDING_NGLLOGGER
#error Do not include me outside NGLLogger library - only use INGLLogger.h!
#endif
#include "INGLLogger.h"
#include <string>
#include <log4qt/logger.h>
#include <log4qt/rollingfileappender.h>
namespace NGL
{
class CleanupHelper;
class LtsRollingFileAppender final : public Log4Qt::RollingFileAppender
{
Q_OBJECT
public:
using Log4Qt::RollingFileAppender::RollingFileAppender;
static void setLtsLogfileName(const QString &ltsLogfileName);
void activateOptions() override;
private:
static QString m_ltsLogfileName;
};
class NGLLogger final : public INGLLogger
{
explicit NGLLogger(const std::string &fullqualifiedname);
public:
class NotCreatedError {};
class AlreadyCreatedError {};
INGLLogger &getNGLLogger(const char *fullqualifiedname) override;
INGLLogger &getNGLLogger(const std::string &fullqualifiedname) override;
inline bool isTraceEnabled() const override { return currentLevel <= LogLevel::Trace; }
inline bool isDebugEnabled() const override { return currentLevel <= LogLevel::Debug; }
inline bool isInfoEnabled() const override { return currentLevel <= LogLevel::Info; }
inline bool isWarningEnabled() const override { return currentLevel <= LogLevel::Warning; }
inline bool isErrorEnabled() const override { return currentLevel <= LogLevel::Error; }
inline bool isFatalEnabled() const override { return currentLevel <= LogLevel::Fatal; }
inline bool isLevelEnabled(LogLevel level) const override { return currentLevel <= level; }
void log(LogLevel level, const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) override;
void logTrace(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) override;
void logDebug(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) override;
void logInfo(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) override;
void logWarning(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) override;
void logError(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) override;
void logFatal(const INGLLogger::String &message, const char *file = nullptr, int line = -1, const char *function = nullptr) override;
void logStartup(const char *file, int line, const char *function = nullptr) override;
void logShutdown(const char *file, int line, const char *function = nullptr) override;
inline void setNoSpace(bool bNoSpace) override { m_bNoSpace = bNoSpace; }
inline bool noSpace() const override { return m_bNoSpace; }
inline std::string getLoggerName() const override { return name; }
static NGLLogger &getNGLRootLogger();
static NGLLogger &createNGLRootLogger(const QString &configfilename,
bool ignorealreadycreated,
const QString &logOutputName = QString(),
bool quiet = false);
Log4Qt::Logger *log4qtLogger() { return logger_ptr; }
protected:
static void configurationFileChanged();
void configChanged();
private:
Log4Qt::Logger *logger_ptr;
const std::string name;
LogLevel currentLevel;
bool m_bNoSpace;
static NGLLogger *rootlogger_ptr;
friend class CleanupHelper;
static CleanupHelper s_cleanup;
friend class XMLWatchdog;
};
}
+30
View File
@@ -0,0 +1,30 @@
#include "NGLLoggerBootstrap.h"
#include "NGLLogger.h"
NGL::INGLLogger & NGL::NGLLoggerBootstrap::getNGLRootLogger()
{
return NGL::NGLLogger::getNGLRootLogger();
}
NGL::INGLLogger & NGL::NGLLoggerBootstrap::createNGLRootLogger(const QString &configfilename,
bool ignorealreadycreated,
const QString &logOutputName,
bool quiet)
{
return NGL::NGLLogger::createNGLRootLogger(configfilename, ignorealreadycreated, logOutputName, quiet);
}
+59
View File
@@ -0,0 +1,59 @@
#ifndef NGLLOGGERBOOTSTRAP_H
#define NGLLOGGERBOOTSTRAP_H
#include "INGLLogger.h"
#include "NGLLogger_export.h"
namespace NGL
{
namespace NGLLoggerBootstrap
{
class AlreadyCreatedError final : public std::exception
{
const char* what() const noexcept override
{
return "NGLLogger rootlogger already created!";
}
};
class NotCreatedError final : public std::exception
{
const char* what() const noexcept override
{
return "NGLLogger rootlogger not yet created!";
}
};
NGLLOGGER_EXPORT INGLLogger &getNGLRootLogger();
NGLLOGGER_EXPORT INGLLogger &createNGLRootLogger(const QString &configfilename,
bool ignorealreadycreated,
const QString &logOutputName = QString(),
bool quiet = false);
inline INGLLogger &createNGLRootLogger(const char *configfilename,
bool ignorealreadycreated,
const QString &logOutputName = QString())
{
return createNGLRootLogger(QString::fromUtf8(configfilename), ignorealreadycreated, logOutputName);
}
}
}
#endif
+22
View File
@@ -0,0 +1,22 @@
#ifndef NGLLOGGER_EXPORT_H
#define NGLLOGGER_EXPORT_H
#ifndef NGLLOGGER_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define NGLLOGGER_EXPORT
# else
# ifdef WIN32
# ifdef MAKE_NGLLOGGER_LIB
# define NGLLOGGER_EXPORT __declspec(dllexport)
# else
# define NGLLOGGER_EXPORT __declspec(dllimport)
# endif
# else
# define NGLLOGGER_EXPORT __attribute__((visibility("default")))
# endif
# endif
#endif
#endif
+42
View File
@@ -0,0 +1,42 @@
log4j.reset=true
log4j.rootLogger=ERROR, stdout
log4j.logger.Gui=TRACE, console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%p %d %t %c{1} - %F:%L %m%n
log4j.logger.ngs=FATAL, stdout
log4j.logger.ngs.Application_1=INFO, file
log4j.logger.ngs.Application_2=ERROR
log4j.logger.ngs.Application_3=ERROR
log4j.logger.libsymbol.SymbolTable=WARN, stdout
log4j.logger.libsymbol.SymbolReader=WARN, stdout
log4j.logger.libngldb=INFO, stdout
log4j.logger.NGL.main=INFO, stdout, file
log4j.logger.NGL.MainWindow=INFO, stdout, file
log4j.logger.NGL.zwmsqt=INFO, stdout, file
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=#ngs# %r %p %d %t %c %c{1} - %F:%L %m%n
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=9
log4j.appender.file.file=log.out
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=#ngs# %r %p %d %t %c %c{1} - %F:%L %m%n
log4j.appender.syslog=org.apache.log4j.SyslogAppender
log4j.appender.syslog.Threshold=WARN
log4j.appender.syslog.SysLogHost=localhost
log4j.appender.syslog.Facility=LOCAL7
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
log4j.appender.syslog.layout.ConversionPattern= %-4r %-5p %c %x - %m
log4j.appender.syslog.LevelRangeFilter.AcceptOnMatch=true
log4j.appender.syslog.LevelRangeFilter.LevelMin=INFO
log4j.appender.syslog.LevelRangeFilter.LevelMax=FATAL
+34
View File
@@ -0,0 +1,34 @@
#include "INGLLogger.h"
#include "NGLLoggerBootstrap.h"
#include <QCoreApplication>
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
NGL::NGLLoggerBootstrap::createNGLRootLogger("log4cxx.props", false);
NGL::INGLLogger &l = NGL::NGLLoggerBootstrap::getNGLRootLogger(). getNGLLogger( "Gui" );
STARTUP_LOG(l);
SHUTDOWN_LOG(l);
NOTICE_LOG(l) << "Gui - NOTICE";
TRACE_LOG(l) << "Gui - TRACE";
DEBUG_LOG(l) << "Gui - DEBUG";
INFO_LOG(l) << "Gui - INFO";
WARNING_LOG(l) << "Gui - WARNING";
ERROR_LOG(l) << "Gui - ERROR";
FATAL_LOG(l) << "Gui - FATAL";
NGL::INGLLogger &l2 = NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger( "Gui.AES" );
NOTICE_LOG(l2) << "Gui.AES - NOTICE";
TRACE_LOG(l2) << "Gui.AES - TRACE";
DEBUG_LOG(l2) << "Gui.AES - DEBUG";
INFO_LOG(l2) << "Gui.AES - INFO";
WARNING_LOG(l2) << "Gui.AES - WARNING";
ERROR_LOG(l2) << "Gui.AES - ERROR";
FATAL_LOG(l2) << "Gui.AES - FATAL";
SHUTDOWN_LOG(l2)
return 0;
}
+51
View File
@@ -0,0 +1,51 @@
# QtSingleApplication solution from
# http://qt.nokia.com/products/appdev/add-on-products/catalog/4/Utilities/qtsingleapplication
# LGPL
SET(qtsapp_common_SRCS
qtlocalpeer.cpp
qtlocalpeer.h
)
QT5_WRAP_CPP(qtsapp_common_SRCS qtlockedfile.h)
NGL_ADD_LIBRARY(WS AAR SV qtsa_common STATIC ${qtsapp_common_SRCS})
NGL_TARGET_LINK_LIBRARIES(qtsa_common
PUBLIC
Qt5::Network
Qt5::Core
)
SET(qtsapp_SRCS
qtsingleapplication.cpp
qtsingleapplication.h
)
NGL_ADD_LIBRARY(WS qtsingleapplication SHARED ${qtsapp_SRCS})
NGL_INSTALL_TARGET(qtsingleapplication)
NGL_TARGET_INCLUDE_DIRECTORIES(qtsingleapplication
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/..
)
NGL_TARGET_LINK_LIBRARIES(qtsingleapplication
PRIVATE
qtsa_common
PUBLIC
Qt5::Core
Qt5::Widgets
)
SET(qtscoreapp_SRCS
qtsinglecoreapplication.h
qtsinglecoreapplication.cpp
)
NGL_ADD_LIBRARY(AAR SV qtsinglecoreapplication SHARED ${qtscoreapp_SRCS})
NGL_INSTALL_TARGET(qtsinglecoreapplication)
NGL_TARGET_INCLUDE_DIRECTORIES(qtsinglecoreapplication
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/..
)
NGL_TARGET_LINK_LIBRARIES(qtsinglecoreapplication
PRIVATE
qtsa_common
PUBLIC
Qt5::Core
)
+1
View File
@@ -0,0 +1 @@
#include "qtlockedfile.h"
+1
View File
@@ -0,0 +1 @@
#include "qtsingleapplication.h"
+1
View File
@@ -0,0 +1 @@
#include "qtsinglecoreapplication.h"
+167
View File
@@ -0,0 +1,167 @@
#include "qtlocalpeer.h"
#include <QCoreApplication>
#include <QDataStream>
#include <QTime>
#if defined(Q_OS_WIN)
#include <QLibrary>
#include <qt_windows.h>
typedef BOOL(WINAPI*PProcessIdToSessionId)(DWORD,DWORD*);
static PProcessIdToSessionId pProcessIdToSessionId = 0;
#endif
#if defined(Q_OS_UNIX)
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#endif
namespace QtLP_Private {
#include "qtlockedfile.cpp"
#if defined(Q_OS_WIN)
#include "qtlockedfile_win.cpp"
#else
#include "qtlockedfile_unix.cpp"
#endif
}
const char* QtLocalPeer::ack = "ack";
QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId)
: QObject(parent), id(appId)
{
QString prefix = id;
if (id.isEmpty()) {
id = QCoreApplication::applicationFilePath();
#if defined(Q_OS_WIN)
id = id.toLower();
#endif
prefix = id.section(QLatin1Char('/'), -1);
}
prefix.remove(QRegExp(QLatin1String("[^a-zA-Z]")));
prefix.truncate(6);
QByteArray idc = id.toUtf8();
quint16 idNum = qChecksum(idc.constData(), idc.size());
socketName = QLatin1String("qtsingleapp-") + prefix
+ QLatin1Char('-') + QString::number(idNum, 16);
#if defined(Q_OS_WIN)
if (!pProcessIdToSessionId) {
QLibrary lib(QLatin1String("kernel32"));
pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId");
}
if (pProcessIdToSessionId) {
DWORD sessionId = 0;
pProcessIdToSessionId(GetCurrentProcessId(), &sessionId);
socketName += QLatin1Char('-') + QString::number(sessionId, 16);
}
#else
socketName += QLatin1Char('-') + QString::number(::getuid(), 16);
#endif
server = new QLocalServer(this);
QString lockName = QDir(QDir::tempPath()).absolutePath()
+ QLatin1Char('/') + socketName
+ QLatin1String("-lockfile");
lockFile.setFileName(lockName);
lockFile.open(QIODevice::ReadWrite);
}
bool QtLocalPeer::isClient()
{
if (lockFile.isLocked())
return false;
if (!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false))
return true;
bool res = server->listen(socketName);
#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(4,5,0))
if (!res && server->serverError() == QAbstractSocket::AddressInUseError) {
QFile::remove(QDir::cleanPath(QDir::tempPath())+QLatin1Char('/')+socketName);
res = server->listen(socketName);
}
#endif
if (!res)
qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
QObject::connect(server, &QLocalServer::newConnection, this, &QtLocalPeer::receiveConnection);
return false;
}
bool QtLocalPeer::sendMessage(const QString &message, int timeout)
{
if (!isClient())
return false;
QLocalSocket socket;
bool connOk = false;
for(int i = 0; i < 2; i++) {
socket.connectToServer(socketName);
connOk = socket.waitForConnected(timeout/2);
if (connOk || i)
break;
int ms = 250;
#if defined(Q_OS_WIN)
Sleep(DWORD(ms));
#else
struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
nanosleep(&ts, nullptr);
#endif
}
if (!connOk)
return false;
QByteArray uMsg(message.toUtf8());
QDataStream ds(&socket);
ds.writeBytes(uMsg.constData(), uMsg.size());
bool res = socket.waitForBytesWritten(timeout);
if (res) {
res &= socket.waitForReadyRead(timeout);
if (res)
res &= (socket.read(qstrlen(ack)) == ack);
}
return res;
}
void QtLocalPeer::receiveConnection()
{
QLocalSocket* socket = server->nextPendingConnection();
if (!socket)
return;
while (socket->bytesAvailable() < (int)sizeof(quint32))
socket->waitForReadyRead();
QDataStream ds(socket);
QByteArray uMsg;
quint32 remaining;
ds >> remaining;
uMsg.resize(remaining);
int got = 0;
char* uMsgBuf = uMsg.data();
do {
got = ds.readRawData(uMsgBuf, remaining);
remaining -= got;
uMsgBuf += got;
} while (remaining && got >= 0 && socket->waitForReadyRead(2000));
if (got < 0) {
qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData());
delete socket;
return;
}
QString message(QString::fromUtf8(uMsg));
socket->write(ack, qstrlen(ack));
socket->waitForBytesWritten(1000);
socket->waitForDisconnected(1000);
delete socket;
emit messageReceived(message);
}
+40
View File
@@ -0,0 +1,40 @@
#ifndef QTLOCALPEER_H
#define QTLOCALPEER_H
#include <QLocalServer>
#include <QLocalSocket>
#include <QDir>
#include "qtlockedfile.h"
class QtLocalPeer : public QObject
{
Q_OBJECT
public:
QtLocalPeer(QObject *parent = nullptr, const QString &appId = QString());
bool isClient();
bool sendMessage(const QString &message, int timeout);
QString applicationId() const
{ return id; }
Q_SIGNALS:
void messageReceived(const QString &message);
protected Q_SLOTS:
void receiveConnection();
protected:
QString id;
QString socketName;
QLocalServer* server;
QtLP_Private::QtLockedFile lockFile;
private:
static const char* ack;
};
#endif
+68
View File
@@ -0,0 +1,68 @@
#include "qtlockedfile.h"
QtLockedFile::QtLockedFile()
: QFile()
{
#ifdef Q_OS_WIN
wmutex = 0;
rmutex = 0;
#endif
m_lock_mode = NoLock;
}
QtLockedFile::QtLockedFile(const QString &name)
: QFile(name)
{
#ifdef Q_OS_WIN
wmutex = 0;
rmutex = 0;
#endif
m_lock_mode = NoLock;
}
bool QtLockedFile::open(OpenMode mode)
{
if (mode & QIODevice::Truncate) {
qWarning("QtLockedFile::open(): Truncate mode not allowed.");
return false;
}
return QFile::open(mode);
}
bool QtLockedFile::isLocked() const
{
return m_lock_mode != NoLock;
}
QtLockedFile::LockMode QtLockedFile::lockMode() const
{
return m_lock_mode;
}
+61
View File
@@ -0,0 +1,61 @@
#ifndef QTLOCKEDFILE_H
#define QTLOCKEDFILE_H
#include <QFile>
#ifdef Q_OS_WIN
#include <QVector>
#endif
#if defined(Q_OS_WIN)
# if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT)
# define QT_QTLOCKEDFILE_EXPORT
# elif defined(QT_QTLOCKEDFILE_IMPORT)
# if defined(QT_QTLOCKEDFILE_EXPORT)
# undef QT_QTLOCKEDFILE_EXPORT
# endif
# define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport)
# elif defined(QT_QTLOCKEDFILE_EXPORT)
# undef QT_QTLOCKEDFILE_EXPORT
# define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport)
# endif
#else
# define QT_QTLOCKEDFILE_EXPORT
#endif
namespace QtLP_Private {
class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile
{
Q_OBJECT
public:
enum LockMode { NoLock = 0, ReadLock, WriteLock };
QtLockedFile();
explicit QtLockedFile(const QString &name);
~QtLockedFile();
bool open(OpenMode mode);
bool lock(LockMode mode, bool block = true);
bool unlock();
bool isLocked() const;
LockMode lockMode() const;
private:
#ifdef Q_OS_WIN
Qt::HANDLE wmutex;
Qt::HANDLE rmutex;
QVector<Qt::HANDLE> rmutexes;
QString mutexname;
Qt::HANDLE getMutexHandle(int idx, bool doCreate);
bool waitMutex(Qt::HANDLE mutex, bool doBlock);
#endif
LockMode m_lock_mode;
};
}
#endif
+78
View File
@@ -0,0 +1,78 @@
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include "qtlockedfile.h"
bool QtLockedFile::lock(LockMode mode, bool block)
{
if (!isOpen()) {
qWarning("QtLockedFile::lock(): file is not opened");
return false;
}
if (mode == NoLock)
return unlock();
if (mode == m_lock_mode)
return true;
if (m_lock_mode != NoLock)
unlock();
struct flock fl;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK;
int cmd = block ? F_SETLKW : F_SETLK;
int ret = fcntl(handle(), cmd, &fl);
if (ret == -1) {
if (errno != EINTR && errno != EAGAIN)
qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
return false;
}
m_lock_mode = mode;
return true;
}
bool QtLockedFile::unlock()
{
if (!isOpen()) {
qWarning("QtLockedFile::unlock(): file is not opened");
return false;
}
if (!isLocked())
return true;
struct flock fl;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
fl.l_type = F_UNLCK;
int ret = fcntl(handle(), F_SETLKW, &fl);
if (ret == -1) {
qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
return false;
}
m_lock_mode = NoLock;
return true;
}
QtLockedFile::~QtLockedFile()
{
if (isOpen())
unlock();
}
+174
View File
@@ -0,0 +1,174 @@
#include "qtlockedfile.h"
#include <qt_windows.h>
#include <QFileInfo>
#define MUTEX_PREFIX "QtLockedFile mutex "
#define MAX_READERS MAXIMUM_WAIT_OBJECTS
#if QT_VERSION >= 0x050000
#define QT_WA(unicode, ansi) unicode
#endif
Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate)
{
if (mutexname.isEmpty()) {
QFileInfo fi(*this);
mutexname = QString::fromLatin1(MUTEX_PREFIX)
+ fi.absoluteFilePath().toLower();
}
QString mname(mutexname);
if (idx >= 0)
mname += QString::number(idx);
Qt::HANDLE mutex;
if (doCreate) {
QT_WA( { mutex = CreateMutexW(NULL, FALSE, (TCHAR*)mname.utf16()); },
{ mutex = CreateMutexA(NULL, FALSE, mname.toLocal8Bit().constData()); } );
if (!mutex) {
qErrnoWarning("QtLockedFile::lock(): CreateMutex failed");
return 0;
}
}
else {
QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (TCHAR*)mname.utf16()); },
{ mutex = OpenMutexA(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, mname.toLocal8Bit().constData()); } );
if (!mutex) {
if (GetLastError() != ERROR_FILE_NOT_FOUND)
qErrnoWarning("QtLockedFile::lock(): OpenMutex failed");
return 0;
}
}
return mutex;
}
bool QtLockedFile::waitMutex(Qt::HANDLE mutex, bool doBlock)
{
Q_ASSERT(mutex);
DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0);
switch (res) {
case WAIT_OBJECT_0:
case WAIT_ABANDONED:
return true;
break;
case WAIT_TIMEOUT:
break;
default:
qErrnoWarning("QtLockedFile::lock(): WaitForSingleObject failed");
}
return false;
}
bool QtLockedFile::lock(LockMode mode, bool block)
{
if (!isOpen()) {
qWarning("QtLockedFile::lock(): file is not opened");
return false;
}
if (mode == NoLock)
return unlock();
if (mode == m_lock_mode)
return true;
if (m_lock_mode != NoLock)
unlock();
if (!wmutex && !(wmutex = getMutexHandle(-1, true)))
return false;
if (!waitMutex(wmutex, block))
return false;
if (mode == ReadLock) {
int idx = 0;
for (; idx < MAX_READERS; idx++) {
rmutex = getMutexHandle(idx, false);
if (!rmutex || waitMutex(rmutex, false))
break;
CloseHandle(rmutex);
}
bool ok = true;
if (idx >= MAX_READERS) {
qWarning("QtLockedFile::lock(): too many readers");
rmutex = 0;
ok = false;
}
else if (!rmutex) {
rmutex = getMutexHandle(idx, true);
if (!rmutex || !waitMutex(rmutex, false))
ok = false;
}
if (!ok && rmutex) {
CloseHandle(rmutex);
rmutex = 0;
}
ReleaseMutex(wmutex);
if (!ok)
return false;
}
else {
Q_ASSERT(rmutexes.isEmpty());
for (int i = 0; i < MAX_READERS; i++) {
Qt::HANDLE mutex = getMutexHandle(i, false);
if (mutex)
rmutexes.append(mutex);
}
if (rmutexes.size()) {
DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(),
TRUE, block ? INFINITE : 0);
if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) {
if (res != WAIT_TIMEOUT)
qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed");
m_lock_mode = WriteLock;
unlock();
return false;
}
}
}
m_lock_mode = mode;
return true;
}
bool QtLockedFile::unlock()
{
if (!isOpen()) {
qWarning("QtLockedFile::unlock(): file is not opened");
return false;
}
if (!isLocked())
return true;
if (m_lock_mode == ReadLock) {
ReleaseMutex(rmutex);
CloseHandle(rmutex);
rmutex = 0;
}
else {
for (Qt::HANDLE mutex : qAsConst(rmutexes)) {
ReleaseMutex(mutex);
CloseHandle(mutex);
}
rmutexes.clear();
ReleaseMutex(wmutex);
}
m_lock_mode = QtLockedFile::NoLock;
return true;
}
QtLockedFile::~QtLockedFile()
{
if (isOpen())
unlock();
if (wmutex)
CloseHandle(wmutex);
}
+104
View File
@@ -0,0 +1,104 @@
#include "qtsingleapplication.h"
#include "qtlocalpeer.h"
#include <QWidget>
void QtSingleApplication::sysInit(const QString &appId)
{
actWin = nullptr;
peer = new QtLocalPeer(this, appId);
connect(peer, &QtLocalPeer::messageReceived, this, &QtSingleApplication::messageReceived);
}
QtSingleApplication::QtSingleApplication(int &argc, char **argv, bool GUIenabled)
: QApplication(argc, argv, GUIenabled)
{
sysInit();
}
QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char **argv)
: QApplication(argc, argv)
{
sysInit(appId);
}
bool QtSingleApplication::isRunning()
{
return peer->isClient();
}
bool QtSingleApplication::sendMessage(const QString &message, int timeout)
{
return peer->sendMessage(message, timeout);
}
QString QtSingleApplication::id() const
{
return peer->applicationId();
}
void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessage)
{
actWin = aw;
if (activateOnMessage)
connect(peer, &QtLocalPeer::messageReceived, this, &QtSingleApplication::activateWindow);
else
disconnect(peer, &QtLocalPeer::messageReceived, this, &QtSingleApplication::activateWindow);
}
QWidget* QtSingleApplication::activationWindow() const
{
return actWin;
}
void QtSingleApplication::activateWindow()
{
if (actWin) {
actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized);
actWin->raise();
actWin->activateWindow();
}
}
+56
View File
@@ -0,0 +1,56 @@
#ifndef QTSINGLEAPPLICATION_H
#define QTSINGLEAPPLICATION_H
#include <QApplication>
class QtLocalPeer;
#ifndef QTSINGLEAPPLICATION_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define QTSINGLEAPPLICATION_EXPORT
# else
# if defined(MAKE_QTSINGLEAPPLICATION_LIB)
# define QTSINGLEAPPLICATION_EXPORT Q_DECL_EXPORT
# else
# define QTSINGLEAPPLICATION_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
class QTSINGLEAPPLICATION_EXPORT QtSingleApplication : public QApplication
{
Q_OBJECT
public:
QtSingleApplication(int &argc, char **argv, bool GUIenabled = true);
QtSingleApplication(const QString &appId, int &argc, char **argv);
bool isRunning();
QString id() const;
void setActivationWindow(QWidget* aw, bool activateOnMessage = true);
QWidget* activationWindow() const;
void initialize(bool dummy = true)
{ isRunning(); Q_UNUSED(dummy) }
public Q_SLOTS:
bool sendMessage(const QString &message, int timeout = 5000);
void activateWindow();
Q_SIGNALS:
void messageReceived(const QString &message);
private:
void sysInit(const QString &appId = QString());
QtLocalPeer *peer;
QWidget *actWin;
};
#endif
+60
View File
@@ -0,0 +1,60 @@
#include "qtsinglecoreapplication.h"
#include "qtlocalpeer.h"
QtSingleCoreApplication::QtSingleCoreApplication(int &argc, char **argv)
: QCoreApplication(argc, argv)
{
peer = new QtLocalPeer(this);
connect(peer, &QtLocalPeer::messageReceived, this, &QtSingleCoreApplication::messageReceived);
}
QtSingleCoreApplication::QtSingleCoreApplication(const QString &appId, int &argc, char **argv)
: QCoreApplication(argc, argv)
{
peer = new QtLocalPeer(this, appId);
connect(peer, &QtLocalPeer::messageReceived, this, &QtSingleCoreApplication::messageReceived);
}
bool QtSingleCoreApplication::isRunning()
{
return peer->isClient();
}
bool QtSingleCoreApplication::sendMessage(const QString &message, int timeout)
{
return peer->sendMessage(message, timeout);
}
QString QtSingleCoreApplication::id() const
{
return peer->applicationId();
}
+46
View File
@@ -0,0 +1,46 @@
#ifndef QTSINGLECOREAPPLICATION_H
#define QTSINGLECOREAPPLICATION_H
#include <QCoreApplication>
class QtLocalPeer;
#ifndef QTSINGLECOREAPPLICATION_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define QTSINGLEAPPLICATION_EXPORT
# else
# if defined(MAKE_QTSINGLECOREAPPLICATION_LIB)
# define QTSINGLECOREAPPLICATION_EXPORT Q_DECL_EXPORT
# else
# define QTSINGLECOREAPPLICATION_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
class QTSINGLECOREAPPLICATION_EXPORT QtSingleCoreApplication : public QCoreApplication
{
Q_OBJECT
public:
QtSingleCoreApplication(int &argc, char **argv);
QtSingleCoreApplication(const QString &appId, int &argc, char **argv);
bool isRunning();
QString id() const;
public Q_SLOTS:
bool sendMessage(const QString &message, int timeout = 5000);
Q_SIGNALS:
void messageReceived(const QString &message);
private:
QtLocalPeer* peer;
};
#endif
+35
View File
@@ -0,0 +1,35 @@
#
# $Id$
# $HeadURL$
# $Author$
#
SET(wms_ds_SRCS
IECC2WMS.h
IWMS2ECC.h
wms_ecc_equipmenttypes.cpp
wms_ecc_equipmenttypes.h
wms_ecc_equipRequirements.cpp
wms_ecc_equipRequirements.h
wms_ecc_exercises.cpp
wms_ecc_exercises.h
wms_ecc_ibase.h
wms_ecc_playerInfo.cpp
wms_ecc_playerInfo.h
wms_ecc_registration.cpp
wms_ecc_registration.h
wms_ecc_unregister.cpp
wms_ecc_unregister.h
json_keys.h
)
NGL_ADD_LIBRARY2(AAR SV wms_json_ds SHARED ${wms_ds_SRCS})
NGL_TARGET_INCLUDE_DIRECTORIES(wms_json_ds
INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(wms_json_ds
PUBLIC
Qt5::Core
)
+20
View File
@@ -0,0 +1,20 @@
#pragma once
namespace WmsJson
{
class IECC2WMS
{
public:
IECC2WMS() = default;
virtual ~IECC2WMS() = default;
virtual void playerChanged(int playerId, int exerciseId) = 0;
virtual void exerciseDataChanged(int exerciseId, int betrZustand) = 0;
};
}
+137
View File
@@ -0,0 +1,137 @@
#pragma once
#include <QString>
#include <QMap>
#include <QSet>
#include <QMetaType>
class IWMS2ECC
{
public:
IWMS2ECC() = default;
virtual ~IWMS2ECC() = default;
enum RegisterReturnValue
{
RegistrationOk = 0,
PlayerNotFound = 1,
PlayerDeleted = 2,
AssignmentIncorrect = 3,
EquipNoAlreadyAssigned = 4,
RegistrationFailed = 5
};
enum UnregisterReturnValue
{
UnregisterOk = 0,
EquipNoNotFound = 1,
UnregisterFailed = 2
};
enum PlayerState
{
NOT_FOUND = 0,
FOUND = 1,
DELETED = 2
};
enum PlayerAssignState
{
UNDEFINED = -2,
NOT_ASSIGNED = -1,
ASSIGNED = 0,
HANDOUT_EXCON = 1,
HANDOUT_WMS = 2,
HANDOUT_EXCON_OVERRULED_WMS = 3
};
static inline PlayerAssignState int2PlayerAssignState(int s)
{
switch (s)
{
case UNDEFINED:
case NOT_ASSIGNED:
case ASSIGNED:
case HANDOUT_EXCON:
case HANDOUT_WMS:
case HANDOUT_EXCON_OVERRULED_WMS:
return static_cast<PlayerAssignState>(s);
}
Q_ASSERT(false);
return UNDEFINED;
}
struct PlayerInfo
{
PlayerState playerState = NOT_FOUND;
int playerId = -1;
int parentPlayerId = -1;
int equipNo = -1;
PlayerAssignState assignState = UNDEFINED;
int exerciseId = -1;
int forceId = -1;
int typeId = -1;
int equipTypeId = -1;
int typeClassId = -1;
int symbolColor = -1;
bool isDeleted = false;
QByteArray symbolPNG;
QString hierarchy;
QString designator;
QString tactIdent;
QString info;
QString alias;
QString forceName;
};
struct Exercise
{
int id = -1;
int actExercise = 0;
time_t start = 0;
time_t end = 0;
QString name;
QString stateAsString;
};
using exerciseMap = QMap<int, Exercise>;
struct EquipmentType
{
QString name;
int id = 0;
int specialType = 0;
int minEquipNo = 0;
int maxEquipNo = 0;
int taVulnerabilityModelId = 0;
int taPlayerTypeId = 0;
bool deletedInWMS = false;
};
using equipTypeMap = QMap<int, EquipmentType>;
virtual RegisterReturnValue registerPlayer(int playerId, int equipNo, const PlayerAssignState &zuordnung, const QString &alias,
const QString &info, int exerciseId) = 0;
virtual UnregisterReturnValue unregister(int equipNo, int exerciseId) = 0;
virtual PlayerInfo getPlayerInfo(int playerId, int exerciseId) = 0;
virtual exerciseMap getExercises() const = 0;
virtual Exercise getActualExercise() const = 0;
virtual QMap<int, int> getEquipRequirements(int exerciseId) const = 0;
virtual QMap<int, PlayerInfo> getAllPlayers(int exerciseId) const = 0;
virtual QMap<int, PlayerInfo> getAllVehicles(int exerciseId) const = 0;
virtual int getPlayerId(int equipNo, int exerciseId) const = 0;
virtual int getEquipNo(int playerId, int exerciseId) const = 0;
virtual int getTypeClassId(int equipTypeId) const = 0;
};
Q_DECLARE_METATYPE(IWMS2ECC::Exercise)
Q_DECLARE_METATYPE(IWMS2ECC::EquipmentType)
Q_DECLARE_METATYPE(IWMS2ECC::RegisterReturnValue)
+52
View File
@@ -0,0 +1,52 @@
#pragma once
#include <QtCore/QString>
namespace WebSocketInterface
{
namespace JsonKeys
{
inline QString EXERCISE_ID() { return QStringLiteral("exerciseId"); }
inline QString DATA_MODIFICATION() { return QStringLiteral("dataModification"); }
inline QString PARTICIPANT_ID() { return QStringLiteral("participantId"); }
inline QString REGISTRATION_RETURN_VALUE() { return QStringLiteral("registrationReturnValue"); }
inline QString EQUIPMENT_TYPES_REQUEST() { return QStringLiteral("equipmentTypesRequest"); }
inline QString EQUIPMENT_TYPES_REPLY() { return QStringLiteral("equipmentTypesReply"); }
inline QString EXERCISES_REQUEST() { return QStringLiteral("exercisesRequest"); }
inline QString EXERCISES_REPLY() { return QStringLiteral("exercisesReply"); }
inline QString EXERCISE_UPDATE() { return QStringLiteral("exercisesUpdate"); }
inline QString PARTICIPANTS_REQUEST() { return QStringLiteral("participantsRequest"); }
inline QString PARTICIPANTS_REPLY() { return QStringLiteral("participantsReply"); }
inline QString PARTICIPANTS_UPDATE() { return QStringLiteral("participantsUpdate"); }
inline QString PARTICIPANT_REGISTER_IN_EXCON_REQUEST() { return QStringLiteral("participantRegisterInEXCONRequest");}
inline QString PARTICIPANT_REGISTER_IN_EXCON_REPLY() { return QStringLiteral("participantRegisterInEXCONReply");}
}
}
+71
View File
@@ -0,0 +1,71 @@
#include "wms_ecc_equipRequirements.h"
#include <QJsonArray>
#include <QJsonObject>
QJsonObject EquipRequirements::toJson() const
{
QJsonArray arr;
for (QMap<int, int>::ConstIterator it = m_equipRequire.begin(); it != m_equipRequire.end(); ++it)
{
QJsonObject obj;
obj[QLatin1String("key")] = it.key();
obj[QLatin1String("value")] = it.value();
arr.append(obj);
}
QJsonObject retMap;
retMap[QLatin1String("equipMap")] = arr;
retMap[QLatin1String("ok")] = m_ok;
return retMap;
}
EquipRequirements EquipRequirements::fromJson(const QJsonObject &map)
{
EquipRequirements eq;
const QJsonArray arr = map[QLatin1String("equipMap")].toArray();
for (const auto &ele : arr)
{
const QJsonObject obj = ele.toObject();
int equipmentTypeId = obj[QLatin1String("key")].toInt();
int amount = obj[QLatin1String("value")].toInt();
eq.m_equipRequire.insert(equipmentTypeId, amount);
}
eq.m_ok = map[QLatin1String("ok")].toBool();
return eq;
}
QVariantMap EquipRequirements::toVariantMap() const
{
QVariantMap viMap;
for (QMap<int, int>::ConstIterator it = m_equipRequire.begin(); it != m_equipRequire.end(); ++it)
viMap.insert(QString::number(it.key()), QVariant(it.value()));
QVariantMap retMap;
retMap[QLatin1String("equipMap")] = QVariant(viMap);
retMap[QLatin1String("ok")] = QVariant(m_ok);
return retMap;
}
EquipRequirements EquipRequirements::fromVariantMap(const QVariantMap &map)
{
EquipRequirements eq;
const QVariantMap viMap = map[QLatin1String("equipMap")].toMap();
for (QVariantMap::ConstIterator it = viMap.begin(); it != viMap.end(); ++it)
{
const int key = it.key().toInt();
eq.m_equipRequire.insert(key, it.value().toInt());
}
eq.m_ok = map[QLatin1String("ok")].toBool();
return eq;
}
+30
View File
@@ -0,0 +1,30 @@
#pragma once
#include "wms_ecc_ibase.h"
#include "IWMS2ECC.h"
#include <QtCore/QVariantMap>
class WMS_JSON_DS_EXPORT EquipRequirements : public IBase
{
public:
QJsonObject toJson() const;
static EquipRequirements fromJson(const QJsonObject &map);
QVariantMap toVariantMap() const;
static EquipRequirements fromVariantMap(const QVariantMap &map);
QMap<int, int> getEquipRequirements() const { return m_equipRequire; }
bool getOk() const { return m_ok; }
void setEquipRequirements(const QMap<int, int> &equip) { m_equipRequire = equip; }
void setOk(bool ok) { m_ok = ok; }
private:
QMap<int, int> m_equipRequire;
bool m_ok = false;
};
+132
View File
@@ -0,0 +1,132 @@
#include "wms_ecc_equipmenttypes.h"
#include <QJsonArray>
QJsonObject EquipmentTypes::toJson(const IWMS2ECC::EquipmentType &et)
{
QJsonObject obj;
obj[QLatin1String("id")] = et.id;
obj[QLatin1String("name")] = et.name;
obj[QLatin1String("minEquipNo")] = et.minEquipNo;
obj[QLatin1String("maxEquipNo")] = et.maxEquipNo;
obj[QLatin1String("specialType")] = et.specialType;
obj[QLatin1String("taVulnerabilityModelId")] = et.taVulnerabilityModelId;
obj[QLatin1String("taPlayerTypeId")] = et.taPlayerTypeId;
obj[QLatin1String("deletedInWMS")] = et.deletedInWMS;
return obj;
}
IWMS2ECC::EquipmentType EquipmentTypes::fromJson(const QJsonObject &obj)
{
IWMS2ECC::EquipmentType et;
et.id = obj[QLatin1String("id")].toInt();
et.name = obj[QLatin1String("name")].toString();
et.minEquipNo = obj[QLatin1String("minEquipNo")].toInt();
et.maxEquipNo = obj[QLatin1String("maxEquipNo")].toInt();
et.specialType = obj[QLatin1String("specialType")].toInt();
et.taVulnerabilityModelId = obj[QLatin1String("taVulnerabilityModelId")].toInt();
et.taPlayerTypeId = obj[QLatin1String("taPlayerTypeId")].toInt();
et.deletedInWMS = obj[QLatin1String("deletedInWMS")].toBool();
return et;
}
QJsonObject EquipmentTypes::toJsonAll() const
{
QJsonArray arr;
for (const IWMS2ECC::EquipmentType &et : m_equipmentTypes)
arr.append(toJson(et));
QJsonObject retMap;
retMap[QLatin1String("etMap")] = arr;
retMap[QLatin1String("ok")] = m_ok;
return retMap;
}
EquipmentTypes EquipmentTypes::fromJsonAll(const QJsonObject &map)
{
EquipmentTypes ets;
const QJsonArray arr = map[QLatin1String("etMap")].toArray();
for (const auto &ele : arr)
{
const IWMS2ECC::EquipmentType val = fromJson(ele.toObject());
ets.m_equipmentTypes.insert(val.id, val);
}
ets.m_ok = map[QLatin1String("ok")].toBool();
return ets;
}
QVariantMap EquipmentTypes::toVariantMap() const
{
QVariantMap vMap;
vMap[QLatin1String("id")] = QVariant(m_equipmentType.id);
vMap[QLatin1String("name")] = m_equipmentType.name;
vMap[QLatin1String("minEquipNo")] = QVariant((int)m_equipmentType.minEquipNo);
vMap[QLatin1String("maxEquipNo")] = QVariant((int)m_equipmentType.maxEquipNo);
vMap[QLatin1String("specialType")] = QVariant(m_equipmentType.specialType);
vMap[QLatin1String("deletedInWMS")] = QVariant(m_equipmentType.deletedInWMS);
vMap[QLatin1String("ok")] = QVariant(m_ok);
return vMap;
}
EquipmentTypes EquipmentTypes::fromVariantMap(const QVariantMap &map)
{
EquipmentTypes ets;
ets.m_equipmentType.id = map[QLatin1String("id")].toInt();
ets.m_equipmentType.name = map[QLatin1String("name")].toString();
ets.m_equipmentType.minEquipNo = map[QLatin1String("minEquipNo")].toInt();
ets.m_equipmentType.maxEquipNo = map[QLatin1String("maxEquipNo")].toInt();
ets.m_equipmentType.specialType = map[QLatin1String("specialType")].toInt();
ets.m_equipmentType.deletedInWMS = map[QLatin1String("deletedInWMS")].toBool();
ets.m_ok = map[QLatin1String("ok")].toBool();
return ets;
}
QVariantMap EquipmentTypes::toVariantMapAll() const
{
QVariantMap vMap;
for (IWMS2ECC::equipTypeMap::ConstIterator it = m_equipmentTypes.begin(); it != m_equipmentTypes.end(); ++it)
{
m_equipmentType = it.value();
vMap.insert(QString::number(it.key()), QVariant(toVariantMap()));
}
QVariantMap retMap;
retMap[QLatin1String("etMap")] = QVariant(vMap);
retMap[QLatin1String("ok")] = QVariant(m_ok);
return retMap;
}
EquipmentTypes EquipmentTypes::fromVariantMapAll(const QVariantMap &map)
{
EquipmentTypes ets;
const QVariantMap vMap = map[QLatin1String("etMap")].toMap();
for (QVariantMap::ConstIterator it = vMap.begin(); it != vMap.end(); ++it)
{
int key = it.key().toInt();
IWMS2ECC::EquipmentType et = EquipmentTypes::fromVariantMap(it.value().toMap()).m_equipmentType;
ets.m_equipmentTypes.insert(key, et);
}
ets.m_ok = map[QLatin1String("ok")].toBool();
return ets;
}
+37
View File
@@ -0,0 +1,37 @@
#pragma once
#include "wms_ecc_ibase.h"
#include "IWMS2ECC.h"
#include <QJsonObject>
#include <QVariantMap>
class WMS_JSON_DS_EXPORT EquipmentTypes : public IBase
{
public:
QJsonObject toJsonAll() const;
static EquipmentTypes fromJsonAll(const QJsonObject &map);
static QJsonObject toJson(const IWMS2ECC::EquipmentType &et);
static IWMS2ECC::EquipmentType fromJson(const QJsonObject &obj);
QVariantMap toVariantMapAll() const;
static EquipmentTypes fromVariantMapAll(const QVariantMap &map);
QVariantMap toVariantMap() const;
static EquipmentTypes fromVariantMap(const QVariantMap &map);
IWMS2ECC::EquipmentType getEquipmentType() const { return m_equipmentType; }
IWMS2ECC::equipTypeMap getEquipmentTypes() const { return m_equipmentTypes; }
bool getOk() const { return m_ok; }
void setEquipmentType(const IWMS2ECC::EquipmentType &et) { m_equipmentType = et; }
void setEquipmentTypes(const IWMS2ECC::equipTypeMap &map) { m_equipmentTypes = map; }
void setOk(bool ok) { m_ok = ok; }
private:
IWMS2ECC::equipTypeMap m_equipmentTypes;
mutable IWMS2ECC::EquipmentType m_equipmentType;
bool m_ok = false;
};
+135
View File
@@ -0,0 +1,135 @@
#include "wms_ecc_exercises.h"
#include <QJsonArray>
#include <QJsonObject>
namespace EXCON
{
QJsonObject Exercises::toJson(const IWMS2ECC::Exercise &ex) const
{
QJsonObject obj;
obj[QLatin1String("id")] = ex.id;
obj[QLatin1String("actExercise")] = ex.actExercise;
obj[QLatin1String("start")] = static_cast<qint64>(ex.start);
obj[QLatin1String("end")] = static_cast<qint64>(ex.end);
obj[QLatin1String("name")] = ex.name;
obj[QLatin1String("state")] = ex.stateAsString;
obj[QLatin1String("ok")] = m_ok;
return obj;
}
IWMS2ECC::Exercise Exercises::fromJson(const QJsonObject &obj)
{
IWMS2ECC::Exercise ex;
ex.id = obj[QLatin1String("id")].toInt();
ex.actExercise = obj[QLatin1String("actExercise")].toInt();
ex.start = static_cast<time_t>(obj[QLatin1String("start")].toInt());
ex.end = static_cast<time_t>(obj[QLatin1String("end")].toInt());
ex.name = obj[QLatin1String("name")].toString();
ex.stateAsString = obj[QLatin1String("state")].toString();
return ex;
}
QJsonObject Exercises::toJsonAll() const
{
QJsonArray arr;
for (const IWMS2ECC::Exercise &ex : m_exercises)
arr.append(toJson(ex));
QJsonObject obj;
obj[QLatin1String("exMap")] = arr;
obj[QLatin1String("ok")] = m_ok;
return obj;
}
Exercises Exercises::fromJsonAll(const QJsonObject &map)
{
Exercises ex;
const QJsonArray arr = map[QLatin1String("exMap")].toArray();
for (const QJsonValue &val : arr)
{
const IWMS2ECC::Exercise exinfo = fromJson(val.toObject());
ex.m_exercises.insert(exinfo.id, exinfo);
}
ex.m_ok = map[QLatin1String("ok")].toBool();
return ex;
}
QVariantMap Exercises::toVariantMap() const
{
QVariantMap vMap;
vMap[QLatin1String("id")] = QVariant(m_exercise.id);
vMap[QLatin1String("name")] = m_exercise.name;
vMap[QLatin1String("start")] = QVariant(static_cast<qint64>(m_exercise.start));
vMap[QLatin1String("end")] = QVariant(static_cast<qint64>(m_exercise.end));
vMap[QLatin1String("state")] = m_exercise.stateAsString;
vMap[QLatin1String("ok")] = QVariant(m_ok);
return vMap;
}
Exercises Exercises::fromVariantMap(const QVariantMap &map)
{
Exercises ex;
ex.m_exercise.id = map[QLatin1String("id")].toInt();
ex.m_exercise.name = map[QLatin1String("name")].toString();
ex.m_exercise.start = map[QLatin1String("start")].toLongLong();
ex.m_exercise.end = map[QLatin1String("end")].toLongLong();
ex.m_exercise.stateAsString = map[QLatin1String("state")].toString();
ex.m_ok = map[QLatin1String("ok")].toBool();
return ex;
}
QVariantMap Exercises::toVariantMapAll() const
{
QVariantMap vMap;
for (IWMS2ECC::exerciseMap::ConstIterator it = m_exercises.begin(); it != m_exercises.end(); ++it)
{
m_exercise = it.value();
vMap.insert(QString::number(it.key()), QVariant(toVariantMap()));
}
QVariantMap retMap;
retMap[QLatin1String("exeMap")] = QVariant(vMap);
retMap[QLatin1String("ok")] = QVariant(m_ok);
return retMap;
}
Exercises Exercises::fromVariantMapAll(const QVariantMap &map)
{
Exercises ex;
const QVariantMap vMap = map[QLatin1String("exeMap")].toMap();
for (QVariantMap::ConstIterator it = vMap.begin(); it != vMap.end(); ++it)
{
int key = it.key().toInt();
IWMS2ECC::Exercise e = Exercises::fromVariantMap(it.value().toMap()).m_exercise;
ex.m_exercises.insert(key, e);
}
ex.m_ok = map[QLatin1String("ok")].toBool();
return ex;
}
}
+41
View File
@@ -0,0 +1,41 @@
#pragma once
#include "wms_ecc_ibase.h"
#include "IWMS2ECC.h"
#include <QVariantMap>
namespace EXCON
{
class WMS_JSON_DS_EXPORT Exercises : public IBase
{
public:
QJsonObject toJsonAll() const;
static Exercises fromJsonAll(const QJsonObject &map);
QJsonObject toJson(const IWMS2ECC::Exercise &ex) const;
static IWMS2ECC::Exercise fromJson(const QJsonObject &obj);
QVariantMap toVariantMapAll() const;
static Exercises fromVariantMapAll(const QVariantMap &map);
QVariantMap toVariantMap() const;
static Exercises fromVariantMap(const QVariantMap &map);
IWMS2ECC::Exercise getExercise() const { return m_exercise; }
IWMS2ECC::exerciseMap getExercises() const { return m_exercises; }
bool getOk() const { return m_ok; }
void setExercise(const IWMS2ECC::Exercise &exe) { m_exercise = exe; }
void setExercises(const IWMS2ECC::exerciseMap &exe) { m_exercises = exe; }
void setOk(bool ok) { m_ok = ok; }
private:
IWMS2ECC::exerciseMap m_exercises;
mutable IWMS2ECC::Exercise m_exercise;
bool m_ok = false;
};
}
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include <WMS_Interface/wms_json_ds_export.h>
class WMS_JSON_DS_EXPORT IBase
{
public:
IBase() = default;
virtual ~IBase() = default;
};
+176
View File
@@ -0,0 +1,176 @@
#include "wms_ecc_playerInfo.h"
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonDocument>
QJsonObject PlayerInfo::toJson(const IWMS2ECC::PlayerInfo &pi)
{
QJsonObject obj;
obj[QLatin1String("playerState")] = pi.playerState;
obj[QLatin1String("playerId")] = pi.playerId;
obj[QLatin1String("parentPlayerId")] = pi.parentPlayerId;
obj[QLatin1String("equipNo")] = pi.equipNo;
obj[QLatin1String("assignState")] = pi.assignState;
obj[QLatin1String("exerciseId")] = pi.exerciseId;
obj[QLatin1String("forceId")] = pi.forceId;
obj[QLatin1String("typeId")] = pi.typeId;
obj[QLatin1String("isDeleted")] = pi.isDeleted;
obj[QLatin1String("equipTypeId")] = pi.equipTypeId;
obj[QLatin1String("typeClassId")] = pi.typeClassId;
obj[QLatin1String("symbolColor")] = pi.symbolColor;
obj[QLatin1String("symbolPNG")] = QString::fromLatin1(pi.symbolPNG.toBase64());
obj[QLatin1String("hierarchy")] = pi.hierarchy;
obj[QLatin1String("designator")] = pi.designator;
obj[QLatin1String("tactIdent")] = pi.tactIdent;
obj[QLatin1String("info")] = pi.info;
obj[QLatin1String("alias")] = pi.alias;
obj[QLatin1String("forceName")] = pi.forceName;
return obj;
}
IWMS2ECC::PlayerInfo PlayerInfo::fromJson(const QJsonObject &obj)
{
IWMS2ECC::PlayerInfo pi;
pi.playerState = static_cast<IWMS2ECC::PlayerState>(obj[QLatin1String("playerState")].toInt());
pi.playerId = obj[QLatin1String("playerId")].toInt();
pi.parentPlayerId = obj[QLatin1String("parentPlayerId")].toInt();
pi.equipNo = obj[QLatin1String("equipNo")].toInt();
pi.assignState = static_cast<IWMS2ECC::PlayerAssignState>(obj[QLatin1String("assignState")].toInt());
pi.exerciseId = obj[QLatin1String("exerciseId")].toInt();
pi.forceId = obj[QLatin1String("forceId")].toInt();
pi.typeId = obj[QLatin1String("typeId")].toInt();
pi.isDeleted = obj[QLatin1String("isDeleted")].toBool();
pi.equipTypeId = obj[QLatin1String("equipTypeId")].toInt();
pi.typeClassId = obj[QLatin1String("typeClassId")].toInt();
pi.symbolColor = obj[QLatin1String("symbolColor")].toInt();
pi.symbolPNG = QByteArray::fromBase64(obj[QLatin1String("symbolPNG")].toString().toLatin1());
pi.hierarchy = obj[QLatin1String("hierarchy")].toString();
pi.designator = obj[QLatin1String("designator")].toString();
pi.tactIdent = obj[QLatin1String("tactIdent")].toString();
pi.info = obj[QLatin1String("info")].toString();
pi.alias = obj[QLatin1String("alias")].toString();
pi.forceName = obj[QLatin1String("forceName")].toString();
return pi;
}
QJsonObject PlayerInfo::toJsonAll() const
{
QJsonArray arr;
for (const IWMS2ECC::PlayerInfo &pi : m_allPlayerInfo)
arr.append(toJson(pi));
QJsonObject retMap;
retMap[QLatin1String("piMap")] = arr;
retMap[QLatin1String("ok")] = m_ok;
return retMap;
}
PlayerInfo PlayerInfo::fromJsonAll(const QJsonObject &map)
{
PlayerInfo pi;
const QJsonArray arr = map[QLatin1String("piMap")].toArray();
for (const QJsonValue &val : arr)
{
const IWMS2ECC::PlayerInfo player = fromJson(val.toObject());
pi.m_allPlayerInfo.insert(player.playerId, player);
}
pi.m_ok = map[QLatin1String("ok")].toBool();
return pi;
}
QVariantMap PlayerInfo::toVariantMap() const
{
QVariantMap retMap;
retMap[QLatin1String("playerId")] = QVariant(m_playerInfo.playerId);
retMap[QLatin1String("parentPlayerId")] = QVariant(m_playerInfo.parentPlayerId);
retMap[QLatin1String("equipNo")] = QVariant(m_playerInfo.equipNo);
retMap[QLatin1String("equipTypeId")] = QVariant(m_playerInfo.equipTypeId);
retMap[QLatin1String("typeClassId")] = QVariant(m_playerInfo.typeClassId);
retMap[QLatin1String("forceId")] = QVariant(m_playerInfo.forceId);
retMap[QLatin1String("designator")] = m_playerInfo.designator;
retMap[QLatin1String("tactIdent")] = m_playerInfo.tactIdent;
retMap[QLatin1String("hierarchy")] = m_playerInfo.hierarchy;
retMap[QLatin1String("forceName")] = m_playerInfo.forceName;
retMap[QLatin1String("info")] = m_playerInfo.info;
retMap[QLatin1String("alias")] = m_playerInfo.alias;
retMap[QLatin1String("symbolPNG")] = QVariant(m_playerInfo.symbolPNG);
retMap[QLatin1String("symbolColor")] = QVariant(m_playerInfo.symbolColor);
retMap[QLatin1String("assignState")] = QVariant(m_playerInfo.assignState);
retMap[QLatin1String("playerState")] = QVariant(m_playerInfo.playerState);
retMap[QLatin1String("ok")] = QVariant(m_ok);
return retMap;
}
PlayerInfo PlayerInfo::fromVariantMap(const QVariantMap &map)
{
PlayerInfo pi;
pi.m_playerInfo.playerId = map[QLatin1String("playerId")].toInt();
pi.m_playerInfo.parentPlayerId = map[QLatin1String("parentPlayerId")].toInt();
pi.m_playerInfo.equipNo = map[QLatin1String("equipNo")].toInt();
pi.m_playerInfo.forceId = map[QLatin1String("forceId")].toInt();
pi.m_playerInfo.equipTypeId = map[QLatin1String("equipTypeId")].toInt();
pi.m_playerInfo.typeClassId = map[QLatin1String("typeClassId")].toInt();
pi.m_playerInfo.designator = map[QLatin1String("designator")].toString();
pi.m_playerInfo.tactIdent = map[QLatin1String("tactIdent")].toString();
pi.m_playerInfo.hierarchy = map[QLatin1String("hierarchy")].toString();
pi.m_playerInfo.forceName = map[QLatin1String("forceName")].toString();
pi.m_playerInfo.info = map[QLatin1String("info")].toString();
pi.m_playerInfo.alias = map[QLatin1String("alias")].toString();
pi.m_playerInfo.symbolPNG = map[QLatin1String("symbolPNG")].toByteArray();
pi.m_playerInfo.symbolColor = map[QLatin1String("symbolColor")].toInt();
pi.m_playerInfo.assignState = (IWMS2ECC::PlayerAssignState) map[QLatin1String("assignState")].toInt();
pi.m_playerInfo.playerState = (IWMS2ECC::PlayerState) map[QLatin1String("playerState")].toInt();
pi.m_ok = map[QLatin1String("ok")].toBool();
return pi;
}
QVariantMap PlayerInfo::toVariantMapAll() const
{
QVariantMap vMap;
for (const IWMS2ECC::PlayerInfo &pi : m_allPlayerInfo)
{
m_playerInfo = pi;
vMap.insert(QString::number(pi.playerId), QVariant(toVariantMap()));
}
QVariantMap retMap;
retMap[QLatin1String("plMap")] = QVariant(vMap);
retMap[QLatin1String("ok")] = QVariant(m_ok);
return retMap;
}
PlayerInfo PlayerInfo::fromVariantMapAll(const QVariantMap &map)
{
PlayerInfo players;
const QVariantMap vMap = map[QLatin1String("plMap")].toMap();
for (const QVariant &data : vMap)
{
PlayerInfo player = PlayerInfo::fromVariantMap(data.toMap());
IWMS2ECC::PlayerInfo pi = player.getPlayerInfo();
players.m_allPlayerInfo.insert(pi.playerId, pi);
}
players.m_ok = vMap[QLatin1String("ok")].toBool();
return players;
}
+40
View File
@@ -0,0 +1,40 @@
#pragma once
#include "wms_ecc_ibase.h"
#include "IWMS2ECC.h"
#include <QtCore/QVariantMap>
class WMS_JSON_DS_EXPORT PlayerInfo : public IBase
{
public:
static QJsonObject toJson(const IWMS2ECC::PlayerInfo &pi);
static IWMS2ECC::PlayerInfo fromJson(const QJsonObject &obj);
QJsonObject toJsonAll() const;
static PlayerInfo fromJsonAll(const QJsonObject &map);
QVariantMap toVariantMap() const;
static PlayerInfo fromVariantMap(const QVariantMap &map);
QVariantMap toVariantMapAll() const;
static PlayerInfo fromVariantMapAll(const QVariantMap &map);
IWMS2ECC::PlayerInfo getPlayerInfo() const { return m_playerInfo; }
QMap<int, IWMS2ECC::PlayerInfo> getAllPlayerInfo() const { return m_allPlayerInfo; }
bool getOk() const { return m_ok; }
void setPlayerInfo(const IWMS2ECC::PlayerInfo &info) { m_playerInfo = info; }
void setAllPlayerInfo(const QMap<int, IWMS2ECC::PlayerInfo> &pi) { m_allPlayerInfo = pi; }
void setOk(bool ok) { m_ok = ok; }
private:
QMap<int, IWMS2ECC::PlayerInfo> m_allPlayerInfo;
mutable IWMS2ECC::PlayerInfo m_playerInfo;
bool m_ok = false;
};
+89
View File
@@ -0,0 +1,89 @@
#include "wms_ecc_registration.h"
#include <QJsonObject>
QJsonObject Registration::toJson() const
{
QJsonObject obj;
obj[QLatin1String("playerId")] = m_playerId;
obj[QLatin1String("assignment")] = m_assignment;
obj[QLatin1String("exerciseId")] = m_exerciseId;
obj[QLatin1String("ok")] = m_ok;
if (m_bEquipNoIsSet)
obj[QLatin1String("equipNo")] = m_equipNo;
if (m_bAliasIsSet)
obj[QLatin1String("alias")] = m_alias;
if (m_bInfoIsSet)
obj[QLatin1String("info")] = m_info;
return obj;
}
Registration Registration::fromJson(const QJsonObject &obj)
{
Registration rg;
rg.m_playerId = obj[QLatin1String("playerId")].toInt();
rg.m_assignment = IWMS2ECC::int2PlayerAssignState(obj[QLatin1String("assignment")].toInt());
rg.m_exerciseId = obj[QLatin1String("exerciseId")].toInt();
rg.m_bEquipNoIsSet = obj.contains(QLatin1String("equipNo"));
if (rg.m_bEquipNoIsSet)
rg.m_equipNo = obj[QLatin1String("equipNo")].toInt();
rg.m_bAliasIsSet = obj.contains(QLatin1String("alias"));
if (rg.m_bAliasIsSet)
rg.m_alias = obj[QLatin1String("alias")].toString();
rg.m_bInfoIsSet = obj.contains(QLatin1String("info"));
if (rg.m_bInfoIsSet)
rg.m_info = obj[QLatin1String("info")].toString();
rg.m_ok = obj[QLatin1String("ok")].toBool();
return rg;
}
QVariantMap Registration::toVariantMap() const
{
QVariantMap retMap;
retMap[QLatin1String("playerId")] = QVariant(m_playerId);
retMap[QLatin1String("assignment")] = QVariant(m_assignment);
retMap[QLatin1String("exerciseId")] = QVariant(m_exerciseId);
if (m_bEquipNoIsSet)
retMap[QLatin1String("equipNo")] = QVariant(m_equipNo);
if (m_bAliasIsSet)
retMap[QLatin1String("alias")] = m_alias;
if (m_bInfoIsSet)
retMap[QLatin1String("info")] = m_info;
retMap[QLatin1String("ok")] = QVariant(m_ok);
return retMap;
}
Registration Registration::fromVariantMap(const QVariantMap &map)
{
Registration rg;
rg.m_playerId = map[QLatin1String("playerId")].toInt();
rg.m_assignment = IWMS2ECC::int2PlayerAssignState(map[QLatin1String("assignment")].toInt());
rg.m_exerciseId = map[QLatin1String("exerciseId")].toInt();
rg.m_ok = map[QLatin1String("ok")].toBool();
rg.m_bEquipNoIsSet = map.contains(QLatin1String("equipNo"));
if (rg.m_bEquipNoIsSet)
rg.m_equipNo = map[QLatin1String("equipNo")].toInt();
rg.m_bAliasIsSet = map.contains(QLatin1String("alias"));
if (rg.m_bAliasIsSet)
rg.m_alias = map[QLatin1String("alias")].toString();
rg.m_bInfoIsSet = map.contains(QLatin1String("info"));
if (rg.m_bInfoIsSet)
rg.m_info = map[QLatin1String("info")].toString();
return rg;
}
+55
View File
@@ -0,0 +1,55 @@
#pragma once
#include "wms_ecc_ibase.h"
#include "IWMS2ECC.h"
#include <QtCore/QString>
#include <QtCore/QVariantMap>
class WMS_JSON_DS_EXPORT Registration : public IBase
{
public:
QJsonObject toJson() const;
static Registration fromJson(const QJsonObject &obj);
QVariantMap toVariantMap() const;
static Registration fromVariantMap(const QVariantMap &map);
int getPlayerId() const { return m_playerId; }
int getEquipNo() const { return m_equipNo; }
int getExerciseId() const { return m_exerciseId; }
QString getAlias() const { return m_alias; }
QString getInfo() const { return m_info; }
bool isEquipNoSet() const { return m_bEquipNoIsSet; }
bool isAliasSet() const { return m_bAliasIsSet; }
bool isInfoSet() const { return m_bInfoIsSet; }
IWMS2ECC::PlayerAssignState getAssignment() const { return m_assignment; }
bool getOk() const { return m_ok; }
void setPlayerId(int playerId) { m_playerId = playerId; }
void setEquipNo(int equipNo) { m_equipNo = equipNo; m_bEquipNoIsSet = true; }
void setAssignment(IWMS2ECC::PlayerAssignState assignment) { m_assignment = assignment; }
void setExerciseId(int exerciseId) { m_exerciseId = exerciseId; }
void setAlias(const QString &alias) { m_alias = alias; m_bAliasIsSet = true; }
void setInfo(const QString &info) { m_info = info; m_bInfoIsSet = true; }
void setOk(bool ok) { m_ok = ok; }
private:
QString m_alias;
QString m_info;
IWMS2ECC::PlayerAssignState m_assignment = IWMS2ECC::UNDEFINED;
int m_playerId = 0;
int m_equipNo = 0;
int m_exerciseId = -1;
bool m_bEquipNoIsSet = false;
bool m_bAliasIsSet = false;
bool m_bInfoIsSet = false;
bool m_ok = false;
};
+50
View File
@@ -0,0 +1,50 @@
#include "wms_ecc_unregister.h"
#include <QJsonObject>
QJsonObject Unregister::toJson() const
{
QJsonObject obj;
obj[QLatin1String("equipNo")] = m_equipNo;
obj[QLatin1String("exerciseId")] = m_exerciseId;
obj[QLatin1String("ok")] = m_ok;
return obj;
}
Unregister Unregister::fromJson(const QJsonObject &obj)
{
Unregister ur;
ur.m_equipNo = obj[QLatin1String("equipNo")].toInt();
ur.m_exerciseId = obj[QLatin1String("exerciseId")].toInt();
ur.m_ok = obj[QLatin1String("ok")].toBool();
return ur;
}
QVariantMap Unregister::toVariantMap() const
{
QVariantMap retMap;
retMap[QLatin1String("equipNo")] = QVariant(m_equipNo);
retMap[QLatin1String("exerciseId")] = QVariant(m_exerciseId);
retMap[QLatin1String("ok")] = QVariant(m_ok);
return retMap;
}
Unregister Unregister::fromVariantMap(const QVariantMap &map)
{
Unregister ur;
ur.m_equipNo = map[QLatin1String("equipNo")].toInt();
ur.m_exerciseId = map[QLatin1String("exerciseId")].toInt();
ur.m_ok = map[QLatin1String("ok")].toBool();
return ur;
}
+32
View File
@@ -0,0 +1,32 @@
#pragma once
#include "wms_ecc_ibase.h"
#include <QtCore/QString>
#include <QtCore/QVariantMap>
class WMS_JSON_DS_EXPORT Unregister : public IBase
{
public:
QJsonObject toJson() const;
static Unregister fromJson(const QJsonObject &obj);
QVariantMap toVariantMap() const;
static Unregister fromVariantMap(const QVariantMap &map);
int getEquipNo() const { return m_equipNo; }
int getExerciseId() const { return m_exerciseId; }
bool getOk() const { return m_ok; }
void setEquipNo(int equipNo) { m_equipNo = equipNo; }
void setExerciseId(int exerciseId) { m_exerciseId = exerciseId; }
void setOk(bool ok) { m_ok = ok; }
private:
int m_equipNo = 0;
int m_exerciseId = -1;
bool m_ok = false;
};
+134
View File
@@ -0,0 +1,134 @@
#
# $Id$
# $HeadURL$
# $Author$
#
#
# nglapplication
#
SET(nglapplication_SRCS
nglapplication.cpp
nglapplication.h
nglloggerhandler.cpp
nglloggerhandler.h
ngl_qt_msg_handler.inc
ngl_signal_handler.inc
)
NGL_ADD_LIBRARY(WS AAR SV HLA nglapplication SHARED ${nglapplication_SRCS})
NGL_TARGET_INCLUDE_DIRECTORIES(nglapplication
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(nglapplication
PRIVATE
NGLLogger
nglsettings
PUBLIC
Qt5::Core
Qt5::Widgets
)
NGL_INSTALL_TARGET(nglapplication)
#
# nglsingleapplication
#
SET(nglsingleapplication_SRCS
nglsingleapplication.cpp
nglsingleapplication.h
nglloggerhandler.cpp
nglloggerhandler.h
ngl_qt_msg_handler.inc
ngl_signal_handler.inc
)
NGL_ADD_LIBRARY(WS nglsingleapplication SHARED ${nglsingleapplication_SRCS})
NGL_TARGET_INCLUDE_DIRECTORIES(nglsingleapplication
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(nglsingleapplication
PRIVATE
NGLLogger
nglsettings
PUBLIC
qtsingleapplication
)
NGL_INSTALL_TARGET(nglsingleapplication)
#
# nglcoreapplication
#
SET(nglcoreapplication_SRCS
nglcoreapplication.cpp
nglcoreapplication.h
nglloggerhandler.cpp
nglloggerhandler.h
ngl_qt_msg_handler.inc
ngl_signal_handler.inc
)
NGL_ADD_LIBRARY(ALL nglcoreapplication SHARED ${nglcoreapplication_SRCS})
NGL_TARGET_INCLUDE_DIRECTORIES(nglcoreapplication
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(nglcoreapplication
PRIVATE
NGLLogger
nglsettings
PUBLIC
Qt5::Core
)
NGL_INSTALL_TARGET(nglcoreapplication)
#
# nglsinglecoreapplication
#
SET(nglsinglecoreapplication_SRCS
nglsinglecoreapplication.cpp
nglsinglecoreapplication.h
nglloggerhandler.cpp
nglloggerhandler.h
ngl_qt_msg_handler.inc
ngl_signal_handler.inc
)
NGL_ADD_LIBRARY(AAR SV nglsinglecoreapplication SHARED ${nglsinglecoreapplication_SRCS})
NGL_TARGET_INCLUDE_DIRECTORIES(nglsinglecoreapplication
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(nglsinglecoreapplication
PRIVATE
NGLLogger
nglsettings
PUBLIC
qtsinglecoreapplication
)
NGL_INSTALL_TARGET(nglsinglecoreapplication)
#
# nglguiapplication
#
SET(nglguiapplication_SRCS
nglguiapplication.cpp
nglguiapplication.h
nglloggerhandler.cpp
nglloggerhandler.h
ngl_qt_msg_handler.inc
ngl_signal_handler.inc
)
NGL_ADD_LIBRARY(ALL nglguiapplication SHARED ${nglguiapplication_SRCS})
NGL_TARGET_INCLUDE_DIRECTORIES(nglguiapplication
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(nglguiapplication
PRIVATE
NGLLogger
nglsettings
PUBLIC
Qt5::Gui
)
NGL_INSTALL_TARGET(nglguiapplication)
+64
View File
@@ -0,0 +1,64 @@
/**
* @RDE_HEADER@
* callback to catch qt log messages
* $Id$
* $HeadURL$
* $Author$
*/
#include <NGLLogger/NGLLoggerBootstrap.h>
#include <QtCore/qglobal.h>
static void qtMsgHandler(QtMsgType type, const QMessageLogContext &, const QString &msg)
{
// pulse audio connect errors are important but can be very annoying - so only print it ONE time only and also as an error
static bool pulseAudioMessageSent = false;
static QString pulseAudioMessage = QStringLiteral("PulseAudioService: pa_context_connect() failed");
if (msg.startsWith(pulseAudioMessage))
{
if (pulseAudioMessageSent)
{
return;
}
type = QtCriticalMsg;
pulseAudioMessageSent = true;
}
try
{
NGL::INGLLogger &l = NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger( "NGL.Qt" );
switch (type) {
case QtDebugMsg:
DEBUG_LOG(l) << msg ;
break;
case QtInfoMsg:
INFO_LOG(l) << msg ;
break;
case QtWarningMsg:
WARNING_LOG(l) << msg ;
break;
case QtCriticalMsg:
ERROR_LOG(l) << msg ;
break;
case QtFatalMsg:
FATAL_LOG(l) << msg ;
break;
}
} catch (...) {
switch (type)
{
case QtDebugMsg:
case QtInfoMsg:
fputs(qPrintable(msg), stdout);
break;
case QtWarningMsg:
case QtCriticalMsg:
case QtFatalMsg:
fputs(qPrintable(msg), stderr);
break;
}
}
}
+41
View File
@@ -0,0 +1,41 @@
/**
* @RDE_HEADER@
* small stub to catch SIGTERM for proper shutdown
* $Id$
* $HeadURL$
* $Author$
*/
#include <signal.h>
#include <QtCore/QCoreApplication>
#ifdef Q_OS_WIN
#include <QtCore/QAbstractNativeEventFilter>
#include <windows.h>
class MyEventFilter final : public QAbstractNativeEventFilter
{
public:
bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) override
{
Q_UNUSED(eventType);
Q_UNUSED(result);
const MSG *msg = reinterpret_cast<const MSG*>(message);
if (msg->message == WM_CLOSE && msg->hwnd == nullptr)
QCoreApplication::quit();
return false;
}
};
#endif
#ifndef SIGTERM
# define SIGTERM 15
#endif
static void signalHandler(int signal_number)
{
if(signal_number != SIGTERM)
return;
QCoreApplication::quit();
}
+31
View File
@@ -0,0 +1,31 @@
#include "nglapplication.h"
#include "ngl_signal_handler.inc"
NGLApplication::NGLApplication(int &argc, char **argv)
: QApplication(argc, argv)
{
signal(SIGTERM, &signalHandler);
#ifdef Q_OS_WIN
installNativeEventFilter(new MyEventFilter);
#endif
}
bool NGLApplication::notify(QObject *o, QEvent *e)
{
bool bRet = false;
try
{
bRet = QApplication::notify(o, e);
}
catch (const std::exception &e)
{
fprintf(stderr, "exception %s\n", e.what());
}
return bRet;
}
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#include <QApplication>
#include "nglloggerhandler.h"
#ifndef NGLAPPLICATION_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define NGLAPPLICATION_EXPORT
# else
# ifdef MAKE_NGLAPPLICATION_LIB
# define NGLAPPLICATION_EXPORT Q_DECL_EXPORT
# else
# define NGLAPPLICATION_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
namespace NGL
{
class INGLLogger;
}
class NGLAPPLICATION_EXPORT NGLApplication : public QApplication, public NGL::LoggerHandler
{
Q_OBJECT
public:
NGLApplication(int &argc, char **argv);
protected:
bool notify(QObject *o, QEvent *e) override;
};
#define nglApp static_cast<NGLApplication*>(NGLApplication::instance())
+17
View File
@@ -0,0 +1,17 @@
#include "nglcoreapplication.h"
#include "ngl_signal_handler.inc"
NGLCoreApplication::NGLCoreApplication(int &argc, char **argv)
: QCoreApplication(argc, argv)
{
signal(SIGTERM, &signalHandler);
#ifdef Q_OS_WIN
installNativeEventFilter(new MyEventFilter);
#endif
}
+31
View File
@@ -0,0 +1,31 @@
#pragma once
#include <QtCore/QCoreApplication>
#include "nglloggerhandler.h"
#ifndef NGLCOREAPPLICATION_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define NGLCOREAPPLICATION_EXPORT
# else
# ifdef MAKE_NGLCOREAPPLICATION_LIB
# define NGLCOREAPPLICATION_EXPORT Q_DECL_EXPORT
# else
# define NGLCOREAPPLICATION_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
namespace NGL
{
class INGLLogger;
}
class NGLCOREAPPLICATION_EXPORT NGLCoreApplication : public QCoreApplication, public NGL::LoggerHandler
{
Q_OBJECT
public:
NGLCoreApplication(int &argc, char **argv);
};
+17
View File
@@ -0,0 +1,17 @@
#include "nglguiapplication.h"
#include "ngl_signal_handler.inc"
NGLGuiApplication::NGLGuiApplication(int &argc, char **argv)
: QGuiApplication(argc, argv)
{
signal(SIGTERM, &signalHandler);
#ifdef Q_OS_WIN
installNativeEventFilter(new MyEventFilter);
#endif
}
+33
View File
@@ -0,0 +1,33 @@
#pragma once
#include <QtGui/QGuiApplication>
#include "nglloggerhandler.h"
#ifndef NGLGUIAPPLICATION_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define NGLGUIAPPLICATION_EXPORT
# else
# ifdef MAKE_NGLGUIAPPLICATION_LIB
# define NGLGUIAPPLICATION_EXPORT Q_DECL_EXPORT
# else
# define NGLGUIAPPLICATION_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
namespace NGL
{
class INGLLogger;
}
class NGLGUIAPPLICATION_EXPORT NGLGuiApplication : public QGuiApplication, public NGL::LoggerHandler
{
Q_OBJECT
public:
NGLGuiApplication(int &argc, char **argv);
};
#define nglGuiApp static_cast<NGLGuiApplication*>(NGLGuiApplication::instance())
+91
View File
@@ -0,0 +1,91 @@
#include "nglloggerhandler.h"
#include "ngl_qt_msg_handler.inc"
#include <NGLLogger/NGLLoggerBootstrap.h>
#include <nglsettings/nglsettings_settings.h>
#include <nglcoreapplication.h>
namespace NGL
{
static QByteArray username()
{
#ifdef Q_OS_WIN
return qgetenv("USERNAME");
#else
return qgetenv("USER");
#endif
}
static void setEnvVars()
{
const QString logPath = NGL::Settings::logPath();
qputenv("LOG4QT_LOGDIR", logPath.toLocal8Bit());
qputenv("LOG4QT_USER", username());
}
void LoggerHandler::createLogger(const QByteArray &baseName, const char *configFileName, bool quiet)
{
setEnvVars();
m_baseLoggerName = baseName;
const QString bnStr(QString::fromLatin1(baseName.toLower()));
const QString logPath = NGL::Settings::logPath();
m_loggerFilenamePostfix = logPath + QLatin1Char('/') + QString::fromLocal8Bit(username()) + QLatin1Char('_') + bnStr;
m_loggerFilenamePrefix = QLatin1String(".log");
const QString logOutputName = m_loggerFilenamePostfix + m_loggerFilenamePrefix;
NGL::NGLLoggerBootstrap::createNGLRootLogger(QString::fromLatin1(configFileName), false, logOutputName, quiet);
qInstallMessageHandler(&qtMsgHandler);
}
void LoggerHandler::createLogger(const QByteArray &baseName, int exerciseId, int additionalId, bool quiet)
{
setEnvVars();
const QString bnStr(QString::fromLatin1(baseName.toLower()));
const QString configFileName = QLatin1String("log4cxx_") + bnStr + QLatin1String(".props");
const QString logPath = NGL::Settings::logPath();
m_loggerFilenamePostfix = logPath + QLatin1Char('/') + QString::fromLocal8Bit(username()) + QLatin1Char('_') + bnStr;
if (exerciseId > 0)
m_loggerFilenamePostfix += QLatin1Char('_') + QString::number(exerciseId);
if (additionalId > 0)
m_loggerFilenamePostfix += QLatin1Char('_') + QString::number(additionalId);
m_loggerFilenamePrefix = QLatin1String(".log");
m_baseLoggerName = baseName + QByteArray(".main");
const QString logOutputName = m_loggerFilenamePostfix + m_loggerFilenamePrefix;
NGL::NGLLoggerBootstrap::createNGLRootLogger(configFileName, false, logOutputName, quiet);
qInstallMessageHandler(&qtMsgHandler);
}
NGL::INGLLogger &LoggerHandler::baseLogger() const
{
return NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger(m_baseLoggerName.data());
}
NGL::INGLLogger &LoggerHandler::logger(const char *loggerName) const
{
return NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger(loggerName);
}
LoggerHandler *LoggerHandler::getLoggerHandler()
{
return dynamic_cast<LoggerHandler*>(QCoreApplication::instance());
}
}
+67
View File
@@ -0,0 +1,67 @@
#pragma once
#include <QByteArray>
#include <QString>
#ifndef LOGGERHANDLER_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define LOGGERHANDLER_EXPORT
# else
# if defined(MAKE_NGLCOREAPPLICATION_LIB) || defined(MAKE_NGLGUIAPPLICATION_LIB) || defined(MAKE_NGLAPPLICATION_LIB) || defined(MAKE_NGLSINGLECOREAPPLICATION_LIB) || defined(MAKE_NGLSINGLEAPPLICATION_LIB)
# define LOGGERHANDLER_EXPORT Q_DECL_EXPORT
# else
# define LOGGERHANDLER_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
namespace NGL
{
class INGLLogger;
class LOGGERHANDLER_EXPORT LoggerHandler
{
public:
LoggerHandler() = default;
~LoggerHandler() = default;
void createLogger(const QByteArray &baseName,
const char *configFileName,
bool quiet = false);
void createLogger(const QByteArray &baseName,
int exerciseId = 0,
int additionalId = 0,
bool quiet = false);
NGL::INGLLogger &baseLogger() const;
NGL::INGLLogger &logger(const char *loggerName) const;
QString loggerNamePostfix() const { return m_loggerFilenamePostfix; }
QString loggerNamePrefix() const { return m_loggerFilenamePrefix; }
static LoggerHandler *getLoggerHandler();
private:
QByteArray m_baseLoggerName;
QString m_loggerFilenamePostfix;
QString m_loggerFilenamePrefix;
};
}
+32
View File
@@ -0,0 +1,32 @@
#include "nglsingleapplication.h"
#include "ngl_signal_handler.inc"
NGLSingleApplication::NGLSingleApplication(int &argc, char **argv)
: QtSingleApplication(argc, argv)
{
signal(SIGTERM, &signalHandler);
#ifdef Q_OS_WIN
installNativeEventFilter(new MyEventFilter);
#endif
}
bool NGLSingleApplication::notify(QObject *o, QEvent *e)
{
bool bRet = false;
try
{
bRet = QtSingleApplication::notify(o, e);
}
catch (const std::exception &e)
{
fprintf(stderr, "exception %s\n", e.what());
}
return bRet;
}
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#include <QtSingleApplication/QtSingleApplication>
#include "nglloggerhandler.h"
#ifndef NGLSINGLEAPPLICATION_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define NGLSINGLEAPPLICATION_EXPORT
# else
# ifdef MAKE_NGLSINGLEAPPLICATION_LIB
# define NGLSINGLEAPPLICATION_EXPORT Q_DECL_EXPORT
# else
# define NGLSINGLEAPPLICATION_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
namespace NGL
{
class INGLLogger;
}
class NGLSINGLEAPPLICATION_EXPORT NGLSingleApplication : public QtSingleApplication, public NGL::LoggerHandler
{
Q_OBJECT
public:
NGLSingleApplication(int &argc, char **argv);
protected:
bool notify(QObject *o, QEvent *e) override;
};
#define nglApp static_cast<NGLSingleApplication*>(NGLSingleApplication::instance())
+17
View File
@@ -0,0 +1,17 @@
#include "nglsinglecoreapplication.h"
#include "ngl_signal_handler.inc"
NGLSingleCoreApplication::NGLSingleCoreApplication(int &argc, char **argv)
: QtSingleCoreApplication(argc, argv)
{
signal(SIGTERM, &signalHandler);
#ifdef Q_OS_WIN
installNativeEventFilter(new MyEventFilter);
#endif
}
+31
View File
@@ -0,0 +1,31 @@
#pragma once
#include <QtSingleApplication/QtSingleCoreApplication>
#include "nglloggerhandler.h"
#ifndef NGLSINGLECOREAPPLICATION_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define NGLSINGLECOREAPPLICATION_EXPORT
# else
# ifdef MAKE_NGLSINGLECOREAPPLICATION_LIB
# define NGLSINGLECOREAPPLICATION_EXPORT Q_DECL_EXPORT
# else
# define NGLSINGLECOREAPPLICATION_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
namespace NGL
{
class INGLLogger;
}
class NGLSINGLECOREAPPLICATION_EXPORT NGLSingleCoreApplication : public QtSingleCoreApplication, public NGL::LoggerHandler
{
Q_OBJECT
public:
NGLSingleCoreApplication(int &argc, char **argv);
};
+47
View File
@@ -0,0 +1,47 @@
#
# CMake Script
# $Id$
# $HeadURL$
# $Author$
#
FIND_PACKAGE(BZip2 REQUIRED)
SET(nglcomp_SRCS
nglcomp_bzip2iodevice.cpp
nglcomp_bzip2iodevice.h
nglcomp_compress.cpp
nglcomp_compress.h
nglcomp_export.h
nglcomp_tarfilter.cpp
nglcomp_tarfilter.h
)
NGL_ADD_LIBRARY(WS nglcompression SHARED ${nglcomp_SRCS})
NGL_TARGET_LINK_LIBRARIES(nglcompression
PUBLIC
Qt5::Core
PRIVATE
Qt5::Concurrent
NGLLogger
${BZIP2_LIBRARIES}
# BZip2::BZip2 # not available with cmake 3.5
)
NGL_TARGET_INCLUDE_DIRECTORIES(nglcompression
PRIVATE
${BZIP2_INCLUDE_DIR}
)
NGL_INSTALL_TARGET(nglcompression)
IF(BUILD_WS AND BUILD_TESTING)
REMOVE_DEFINITIONS(-DQT_GUI_LIB)
ADD_EXECUTABLE(nglcomp_test nglcomp_test.cpp nglcomp_test.h)
TARGET_LINK_LIBRARIES(nglcomp_test
NGLLogger
nglcoreapplication
ngltools
nglcompression
Qt5::Test
)
ADD_TEST(NAME nglcomp_test COMMAND $<TARGET_FILE:nglcomp_test>)
ENDIF()
+360
View File
@@ -0,0 +1,360 @@
#include "nglcomp_bzip2iodevice.h"
#include <QIODevice>
#include <QString>
#include <bzlib.h>
class BZip2IODevice::Private
{
public:
Private(BZip2IODevice *parent_, QIODevice *dev, int bs)
: parent(parent_)
, device(dev)
, iCurPos(0)
, iMaxBufSize(1024 * 1024)
, blocksize(bs)
, initialized(false)
, decomressStreamEnd(false)
{
buffer.resize(iMaxBufSize);
}
bool initializeCompress();
qint64 doCompress(const char *in, qint64 iMaxLen);
bool finishCompress();
bool initializeDecompress();
qint64 doDecompress(char *out, qint64 iMaxLen);
bool finishDecompress();
static QString bzipError2String(int errCode);
QAtomicInt aborted { 0 };
BZip2IODevice *parent;
QIODevice *device;
unsigned int iCurPos;
unsigned int iMaxBufSize;
unsigned int blocksize;
bool initialized;
bool decomressStreamEnd;
QByteArray buffer;
bz_stream stream;
};
bool BZip2IODevice::Private::initializeCompress()
{
if (initialized)
return true;
memset(&stream, 0, sizeof(stream));
int blockSize = (blocksize > 0 && blocksize < 10) ? blocksize : 10;
int ret = BZ2_bzCompressInit(&stream, blockSize, 0, 0);
if (ret != BZ_OK)
{
parent->setErrorString(QStringLiteral("Error initializing bzip2 %1").arg(bzipError2String(ret)));
initialized = false;
}
else
initialized = true;
return initialized;
}
qint64 BZip2IODevice::Private::doCompress(const char *in, qint64 iMaxLen)
{
if (!initialized)
{
if (parent->errorString().isEmpty())
parent->setErrorString(QLatin1String("Internal Error - bzip not initialized"));
finishCompress();
return -1;
}
if (iMaxLen > 2 * 1024 * 1024 * 1024LL)
{
finishCompress();
parent->setErrorString(QLatin1String("Currently can't handle more than 2GB!"));
return -1;
}
stream.next_in = const_cast<char *>(in);
stream.avail_in = iMaxLen;
do
{
if (aborted) return 0;
stream.next_out = buffer.data();
stream.avail_out = buffer.size();
const int ret = BZ2_bzCompress(&stream, BZ_RUN);
if (ret != BZ_RUN_OK)
{
finishCompress();
parent->setErrorString(QStringLiteral("Error executing BZ2_bzCompress: %1").arg(bzipError2String(ret)));
return -1;
}
int iBytesToWrite = buffer.size() - stream.avail_out;
if (iBytesToWrite)
{
if (device->write(buffer.constData(), iBytesToWrite) != iBytesToWrite)
{
finishCompress();
parent->setErrorString(QLatin1String("Error writing to QIODevice"));
return -1;
}
}
}
while (stream.avail_in != 0);
return stream.next_in - in;
}
bool BZip2IODevice::Private::finishCompress()
{
if (!initialized || aborted)
return true;
int ret = -1;
do
{
stream.next_out = buffer.data();
stream.avail_out = buffer.size();
ret = BZ2_bzCompress(&stream, BZ_FINISH);
if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
{
finishCompress();
parent->setErrorString(QStringLiteral("Error executing BZ2_bzCompress: %1").arg(bzipError2String(ret)));
return false;
}
int iBytesToWrite = buffer.size() - stream.avail_out;
if (device->write(buffer.constData(), iBytesToWrite) != iBytesToWrite)
{
finishCompress();
parent->setErrorString(QLatin1String("Error writing to QIODevice"));
return false;
}
}
while (ret != BZ_STREAM_END);
BZ2_bzCompressEnd(&stream);
initialized = false;
return true;
}
bool BZip2IODevice::Private::initializeDecompress()
{
if (initialized)
return true;
memset(&stream, 0, sizeof(stream));
int ret = BZ2_bzDecompressInit(&stream, 0, 0);
if (ret != BZ_OK)
{
parent->setErrorString(QStringLiteral("Error initializing bzip2: %1").arg(bzipError2String(ret)));
initialized = false;
}
else
initialized = true;
decomressStreamEnd = false;
return initialized;
}
qint64 BZip2IODevice::Private::doDecompress(char *out, qint64 iMaxLen)
{
int ret = -1;
if (!initialized)
{
if (parent->errorString().isEmpty())
parent->setErrorString(QLatin1String("Internal Error - bzip not initialized"));
finishDecompress();
return -1;
}
if (decomressStreamEnd)
return 0;
if (iMaxLen > 2 * 1024 * 1024 * 1024LL)
{
finishCompress();
parent->setErrorString(QLatin1String("Currently can't handle more than 2GB!"));
return -1;
}
stream.next_out = out;
stream.avail_out = iMaxLen;
do
{
if (ret != BZ_STREAM_END && stream.avail_in == 0)
{
qint64 iReadCnt = device->read(buffer.data(), buffer.size());
if (iReadCnt <= 0)
return -1;
stream.next_in = buffer.data();
stream.avail_in = iReadCnt;
}
ret = BZ2_bzDecompress(&stream);
if (ret != BZ_OK && ret != BZ_STREAM_END)
{
parent->setErrorString(QStringLiteral("Error executing BZ2_bzCompress: %1").arg(bzipError2String(ret)));
finishDecompress();
return -1;
}
}
while (stream.avail_out != 0 && ret != BZ_STREAM_END);
decomressStreamEnd = (ret == BZ_STREAM_END);
return stream.next_out - out;
}
bool BZip2IODevice::Private::finishDecompress()
{
if (!initialized)
return true;
BZ2_bzDecompressEnd(&stream);
initialized = false;
return true;
}
QString BZip2IODevice::Private::bzipError2String(int errCode)
{
switch (errCode)
{
case BZ_SEQUENCE_ERROR:
return QLatin1String("Sequence error");
case BZ_PARAM_ERROR:
return QLatin1String("Parameter not correct");
case BZ_MEM_ERROR:
return QLatin1String("Memory allocation error");
case BZ_DATA_ERROR:
return QLatin1String("Invalid input data");
case BZ_DATA_ERROR_MAGIC:
return QLatin1String("Not a bzip2 file");
case BZ_IO_ERROR:
return QLatin1String("I/O error");
case BZ_UNEXPECTED_EOF:
return QLatin1String("Unexpected end of file");
case BZ_OUTBUFF_FULL:
return QLatin1String("Output buffer full");
case BZ_CONFIG_ERROR:
return QLatin1String("Wrong config parameter");
};
return QString::number(errCode);
}
BZip2IODevice::BZip2IODevice(QIODevice *dev, int blocksize)
: d(new Private(this, dev, blocksize))
{}
BZip2IODevice::~BZip2IODevice()
{
close();
delete d;
}
void BZip2IODevice::setBufferSize(unsigned int size)
{
d->iMaxBufSize = size > 1024 ? size : 1024;
d->buffer.resize(d->iMaxBufSize);
}
void BZip2IODevice::setBlockSize(unsigned int size)
{
if (isOpen())
return;
d->blocksize = size;
}
bool BZip2IODevice::isSequential() const
{
return true;
}
bool BZip2IODevice::open(OpenMode mode)
{
if ((mode & QIODevice::ReadWrite) == 0)
{
setErrorString(QStringLiteral("Unsupported OpenMode %1").arg(mode));
return false;
}
if ((mode & QIODevice::ReadWrite) == QIODevice::ReadWrite)
{
setErrorString(QLatin1String("Can't read and write simultaniously"));
return false;
}
if ((mode & QIODevice::ReadOnly) == QIODevice::ReadOnly)
{
if (!d->device)
{
setErrorString(QLatin1String("No QIODevice for reading available"));
return false;
}
if ((d->device->openMode() & QIODevice::ReadOnly) == 0)
{
setErrorString(QLatin1String("QIODevice not opened for reading"));
return false;
}
if (!d->initializeDecompress())
return false;
}
else
{
if (!d->device)
{
setErrorString(QLatin1String("No QIODevice for writing available"));
return false;
}
if ((d->device->openMode() & QIODevice::WriteOnly) == 0)
{
setErrorString(QLatin1String("QIODevice not opened for writing"));
return false;
}
if (!d->initializeCompress())
return false;
}
setErrorString(QString());
setOpenMode(mode);
return QIODevice::open(mode);
}
void BZip2IODevice::abort()
{
d->aborted = 1;
}
void BZip2IODevice::close()
{
if (!isOpen())
return;
if ((openMode() & QIODevice::ReadOnly) == QIODevice::ReadOnly)
d->finishDecompress();
else
d->finishCompress();
QIODevice::close();
}
bool BZip2IODevice::atEnd() const
{
if (!d->device)
return true;
return d->device->atEnd() && d->decomressStreamEnd && QIODevice::atEnd();
}
qint64 BZip2IODevice::readData(char *data, qint64 maxSize)
{
return d->doDecompress(data, maxSize);
}
qint64 BZip2IODevice::writeData(const char *data, qint64 maxSize)
{
return d->doCompress(data, maxSize);
}
+42
View File
@@ -0,0 +1,42 @@
#ifndef BZIP2IODEVICE_H
#define BZIP2IODEVICE_H
#include <QString>
#include <QIODevice>
class BZip2IODevice : public QIODevice
{
public:
BZip2IODevice(QIODevice *dev, int blocksize = 5);
virtual ~BZip2IODevice();
void abort();
void setBufferSize(unsigned int size);
void setBlockSize(unsigned int size);
virtual bool isSequential() const;
virtual bool open(OpenMode mode);
virtual void close();
virtual bool atEnd() const;
protected:
virtual qint64 readData(char *data, qint64 maxSize);
virtual qint64 writeData(const char *data, qint64 maxSize);
private:
class Private;
friend class Private;
Private *const d;
};
#endif
+566
View File
@@ -0,0 +1,566 @@
#include "nglcomp_compress.h"
#include "nglcomp_bzip2iodevice.h"
#include "nglcomp_tarfilter.h"
#include <NGLLogger/NGLLoggerBootstrap.h>
#include <QBuffer>
#include <QtConcurrent>
#include <QCoreApplication>
#include <QDir>
#include <QFileInfo>
#include <QFutureWatcher>
#include <QIODevice>
#include <QStringList>
#include <memory>
#include <QDebug>
namespace NGL
{
Compress::Compress(QObject *parent)
: QObject(parent)
, m_u2_memFiles()
, m_aborted(0)
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("nglcompress"))
{
DEBUG_LOG(m_logger) << "c_tor";
QTimer *t = new QTimer(this);
t->setInterval(1000);
connect(t, &QTimer::timeout, this, [](){qWarning() << "still alive ...";});
t->start();
}
Compress::~Compress()
{
qWarning() << "## COMPRESS DTOR!!!!";
DEBUG_LOG(m_logger) << "~";
abort();
m_future.waitForFinished();
DEBUG_LOG(m_logger) << "~ finished";
}
void Compress::abort()
{
DEBUG_LOG(m_logger) << "ABORT";
m_aborted = 1;
m_lastError = tr("Aborted");
if (m_currentTarFilter != nullptr)
{
DEBUG_LOG(m_logger) << "aborting tar";
m_currentTarFilter->abort();
}
if (m_currentBzipDevice != nullptr)
{
DEBUG_LOG(m_logger) << "aborting bzip";
m_currentBzipDevice->abort();
}
}
void Compress::compress(QIODevice *out,
const QString &filesRootDir,
const QVector<FileInformations> &files,
const QVector<FileInformations> &memFiles,
const QString &destRootDir)
{
DEBUG_LOG(m_logger) << "compress #2";
reset();
setupFutureWatcher(QtConcurrent::run(this, &Compress::_compress, out, filesRootDir, files, memFiles, destRootDir));
}
void Compress::compress(QIODevice *out, const QString &sourceDir, const QString &destRootDir)
{
DEBUG_LOG(m_logger) << "compress #1 source dir: " << sourceDir << ", destRootDir: " << destRootDir;
reset();
QVector<Compress::FileInformations> inFiles = directoryFileList(sourceDir, true);
int len = sourceDir.length();
if (!sourceDir.endsWith(QLatin1Char('/')))
len += 1;
for (auto &fi : inFiles)
{
fi.inputFileName = fi.inputFileName.mid(len);
fi.bAbsInputPath = false;
DEBUG_LOG(m_logger) << "fi: ifm = " << fi.inputFileName << ", abs = " << fi.bAbsInputPath;
}
DEBUG_LOG(m_logger) << "FI list size: " << inFiles.count();
compress(out, sourceDir, inFiles, {}, destRootDir);
}
bool Compress::_compress(QIODevice *output,
const QString &filesRootDir,
const QVector<FileInformations> &files,
const QVector<FileInformations> &memFiles,
const QString &_destRootDir)
{
std::shared_ptr<int> invalidatePointersOnScopeLeave(nullptr, [this](int *)
{
DEBUG_LOG(m_logger) << "invalidatePointersOnScopeLeave #1";
m_currentTarFilter = nullptr;
m_currentBzipDevice = nullptr;
});
(void)invalidatePointersOnScopeLeave;
if (!output || !output->isWritable())
{
m_lastError = tr("Device is not writeable");
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;;
return false;
}
const QString destRootDir = _destRootDir.endsWith(QLatin1Char('/')) ?
_destRootDir : _destRootDir + QLatin1Char('/');
const qint64 maxCount = files.count() + memFiles.count();
qint64 count = 0;
DEBUG_LOG(m_logger) << "destRootDir = " << destRootDir << ", maxCount = " << maxCount << ", count = " << count;
BZip2IODevice bzip2(output, 9);
m_currentBzipDevice = &bzip2;
if (!bzip2.open(QIODevice::WriteOnly))
{
m_lastError = bzip2.errorString();
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
return false;
}
qint64 bytesTotal = 0;
for (const FileInformations &file : qAsConst(files))
{
if (m_aborted) return false;
const QString in = file.bAbsInputPath ? file.inputFileName : filesRootDir + QLatin1Char('/') + file.inputFileName;
const QFileInfo fi(in);
bytesTotal += fi.size();
}
qint64 currentFileSize = 0;
QString currentFileName;
auto readCallback = [this, &maxCount, &count, &currentFileSize, &currentFileName, &bytesTotal](const qint64 iSize)
{
DEBUG_LOG(m_logger) << "readCallback: maxCount = " << maxCount << ", count = " << count
<< ", currentFileSize = " << currentFileSize << ", currentFileName = " << currentFileName << ", iSize = " << iSize;
emit compressInfoEx(maxCount, count, currentFileSize, (currentFileSize - iSize), currentFileName, bytesTotal);
};
TarFilter tf(&bzip2, nullptr, readCallback);
m_currentTarFilter = &tf;
const QVector<QStringRef> paths = destRootDir.splitRef(QLatin1Char('/'), QString::SkipEmptyParts);
QString curPath;
DEBUG_LOG(m_logger) << "prepairing tar filter";
for (const QStringRef &path : paths)
{
DEBUG_LOG(m_logger) << "path = " << path.toString();
if (m_aborted) return false;
if (curPath.isEmpty())
curPath = path + QLatin1Char('/');
else
curPath += path + QLatin1Char('/');
DEBUG_LOG(m_logger) << "curPath = " << curPath << ", filesRootDir.isEmpty() = " << filesRootDir.isEmpty();
if (filesRootDir.isEmpty())
{
if (!tf.addData(curPath, QByteArray(), true))
{
m_lastError = tf.lastError();
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
return false;
}
}
else
{
if (!tf.addFile(filesRootDir, curPath))
{
m_lastError = tf.lastError();
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
return false;
}
}
}
m_c_sizeInfo.realSize = 0;
for (const FileInformations &file : qAsConst(files))
{
DEBUG_LOG(m_logger) << "file = " << file.inputFileName;
emit compressInfo(maxCount, ++count, file.inputFileName);
if (m_aborted) return false;
QString in = file.bAbsInputPath ? file.inputFileName : filesRootDir + QLatin1Char('/') + file.inputFileName;
QString out = destRootDir + (file.outputFileName.isEmpty() ? file.inputFileName : file.outputFileName);
DEBUG_LOG(m_logger) << "in = " << in << ", out = " << out;
QFileInfo fi(in);
currentFileName = fi.fileName();
currentFileSize = fi.size();
m_c_sizeInfo.realSize += currentFileSize;
DEBUG_LOG(m_logger) << "currentFileName = " << currentFileName << ", currentFileSize = " << currentFileSize << "m_c_sizeInfo.realSize" << m_c_sizeInfo.realSize;
if (!tf.addFile(in, out))
{
m_lastError = tf.lastError();
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
return false;
}
}
for (const FileInformations &file : qAsConst(memFiles))
{
DEBUG_LOG(m_logger) << "(mem) file = " << file.inputFileName;
emit compressInfo(maxCount, ++count, file.inputFileName);
if (m_aborted) return false;
currentFileName = file.inputFileName;
currentFileSize = file.fileData.size();
m_c_sizeInfo.compressedSize += currentFileSize;
DEBUG_LOG(m_logger) << "(mem) currentFileName = " << currentFileName << ", currentFileSize = " << currentFileSize << "m_c_sizeInfo.realSize" << m_c_sizeInfo.realSize;
if (!tf.addData(file.inputFileName, file.fileData))
{
m_lastError = tf.lastError();
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
return false;
}
}
DEBUG_LOG(m_logger) << "writing eos";
tf.writeEOS();
DEBUG_LOG(m_logger) << "closing bzip";
bzip2.close();
m_c_sizeInfo.compressedSize = output->size();
DEBUG_LOG(m_logger) << "m_c_sizeInfo.compressedSize = " << m_c_sizeInfo.compressedSize;
m_success = true;
DEBUG_LOG(m_logger) << "DONE!";
return true;
}
void Compress::uncompress(QIODevice *in, const QString &outDir)
{
DEBUG_LOG(m_logger) << "uncompress #1";
reset();
setupFutureWatcher(QtConcurrent::run(this, &Compress::_uncompressDirectory, in, outDir));
}
bool Compress::_uncompressDirectory(QIODevice *input, const QString &outDir)
{
DEBUG_LOG(m_logger) << "_uncompressDirectory";
std::shared_ptr<int> invalidatePointersOnScopeLeave(nullptr, [this](int *)
{
DEBUG_LOG(m_logger) << "invalidatePointersOnScopeLeave #2";
m_currentTarFilter = nullptr;
m_currentBzipDevice = nullptr;
});
(void)invalidatePointersOnScopeLeave;
if (!input || !input->isReadable())
{
m_lastError = tr("Device is not readable");
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
return false;
}
BZip2IODevice bzip2(input, 9);
m_currentBzipDevice = &bzip2;
if (!bzip2.open(QIODevice::ReadOnly))
{
m_lastError = bzip2.errorString();
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
return false;
}
TarFilter tf(&bzip2);
m_currentTarFilter = &tf;
TarFilter::FileInformations tfi;
QDir dir(outDir);
DEBUG_LOG(m_logger) << "dir = " << dir.path();
while (tf.getData(tfi))
{
DEBUG_LOG(m_logger) << "tfi.fileName = " << tfi.fileName;
emit uncompressInfo(input->size(), input->pos(), tfi.fileName);
if (m_aborted) return false;
QString path = outDir + QLatin1Char('/') + tfi.fileName;
DEBUG_LOG(m_logger) << "path = " << path;
if (tfi.fileType == TarFilter::directory)
{
DEBUG_LOG(m_logger) << "tfi.fileType == TarFilter::directory";
if (!dir.exists(path) && !dir.mkpath(path))
{
m_lastError = tr("Error creating directory %1").arg(outDir);
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
return false;
}
}
else
{
QString pathName = QFileInfo(path).absolutePath();
if (!dir.exists(pathName) && !dir.mkpath(pathName))
{
m_lastError = tr("Error creating directory %1").arg(pathName);
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
return false;
}
QFile f(path);
if (!f.open(QIODevice::WriteOnly))
{
m_lastError = tr("Error opening %1 for writing (%2)").arg(path, f.errorString());
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
return false;
}
if (!tf.getData(&f))
{
m_lastError = tf.lastError();
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
return false;
}
}
}
DEBUG_LOG(m_logger) << "uncompress done!";
m_success = true;
return true;
}
void Compress::uncompress(QIODevice *in)
{
DEBUG_LOG(m_logger) << "uncompress #2!";
reset();
setupFutureWatcher(QtConcurrent::run(this, &Compress::_uncompressBuffer, in));
}
bool Compress::_uncompressBuffer(QIODevice *input)
{
DEBUG_LOG(m_logger) << "uncompressBuffer";
std::shared_ptr<int> invalidatePointersOnScopeLeave(nullptr, [this](int *)
{
DEBUG_LOG(m_logger) << "invalidatePointersOnScopeLeave #2";
m_currentTarFilter = nullptr;
m_currentBzipDevice = nullptr;
});
(void)invalidatePointersOnScopeLeave;
if (!input->isReadable())
{
m_lastError = tr("Device is not readable");
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
return false;
}
BZip2IODevice bzip2(input, 9);
m_currentBzipDevice = &bzip2;
if (!bzip2.open(QIODevice::ReadOnly))
{
m_lastError = bzip2.errorString();
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
return false;
}
TarFilter tf(&bzip2);
m_currentTarFilter = &tf;
TarFilter::FileInformations tfi;
while (tf.getData(tfi))
{
DEBUG_LOG(m_logger) << "tfi.fileName = " << tfi.fileName;
emit uncompressInfo(input->size(), input->pos(), tfi.fileName);
if (m_aborted) return false;
FileInformations fi;
fi.outputFileName = tfi.fileName;
DEBUG_LOG(m_logger) << "fi.outputFileName = " << fi.outputFileName;
if (tfi.fileType == TarFilter::directory)
{
fi.outputFileName += QLatin1Char('/');
DEBUG_LOG(m_logger) << "> fi.outputFileName = " << fi.outputFileName;
}
else
{
DEBUG_LOG(m_logger) << "stuff";
QBuffer buf(&fi.fileData);
if (!buf.open(QIODevice::WriteOnly))
{
m_lastError = tr("Error opening buffer for writing (%1)").arg(buf.errorString());
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
return false;
}
if (!tf.getData(&buf))
{
m_lastError = tf.lastError();
ERROR_LOG(m_logger) << "compress failed: " << m_lastError;
return false;
}
}
fi.bAbsInputPath = fi.outputFileName.startsWith(QLatin1Char('/'));
DEBUG_LOG(m_logger) << "added fi.bAbsInputPath = " << fi.bAbsInputPath;
m_u2_memFiles += fi;
}
return true;
}
bool Compress::success() const
{
ERROR_LOG(m_logger) << "success? " << (m_future.isFinished() && !m_future.isCanceled() && m_success);
ERROR_LOG(m_logger) << "success details: "
<< "success m_future.isFinished() = " << (m_future.isFinished())
<< " !m_future.isCanceled() = " << !m_future.isCanceled()
<< " m_success = " << m_success;
return (m_future.isFinished() && !m_future.isCanceled() && m_success);
}
bool Compress::waitForFinished()
{
DEBUG_LOG(m_logger) << "waitForFinished...";
m_future.waitForFinished();
DEBUG_LOG(m_logger) << "waitForFinished... done!";
return success();
}
QVector<Compress::FileInformations> Compress::directoryFileList(const QString &dir, bool recursive)
{
DEBUG_LOG(m_logger) << "directoryFileList";
QVector<FileInformations> sl_absolute;
QDir d(dir);
if (d.exists())
{
DEBUG_LOG(m_logger) << "exists";
const auto entries = d.entryList(QDir::Files);
sl_absolute.reserve(sl_absolute.size() + entries.size());
for (const QString &entry : entries)
sl_absolute << FileInformations(QFileInfo(d, entry).absoluteFilePath(), true);
}
if (recursive)
{
DEBUG_LOG(m_logger) << "recursive";
const auto entries = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
sl_absolute.reserve(sl_absolute.size() + entries.size());
for (const QString &s : entries)
sl_absolute << directoryFileList(dir + QLatin1Char('/') + s, true);
}
DEBUG_LOG(m_logger) << "done";
return sl_absolute;
}
void Compress::reset()
{
DEBUG_LOG(m_logger) << "reset";
m_u2_memFiles.clear();
m_lastError.clear();
m_c_sizeInfo.realSize = 0;
m_c_sizeInfo.compressedSize = 0;
m_success = false;
}
void Compress::setupFutureWatcher(const QFuture<bool> &future)
{
DEBUG_LOG(m_logger) << "setupFutureWatcher";
m_future = future;
QFutureWatcher<bool> *fw = new QFutureWatcher<bool>(this);
QObject::connect(fw, &QObject::destroyed, this, [this]() { DEBUG_LOG(m_logger) << "Future Watcher destroyed"; });
QObject::connect(fw, &QFutureWatcher<bool>::finished, this, &Compress::finished);
QObject::connect(fw, &QFutureWatcher<bool>::finished, fw, &QObject::deleteLater);
QObject::connect(fw, &QFutureWatcher<bool>::finished, fw, [this]() { DEBUG_LOG(m_logger) << "Future Watcher about to be deleted"; });
fw->setFuture(m_future);
}
}
+140
View File
@@ -0,0 +1,140 @@
#pragma once
#include "nglcomp_export.h"
#include <NGLLogger/INGLLogger.h>
#include <QByteArray>
#include <QFuture>
#include <QObject>
#include <QString>
#include <QVector>
class QIODevice;
class TarFilter;
class BZip2IODevice;
namespace NGL
{
class NGLCOMPRESSION_EXPORT Compress : public QObject
{
Q_OBJECT
public:
struct FileInformations
{
QString inputFileName;
QString outputFileName;
QByteArray fileData;
bool bAbsInputPath = true;
FileInformations() = default;
FileInformations(const QString &name, bool isAbsolute)
: inputFileName(name)
, bAbsInputPath(isAbsolute)
{}
};
struct FileSizeInfo
{
qint64 realSize = 0;
qint64 compressedSize = 0;
};
explicit Compress(QObject *parent = nullptr);
~Compress();
QVector<FileInformations> getMemFiles() const { return m_u2_memFiles; }
FileSizeInfo getFileSizeInfo() const { return m_c_sizeInfo; }
bool success() const;
void compress(QIODevice *out,
const QString &sourceRootDir,
const QVector<FileInformations> &files,
const QVector<FileInformations> &memFiles,
const QString &destRootDir);
void compress(QIODevice *out,
const QString &sourceDir,
const QString &destRootDir);
void uncompress(QIODevice *in,
const QString &outDir);
void uncompress(QIODevice *in);
QString lastError() const { return m_lastError; }
bool waitForFinished();
public Q_SLOTS:
void abort();
Q_SIGNALS:
void uncompressInfo(qint64 totalSize, qint64 curPos, const QString &curName);
void compressInfo(qint64 totalFiles, qint64 curFile, const QString &curName);
void compressInfoEx(qint64 totalFiles, qint64 curFile, qint64 totalSize, qint64 curPos, const QString &curName, const qint64 bytesTotal);
void error(const QString &errorString);
void finished();
private:
bool _compress(QIODevice *output,
const QString &filesRootDir,
const QVector<FileInformations> &files,
const QVector<FileInformations> &memFiles,
const QString &_destRootDir);
bool _uncompressDirectory(QIODevice *input, const QString &outDir);
bool _uncompressBuffer(QIODevice *input);
void reset();
void setupFutureWatcher(const QFuture<bool> &future);
QVector<FileInformations> directoryFileList(const QString &dir, bool recursive = false);
FileSizeInfo m_c_sizeInfo;
QVector<FileInformations> m_u2_memFiles;
QString m_lastError;
QAtomicInt m_aborted;
TarFilter *m_currentTarFilter { nullptr };
BZip2IODevice *m_currentBzipDevice { nullptr };
QFuture<bool> m_future;
bool m_success { false };
NGL::INGLLogger &m_logger;
};
}
Q_DECLARE_TYPEINFO(NGL::Compress::FileInformations, Q_MOVABLE_TYPE);
+17
View File
@@ -0,0 +1,17 @@
#pragma once
#include <QtCore/qglobal.h>
#ifndef NGLCOMPRESSION_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define NGLCOMPRESSION_EXPORT
# else
# if defined(MAKE_NGLCOMPRESSION_LIB)
# define NGLCOMPRESSION_EXPORT Q_DECL_EXPORT
# else
# define NGLCOMPRESSION_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
+525
View File
@@ -0,0 +1,525 @@
#include <QBuffer>
#include <QFile>
#include <QIODevice>
#include <QFileInfo>
#include <QDateTime>
#include <QTextCodec>
#include <time.h>
#include "nglcomp_tarfilter.h"
#ifndef Q_OS_WIN
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#endif
class TarFilter::Private
{
public:
Private(QIODevice *dev, QTextCodec *c)
: device(dev)
, codec(c ? c : QTextCodec::codecForLocale())
, iBufSize(1024 * 1024)
, nextChunkSize(-1)
{}
struct tar_posix_header
{
char name[100];
char mode[8];
char uid[8];
char gid[8];
char size[12];
char mtime[12];
char chksum[8];
char typeflag;
char linkname[100];
char magic[6];
char version[2];
char uname[32];
char gname[32];
char devmajor[8];
char devminor[8];
char prefix[155];
char unused[12];
};
bool fi2tph(const FileInformations &infos);
bool addHeader(const FileInformations &infos);
bool tph2fi(FileInformations &infos);
bool getHeader(FileInformations &infos);
bool checkDevice(QIODevice *in, QIODevice *out);
bool copyData(QIODevice *in, QIODevice *out, qint64 iSize);
QIODevice *device;
QTextCodec *codec;
QString lastError;
unsigned int iBufSize;
qint64 nextChunkSize;
QAtomicInt aborted { 0 };
std::function<void(qint64)> readCallback;
};
bool TarFilter::Private::fi2tph(const FileInformations &infos)
{
QByteArray fn = codec->fromUnicode(infos.fileName);
#ifdef Q_OS_WIN
if (fn.size() > 3 && fn[1] == ':' && (fn[2] == '\\' || fn[2] == '/'))
fn = fn.mid(3);
#endif
if (fn.startsWith('/'))
fn = fn.mid(1);
long unsigned int fileSize = infos.fileType == directory ? 0 : infos.fileSize;
long unsigned int mtime = infos.mtime != -1 ? infos.mtime : time(nullptr);
tar_posix_header hdr;
memset(&hdr, 0, sizeof(hdr));
QByteArray fn_part1 = fn.left(sizeof(hdr.name));
memcpy(hdr.name, fn_part1.constData(), fn_part1.size());
sprintf(hdr.mode, "%07x", 0x0fff & infos.mode);
sprintf(hdr.uid, "%07o", infos.uid);
sprintf(hdr.gid, "%07o", infos.gid);
sprintf(hdr.size, "%011lo", fileSize);
sprintf(hdr.mtime, "%011lo", mtime);
memset(hdr.chksum, ' ', sizeof(hdr.chksum));
hdr.typeflag = infos.fileType;
memcpy(hdr.magic, "ustar ",sizeof(hdr.magic) + sizeof(hdr.version));
#ifdef Q_OS_WIN
#else
qstrncpy(hdr.uname, codec->fromUnicode(infos.uname).constData(), sizeof(hdr.uname));
qstrncpy(hdr.gname, codec->fromUnicode(infos.gname).constData(), sizeof(hdr.gname));
#endif
unsigned int checksum = 0;
const unsigned char *ptr = reinterpret_cast<const unsigned char *>(&hdr);
for (unsigned i = 0; i < sizeof(hdr); i++)
checksum += ptr[i];
constexpr int octalMax = 01000000;
while (checksum > octalMax)
checksum -= octalMax;
sprintf(hdr.chksum, "%06o", checksum);
if (!device->write((const char *)&hdr, sizeof(hdr)))
{
lastError = QLatin1String("Error writing to QIODevice");
return false;
}
return true;
}
bool TarFilter::Private::addHeader(const FileInformations &infos)
{
QByteArray fn = codec->fromUnicode(infos.fileName);
#ifdef Q_OS_WIN
if (fn.size() > 3 && fn[1] == ':' && (fn[2] == '\\' || fn[2] == '/'))
fn = fn.mid(3);
#endif
if (fn.startsWith('/'))
fn = fn.mid(1);
if (fn.size() > 512)
{
lastError = QLatin1String("Can't handle filenames with more then 512 bytes");
return false;
}
if (fn.size() > 100)
{
FileInformations longlink;
longlink.fileName = QLatin1String("././@LongLink");
longlink.fileType = gnu_longname;
longlink.fileSize = strlen(fn.constData()) + 1;
longlink.mtime = 0;
longlink.uid = 0;
longlink.gid = 0;
#ifndef Q_OS_WIN
struct passwd *p = getpwuid(longlink.uid);
if (p)
longlink.uname = codec->toUnicode(p->pw_name);
struct group *g = getgrgid(longlink.gid);
if (g)
longlink.gname = codec->toUnicode(g->gr_name);
#endif
fi2tph(longlink);
QByteArray ba(512, '\0');
qstrncpy(ba.data(), fn.constData(), ba.size());
if (!device->write(ba.constData(), ba.size()))
{
lastError = QLatin1String("Error writing to QIODevice");
return false;
}
}
if (!fi2tph(infos))
return false;
return true;
}
bool TarFilter::Private::tph2fi(FileInformations &infos)
{
Private::tar_posix_header hdr;
do
{
int iBytesRead = device->read((char *)&hdr, sizeof(hdr));
if (iBytesRead != sizeof(hdr))
{
if (iBytesRead == 0 && device->atEnd())
{
lastError = QString();
return false;
}
lastError = QStringLiteral("Error reading from QIODevice! needed: %1, got: %2").arg(sizeof(hdr)).arg(iBytesRead);
return false;
}
}
while (memcmp(hdr.magic, "\0\0\0\0\0\0", sizeof(hdr.magic)) == 0);
if (memcmp(hdr.magic, "ustar ", sizeof(hdr.magic)))
{
lastError = QLatin1String("The archive is not supported");
return false;
}
int checksum = QByteArray(hdr.chksum, sizeof(hdr.chksum)).toUInt(nullptr, 8);
memset(hdr.chksum, ' ', sizeof(hdr.chksum));
int realChecksum = 0;
const unsigned char *ptr = reinterpret_cast<const unsigned char *>(&hdr);
for (unsigned i = 0; i < sizeof(hdr); i++)
realChecksum += ptr[i];
if (checksum != realChecksum)
{
lastError = QStringLiteral("Checksum does not match! needed: %1, got: %2").arg(checksum).arg(realChecksum);
return false;
}
QByteArray ba(hdr.name, sizeof(hdr.name));
ba.resize(qstrlen(ba.constData()));
infos.fileName = codec->toUnicode(ba);
infos.fileSize = QByteArray(hdr.size, sizeof(hdr.size)).toUInt(nullptr, 8);
infos.mode = static_cast<QFile::Permissions>(QByteArray(hdr.mode, sizeof(hdr.mode)).toUInt(nullptr, 16));
infos.uid = QByteArray(hdr.uid, sizeof(hdr.uid)).toUInt(nullptr, 8);
infos.gid = QByteArray(hdr.gid, sizeof(hdr.gid)).toUInt(nullptr, 8);
infos.mtime = QByteArray(hdr.mtime, sizeof(hdr.mtime)).toUInt(nullptr, 8);
infos.fileType = (FileType)hdr.typeflag;
infos.uname = codec->toUnicode(hdr.uname, sizeof(hdr.uname));
infos.gname = codec->toUnicode(hdr.gname, sizeof(hdr.gname));
return true;
}
bool TarFilter::Private::getHeader(FileInformations &infos)
{
if (!tph2fi(infos))
return false;
switch (infos.fileType)
{
case regular:
case regular2:
case directory:
case gnu_longname:
break;
default:
lastError = QStringLiteral("Unsupported fileType %1").arg(infos.fileType);
return false;
}
if (infos.fileType == gnu_longname)
{
const QByteArray fn = device->read(512);
if (fn.size() != 512)
{
lastError = QLatin1String("Unexpected end of inputstream");
return false;
}
if (!tph2fi(infos))
return false;
const int len = qstrlen(fn.constData());
infos.fileName = codec->toUnicode(fn.constData(), len);
}
return true;
}
bool TarFilter::Private::checkDevice(QIODevice *in, QIODevice *out)
{
if (!in)
{
lastError = QLatin1String("No QIODevice for reading available");
return false;
}
if ((in->openMode() & QIODevice::ReadOnly) == 0)
{
lastError = QLatin1String("QIODevice not opened for reading");
return false;
}
if (!out)
{
lastError = QLatin1String("No QIODevice for writing available");
return false;
}
if ((out->openMode() & QIODevice::WriteOnly) == 0)
{
lastError = QLatin1String("QIODevice not opened for writing");
return false;
}
return true;
}
bool TarFilter::Private::copyData(QIODevice *in, QIODevice *out, qint64 iSize)
{
if (iSize <= 0)
return true;
while (iSize > 0)
{
if (aborted) return false;
const qint64 iBytesToRead = iSize > iBufSize ? iBufSize : iSize;
const QByteArray ba = in->read(iBytesToRead);
if (aborted) return false;
if (ba.size() == 0)
{
lastError = QStringLiteral("Could not read %1 bytes from QIODevice").arg(iBytesToRead);
return false;
}
if (out->write(ba) != ba.size())
{
lastError = QStringLiteral("Could not write %1 bytes to QIODevice").arg(ba.size());
return false;
}
iSize -= ba.size();
if (readCallback)
readCallback(iSize);
}
return true;
}
TarFilter::TarFilter(QIODevice *dev, QTextCodec *codec, const std::function<void(qint64)> &readCallback)
: d(new Private(dev, codec))
{
d->readCallback = readCallback;
}
TarFilter::~TarFilter()
{
delete d;
}
void TarFilter::abort()
{
d->aborted = 1;
}
void TarFilter::setLocaleCodec(QTextCodec *codec)
{
d->codec = codec ? codec : QTextCodec::codecForLocale();
}
void TarFilter::setBufferSize(unsigned int size)
{
d->iBufSize = size > 1024 ? size : 1024;
}
bool TarFilter::error() const
{
return !d->lastError.isEmpty();
}
QString TarFilter::lastError() const
{
return d->lastError;
}
bool TarFilter::addFile(const QString &filename, const QString &filenameInArchive)
{
QFileInfo fi(filename);
if (!fi.exists())
{
d->lastError = QStringLiteral("File %1 does not exist").arg(filename);
return false;
}
if (!(fi.isDir() || fi.isFile()))
{
d->lastError = QStringLiteral("%1 isn't a directory or a regular file").arg(filename);
return false;
}
FileInformations fInfos;
fInfos.fileName = (filenameInArchive.isEmpty() ? filename : filenameInArchive);
fInfos.fileSize = fi.isDir() ? 0 : fi.size();
fInfos.mode = fi.permissions() & 0x0fff;
#ifdef Q_OS_WIN
fInfos.uid = 1000;
fInfos.gid = 100;
#else
fInfos.uid = fi.ownerId();
fInfos.gid = fi.groupId();
fInfos.uname = fi.owner();
fInfos.gname = fi.group();
#endif
fInfos.mtime = fi.lastModified().toSecsSinceEpoch();
fInfos.fileType = fi.isDir() ? directory : regular;
if (fi.isDir())
{
QBuffer buf;
buf.open(QIODevice::ReadOnly);
return addData(fInfos, &buf);
}
QFile f(filename);
if (!f.open(QIODevice::ReadOnly))
{
d->lastError = QStringLiteral("Error opening %1 for reading").arg(filename);
return false;
}
if (d->aborted) return false;
return addData(fInfos, &f);
}
bool TarFilter::addData(const QString &filename, const QByteArray &data, bool bIsDir)
{
if (d->aborted) return false;
FileInformations fi;
fi.fileName = filename;
fi.fileSize = bIsDir ? 0 : data.size();
fi.mode = static_cast<QFile::Permissions>(bIsDir ? 0x0755 : 0x0644);
fi.fileType = bIsDir ? directory : regular;
#ifndef Q_OS_WIN
fi.uid = getuid();
fi.gid = getgid();
char name[256];
struct passwd *p_ptr = nullptr;
struct passwd p;
getpwuid_r(fi.uid, &p, name, sizeof(name) - 1, &p_ptr);
if (p_ptr)
fi.uname = d->codec->toUnicode(p_ptr->pw_name);
struct group *g_ptr;
struct group g;
getgrgid_r(fi.gid, &g, name, sizeof(name) - 1, &g_ptr);
if (g_ptr)
fi.gname = d->codec->toUnicode(g_ptr->gr_name);
#endif
QBuffer buf(const_cast<QByteArray *>(&data));
if (!buf.open(QIODevice::ReadOnly))
{
d->lastError = QLatin1String("Internal Error - can't open QBuffer for reading!");
return false;
}
return addData(fi, &buf);
}
bool TarFilter::addData(const FileInformations &fi, QIODevice *in)
{
if (d->aborted) return false;
if (!d->checkDevice(in, d->device))
return false;
if (!d->addHeader(fi))
return false;
if (fi.fileSize)
{
if (!d->copyData(in, d->device, fi.fileSize))
return false;
int align = fi.fileSize % 512;
if (align)
{
align = 512 - align;
QByteArray ba2(align, '\0');
d->device->write(ba2.constData(), align);
}
}
return true;
}
bool TarFilter::writeEOS()
{
const int size = sizeof(TarFilter::Private::tar_posix_header) * 2;
QByteArray ba(size, '\0');
return (d->device->write(ba) == size);
}
bool TarFilter::getData(FileInformations &fi)
{
if (d->aborted) return false;
d->nextChunkSize = -1;
if (!d->getHeader(fi))
return false;
d->nextChunkSize = fi.fileSize;
return true;
}
bool TarFilter::getData(QIODevice *out)
{
if (d->aborted) return false;
if (!d->checkDevice(d->device, out))
return false;
if (d->nextChunkSize < 0)
{
d->lastError = QLatin1String("No informations about next chunk size. Did you call getData(FileInformations &fi) before?");
return false;
}
if (!d->copyData(d->device, out, d->nextChunkSize))
return false;
int align = d->nextChunkSize % 512;
if (align)
d->device->read(512 - align);
d->nextChunkSize = -1;
return true;
}
bool TarFilter::getData(FileInformations &fi, QByteArray &data)
{
if (!getData(fi))
return false;
QBuffer buf(&data);
buf.open(QIODevice::WriteOnly);
return getData(&buf);
}
bool TarFilter::getData(FileInformations &fi, QIODevice *out)
{
if (!getData(fi))
return false;
return getData(out);
}
+82
View File
@@ -0,0 +1,82 @@
#ifndef TARFILTER_H
#define TARFILTER_H
#include <QString>
#include <QFile>
#include <functional>
class QIODevice;
class QTextCodec;
class QByteArray;
class TarFilter
{
public:
Q_DISABLE_COPY(TarFilter)
enum FileType
{
regular = '0',
regular2 = '\0',
link = '1',
reserved = '2',
charType = '3',
block = '4',
directory = '5',
fifo = '6',
reserved2 = '7',
gnu_longLink = 'K',
gnu_longname = 'L',
};
struct FileInformations
{
QString fileName;
qint64 fileSize = 0;
int uid = 1000;
int gid = 100;
QString uname;
QString gname;
time_t mtime = -1;
FileType fileType = regular;
QFile::Permissions mode = QFile::ReadOwner | QFile::WriteOwner | QFile::ReadGroup | QFile::ReadOther;
};
TarFilter(QIODevice *dev, QTextCodec *codec = nullptr, const std::function<void(qint64)> &readCallback = nullptr);
~TarFilter();
void abort();
void setLocaleCodec(QTextCodec *codec);
void setBufferSize(unsigned int size);
bool error() const;
QString lastError() const;
bool addData(const FileInformations &fi, QIODevice *in);
bool addFile(const QString &filename, const QString &filenameInArchive = QString());
bool addData(const QString &filename, const QByteArray &data = QByteArray(), bool bIsDir = false);
bool writeEOS();
bool getData(FileInformations &fi, QIODevice *out);
bool getData(FileInformations &fi);
bool getData(QIODevice *out);
bool getData(FileInformations &fi, QByteArray &data);
private:
class Private;
Private *const d;
};
#endif
+175
View File
@@ -0,0 +1,175 @@
#include "nglcomp_test.h"
#include "nglcomp_compress.h"
#include <ngltools/ngltools_filesystem.h>
#include <nglapplication/nglcoreapplication.h>
#include <NGLLogger/NGLLoggerBootstrap.h>
#include <QtTest>
void nglcomp_test::initTestCase()
{
m_tempDirIn.setAutoRemove(true);
m_tempDirOut.setAutoRemove(true);
QVERIFY(m_tempDirIn.isValid());
QVERIFY(m_tempDirOut.isValid());
QVERIFY(m_tf.open());
m_tf.setAutoRemove(true);
m_fileContent[QLatin1String("1.txt")] = "111111111111111111111111";
m_fileContent[QLatin1String("sub1/s1.txt")] = "222222222222222222222222";
m_fileContent[QLatin1String("sub1/sub11/s11.txt")] = "333333333333333333333333";
m_fileContent[QLatin1String("sub1/sub12/s12.txt")] = "444444444444444444444444";
m_fileContent[QLatin1String("sub2/2.txt")] = "555555555555555555555555";
}
void nglcomp_test::testCompressFile()
{
QDir dir;
const auto directories = {
QLatin1String("sub1"),
QLatin1String("sub1/sub11"),
QLatin1String("sub1/sub12"),
QLatin1String("sub2")
};
for (const QLatin1String &directory : directories)
QVERIFY(dir.mkdir(subPathIn(directory)));
for (auto it = m_fileContent.cbegin(); it != m_fileContent.cend(); ++it)
writeTestFile(it.key(), it.value());
NGL::Compress c;
c.compress(&m_tf, subPathIn(QString()), QLatin1String("out"));
QVERIFY(c.waitForFinished());
}
void nglcomp_test::testCompressMemory()
{
QBuffer f(&m_ba);
QVERIFY(f.open(QIODevice::WriteOnly));
QVector<NGL::Compress::FileInformations> fi1;
QVector<NGL::Compress::FileInformations> fi2;
NGL::Compress::FileInformations fi;
fi.inputFileName = QLatin1String("chris.txt");
fi.fileData = QByteArray("dumdidum\n");
fi2 += fi;
fi.inputFileName = QLatin1String("blub/chris.txt");
fi.fileData = QByteArray("dumdidum im Verzeichnis blub\n");
fi2 += fi;
fi.inputFileName = QLatin1String("blub/blub/chris2.txt");
fi.fileData = QByteArray("dumdidum im Verzeichnis blub/blub\n");
fi2 += fi;
NGL::Compress c;
c.compress(&f, QString(), fi1, fi2, QLatin1String("blub"));
QVERIFY(c.waitForFinished());
f.close();
}
void nglcomp_test::testUncompressMemory()
{
QBuffer f(&m_ba);
QVERIFY(f.open(QIODevice::ReadOnly));
NGL::Compress c;
c.uncompress(&f, subPathIn(QString()));
QVERIFY(c.waitForFinished());
f.close();
QVERIFY(f.open(QIODevice::ReadOnly));
c.uncompress(&f);
QVERIFY(c.waitForFinished());
QVector<NGL::Compress::FileInformations> fi1 = c.getMemFiles();
QVERIFY(fi1.count() == 4);
f.close();
}
void nglcomp_test::testUncompressFile()
{
NGL::Compress c;
m_tf.seek(0);
c.uncompress(&m_tf, subPathOut(QString()));
QVERIFY(c.waitForFinished());
for (auto it = m_fileContent.cbegin(); it != m_fileContent.cend(); ++it)
checkContent(it.key(), it.value());
}
void nglcomp_test::cleanupTestCase()
{
m_tf.close();
m_tempDirIn.remove();
m_tempDirOut.remove();
}
void nglcomp_test::writeTestFile(const QString &fn, const QByteArray &content) const
{
QFile f(subPathIn(fn));
QVERIFY(f.open(QIODevice::WriteOnly));
QVERIFY(f.write(content) == content.size());
f.close();
}
void nglcomp_test::checkContent(const QString &fn, const QByteArray &content) const
{
QFile f(subPathOut(QLatin1String("out/") + fn));
QVERIFY(f.open(QIODevice::ReadOnly));
QCOMPARE(f.readAll(), content);
}
QString nglcomp_test::subPathIn(const QString &p) const
{
return m_tempDirIn.path() + QLatin1Char('/') + p;
}
QString nglcomp_test::subPathOut(const QString &p) const
{
return m_tempDirOut.path() + QLatin1Char('/') + p;
}
int main(int argc, char *argv[])
{
NGLCoreApplication app(argc, argv);
app.createLogger("nglcomp_test", "log4cxx_nglcomp_test.props");
nglcomp_test tc;
return QTest::qExec(&tc, argc, argv);
}
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#include <QByteArray>
#include <QHash>
#include <QObject>
#include <QTemporaryDir>
#include <QTemporaryFile>
class nglcomp_test : public QObject
{
Q_OBJECT
public:
nglcomp_test() = default;
private Q_SLOTS:
void initTestCase();
void testCompressFile();
void testCompressMemory();
void testUncompressFile();
void testUncompressMemory();
void cleanupTestCase();
private:
void writeTestFile(const QString &fn, const QByteArray &content) const;
void checkContent(const QString &fn, const QByteArray &content) const;
QString subPathIn(const QString &p) const;
QString subPathOut(const QString &p) const;
private:
QHash<QString, QByteArray> m_fileContent;
QByteArray m_ba;
QTemporaryFile m_tf;
QTemporaryDir m_tempDirIn;
QTemporaryDir m_tempDirOut;
};
+45
View File
@@ -0,0 +1,45 @@
# NGLDB
FIND_PACKAGE(PostgreSQL REQUIRED)
OPTION(ENABLE_DB_TRACING "Enable trace output for NGLDB library" OFF)
IF(ENABLE_DB_TRACING)
add_compile_definitions(NGLDB_ENABLE_TRACE)
ENDIF(ENABLE_DB_TRACING)
#
# NGL Database Library
#
SET(ngldb_SRCS
dbcommon.h
dbconnection.cpp
dbconnection.h
db_service_handler.h
dbtransaction.cpp
dbtransaction.h
ngldb_export.h
ngldb_logger.cpp
ngldb_logger.h
nsqlquery.cpp
nsqlquery.h
sql_query_janitor.cpp
sql_query_janitor.h
)
NGL_ADD_LIBRARY(AAR SV HLA WS ngldb SHARED ${ngldb_SRCS})
NGL_TARGET_LINK_LIBRARIES(ngldb
PRIVATE
NGLLogger
nglsettings
${PostgreSQL_LIBRARIES}
PUBLIC
Qt5::Core
Qt5::Sql
)
NGL_TARGET_INCLUDE_DIRECTORIES(ngldb
PRIVATE
${PostgreSQL_INCLUDE_DIR}
INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/../
)
NGL_INSTALL_TARGET(ngldb)
+58
View File
@@ -0,0 +1,58 @@
#pragma once
#include <nglsettings/nglsettings_settings.h>
#include <memory>
class QSqlDatabase;
namespace NGLDB
{
template<typename DB>
class DbServiceHandler
{
public:
DbServiceHandler() = default;
~DbServiceHandler() = default;
bool init(int exerciseId, NGL::Settings *settings)
{
if (m_dbInterface)
return true;
m_dbInterface = DB::create(exerciseId);
if (!m_dbInterface->init(m_dbInterface->dbUser(),
settings->databasePassword(m_dbInterface->dbUser()),
settings->databaseDriver(),
settings->databaseHostname(),
settings->databaseName()))
{
m_dbInterface = nullptr;
return false;
}
return true;
}
bool init(int exerciseId, const QSqlDatabase &db)
{
if (m_dbInterface)
return true;
m_dbInterface = DB::create(exerciseId);
if (!m_dbInterface->init(db))
{
m_dbInterface = nullptr;
return false;
}
return true;
}
std::shared_ptr<DB> db() const { return m_dbInterface; }
private:
std::shared_ptr<DB> m_dbInterface;
};
}
+41
View File
@@ -0,0 +1,41 @@
#pragma once
#include "ngldb_export.h"
#include <QString>
namespace DBCommon
{
enum class eDatabaseSchema
{
Exercise
};
inline QString getExerciseSchemaName(int exerciseId)
{
return QLatin1String("ex_") + QString::number(exerciseId);
}
inline QString getTableName(const QString &tableName, const QString &schemaName)
{
if (schemaName.isEmpty())
return tableName;
return schemaName + QLatin1Char('.') + tableName;
}
inline QString getExerciseTableName(const QString &tableName, int exerciseId)
{
return getTableName(tableName, getExerciseSchemaName(exerciseId));
}
}
+68
View File
@@ -0,0 +1,68 @@
#include "dbconnection.h"
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlError>
#include <NGLLogger/INGLLogger.h>
#include "nsqlquery.h"
namespace DBConnection
{
QSqlDatabase open(NGL::INGLLogger &logger,
const QString &dbUser,
const QString &dbPasswd,
const QString &dbDriver,
const QString &dbHost,
const QString &dbName,
const QString &schemaName,
const QString &connectionName)
{
DEBUG_LOG(logger) << "host: " << dbHost << " database: " << dbName;
QString realConnectionName(connectionName);
if (connectionName.isEmpty())
{
realConnectionName = dbHost + QLatin1Char('_') + dbName;
if (!schemaName.isEmpty())
realConnectionName += QLatin1Char('_') + schemaName;
}
auto dbConnection = QSqlDatabase::addDatabase(dbDriver, realConnectionName);
dbConnection.setHostName(dbHost);
dbConnection.setDatabaseName(dbName);
dbConnection.setUserName(dbUser);
dbConnection.setPassword(dbPasswd);
if (!dbConnection.open())
{
const QString err = dbConnection.lastError().nativeErrorCode();
FATAL_LOG(logger) << "Error opening database " << dbHost
<< ":" << dbName << " as user " << dbUser;
FATAL_LOG(logger) << dbConnection.lastError().driverText() << " "
<< dbConnection.lastError().databaseText() << " " << err;
return dbConnection;
}
DEBUG_LOG(logger) << "Database Initialisation successful -> DB: " << dbName << ", con: " << realConnectionName;
if (!schemaName.isEmpty())
{
const QString stmt = QLatin1String("SET SEARCH_PATH TO ") + schemaName + QLatin1String(", PUBLIC");
NSqlQuery q(dbConnection);
if (!q.exec(stmt))
{
ERROR_LOG(logger) << "Set SEARCH_PATH to " << schemaName << " failed!";
dbConnection.close();
}
}
return dbConnection;
}
}
+24
View File
@@ -0,0 +1,24 @@
#pragma once
#include <QtSql/QSqlDatabase>
#include "ngldb_export.h"
namespace NGL
{
class INGLLogger;
}
namespace DBConnection
{
NGLDB_EXPORT QSqlDatabase open(NGL::INGLLogger &logger,
const QString &dbUser,
const QString &dbPasswd,
const QString &dbDriver,
const QString &dbHost,
const QString &dbName,
const QString &schemaName = QString(),
const QString &connectionName = QString());
}
+82
View File
@@ -0,0 +1,82 @@
#include "dbtransaction.h"
#include "ngldb_logger.h"
#include <QtSql/QSqlError>
thread_local int s_refCounter = 0;
DBTransaction::DBTransaction(const QSqlDatabase &db)
: m_db(db)
, m_bCommitted(true)
, mLogger(NGLDB::getLogger("DBTransaction"))
{
++s_refCounter;
if (s_refCounter == 1)
begin();
}
DBTransaction::~DBTransaction()
{
if (s_refCounter == 1)
{
if (!m_bCommitted)
rollback();
}
--s_refCounter;
}
bool DBTransaction::begin()
{
if (!m_bCommitted)
return setState(false);
if (!m_db.transaction())
{
ERROR_LOG(mLogger) << "Error starting a transaction: " << m_db.lastError().driverText();
return setState(false);
}
m_bCommitted = false;
return setState(true);
}
bool DBTransaction::commit()
{
if (s_refCounter == 1)
{
if (!m_db.commit())
{
ERROR_LOG(mLogger) << "Error committing a transaction: " << m_db.lastError().driverText();
return setState(false);
}
m_bCommitted = true;
return setState(true);
}
return true;
}
bool DBTransaction::rollback()
{
if (s_refCounter == 1)
{
if (!m_db.rollback())
{
ERROR_LOG(mLogger) << "Error rolling back a transaction" << m_db.lastError().driverText();
return setState(false);
}
m_bCommitted = true;
return setState(true);
}
return true;
}
bool DBTransaction::state() const
{
return m_lastState;
}
bool DBTransaction::setState(bool bState)
{
m_lastState = bState;
return m_lastState;
}
+48
View File
@@ -0,0 +1,48 @@
#pragma once
#include <QtSql/QSqlDatabase>
#include "ngldb_export.h"
namespace NGL
{
class INGLLogger;
}
class NGLDB_EXPORT DBTransaction
{
public:
explicit DBTransaction(const QSqlDatabase &db);
~DBTransaction();
bool begin();
bool commit();
bool rollback();
bool state() const;
private:
bool setState(bool bState);
QSqlDatabase m_db;
bool m_bCommitted;
bool m_lastState;
NGL::INGLLogger &mLogger;
};
+17
View File
@@ -0,0 +1,17 @@
#pragma once
#include <QtCore/qglobal.h>
#ifndef NGLDB_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define NGLDB_EXPORT
# else
# if defined(MAKE_NGLDB_LIB)
# define NGLDB_EXPORT Q_DECL_EXPORT
# else
# define NGLDB_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
+24
View File
@@ -0,0 +1,24 @@
#include "ngldb_logger.h"
#include <NGLLogger/NGLLoggerBootstrap.h>
NGLDB::LOGGER_T NGLDB::getLogger(const char *name)
{
static const char ns[] = "NGLDB.";
std::string loggerName;
const size_t len = strlen(name);
loggerName.reserve(sizeof(ns) + len);
loggerName.append(ns, sizeof(ns) - 1);
loggerName.append(name, len);
try {
return NGL::NGLLoggerBootstrap::getNGLRootLogger().
getNGLLogger( loggerName );
} catch ( const std::exception &ex )
{
fprintf(stderr, "Error retrieving logger: %s", ex.what());
abort();
}
}
+31
View File
@@ -0,0 +1,31 @@
#pragma once
#include <NGLLogger/INGLLogger.h>
#ifdef Q_CC_GNU
#define DB_TRACE_FUNCTION __PRETTY_FUNCTION__
#else
#define DB_TRACE_FUNCTION __FUNCTION__
#endif
#ifdef NGLDB_ENABLE_TRACE
#define DB_TRACE { TRACE_LOG(mLogger) << DB_TRACE_FUNCTION }
#define DB_TRACE2(x) { TRACE_LOG(mLogger) << DB_TRACE_FUNCTION << x }
#else
#define DB_TRACE
#define DB_TRACE2(x)
#endif
namespace NGLDB
{
typedef NGL::INGLLogger &LOGGER_T;
LOGGER_T getLogger(const char *name);
inline LOGGER_T getLogger(const QString &loggerName)
{
return getLogger(loggerName.toUtf8().constData());
}
}
+457
View File
@@ -0,0 +1,457 @@
#include "nsqlquery.h"
#include <QtCore/QVariant>
#include <QtSql/QSqlDriver>
#include <QtSql/QSqlError>
#include <QtSql/QSqlRecord>
#include <QtSql/QSqlResult>
#include <QtCore/QTextStream>
#include <QtCore/QFile>
#include <QtCore/QDateTime>
#include <QtCore/QJsonValue>
#include "ngldb_logger.h"
#include <libpq-fe.h>
static QString getSqlErrorString(const QSqlError &error)
{
return error.driverText() + QLatin1Char(' ') +
error.databaseText() + QLatin1Char(' ') +
error.nativeErrorCode();
}
NSqlQuery::NSqlQuery(const QSqlDatabase &db)
: QSqlQuery(db)
, m_db(db)
, mLogger(NGLDB::getLogger("NSqlQuery"))
{
DB_TRACE
setForwardOnly(true);
}
NSqlQuery::NSqlQuery(const QSqlDatabase &db, NGL::INGLLogger &logger)
: QSqlQuery(db)
, m_db(db)
, mLogger(logger)
{
DB_TRACE
setForwardOnly(true);
}
NSqlQuery::NSqlQuery(const QString &query, const QSqlDatabase &db)
: QSqlQuery(query, db)
, m_db(db)
, mLogger(NGLDB::getLogger("NSqlQuery"))
{
DB_TRACE
setForwardOnly(true);
}
NSqlQuery::NSqlQuery(const QString &query, const QSqlDatabase &db, NGL::INGLLogger &logger)
: QSqlQuery(query, db)
, m_db(db)
, mLogger(logger)
{
DB_TRACE
setForwardOnly(true);
}
void NSqlQuery::addBindValue(const QVariant &val, QSql::ParamType paramType)
{
DB_TRACE;
DEBUG_LOG(mLogger) << "type: " << val.type() << " paramType: " << paramType;
QSqlQuery::addBindValue(val, paramType);
}
int NSqlQuery::at() const
{
DB_TRACE
return QSqlQuery::at();
}
void NSqlQuery::bindValue(const QString &placeholder, const QVariant &val, QSql::ParamType paramType)
{
DB_TRACE;
TRACE_LOG(mLogger) << "placeholder: " << placeholder << " type: " << val.type() << " paramType: " << paramType;
QSqlQuery::bindValue(placeholder, val, paramType);
}
void NSqlQuery::bindValue(int pos, const QVariant &val, QSql::ParamType paramType)
{
DB_TRACE;
TRACE_LOG(mLogger) << "pos: " << pos << " type: " << val.type() << " paramType: " << paramType;
QSqlQuery::bindValue(pos, val, paramType);
}
QVariant NSqlQuery::boundValue(const QString &placeholder) const
{
DB_TRACE
TRACE_LOG(mLogger) << "placeholder: " << placeholder;
return QSqlQuery::boundValue(placeholder);
}
QVariant NSqlQuery::boundValue(int pos) const
{
DB_TRACE
TRACE_LOG(mLogger) << "pos: " << pos;
return QSqlQuery::boundValue(pos);
}
QMap<QString, QVariant> NSqlQuery::boundValues() const
{
DB_TRACE
return QSqlQuery::boundValues();
}
void NSqlQuery::clear()
{
DB_TRACE
return QSqlQuery::clear();
}
const QSqlDriver *NSqlQuery::driver() const
{
DB_TRACE
return QSqlQuery::driver();
}
bool NSqlQuery::exec(const QString &query, bool bEmitMessageOnError)
{
DB_TRACE;
DEBUG_LOG(mLogger) << "query: " << query;
if (QSqlQuery::exec(query))
return true;
if (bEmitMessageOnError)
printLastSqlError();
return false;
}
bool NSqlQuery::exec(bool bEmitMessageOnError)
{
DB_TRACE
DEBUG_LOG(mLogger) << "query: " << lastQuery();
if (mLogger.isDebugEnabled())
{
const QMap<QString, QVariant> &boundValuesMap = boundValues();
for (auto it=boundValuesMap.begin(); it != boundValuesMap.end(); ++it)
{
if ( it.value().canConvert<QString>())
DEBUG_LOG(mLogger) << "key='" << it.key() << "' value='" << it.value().toString() << "'";
else
DEBUG_LOG(mLogger) << "key='" << it.key() << "' value cant Convert to string'";
}
}
if (QSqlQuery::exec())
return true;
if (bEmitMessageOnError)
printLastSqlError();
return false;
}
bool NSqlQuery::execAndFetch()
{
DB_TRACE
if (!exec())
return false;
return (next());
}
bool NSqlQuery::execAndFetch(const QString &query)
{
DB_TRACE
if (!exec(query))
return false;
return (next());
}
bool NSqlQuery::execBatch(BatchExecutionMode mode)
{
DB_TRACE2("mode: " << mode)
DEBUG_LOG(mLogger) << "mode: " << mode;
if (QSqlQuery::execBatch(mode))
return true;
printLastSqlError();
return false;
}
QString NSqlQuery::executedQuery() const
{
DB_TRACE
return QSqlQuery::executedQuery();
}
void NSqlQuery::finish()
{
DB_TRACE
QSqlQuery::finish();
}
bool NSqlQuery::first()
{
DB_TRACE
if (QSqlQuery::first())
return true;
printLastSqlError();
return false;
}
bool NSqlQuery::isActive() const
{
DB_TRACE
return QSqlQuery::isActive();
}
bool NSqlQuery::isForwardOnly() const
{
DB_TRACE
return QSqlQuery::isForwardOnly();
}
bool NSqlQuery::isNull(int field) const
{
DB_TRACE2("field: " << field)
return QSqlQuery::isNull(field);
}
bool NSqlQuery::isSelect() const
{
DB_TRACE
return QSqlQuery::isSelect();
}
bool NSqlQuery::isValid() const
{
DB_TRACE
return QSqlQuery::isValid();
}
bool NSqlQuery::last()
{
DB_TRACE
if (QSqlQuery::last())
return true;
printLastSqlError();
return false;
}
QSqlError NSqlQuery::lastError() const
{
DB_TRACE
return QSqlQuery::lastError();
}
QString NSqlQuery::sqlstate()
{
const QVariant resultHandle = this->result()->handle();
if (resultHandle.isValid() && (qstrcmp(resultHandle.typeName(), "PGresult*") == 0))
{
const PGresult *pgresHandle = *static_cast<const PGresult * const *>(resultHandle.data());
if (pgresHandle != nullptr)
{
return QString::fromLocal8Bit(PQresultErrorField(pgresHandle, PG_DIAG_SQLSTATE));
}
}
return QStringLiteral("58000");
}
QVariant NSqlQuery::lastInsertId()
{
DB_TRACE
QVariant ret;
if (this->driver()->hasFeature(QSqlDriver::LastInsertId))
ret = QSqlQuery::lastInsertId();
if (!ret.isValid())
{
NSqlQuery q(m_db);
if (q.execAndFetch(QLatin1String("SELECT LASTVAL()")))
ret = q.value(0);
}
return ret;
}
QString NSqlQuery::lastQuery() const
{
DB_TRACE
return QSqlQuery::lastQuery();
}
bool NSqlQuery::next()
{
DB_TRACE
return QSqlQuery::next();
}
bool NSqlQuery::nextResult()
{
DB_TRACE
if (QSqlQuery::nextResult())
return true;
printLastSqlError();
return false;
}
int NSqlQuery::numRowsAffected() const
{
DB_TRACE
return QSqlQuery::numRowsAffected();
}
QSql::NumericalPrecisionPolicy NSqlQuery::numericalPrecisionPolicy() const
{
DB_TRACE
return QSqlQuery::numericalPrecisionPolicy();
}
bool NSqlQuery::prepare(const QString &query)
{
DB_TRACE2("query: " << query)
if (QSqlQuery::prepare(query))
return true;
printLastSqlError();
return false;
}
bool NSqlQuery::previous()
{
DB_TRACE
if (QSqlQuery::previous())
return true;
printLastSqlError();
return false;
}
QSqlRecord NSqlQuery::record() const
{
DB_TRACE
return QSqlQuery::record();
}
const QSqlResult *NSqlQuery::result() const
{
DB_TRACE
return QSqlQuery::result();
}
bool NSqlQuery::seek(int index, bool relative)
{
DB_TRACE2("index: " << index << " relative: " << relative);
if (QSqlQuery::seek(index, relative))
return true;
printLastSqlError();
return false;
}
void NSqlQuery::setForwardOnly(bool forward)
{
DB_TRACE2("forward: " << forward);
QSqlQuery::setForwardOnly(forward);
}
void NSqlQuery::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy)
{
DB_TRACE2("precisionPolicy: " << precisionPolicy);
QSqlQuery::setNumericalPrecisionPolicy(precisionPolicy);
}
int NSqlQuery::size() const
{
DB_TRACE
return QSqlQuery::size();
}
QVariant NSqlQuery::value(int index) const
{
DB_TRACE2("index: " << index)
return QSqlQuery::value(index);
}
NSqlQuery &NSqlQuery::operator= (const NSqlQuery &other)
{
DB_TRACE
QSqlQuery::operator= (other);
return *this;
}
bool NSqlQuery::export2CSV(const QString &filename)
{
DB_TRACE2("export csv to file: " << filename)
QFile data(filename);
QTextStream output(&data);
if (data.open(QFile::WriteOnly | QFile::Truncate))
{
if (isSelect() && isActive())
{
bool isHeaderWritten = false;
while (next())
{
QSqlRecord rec = record();
if (!isHeaderWritten)
{
for (int i = 0; i < rec.count(); ++i)
output << QLatin1Char('\"') + rec.fieldName(i) + QLatin1String("\",");
output << QLatin1Char('\n');
isHeaderWritten = true;
}
for (int i = 0; i < rec.count(); ++i)
output << QLatin1Char('\"') + rec.value(i).toString() + QLatin1String("\",");
output << QLatin1Char('\n');
}
}
data.close();
return true;
}
return false;
}
QVariant NSqlQuery::qDateTimeToQVariant(const QDateTime &dt)
{
if (dt.isValid())
return dt.toMSecsSinceEpoch();
return QVariant();
}
QDateTime NSqlQuery::qVariantToQDateTime(const QVariant &var)
{
if (var.isNull())
return QDateTime();
return QDateTime::fromMSecsSinceEpoch(var.toLongLong());
}
QString NSqlQuery::qVariantToJsonString(const QVariant &value)
{
if (value.isNull())
return QStringLiteral("{}");
return value.toString();
}
QString NSqlQuery::jsonValueToJsonString(const QJsonValue &value)
{
if (value.isNull())
return QStringLiteral("{}");
return value.toString();
}
void NSqlQuery::printLastSqlError()
{
ERROR_LOG(mLogger) << getSqlErrorString(lastError()) << " " << lastQuery();
}
QString NSqlQuery::getLastSqlError()
{
return (getSqlErrorString(lastError()) + QLatin1Char(' ') + lastQuery());
}
+222
View File
@@ -0,0 +1,222 @@
#pragma once
#include <QtSql/QSqlQuery>
#include "ngldb_export.h"
#include "dbcommon.h"
namespace NGL
{
class INGLLogger;
}
class QDateTime;
class QJsonValue;
class NGLDB_EXPORT NSqlQuery final : public QSqlQuery
{
public:
explicit NSqlQuery(const QSqlDatabase &db);
explicit NSqlQuery(const QSqlDatabase &db, NGL::INGLLogger &logger);
explicit NSqlQuery(const QString &query, const QSqlDatabase &db);
explicit NSqlQuery(const QString &query, const QSqlDatabase &db, NGL::INGLLogger &logger);
NSqlQuery(const NSqlQuery &other) = default;
~NSqlQuery() = default;
void addBindValue(const QVariant &val, QSql::ParamType paramType = QSql::In);
int at() const;
void bindValue(const QString &placeholder, const QVariant &val, QSql::ParamType paramType = QSql::In);
void bindValue(int pos, const QVariant &val, QSql::ParamType paramType = QSql::In);
QVariant boundValue(const QString &placeholder) const;
QVariant boundValue(int pos) const;
QMap<QString, QVariant> boundValues() const;
void clear();
const QSqlDriver *driver() const;
bool exec(const QString &query, bool bEmitMessageOnError = true);
bool exec(bool bEmitMessageOnError = true);
bool execAndFetch();
bool execAndFetch(const QString &query);
bool execBatch(BatchExecutionMode mode = ValuesAsRows);
QString executedQuery() const;
void finish();
bool first();
bool isActive() const;
bool isForwardOnly() const;
bool isNull(int field) const;
bool isSelect() const;
bool isValid() const;
bool last();
QSqlError lastError() const;
QString sqlstate();
QVariant lastInsertId();
QString lastQuery() const;
bool next();
bool nextResult();
int numRowsAffected() const;
QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const;
bool prepare(const QString &query);
bool previous();
QSqlRecord record() const;
const QSqlResult *result() const;
bool seek(int index, bool relative = false);
void setForwardOnly(bool forward);
void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy);
int size() const;
QVariant value(int index) const;
NSqlQuery &operator= (const NSqlQuery &other);
bool export2CSV(const QString &filename);
static QVariant qDateTimeToQVariant(const QDateTime &dt);
static QDateTime qVariantToQDateTime(const QVariant &var);
static QString qVariantToJsonString(const QVariant &value);
static QString jsonValueToJsonString(const QJsonValue &value);
static inline QString fixupEmptyJsonString(const QString &str) { return str.isEmpty() ? QLatin1String("{}") : str; }
QString getLastSqlError();
private:
void printLastSqlError();
QSqlDatabase m_db;
NGL::INGLLogger &mLogger;
};
+24
View File
@@ -0,0 +1,24 @@
#include "sql_query_janitor.h"
#include "nsqlquery.h"
#include <QtGlobal>
SqlQueryJanitor::SqlQueryJanitor(NSqlQuery *query)
: m_query(query)
{
Q_ASSERT(m_query);
Q_ASSERT(!m_query->isActive());
}
SqlQueryJanitor::SqlQueryJanitor(const std::unique_ptr<NSqlQuery> &query)
: SqlQueryJanitor(query.get())
{
}
SqlQueryJanitor::~SqlQueryJanitor()
{
m_query->finish();
}
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include "ngldb_export.h"
#include <memory>
class NSqlQuery;
class NGLDB_EXPORT SqlQueryJanitor
{
public:
explicit SqlQueryJanitor(NSqlQuery *query);
explicit SqlQueryJanitor(const std::unique_ptr<NSqlQuery> &query);
~SqlQueryJanitor();
private:
NSqlQuery *m_query;
};
+32
View File
@@ -0,0 +1,32 @@
#
# CMake Script für nglsettings
# $Id$
# $HeadURL$
# $Author$
#
SET(nglsettings_SRCS
nglsettings_connections.cpp
nglsettings_settings.cpp
)
SET(nglsettings_HDRS
nglsettings_connections.h
nglsettings_export.h
nglsettings_settings.h
)
NGL_ADD_LIBRARY(ALL nglsettings SHARED ${nglsettings_SRCS} ${nglsettings_HDRS})
NGL_TARGET_LINK_LIBRARIES(nglsettings
PRIVATE
ngltools
Qt5::Network
PUBLIC
Qt5::Core
)
NGL_TARGET_INCLUDE_DIRECTORIES(nglsettings
INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/../
)
NGL_INSTALL_TARGET(nglsettings)
+175
View File
@@ -0,0 +1,175 @@
#include "nglsettings_connections.h"
#include <QCoreApplication>
#include <QMap>
#include <QPair>
#include <QSettings>
#include <QtNetwork/QHostAddress>
#include <QtNetwork/QHostInfo>
#include <QtNetwork/QNetworkInterface>
namespace NGL
{
namespace Connections
{
enum class eHostConfig
{
public_local,
localhost,
server,
server_avs
};
struct configStruct
{
eHostConfig host;
unsigned short port;
QString name;
};
static QMap<eConnection, configStruct> *s_config = nullptr;
static QSettings *s_settings = nullptr;
static unsigned short s_portOffset = 9000;
static QString *s_serverHostname = nullptr;
static void cleanupSettings()
{
delete s_settings;
s_settings = nullptr;
delete s_serverHostname;
s_serverHostname = nullptr;
delete s_config;
s_config = nullptr;
}
static void insertConfig(eConnection conn, eHostConfig host, unsigned short port, const char *name)
{
if (!s_config)
s_config = new QMap<eConnection, configStruct>();
configStruct s;
s.host = host;
s.port = port;
s.name = QString::fromLatin1(name);
s_config->insert(conn, s);
}
static void initConfig()
{
if (s_config && !s_config->isEmpty())
return;
insertConfig(eConnection::AVS_WORKSTATION, eHostConfig::localhost, 6370, "AVS_WORKSTATION");
insertConfig(eConnection::AVS_WORKSTATION_VD, eHostConfig::localhost, 6380, "AVS_WORKSTATION_VD");
insertConfig(eConnection::AVS_ROOT, eHostConfig::server_avs, 6350, "AVS_ROOT");
insertConfig(eConnection::AVS_FM, eHostConfig::server_avs, 6360, "AVS_FM");
insertConfig(eConnection::AVS_MOTION_RECORDER, eHostConfig::server_avs, 6390, "AVS_MOTION_RECORDER");
insertConfig(eConnection::AVS_AVA, eHostConfig::server_avs, 6391, "AVS_AVA");
insertConfig(eConnection::PWS_WEBSOCKET, eHostConfig::server, 5701, "PWS_WEBSOCKET");
insertConfig(eConnection::SCM_WEBSOCKET, eHostConfig::server, 7300, "SCM_WEBSOCKET");
insertConfig(eConnection::ISM_WEBSOCKET, eHostConfig::server, 2080, "ISM_WEBSOCKET");
insertConfig(eConnection::FLM_THP_SERVER, eHostConfig::server, 2090, "FLM_THP_SERVER");
insertConfig(eConnection::FLM_PDF_SERVER, eHostConfig::server, 3000, "FLM_PDF_SERVER");
insertConfig(eConnection::LVS, eHostConfig::server, 94, "LVS");
insertConfig(eConnection::ZWLVSV, eHostConfig::server, 95, "ZWLVSV");
insertConfig(eConnection::ZWLVWCS, eHostConfig::server, 97, "ZWLVWCS");
insertConfig(eConnection::ZWLVWMS, eHostConfig::server, 98, "ZWLVWMS");
insertConfig(eConnection::ZSLV, eHostConfig::server, 99, "ZSLV");
}
void setIniFile(const QString &iniFileName)
{
if (!s_settings)
qAddPostRoutine(cleanupSettings);
delete s_settings;
s_settings = new QSettings(iniFileName, QSettings::IniFormat);
}
QString iniFile()
{
return s_settings ? s_settings->fileName() : QString();
}
unsigned short portOffset()
{
return s_portOffset;
}
void setPortOffset(unsigned short portOffset)
{
s_portOffset = portOffset;
}
unsigned short port(eConnection connection)
{
initConfig();
unsigned short port = s_config->value(connection).port;
if (s_settings)
{
bool bOk;
QString key = s_config->value(connection).name + QLatin1String("/port");
unsigned short port2 = s_settings->value(key, port).toString().toUShort(&bOk);
if (bOk)
port = port2;
}
if (port < 100)
return portOffset() + port;
return port;
}
QString hostName(eConnection connection)
{
initConfig();
QString host;
switch (s_config->value(connection).host)
{
case eHostConfig::public_local:
host = QString::fromLocal8Bit(qgetenv("HOST"));
break;
case eHostConfig::localhost:
host = QLatin1String("127.0.0.1");
break;
case eHostConfig::server:
if (s_serverHostname)
host = *s_serverHostname;
if (host.isEmpty())
host = QLatin1String("EXCTDS01");
break;
case eHostConfig::server_avs:
host = QStringLiteral("EXCAVS01");
break;
}
if (s_settings)
{
QString key = s_config->value(connection).name + QLatin1String("/host");
QString host2 = s_settings->value(key, host).toString();
if (!host2.isEmpty())
host = host2;
}
return host;
}
void setServerHostname(const QString &serverHostName)
{
if (!s_serverHostname)
s_serverHostname = new QString(serverHostName);
else
*s_serverHostname = serverHostName;
}
QString connectionName(eConnection connection)
{
if (s_config)
{
auto it = s_config->constFind(connection);
if (it != s_config->constEnd())
return it.value().name;
}
return QString::number((int)connection);
}
}
}
+59
View File
@@ -0,0 +1,59 @@
#pragma once
#include <QtCore/QString>
#include "nglsettings_export.h"
namespace NGL
{
namespace Connections
{
enum class eConnection
{
UNKNOWN = 0,
AVS_WORKSTATION,
AVS_WORKSTATION_VD,
AVS_ROOT,
AVS_FM,
AVS_MOTION_RECORDER,
AVS_AVA,
ZWLVSV,
ZSLV,
ZWLVWCS,
ZWLVWMS,
PWS_WEBSOCKET,
SCM_WEBSOCKET,
ISM_WEBSOCKET,
FLM_THP_SERVER,
FLM_PDF_SERVER,
LVS ,
};
NGLSETTINGS_EXPORT void setIniFile(const QString &iniFileName);
NGLSETTINGS_EXPORT QString iniFile();
NGLSETTINGS_EXPORT unsigned short portOffset();
void setPortOffset(unsigned short portOffset);
NGLSETTINGS_EXPORT unsigned short port(eConnection connection);
NGLSETTINGS_EXPORT QString hostName(eConnection connection);
void setServerHostname(const QString &serverHostName);
NGLSETTINGS_EXPORT QString connectionName(eConnection connection);
}
}
+17
View File
@@ -0,0 +1,17 @@
#pragma once
#include <QtCore/qglobal.h>
#ifndef NGLSETTINGS_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define NGLSETTINGS_EXPORT
# else
# ifdef MAKE_NGLSETTINGS_LIB
# define NGLSETTINGS_EXPORT Q_DECL_EXPORT
# else
# define NGLSETTINGS_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
+320
View File
@@ -0,0 +1,320 @@
#include "nglsettings_settings.h"
#include "nglsettings_connections.h"
#include <ngltools/ngltools_filesystem.h>
#include <QCoreApplication>
#include <QDir>
#include <QSettings>
#include <QSize>
#include <QStandardPaths>
namespace NGL
{
QSettings *Settings::s_globalSettings = nullptr;
Settings::Settings(const QString &iniFile_)
: m_settings(nullptr)
{
QString iniFile = iniFile_;
if(iniFile == QLatin1String("gfs_ws.ini")) {
const QByteArray defUser = qgetenv("USER");
if( defUser == "ctc_aar" || defUser == "ctc_rbf" ) {
QByteArray home = qgetenv("HOME");
if(!home.isEmpty()) {
QString fn = QString::fromLocal8Bit(home) +
QLatin1String("/gfs_") +
QString::fromLocal8Bit(defUser.mid(4)) +
QLatin1String(".ini");
QFileInfo fi(fn);
if(fi.exists() && fi.isFile() && fi.isReadable()) {
iniFile = fn;
}
}
}
}
initializeGlobalSettings();
initPre();
if(!iniFile.isEmpty()) {
if(QFileInfo(iniFile).isAbsolute())
m_settings = new QSettings(iniFile, QSettings::IniFormat);
else
m_settings = new QSettings(basePath() + iniFile, QSettings::IniFormat);
initPost();
}
if (!m_settings)
m_settings = new QSettings(QLatin1String("RDE"));
}
Settings::Settings(const QString &organization, const QString &application)
: m_settings(new QSettings(organization, application))
{
initPre();
initPost();
}
Settings::~Settings()
{
delete m_settings;
}
void Settings::initializeGlobalSettings()
{
if (s_globalSettings)
return;
if (!s_globalSettings)
{
QString globalSettingsFile = NGL::findProjectConfigFile();
if (!globalSettingsFile.isEmpty())
s_globalSettings = new QSettings(globalSettingsFile, QSettings::IniFormat);
}
if (!s_globalSettings)
s_globalSettings = new QSettings(QLatin1String("RDE"), QLatin1String("LTS-CC"));
Connections::setPortOffset(portOffset());
Connections::setServerHostname(serverHostname());
}
QString Settings::globalSectionName()
{
QString secName = QLatin1String("Global");
static const char envGlobSecName[] = "LTS_CONF_GLOBAL_SECTION_NAME";
if (qEnvironmentVariableIsSet(envGlobSecName))
secName = QString::fromLocal8Bit(qgetenv(envGlobSecName));
return secName;
}
QString Settings::basePath() const
{
return m_paths["GFS_PATH"];
}
QString Settings::tempPath() const
{
return m_paths["TMP_PATH"];
}
QString Settings::printPath()
{
return getDirectory("PDF", tempPath());
}
QString Settings::logoProject()
{
return QLatin1String(":project/logo.png");
}
QString Settings::bitmapPath()
{
return getDirectory("BITMAPS", basePath() + QLatin1String("DATA"));
}
QString Settings::zsks_rxPath()
{
return getDirectory("ZSKS_RX", tempPath());
}
QString Settings::zsks_txPath()
{
return getDirectory("ZSKS_TX", tempPath());
}
QString Settings::aarServerPath(int exerciseId)
{
return getDirectory(QByteArray::number(exerciseId), QString::fromLocal8Bit("/data/aar/"));
}
bool Settings::isDatabaseConnectionLocal()
{
return (databaseHostname() == QStringLiteral("localhost"));
}
QString Settings::databaseName()
{
initializeGlobalSettings();
return s_globalSettings->value(globalSectionName()+ QLatin1String("/DatabaseName"), QLatin1String("lts_ets_pro")).toString();
}
QString Settings::databaseHostname()
{
initializeGlobalSettings();
return s_globalSettings->value(QLatin1String("Global/DatabaseHostname"), QLatin1String("EXCDBS01")).toString();
}
QString Settings::databaseUser()
{
#ifdef Q_OS_WIN
QByteArray defUser = qgetenv("USERNAME");
#else
QByteArray defUser = qgetenv("USER");
#endif
QString ret = m_settings->value(QLatin1String("db/user"), QString::fromLocal8Bit(defUser)).toString();
return ret;
}
QString Settings::databasePassword(const QString &databaseUser)
{
QString defaultPw = QStringLiteral("ctc11de");
if (!databaseUser.isEmpty())
{
const QVector<QStringRef> &sl = databaseUser.splitRef(QLatin1Char('_'));
if (sl.size() > 1)
defaultPw = sl.at(0).toString() + QStringLiteral("11de");
}
return m_settings->value(QLatin1String("db/passwd"), defaultPw).toString();
}
QString Settings::databaseDriver()
{
return m_settings->value(QLatin1String("db/driver"), QLatin1String("QPSQL")).toString();
}
int Settings::avsKeepAliveTimeout()
{
return m_settings->value(QLatin1String("avs/keepalivetimeout"), 20000).toInt();
}
QString Settings::avsServerHost()
{
return m_settings->value(QLatin1String("avs/serverhost"), QLatin1String("EXCAVS01")).toString();
}
quint16 Settings::avsServerPortAVE()
{
static const quint16 defaultPort = 6350;
bool bOk;
quint16 ret = m_settings->value(QLatin1String("avs/serverport_ave"), defaultPort).toUInt(&bOk);
return bOk ? ret : defaultPort;
}
QSettings *Settings::settings()
{
return m_settings;
}
const QSettings *Settings::settings() const
{
return m_settings;
}
QString Settings::fixupPath(const QString &_path) const
{
QString path = QDir::fromNativeSeparators(_path);
if(!QDir::isAbsolutePath(path))
path = basePath() + path;
path = QDir::cleanPath(path);
if(!path.endsWith(QLatin1Char('/')))
path += QLatin1Char('/');
return path;
}
QString Settings::getDirectory(const QByteArray &_dir, const QString &defPrefix, bool bPathLowercase)
{
if(m_paths[_dir].isEmpty()) {
const QString lowerDir = QString::fromLatin1(_dir.toLower());
const QString dir = bPathLowercase ? lowerDir : QString::fromLatin1(_dir);
QString def = defPrefix + QLatin1Char('/') + dir + QLatin1Char('/');
m_paths[_dir] = fixupPath(m_settings->value(QLatin1String("paths/") + lowerDir, def).toString());
QDir d(m_paths[_dir]);
if(!d.exists())
d.mkpath(d.absolutePath());
}
return m_paths[_dir];
}
void Settings::initPre()
{
#ifdef WIN32
QString path = QString::fromLocal8Bit(qgetenv("GFS_PATH"));
if(path.isEmpty())
path = QCoreApplication::applicationDirPath();
m_paths["GFS_PATH"] = fixupPath(path);
#else
QByteArray path = qgetenv("GFS_PATH");
if(path.isEmpty())
path = qgetenv("HOME");
m_paths["GFS_PATH"] = fixupPath(QString::fromLocal8Bit(path));
#endif
QByteArray tmppath = qgetenv("TMP_PATH");
if(tmppath.isEmpty())
tmppath = qgetenv("TMP");
if (tmppath.isEmpty())
tmppath = QDir::tempPath().toLocal8Bit();
m_paths["TMP_PATH"] = fixupPath(QString::fromLocal8Bit(tmppath));
}
void Settings::initPost()
{
NGL::Connections::setIniFile(m_settings->fileName());
}
int Settings::getInteger(const QString &key, int defVal) const
{
bool bOk;
int ret = m_settings->value(key, defVal).toInt(&bOk);
return bOk ? ret : defVal;
}
float Settings::getFloat(const QString &key, float defVal) const
{
bool bOk;
float ret = m_settings->value(key, defVal).toFloat(&bOk);
return bOk ? ret : defVal;
}
double Settings::getDouble(const QString &key, double defVal) const
{
bool bOk;
double ret = m_settings->value(key, defVal).toDouble(&bOk);
return bOk ? ret : defVal;
}
bool Settings::getBoolean(const QString &key, bool defVal) const
{
return m_settings->value(key, defVal).toBool();
}
QString Settings::getString(const QString &key, const QString &defVal) const
{
return m_settings->value(key, defVal).toString();
}
unsigned short Settings::domainId()
{
initializeGlobalSettings();
return s_globalSettings->value(QLatin1String("Global/DomainId"), 0).toUInt();
}
unsigned short Settings::portOffset()
{
initializeGlobalSettings();
return s_globalSettings->value(QLatin1String("Global/PortOffset"), 9000).toUInt();
}
QString Settings::serverHostname()
{
initializeGlobalSettings();
return s_globalSettings->value(QLatin1String("Global/ServerHostname"), QLatin1String("EXCTDS01")).toString();
}
QString Settings::logPath()
{
initializeGlobalSettings();
#ifdef WIN32
return s_globalSettings->value(QLatin1String("Global/LogPath"), QStandardPaths::writableLocation(QStandardPaths::TempLocation)).toString();
#else
return s_globalSettings->value(QLatin1String("Global/LogPath"), QLatin1String("/shd/CTC/LOG")).toString();
#endif
}
}
+142
View File
@@ -0,0 +1,142 @@
#pragma once
#include <QtCore/QString>
#include <QtCore/QHash>
#include "nglsettings_export.h"
class QSettings;
namespace NGL {
class NGLSETTINGS_EXPORT Settings {
public:
explicit Settings(const QString &iniFile);
explicit Settings(const QString &organization, const QString &application);
Settings(const Settings&) = delete;
Settings &operator=(const Settings&) = delete;
virtual ~Settings();
static void initializeGlobalSettings();
QString basePath() const;
QString tempPath() const;
QString printPath();
QString logoProject();
QString bitmapPath();
QString zsks_rxPath();
QString zsks_txPath();
static QString databaseName();
static QString databaseHostname();
QString databaseUser();
QString databasePassword(const QString &databaseUser = QString());
QString databaseDriver();
QString aarServerPath(int exerciseId);
bool isDatabaseConnectionLocal();
int avsKeepAliveTimeout();
QString avsServerHost();
quint16 avsServerPortAVE();
QSettings *settings();
const QSettings *settings() const;
int getInteger(const QString &key, int defVal) const;
int getInteger(const QString &group, const QString &key, int defVal) const
{
return getInteger(group + QLatin1Char('/') + key, defVal);
}
float getFloat(const QString &key, float defVal) const;
float getFloat(const QString &group, const QString &key, float defVal) const
{
return getFloat(group + QLatin1Char('/') + key, defVal);
}
double getDouble(const QString &key, double defVal) const;
double getDouble(const QString &group, const QString &key, double defVal) const
{
return getDouble(group + QLatin1Char('/') + key, defVal);
}
bool getBoolean(const QString &key, bool defVal) const;
bool getBoolean(const QString &group, const QString &key, bool defVal) const
{
return getBoolean(group + QLatin1Char('/') + key, defVal);
}
QString getString(const QString &key, const QString &defVal) const;
QString getString(const QString &group, const QString &key, const QString &defVal) const
{
return getString(group + QLatin1Char('/') + key, defVal);
}
static unsigned short portOffset();
static unsigned short domainId();
static QString serverHostname();
static QString logPath();
static QString globalSectionName();
private:
QString fixupPath(const QString &path) const;
QString getDirectory(const QByteArray &dir, const QString &defPrefix, bool bPathLowercase = false);
private:
void initPre();
void initPost();
QSettings *m_settings;
static QSettings *s_globalSettings;
QHash<QByteArray, QString> m_paths;
};
}
+34
View File
@@ -0,0 +1,34 @@
#
# CMake Script für ngltools
# $Id$
# $HeadURL$
# $Author$
#
SET(ngltools_SRCS
ngltools_bitset.h
ngltools_convert.cpp
ngltools_convert.h
ngltools_dtg.cpp
ngltools_dtg.h
ngltools_export.h
ngltools_filesystem.cpp
ngltools_filesystem.h
ngltools_helpevent.cpp
ngltools_helpevent.h
)
NGL_ADD_LIBRARY(ALL ngltools SHARED ${ngltools_SRCS})
NGL_TARGET_LINK_LIBRARIES(ngltools
PUBLIC
Qt5::Core
)
NGL_TARGET_COMPILE_DEFINITIONS(ngltools PUBLIC BUILD_BASE_PATH="${CMAKE_BINARY_DIR}")
NGL_TARGET_COMPILE_DEFINITIONS(ngltools PUBLIC INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}")
NGL_TARGET_INCLUDE_DIRECTORIES(ngltools
INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}/../
)
NGL_INSTALL_TARGET(ngltools)
+100
View File
@@ -0,0 +1,100 @@
#pragma once
namespace NGL {
template<class T>
class BitSet {
public:
BitSet(T bitset = T())
: mBitSet(bitset)
, mSize(sizeof(T)*8)
{}
BitSet(const BitSet<T> &other)
: mBitSet(other.mBitSet)
, mSize(other.mSize)
{}
BitSet &operator=(const BitSet<T> &other)
{
if(this == &other)
return *this;
mBitSet = other.mBitSet;
mSize = other.mSize;
return *this;
}
bool operator==(const BitSet<T> &other) const
{
return (mBitSet == other.mBitSet && mSize == other.mSize);
}
bool setBit(unsigned int bitNum)
{
if(bitNum >= mSize)
return false;
mBitSet |= getBit(bitNum);
return true;
}
bool clearBit(unsigned int bitNum)
{
if(bitNum >= mSize)
return false;
mBitSet &= ~(getBit(bitNum));
return true;
}
bool at(unsigned int bitNum) const
{
if(bitNum >= sizeof(T) * 8)
return false;
T compVal = getBit(bitNum);
return ((mBitSet & compVal) == compVal);
}
bool operator[] (unsigned int bitNum) const
{
return at(bitNum);
}
size_t size() const
{
return mSize;
}
bool resize(size_t newSize)
{
if(newSize >= sizeof(T) * 8)
return false;
for(unsigned int i = mSize; i < newSize; ++i)
clearBit(i);
mSize = newSize;
return true;
}
void clear()
{
fill(false);
}
void fill(bool bBitsSet)
{
if(bBitsSet)
mBitSet = ~T();
else
mBitSet = T();
}
T operator()() const { return mBitSet; }
protected:
static T getBit(unsigned int bitNum_)
{
T bitNum = bitNum_;
const T one = 1;
return (one << bitNum);
}
T mBitSet;
size_t mSize;
};
}
+91
View File
@@ -0,0 +1,91 @@
#include "ngltools_convert.h"
#include <QVector>
namespace NGL
{
QByteArray quoteForTelnet(const QVector<QString> &sl)
{
QVector<QByteArray> tmp;
tmp.reserve(sl.size());
for (const QString &s : sl)
tmp += s.toUtf8();
return quoteForTelnet(tmp);
}
QByteArray quoteForTelnet(const QVector<QByteArray> &sl)
{
QByteArray cmd;
for (QByteArray s : sl)
{
s.replace('\"', "\\\"");
if (s.contains(' '))
s = '"' + s + '"';
if (s.isEmpty())
s = "\"\"";
cmd += s + ' ';
}
cmd += '\n';
return cmd;
}
QVector<QByteArray> parseFromTelnet(const QByteArray &ba, const int iStart)
{
QVector<QByteArray> ret;
const char *p = ba.constData() + iStart;
const int iLen = ba.length();
const char *p_end = ba.constData() + iLen;
if (iLen <= iStart)
return ret;
char quoteEndChar = '"';
while (p < p_end && *p)
{
while (isspace(*p))
++p;
if (*p && p < p_end)
{
bool escaped = false;
bool bQuoted = (*p == '\"') || (*p == '{');
if (bQuoted)
{
quoteEndChar = (*p == '\"') ? '\"' : '}';
++p;
}
const char *start = p;
while (true)
{
while (p < p_end && *p != (bQuoted ? quoteEndChar : ' '))
++p;
if (bQuoted)
{
if (* (p - 1) == '\\')
{
++p;
escaped = true;
continue;
}
}
QByteArray result = QByteArray(start, p - start).trimmed();
if (escaped)
{
if (quoteEndChar == '}')
{
result = result.replace("\\{", "{");
result = result.replace("\\}", "}");
}
else
result = result.replace("\\\"", "\"");
}
ret += result;
++p;
break;
}
}
}
return ret;
}
}
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#include "ngltools_export.h"
#include <QByteArray>
#include <QString>
#include <QVector>
namespace NGL
{
NGLTOOLS_EXPORT QByteArray quoteForTelnet(const QVector<QString> &sl);
NGLTOOLS_EXPORT QByteArray quoteForTelnet(const QVector<QByteArray> &sl);
NGLTOOLS_EXPORT QVector<QByteArray> parseFromTelnet(const QByteArray &ba, const int iStart = 0);
}
+372
View File
@@ -0,0 +1,372 @@
#include "ngltools_dtg.h"
#include <QString>
#include <QDateTime>
namespace DTG
{
static char s_timezone = 'Z';
static char s_userDefinedTimezone = s_timezone;
static char s_exerciseDefaultTimezone = s_timezone;
int timezone2Hours(char tz, bool *bOk)
{
if (!isTimezoneValid(tz))
{
if (bOk)
*bOk = false;
return 0;
}
if (bOk)
*bOk = true;
if (tz < 'J')
return tz - 'A' + 1;
if (tz < 'N')
return tz - 'A';
if (tz < 'Z')
return 'Z' - tz - 13;
return 0;
}
int timezone2Secs(char tz, bool *bOk)
{
return 3600 * timezone2Hours(tz, bOk) ;
}
bool setTimezone(char tz, bool bUserDefinedZone)
{
if (!isTimezoneValid(tz))
{
if (!(tz == 0 && bUserDefinedZone))
return false;
}
if (bUserDefinedZone)
s_userDefinedTimezone = tz;
else
s_exerciseDefaultTimezone = tz;
s_timezone = s_userDefinedTimezone != 0 ? s_userDefinedTimezone : s_exerciseDefaultTimezone;
return true;
}
char timezone()
{
return s_timezone;
}
char timezoneUserDefined()
{
return s_userDefinedTimezone;
}
char timezoneExerciseDefault()
{
return s_exerciseDefaultTimezone;
}
bool isTimezoneValid(char tz)
{
tz = toupper(tz);
return !(tz < 'A' || tz == 'J' || tz > 'Z');
}
static DateTimeType s_dateTimeType = DDMMYYYY_Z_HHMMSS;
static DisplayFormat s_defaultDisplayFormat = Long;
void setDateTimeType(DateTimeType dtType)
{
s_dateTimeType = dtType;
}
DateTimeType dateTimeType()
{
return s_dateTimeType;
}
void setDefaultDisplayFormat(DisplayFormat dtFormat)
{
s_defaultDisplayFormat = dtFormat;
}
DisplayFormat defaultDisplayFormat()
{
return s_defaultDisplayFormat;
}
QString toString(const QDateTime &dt, DisplayFormat format, DateTimeType type)
{
if (format == Default)
format = s_defaultDisplayFormat;
static const QDateTime dtNull = QDateTime::fromSecsSinceEpoch(0);
if (!dt.isValid() || dt == dtNull)
return QString();
const QDateTime dateTime = dt.toUTC().addSecs(timezone2Hours(s_timezone) * 3600);
QString ret;
switch (type)
{
case DTG:
{
QString str1;
if (format == Long)
str1 = dateTime.toString(QLatin1String("dd hhmmss"));
else if (format == TurboLong)
str1 = dateTime.toString(QLatin1String("dd hhmmss.z"));
else
{
ret = dateTime.toString(QLatin1String("ddhhmm")) + QLatin1Char(s_timezone);
break;
}
const int month = dateTime.date().month() - 1;
const int year = dateTime.date().year() - 2000;
ret = QStringLiteral("%1 %2 %3 %4")
.arg(str1)
.arg(QLatin1Char(s_timezone))
.arg(months().at(month))
.arg(year, 2, 10, QLatin1Char('0'));
}
break;
case DDMMYYYY_HHMMSS_Z:
{
if (format == Long)
ret = dateTime.toString(QLatin1String("dd.MM.yyyy HH:mm:ss")) + QLatin1Char(s_timezone);
else
ret = dateTime.toString(QLatin1String("dd.MM HH:mm")) + QLatin1Char(s_timezone);
}
break;
case DDMMYYYY_Z_HHMMSS:
if (format == Long)
ret = dateTime.toString(QLatin1String("dd.MM.yyyy "))
+ QLatin1Char(s_timezone)
+ dateTime.toString(QLatin1String(" HH:mm:ss"));
else
ret = dateTime.toString(QLatin1String("dd.MM "))
+ QLatin1Char(s_timezone)
+ dateTime.toString(QLatin1String(" HH:mm"));
break;
}
return ret;
}
QString toStringMSec(qint64 msecSinceEpoch, DisplayFormat format)
{
if (msecSinceEpoch <= 0)
return QString();
return toString(QDateTime::fromMSecsSinceEpoch(msecSinceEpoch), format);
}
static bool check24(const QChar *input, int *output)
{
const int i1 = input[0].unicode() - '0';
const int i2 = input[1].unicode() - '0';
if (i1 > 2)
return false;
if (i1 == 2 && i2 > 5)
return false;
if (output)
*output = i1 * 10 + i2;
return true;
}
static bool check31(const QChar *input, int *output = nullptr)
{
const int i1 = input[0].unicode() - '0';
const int i2 = input[1].unicode() - '0';
if (i1 > 3)
return false;
if (i1 == 3 && i2 > 1)
return false;
if (output)
*output = i1 * 10 + i2;
return true;
}
static bool check60(const QChar *input, int *output)
{
const int i1 = input[0].unicode() - '0';
const int i2 = input[1].unicode() - '0';
if (i1 > 5)
return false;
if (output)
*output = i1 * 10 + i2;
return true;
}
static DTGValidation validate18(const QString &input, QDateTime &dt)
{
int hh, mm, ss;
for (int i = 0; i < 2; ++i)
{
if (!input[i].isDigit())
return Invalid;
}
if (!check31(&input.data() [0]))
return Invalid;
if (input[2] != QLatin1Char(' '))
return Invalid;
if (input.length() == 7)
{
for (int i = 3; i < 7; ++i)
{
if (!input[i].isDigit())
return Invalid;
}
return Intermediate;
}
for (int i = 3; i < 9; ++i)
{
if (!input[i].isDigit())
return Invalid;
}
if (!check24(&input.data() [3], &hh))
return Invalid;
if (!check60(&input.data() [5], &mm))
return Invalid;
if (!check60(&input.data() [7], &ss))
return Invalid;
if (input[9] != QLatin1Char(' '))
return Invalid;
const QChar c = input[10];
if (c < QLatin1Char('A') || c > QLatin1Char('Z'))
return Invalid;
if (c == QLatin1Char('J'))
{
return Invalid;
}
const QString mon = input.mid(12, 3);
int month = months().indexOf(mon);
if (month < 0)
{
return Invalid;
}
for (int i = 16; i < 18; ++i)
{
if (!input[i].isDigit())
return Invalid;
}
const int day = input.leftRef(2).toInt();
const int year = input.midRef(16, 2).toInt() + 2000;
dt = QDateTime(QDate(year, month + 1, day), QTime(hh, mm, ss), Qt::UTC);
if (!dt.isValid())
{
return Invalid;
}
dt = dt.addSecs(-timezone2Hours(c.toLatin1()) * 3600);
return Acceptable;
}
static DTGValidation validate7(const QString &input, QDateTime &dt)
{
int hh, mm;
for (int i = 0; i < 6; ++i)
{
if (!input[i].isDigit())
return Invalid;
}
if (!check31(&input.data() [0]))
return Invalid;
if (!check24(&input.data() [2], &hh))
return Invalid;
if (!check60(&input.data() [4], &mm))
return Invalid;
const QChar c = input[6];
if (c < QLatin1Char('A') || c > QLatin1Char('Z'))
return Invalid;
if (c == QLatin1Char('J'))
{
return Invalid;
}
const int day = input.leftRef(2).toInt();
const QDate curDate = QDate::currentDate();
dt = QDateTime(QDate(curDate.year(), curDate.month(), day), QTime(hh, mm), Qt::UTC);
if (!dt.isValid())
{
return Invalid;
}
dt = dt.addSecs(-timezone2Hours(c.toLatin1()) * 3600);
return Acceptable;
}
QDateTime fromDTGString(const QString &str, bool *bOk)
{
if (bOk)
*bOk = false;
QDateTime dt;
if (str.length() == 7)
{
DTGValidation state = validate7(str, dt);
if (state == Acceptable && bOk)
*bOk = true;
}
else if (str.length() == 18)
{
DTGValidation state = validate18(str, dt);
if (state == Acceptable && bOk)
*bOk = true;
}
return dt;
}
DTGValidation validateString(const QString &str, QDateTime &dt)
{
const int len = str.length();
if (len == 7 || len == 18)
{
if (len == 18 || (str[2] == QLatin1Char(' ')))
return validate18(str, dt);
return validate7(str, dt);
}
return Invalid;
}
QStringList months()
{
return {
QLatin1String("jan"), QLatin1String("feb"), QLatin1String("mar"),
QLatin1String("apr"), QLatin1String("may"), QLatin1String("jun"),
QLatin1String("jul"), QLatin1String("aug"), QLatin1String("sep"),
QLatin1String("oct"), QLatin1String("nov"), QLatin1String("dec")
};
}
}
+87
View File
@@ -0,0 +1,87 @@
#pragma once
#include <QStringList>
#include "ngltools_export.h"
class QDateTime;
namespace DTG
{
enum DateTimeType
{
DTG = 1,
DDMMYYYY_HHMMSS_Z = 2,
DDMMYYYY_Z_HHMMSS = 4
};
enum DisplayFormat
{
Short,
Long,
TurboLong,
Default
};
enum DTGValidation
{
Invalid,
Intermediate,
Acceptable
};
NGLTOOLS_EXPORT void setDateTimeType(DateTimeType dtType);
NGLTOOLS_EXPORT DateTimeType dateTimeType();
NGLTOOLS_EXPORT void setDefaultDisplayFormat(DisplayFormat dtFormat);
NGLTOOLS_EXPORT DisplayFormat defaultDisplayFormat();
NGLTOOLS_EXPORT QString toString(const QDateTime &dt, DisplayFormat format = Default, DateTimeType = dateTimeType());
NGLTOOLS_EXPORT QString toStringMSec(qint64 msecSinceEpoch, DisplayFormat format = Default);
NGLTOOLS_EXPORT QDateTime fromDTGString(const QString &str, bool *bOk = nullptr);
NGLTOOLS_EXPORT DTGValidation validateString(const QString &str, QDateTime &dt);
NGLTOOLS_EXPORT bool setTimezone(char tz, bool bUserDefinedZone);
NGLTOOLS_EXPORT char timezone();
NGLTOOLS_EXPORT char timezoneUserDefined();
NGLTOOLS_EXPORT char timezoneExerciseDefault();
NGLTOOLS_EXPORT bool isTimezoneValid(char tz);
NGLTOOLS_EXPORT int timezone2Hours(char tz, bool *bOk = nullptr);
NGLTOOLS_EXPORT int timezone2Secs(char tz, bool *bOk = nullptr);
NGLTOOLS_EXPORT QStringList months();
}
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#ifndef NGLTOOLS_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define NGLTOOLS_EXPORT
# else
# ifdef WIN32
# ifdef MAKE_NGLTOOLS_LIB
# define NGLTOOLS_EXPORT __declspec(dllexport)
# else
# define NGLTOOLS_EXPORT __declspec(dllimport)
# endif
# else
# define NGLTOOLS_EXPORT __attribute__((visibility("default")))
# endif
# endif
#endif
+289
View File
@@ -0,0 +1,289 @@
#include "ngltools_filesystem.h"
#include <QCoreApplication>
#include <QDir>
#include <QSettings>
namespace NGL
{
bool removeDirContentsRecursively(const QString &d, bool bAlsoDeleteBaseDir)
{
QDir dir(d);
if (!dir.exists())
return false;
bool success = true;
const QFileInfoList list = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries);
for (const QFileInfo &fi : list)
{
bool ret = false;
if (fi.isDir())
{
ret = removeDirContentsRecursively(fi.absoluteFilePath());
if (!ret)
{
}
else
{
ret = dir.rmdir(fi.absoluteFilePath());
if (!ret)
{
}
}
}
else if (fi.isFile() || fi.isSymLink())
{
ret = dir.remove(fi.fileName());
if (!ret)
{
}
}
success &= ret;
}
if (bAlsoDeleteBaseDir)
success &= dir.rmpath(d);
return success;
}
bool copyDirContentsToDir(const QString &source, const QString &destination, bool sourceIsRelative)
{
QString srcPath(source);
if (sourceIsRelative)
{
QVector<QString> pathsToSearch = directories(FileType::ConfigFile);
pathsToSearch.append(directories(FileType::ProjectConfigFile));
for (const QString &basePath : qAsConst(pathsToSearch))
{
QString absolutePath = basePath + QLatin1Char('/') + source;
if (QDir(absolutePath).exists())
{
srcPath = absolutePath;
break;
}
}
if (srcPath.isEmpty())
return false;
}
QDir srcDir(srcPath);
QDir dstDir(destination);
if (!dstDir.exists())
{
bool succ = dstDir.mkdir(destination);
if (!succ)
return false;
}
const QFileInfoList dirList = srcDir.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot);
for (const QFileInfo &fi : dirList)
{
if (!dstDir.exists())
{
bool succ = dstDir.mkdir(fi.fileName());
if (!succ)
return false;
}
bool succ = copyDirContentsToDir(fi.filePath(), dstDir.absolutePath() + QLatin1Char('/') + fi.fileName());
if (!succ)
return false;
}
const QFileInfoList fileList = srcDir.entryInfoList(QDir::Files | QDir::Hidden);
for (const QFileInfo &fi : fileList)
{
QString targetFileName = dstDir.absolutePath() + QLatin1Char('/') + fi.fileName();
QFile targetFile(targetFileName);
if (targetFile.exists())
targetFile.remove();
bool succ = QFile::copy(fi.absoluteFilePath(), targetFileName);
if (!succ)
return false;
}
return true;
}
qint64 getDirectorySize(const QString &dir)
{
QDir d(dir);
qint64 ret = QFileInfo(dir).size();
const QFileInfoList dirList = d.entryInfoList(QDir::AllDirs | QDir::NoDotAndDotDot);
const QFileInfoList fileList = d.entryInfoList(QDir::Files | QDir::Hidden);
for (const QFileInfo &fi : dirList)
ret += getDirectorySize(fi.absoluteFilePath());
for (const QFileInfo &fi : fileList)
ret += fi.size();
return ret;
}
bool isAppInBuildBasePath()
{
bool ret = false;
#ifdef BUILD_BASE_PATH
const QString bbp(QString::fromLocal8Bit(BUILD_BASE_PATH));
if (!bbp.isEmpty())
ret = QCoreApplication::applicationDirPath().startsWith(bbp);
#endif
return ret;
}
QString projectConfigFileName()
{
return QLatin1String("lts-cc.conf");
}
QString findProjectConfigFile()
{
return findFile(FileType::ProjectConfigFile, projectConfigFileName());
}
static QString searchFileInDir(const QString &path, const QString &filename, bool bRecursive)
{
if (QFile::exists(path + QLatin1Char('/') + filename))
return path + QLatin1Char('/') + filename;
if (!bRecursive)
return QString();
const QDir d(path);
const QStringList entryList = d.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
for (const QString &entry : entryList)
{
const QString foundPath = searchFileInDir(path + QLatin1Char('/') + entry, filename, bRecursive);
if (!foundPath.isEmpty())
return foundPath;
}
return QString();
}
QString findFile(FileType fileType, const QString &filename)
{
const QFileInfo fi(filename);
if (fi.isAbsolute())
return fi.exists() ? filename : QString();
const bool bRecursive = (fileType == FileType::ConfigFile);
const QVector<QString> pathsToSearch = directories(fileType);
for (const QString &path : pathsToSearch)
{
const QString foundPath = searchFileInDir(path, filename, bRecursive);
if (!foundPath.isEmpty())
return foundPath;
}
return QString();
}
QVector<QString> directories(FileType fileType)
{
QVector<QString> pathsToSearch;
switch (fileType)
{
case FileType::ProjectConfigFile:
{
#ifdef BUILD_BASE_PATH
const QString bbp(QString::fromLocal8Bit(BUILD_BASE_PATH));
if (!bbp.isEmpty())
{
if (QCoreApplication::applicationDirPath().startsWith(bbp))
pathsToSearch += bbp;
}
#endif
pathsToSearch += QDir::homePath();
#ifdef Q_OS_UNIX
pathsToSearch += QLatin1String("/etc");
#else
pathsToSearch += QStringLiteral("C:/Rheinmetall/Lts/");
pathsToSearch += QCoreApplication::applicationDirPath();
#endif
break;
}
case FileType::ConfigFile:
{
#ifdef BUILD_BASE_PATH
const QString bbp(QString::fromLocal8Bit(BUILD_BASE_PATH));
if (!bbp.isEmpty())
{
if (QCoreApplication::applicationDirPath().startsWith(bbp))
pathsToSearch += bbp + QLatin1String("/share/Lts");
}
#endif
pathsToSearch += QCoreApplication::applicationDirPath() + QLatin1String("/share/Lts");
pathsToSearch += QCoreApplication::applicationDirPath() + QLatin1String("/../share/Lts");
pathsToSearch += QDir::homePath() + QLatin1String("/share/Lts");
#ifdef INSTALL_PREFIX
pathsToSearch += QString::fromLocal8Bit(INSTALL_PREFIX) + QLatin1String("/share/Lts");
#endif
break;
}
}
return pathsToSearch;
}
QString findServiceXmlFile(const QString &serviceShortName)
{
return findFile(FileType::ConfigFile, serviceShortName + QLatin1String(".xml"));
}
QString directory(FileType fileType, const QString &subdir)
{
const QVector<QString> pathsToSearch = directories(fileType);
QFileInfo fi;
for (const QString &path : pathsToSearch)
{
fi.setFile(path + QLatin1Char('/') + subdir);
if (fi.isDir() && fi.exists() && fi.isReadable())
return fi.absoluteFilePath() + QLatin1Char('/');
}
return QString();
}
QString postgresExecutablePath(const QString &psqlProgram, QString &errStr)
{
errStr.clear();
#ifdef Q_OS_LINUX
return QStringLiteral("/usr/bin/") + psqlProgram;
#else
static QString s_postgresBinariesPath;
if (s_postgresBinariesPath.isEmpty())
{
QSettings s(QStringLiteral("HKEY_LOCAL_MACHINE\\SOFTWARE\\PostgreSQL\\Installations"), QSettings::NativeFormat);
const QStringList installations = s.childGroups();
if (installations.isEmpty())
{
errStr = QStringLiteral("Could not find a valid PostgreSQL windows installation...");
return psqlProgram;
}
if (installations.size() > 1)
errStr = QStringLiteral("More than one PostgreSQL windows installation found - using the first one: %1").arg(installations.first());
s.beginGroup(installations.first());
const QString baseDir = s.value(QStringLiteral("Base Directory")).toString();
if (baseDir.isEmpty() || !QDir(baseDir).exists())
{
errStr = QStringLiteral("Could not find a valid PostgreSQL windows installation... - Base Directory is empty or does not exist (%1)").arg(baseDir);
return psqlProgram;
}
s_postgresBinariesPath = baseDir + QStringLiteral("/bin/");
}
return s_postgresBinariesPath + psqlProgram + QStringLiteral(".exe");
#endif
}
}
+38
View File
@@ -0,0 +1,38 @@
#pragma once
#include "ngltools_export.h"
#include <QtCore/QString>
#include <QtCore/QVector>
namespace NGL
{
NGLTOOLS_EXPORT bool removeDirContentsRecursively(const QString &d, bool bAlsoDeleteBaseDir = false);
NGLTOOLS_EXPORT bool copyDirContentsToDir(const QString &source, const QString &destination, bool sourceIsRelative = false);
NGLTOOLS_EXPORT qint64 getDirectorySize(const QString &dir);
enum class FileType
{
ProjectConfigFile,
ConfigFile
};
NGLTOOLS_EXPORT bool isAppInBuildBasePath();
NGLTOOLS_EXPORT QString projectConfigFileName();
NGLTOOLS_EXPORT QString findProjectConfigFile();
NGLTOOLS_EXPORT QString findFile(FileType fileType, const QString &filename);
NGLTOOLS_EXPORT QString findServiceXmlFile(const QString &serviceShortName);
NGLTOOLS_EXPORT QVector<QString> directories(FileType fileType);
NGLTOOLS_EXPORT QString directory(FileType fileType, const QString &subdir);
NGLTOOLS_EXPORT QString postgresExecutablePath(const QString &psqlProgram, QString &errStr);
}
+19
View File
@@ -0,0 +1,19 @@
#include "ngltools_helpevent.h"
#include <QtCore/QCoreApplication>
QEvent::Type NGLHelpEvent::sHelpEventId = (QEvent::Type)(-1);
void NGLHelpEvent::sendHelpEvent(const QString &helpContext)
{
NGLHelpEvent he(helpContext);
QCoreApplication::sendEvent(qApp, &he);
}
QEvent::Type NGLHelpEvent::helpEventId()
{
if(sHelpEventId < 0)
sHelpEventId = (QEvent::Type)(QEvent::registerEventType());
return sHelpEventId;
}
+34
View File
@@ -0,0 +1,34 @@
#pragma once
#include <QtCore/QEvent>
#include <QtCore/QString>
#include "ngltools_export.h"
class NGLTOOLS_EXPORT NGLHelpEvent : public QEvent
{
protected:
explicit NGLHelpEvent(const QString &helpContext)
: QEvent(helpEventId())
, mHelpContext(helpContext)
{}
public:
QString helpContext() const { return mHelpContext; }
static void sendHelpEvent(const QString &helpContext);
static QEvent::Type helpEventId();
protected:
QString mHelpContext;
static QEvent::Type sHelpEventId;
};
+22
View File
@@ -0,0 +1,22 @@
#
# ngltranslator lib
# $Id$
# $HeadURL$
# $Author$
#
SET(my_SRCS
ngltranslator.cpp
ngltranslator.h
ngltranslator_export.h
)
NGL_ADD_LIBRARY(ALL ngltranslator SHARED ${my_SRCS})
NGL_TARGET_LINK_LIBRARIES(ngltranslator
PUBLIC
Qt5::Core
)
NGL_TARGET_INCLUDE_DIRECTORIES(ngltranslator
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/..
)
NGL_INSTALL_TARGET(ngltranslator)
Loaded 100 of 991 files, more files were not shown because too many files have changed in this diff. Show more