Compare commits

..

32 Commits
test ... master

Author SHA1 Message Date
feeaab1ebe pull = fetch/merge 2024-04-15 16:58:00 +02:00
7aed1eed11 changed parameters 2024-04-15 16:44:42 +02:00
d8de4e070e PullRepository(): call fetch and merge 2024-04-15 16:41:11 +02:00
fe46da5417 format code 2024-04-05 12:44:34 +02:00
a3cbb20a53 at least it compiles 2024-04-05 12:13:27 +02:00
1d119cb63e continued merge 2024-04-05 11:41:26 +02:00
a336b507fb forglobal defines 2024-04-05 11:10:12 +02:00
84c422ee38 just safe again 2024-04-03 16:40:46 +02:00
4ab36ec64f just safe 2024-04-03 16:29:58 +02:00
7ba9cb8147 ostern ... 2024-03-28 16:45:46 +01:00
5338c30e79 saving ... 2024-03-27 08:40:16 +01:00
2d8a947cb4 Adapt to new atb-units 2024-03-25 16:13:26 +01:00
f3680754ec save for the weekend 2024-03-22 13:46:54 +01:00
73340cbb7a just save 2024-03-21 16:57:53 +01:00
65f72eca79 own class for git-repo 2024-03-21 16:57:02 +01:00
90853294da add PushLocalRepository() 2024-03-14 15:04:06 +01:00
96994dc37e CommitFile() 2024-03-13 16:09:12 +01:00
c2328b69f0 added CheckoutBranch() 2024-03-13 13:17:02 +01:00
4101823f6e win stuff 2024-03-11 16:41:33 +01:00
a1d59c78b6 Use H- 2024-03-11 16:39:14 +01:00
34fe915e38 win stuff 2024-03-11 16:37:06 +01:00
4e13dda29d wim stuff 2024-03-11 16:36:25 +01:00
3c7b5d0958 xxx 2024-03-11 14:27:33 +01:00
590abe538d added OTHER_FILES 2024-03-11 14:15:13 +01:00
3568c8ecfb first steps 2024-03-11 12:14:28 +01:00
9d4775314c Add message handler for windowsw 2024-03-11 08:48:42 +01:00
19719a2c1f xxx 2024-03-09 09:14:27 +01:00
b26ace2e11 Add new docu 2024-03-09 08:37:45 +01:00
9b9e77c830 add some docu 2024-03-09 08:05:51 +01:00
e925e8b42f von christian 2024-03-08 13:30:02 +01:00
899f8ca02b checkin to test under windows 2024-03-04 16:31:14 +01:00
6f338cc389 checkin to test under windows 2024-03-04 16:23:10 +01:00
55 changed files with 10041 additions and 11756 deletions

View File

@ -1,3 +1,3 @@
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS = Calculator Utilities
SUBDIRS = Calculator CalculatorCInterface

View File

@ -0,0 +1,33 @@
QT+=core
CONFIG+=c++20 console
INCLUDEPATH+="../CalculatorCInterface"
#LIBS += "C:\build-ATBTariffCalculator-Desktop_Qt_6_5_0_MinGW_64_bit-Debug\CalculatorCInterface\debug\libCalculatorCInterface.a"
#LIBS += "C:\build-ATBTariffCalculator-Desktop_Qt_6_5_0_MinGW_64_bit-Debug\CalculatorCInterface\debug\CalculatorCInterface.dll"
unix {
LIBS += -L/opt/ptu5/opt/build-ATBTariffCalculator-Desktop_Qt_5_12_12_GCC_64bit-Debug/CalculatorCInterface/ -lCalculatorCInterface
}
win32 {
INCLUDEPATH += C:\Users\G.Hoffmann\Downloads\libgit2-1.7.2\libgit2-1.7.2\include
LIBS += -LC:\build-ATBTariffCalculator-Desktop_Qt_6_5_0_MinGW_64_bit-Release\CalculatorCInterface\release -lCalculatorCInterface
}
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
message_handler.cpp
HEADERS += message_handler.h
OTHER_FILES += ../tariff.json
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

60
Calculator/main.cpp Normal file
View File

@ -0,0 +1,60 @@
#include <QCoreApplication>
#include <QString>
#include <QDebug>
#include <QLibrary>
#include <stdio.h>
#include <stdlib.h>
#include "message_handler.h"
#include "calculator_c_interface_lib.h"
//#include "tariff_calculator.h"
typedef TariffCalculator *TariffCalculatorHandle;
typedef TariffCalculatorHandle (*NewTariffCalculatorFunc)();
typedef void (*DeleteTariffCalculatorFunc)(TariffCalculatorHandle handle);
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
if (!messageHandlerInstalled()) {
atbInstallMessageHandler(atbDebugOutput);
//setDebugLevel(LOG_NOTICE);
}
#if 1
//TariffCalculatorHandle handle = NewTariffCalculator();
//DeleteTariffCalculator(handle);
//if (InitGitLibrary() > 0) {
// qCritical() << CloneRepository("https://git.mimbach49.de/GerhardHoffmann/customer_999.git", "C:\\tmp\\customer_999");
// qCritical() << CheckoutLocalBranch("C:\\tmp\\customer_999", "master");
// ShutdownGitLibrary();
// }
qCritical() << GetFileMenuSize("customer_999");
#else
QLibrary library("C:\\build-ATBTariffCalculator-Desktop_Qt_6_5_0_MinGW_64_bit-Release\\CalculatorCInterface\\release\\CalculatorCInterface.dll");
if (library.load()) {
qCritical() << "loaded";
NewTariffCalculatorFunc f = (NewTariffCalculatorFunc) library.resolve("NewTariffCalculator");
TariffCalculatorHandle handle = 0;
if (f) {
qCritical() << "resolved";
handle = f();
}
DeleteTariffCalculatorFunc d = (DeleteTariffCalculatorFunc) library.resolve("DeleteTariffCalculator");
if (d) {
qCritical() << "resolved";
d(handle);
}
}
#endif
return 0; // a.exec();
}

View File

@ -0,0 +1,107 @@
#include "message_handler.h"
#include <QDateTime>
#include <cstring>
#include <QString>
#include <QFileInfo>
#include <QMessageLogContext>
#define LOG_EMERG 0
#define LOG_ALERT 1
#define LOG_CRIT 2
#define LOG_ERR 3
#define LOG_WARNING 4
#define LOG_NOTICE 5
#define LOG_INFO 6
#define LOG_DEBUG 7
static char const *DBG_NAME[] = { "DBG ", "WARN ", "CRIT ", "FATAL", "INFO " };
static bool installedMsgHandler = false;
static int debugLevel = LOG_NOTICE;
int getDebugLevel() { return debugLevel; }
void setDebugLevel(int newDebugLevel) {
debugLevel = newDebugLevel;
}
bool messageHandlerInstalled() {
return installedMsgHandler;
}
QtMessageHandler atbInstallMessageHandler(QtMessageHandler handler) {
installedMsgHandler = (handler != 0);
static QtMessageHandler prevHandler = nullptr;
if (handler) {
prevHandler = qInstallMessageHandler(handler);
return prevHandler;
} else {
return qInstallMessageHandler(prevHandler);
}
}
///
/// \brief Print message according to given debug level.
///
/// \note Install this function using qInstallMsgHandler().
///
/// int main(int argc, char **argv) {
/// installMsgHandler(atbDebugOutput);
/// QApplication app(argc, argv);
/// ...
/// return app.exec();
/// }
///
//#if (QT_VERSION > QT_VERSION_CHECK(5, 0, 0) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
void atbDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) {
Q_UNUSED(context);
QString const localMsg = QString(DBG_NAME[type]) + msg.toLocal8Bit();
switch (debugLevel) {
case LOG_DEBUG: { // debug-level message
fprintf(stderr, "LOG_DEBUG %s\n", localMsg.toStdString().c_str());
} break;
case LOG_INFO: { // informational message
if (type != QtDebugMsg) {
fprintf(stderr, "LOG_INFO %s\n", localMsg.toStdString().c_str());
}
} break;
case LOG_NOTICE: { // normal, but significant, condition
if (type != QtDebugMsg) {
fprintf(stderr, "LOG_NOTICE %s\n", localMsg.toStdString().c_str());
}
} break;
case LOG_WARNING: { // warning conditions
if (type != QtInfoMsg && type != QtDebugMsg) {
fprintf(stderr, "LOG_WARN %s\n", localMsg.toStdString().c_str());
}
} break;
case LOG_ERR: { // error conditions
if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) {
fprintf(stderr, "LOG_ERR %s\n", localMsg.toStdString().c_str());
}
} break;
case LOG_CRIT: { // critical conditions
if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) {
fprintf(stderr, "LOG_CRIT %s\n", localMsg.toStdString().c_str());
}
} break;
case LOG_ALERT: { // action must be taken immediately
if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) {
fprintf(stderr, "LOG_ALERT %s\n", localMsg.toStdString().c_str());
}
} break;
case LOG_EMERG: { // system is unusable
if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) {
fprintf(stderr, "LOG_EMERG %s\n", localMsg.toStdString().c_str());
}
} break;
default: {
//fprintf(stderr, "%s No ErrorLevel defined! %s\n",
// datetime.toStdString().c_str(), msg.toStdString().c_str());
}
}
}
//#endif

View File

@ -0,0 +1,23 @@
#ifndef MESSAGE_HANDLER_H_INCLUDED
#define MESSAGE_HANDLER_H_INCLUDED
#include <QtGlobal>
#ifdef __linux__
#include <syslog.h>
#endif
int getDebugLevel();
void setDebugLevel(int newDebugLevel);
bool messageHandlerInstalled();
QtMessageHandler atbInstallMessageHandler(QtMessageHandler handler);
//#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
// typedef void (*QtMessageHandler)(QtMsgType, const char *);
//void atbDebugOutput(QtMsgType type, const char *msg);
//#elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
// typedef void (*QtMessageHandler)(QtMsgType, const QMessageLogContext &, const QString &);
void atbDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg);
//#endif
#endif // MESSAGE_HANDLER_H_INCLUDED

View File

@ -0,0 +1,47 @@
QT+=core
TEMPLATE = lib
DEFINES += CALCULATOR_C_INTERFACE_LIBRARY
QMAKE_CXXFLAGS += -fPIC -std=c++20
unix {
LIBS += -L/usr/lib64 -lgit2
}
win32 {
INCLUDEPATH += C:\Users\G.Hoffmann\Downloads\libgit2-1.7.2\libgit2-1.7.2\include
LIBS += -LC:\Users\G.Hoffmann\Downloads\libgit2-1.7.2\libgit2-1.7.2\build\Debug -lgit2
}
# INCLUDEPATH+=$$_PRO_FILE_PWD_/../Utilities/
CONFIG += c++20 console
#QMAKE_CXX=C:\Qt\Tools\mingw1120_64\g++.exe
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
calculator_c_interface_lib.cpp \
git_library.cpp \
tariff_calculator.cpp \
local_git_repository.cpp
HEADERS += \
calculator_c_interface_lib.h \
calculator_c_interface_lib_global.h \
git_library.h \
tariff_calculator.h \
local_git_repository.h \
global_defines.h
# Default rules for deployment.
unix {
target.path = /usr/lib
}
!isEmpty(target.path): INSTALLS += target

View File

@ -0,0 +1,148 @@
#include "calculator_c_interface_lib.h"
#include "local_git_repository.h"
#include "git_library.h"
//#include <git2/common.h>
#include <QMap>
#include <QString>
#include <QDir>
#include <QFile>
#include <QByteArray>
#include <QRegularExpression>
#include <QRegularExpressionMatch>
#include <mutex>
#include <git2.h>
#include <stdio.h>
#include <stdint.h>
#include <algorithm>
//static QMap<QString, git_repository *> customerRepoMap;
//static std::mutex m;
#ifndef _WIN32
# include <unistd.h>
#endif
#include <errno.h>
#ifdef __cplusplus
extern "C" {
#endif
TariffCalculatorHandle NewTariffCalculator(void) {
return new TariffCalculator();
}
void DeleteTariffCalculator(TariffCalculatorHandle handle) {
delete handle;
}
int InitGitLibraryInternal(void) {
return GitLibrary::Init();
}
int ShutdownGitLibraryInternal(void) {
LocalGitRepository::DestroyAllRepositories();
return GitLibrary::Shutdown();
}
int CloneRepositoryInternal(char const *url, char const *local_path) {
return GitLibrary::CloneRepository(url, local_path);
}
int CheckoutRepositoryInternal(char const *url, char const *localRepoName, char const *branchName) {
return GitLibrary::CheckoutRepository(url, localRepoName, branchName);
}
int CommitFileInternal(char const *localRepoName, char const *branchName,
char const *fName, char const *commitMessage) {
return GitLibrary::CommitFile(localRepoName, branchName, fName, commitMessage);
}
int PushRepositoryInternal(char const *localRepoName, char const *branchName,
char const *userName, char const *userPassword) {
return GitLibrary::PushRepository(localRepoName, branchName, userName, userPassword);
}
int PullRepositoryInternal(char const *localRepoName, char const *remoteRepoName) {
return GitLibrary::PullRepository(localRepoName, remoteRepoName);
}
#include <local_git_repository.h>
void SetReposRootDirectoryInternal(char const *p) {
LocalGitRepository::SetReposRootDirectory(QString::fromUtf8(p));
}
char const *GetReposRootDirectoryInternal() {
return (char const *)LocalGitRepository::GetReposRootDirectory().constData();
}
char const *GetLocalRepositoryPathInternal(char const *localGitRepo) {
return (char const *)LocalGitRepository::GetInstance(localGitRepo)->localRepositoryPath().constData();
}
int32_t GetFileMenuSizeInternal(char const *localGitRepo) {
return LocalGitRepository::GetInstance(localGitRepo)->GetFileMenuSizeInternal();
}
char const *GetFileMenuInternal(const char *localGitRepo) {
QByteArray const &a = LocalGitRepository::GetInstance(localGitRepo)->GetFileMenuInternal().constData();
if (a.isValidUtf8()) {
int const len = GetFileMenuSizeInternal(localGitRepo);
if (len > 0) {
char *json = new char [len+1];
// fprintf(stderr, "allocate pointer %p\n", json);
memset(json, 0x00, len+1);
memcpy(json, a.constData(), std::min(len, (int)a.size()));
return json;
}
}
return nullptr;
}
char const *GetFileNameInternal(char const *localGitRepo, char const *fileId) {
QByteArray const &a = LocalGitRepository::GetInstance(localGitRepo)->GetFileNameInternal(fileId);
if (a.isValidUtf8()) {
char *c = new char[a.size() + 1];
memset(c, 0x00, a.size() + 1);
memcpy(c, a.constData(), a.size());
return c;
}
return nullptr;
}
int32_t GetFileSize(char const *localGitRepo, char const *fileId) {
return LocalGitRepository::GetInstance(localGitRepo)->GetFileSize(fileId);
}
char const *GetFileInternal(char const *localGitRepo, char const *fileId) {
QByteArray const &a = LocalGitRepository::GetInstance(localGitRepo)->GetFileInternal(fileId);
if (a.isValidUtf8()) {
char *c = new char[a.size() + 1];
memset(c, 0x00, a.size() + 1);
memcpy(c, a.constData(), a.size());
return c;
}
return nullptr;
}
bool SetFileInternal(char const *localGitRepo, char const *fileId, char const *json, int size) {
return LocalGitRepository::GetInstance(localGitRepo)->SetFileInternal(QString(fileId), QByteArray(json, size));
}
void DeleteMem(char *p) {
if (p) {
// fprintf(stderr, "delete pointer %p\n", p);
delete p;
}
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,42 @@
#ifndef CALCULATOR_C_INTERFACE_LIB_H_INCLUDED
#define CALCULATOR_C_INTERFACE_LIB_H_INCLUDED
#include "calculator_c_interface_lib_global.h"
#include "tariff_calculator.h"
typedef TariffCalculator *TariffCalculatorHandle;
#ifdef __cplusplus
extern "C" {
#endif
void DeleteMem(char *p) CALCULATOR_C_INTERFACE_LIB_EXPORT;
void SetReposRootDirectoryInternal(char const *p) CALCULATOR_C_INTERFACE_LIB_EXPORT;
char const *GetReposRootDirectoryInternal() CALCULATOR_C_INTERFACE_LIB_EXPORT;
char const *GetLocalRepositoryPathInternal(char const *localRepo) CALCULATOR_C_INTERFACE_LIB_EXPORT;
// interface for menu of webpage
char const *GetFileMenuInternal(char const *localRepo) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int32_t GetFileMenuSizeInternal(char const *localRepo) CALCULATOR_C_INTERFACE_LIB_EXPORT;
char const *GetFileNameInternal(char const *localRepo, char const *fileId) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int32_t GetFileSize(char const *localRepo, char const *fileId) CALCULATOR_C_INTERFACE_LIB_EXPORT;
char const *GetFileInternal(char const *localRepo, char const *fileId) CALCULATOR_C_INTERFACE_LIB_EXPORT;
bool SetFileInternal(char const *localRepo, char const *fileId, char const *json, int size) CALCULATOR_C_INTERFACE_LIB_EXPORT;
TariffCalculatorHandle NewTariffCalculator(void) CALCULATOR_C_INTERFACE_LIB_EXPORT;
void DeleteTariffCalculator(TariffCalculatorHandle handle) CALCULATOR_C_INTERFACE_LIB_EXPORT;
// libgit2
int InitGitLibraryInternal(void) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int ShutdownGitLibraryInternal(void) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int CloneRepositoryInternal(char const *url, char const *local_path) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int CheckoutRepositoryInternal(char const *url, char const *localRepoName, char const *branchName) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int CommitFileInternal(char const *local_path, char const *branch_name, char const *file_name, char const *commit_message) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int PushRepositoryInternal(char const *local_path, char const *branch_name, char const *user, char const *password) CALCULATOR_C_INTERFACE_LIB_EXPORT;
int PullRepositoryInternal(char const *localRepoName, char const *remoteRepoName) CALCULATOR_C_INTERFACE_LIB_EXPORT;
#ifdef __cplusplus
}
#endif
#endif // CALCULATOR_C_INTERFACE_LIB_H_INCLUDED

View File

@ -0,0 +1,23 @@
#ifndef CALCULATOR_C_INTERFACE_GLOBAL_H
#define CALCULATOR_C_INTERFACE_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(CALCULATOR_C_INTERFACE_LIBRARY)
#ifdef __linux__
#define CALCULATOR_C_INTERFACE_LIB_EXPORT
#else
#define CALCULATOR_C_INTERFACE_LIB_EXPORT Q_DECL_EXPORT __stdcall
#endif
#else
#ifdef __linux__
#define CALCULATOR_C_INTERFACE_LIB_EXPORT
#else
#define CALCULATOR_C_INTERFACE_LIB_EXPORT Q_DECL_IMPORT __stdcall
#endif
#endif
#endif // CALCULATOR_C_INTERFACE_GLOBAL_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,47 @@
#ifndef GIT_LIBRARY_H_INCLUDED
#define GIT_LIBRARY_H_INCLUDED
#include <QByteArray>
#include <QString>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QDir>
#include <git2.h>
class CWD {
QDir m_prev;
QDir m_localRepoDir;
QDir m_localRepoGitDir;
bool m_valid;
public:
CWD(QString const &localRepoName);
~CWD();
QDir const &localRepoDir() const { return m_localRepoDir; }
QDir &localRepoDir() { return m_localRepoDir; }
QDir const &localRepoGitDir() const { return m_localRepoGitDir; }
QDir &localRepoGitDir() { return m_localRepoGitDir; }
};
class GitLibrary {
static QString m_userName;
static QString m_userPassword;
public:
static QString &userName() { return m_userName; }
static QString &userPassword() { return m_userPassword; }
static int Init();
static int Shutdown();
static int CloneRepository(char const *url, char const *localRepoName);
static int CheckoutRepository(char const *url, char const *localRepoName, char const *branchName);
static int CommitRepository(char const *localRepoName, char const *branchName, char const *commitMessage);
static int CommitFile(char const *localRepoName, char const *branchName, char const *fName, char const *commitMessage);
static int PushRepository(char const *localRepoName, char const *branchName, char const *userName, char const *userPassword);
static int PullRepository(char const *localRepoName, char const *remoteRepoName);
// explicit GitLibrary();
// ~GitLibrary();
};
#endif // #define GIT_LIBRARY_H_INCLUDED

View File

@ -0,0 +1,7 @@
#ifndef GLOBAL_DEFINES_H_INCLUDED
#define GLOBAL_DEFINES_H_INCLUDED
#define HEADER __func__ << "(" << __LINE__ << ")"
#endif // GLOBAL_DEFINES_H_INCLUDED

View File

@ -0,0 +1,212 @@
#include "local_git_repository.h"
#include "git_library.h"
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QTextStream>
#include <QJsonDocument>
#include <QByteArray>
#include <QRegularExpression>
#include <QRegularExpressionMatch>
#include <QFile>
QString LocalGitRepository::repoRootDirectory = "";
QMap<QString, LocalGitRepository *> LocalGitRepository::localGitRepos;
QMap<QString, LocalGitRepository *> &LocalGitRepository::GetLocalGitRepos() {
return localGitRepos;
}
void LocalGitRepository::SetReposRootDirectory(QString s) {
if (repoRootDirectory.isEmpty()) {
repoRootDirectory = s;
return;
}
qCritical() << __func__ << ":" << __LINE__
<< "ERROR git-repository-root-directory already set"
<< repoRootDirectory;
}
QString LocalGitRepository::GetReposRootDirectory() {
return repoRootDirectory;
}
LocalGitRepository::LocalGitRepository(QString const &localRepository)
: m_localRepository(localRepository)
, m_fileMenu("{}")
, m_fileMenuSize(-1)
, m_git_repository(nullptr) {
}
LocalGitRepository::~LocalGitRepository() {
}
void LocalGitRepository::SetGitRepository(git_repository *git_repo) {
m_git_repository = git_repo;
}
git_repository const *LocalGitRepository::GetGitRepository() const {
return m_git_repository;
}
git_repository *LocalGitRepository::GetGitRepository() {
return m_git_repository;
}
QString LocalGitRepository::localRepositoryName() const { // e.g. customer_999
return m_localRepository;
}
QString LocalGitRepository::localRepositoryPath() const {
if (!repoRootDirectory.isEmpty()) {
return QDir::cleanPath(repoRootDirectory + QDir::separator() + m_localRepository);
}
qCritical() << __func__ << ":" << __LINE__
<< "ERROR git-repository-root-directory not set";
return "";
}
QString LocalGitRepository::localRepositoryPath(QString const &localRepository) {
if (!repoRootDirectory.isEmpty()) {
return QDir::cleanPath(repoRootDirectory + QDir::separator() + localRepository);
}
qCritical() << __func__ << ":" << __LINE__
<< "ERROR git-repository-root-directory not set";
return "";
}
LocalGitRepository *LocalGitRepository::GetInstance(QString const& localRepository) {
LocalGitRepository *repo = nullptr;
if (GetLocalGitRepos().count(localRepository) > 0) {
repo = GetLocalGitRepos()[localRepository];
} else {
repo = new LocalGitRepository(localRepository);
qCritical() << "created local git-repository" << localRepository;
GetLocalGitRepos().insert(localRepository, repo);
}
if (repo == nullptr) {
qCritical() << __func__ << ":" << __LINE__
<< "ERROR: could not find local git-repository" << localRepository;
}
return repo;
}
bool LocalGitRepository::DestroyInstance(QString const &localRepository) {
if (GetLocalGitRepos().count(localRepository) > 0) {
LocalGitRepository *repo = GetLocalGitRepos().take(localRepository);
delete repo;
qCritical() << "deleted local git-repository" << localRepository;
return true;
}
qCritical() << __func__ << ":" << __LINE__
<< "ERROR: could not find local git-repository" << localRepository;
return false;
}
void LocalGitRepository::DestroyAllRepositories() {
for (auto it = GetLocalGitRepos().keyValueBegin(); it != GetLocalGitRepos().keyValueEnd(); ++it) {
QString const &key = it->first;
LocalGitRepository *repo = GetLocalGitRepos()[key];
delete repo;
qCritical() << "deleted local git-repository" << key;
}
GetLocalGitRepos().clear();
}
int32_t LocalGitRepository::GetFileMenuSizeInternal() const {
return m_fileMenuSize;
}
QByteArray LocalGitRepository::GetFileMenuInternal() {
if (m_fileMenuSize == -1) {
QFile f(QDir::cleanPath(repoRootDirectory + QDir::separator()
+ m_localRepository + QDir::separator()
+ "etc/psa_webinterface/menu_config.json"));
if (f.exists()) {
if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
m_fileMenu = QTextStream(&f).readAll().toUtf8();
if (m_fileMenu.isValidUtf8()) {
QString const &s = QString::fromUtf8(m_fileMenu);
m_fileMenuSize = s.toLocal8Bit().size();
}
}
}
}
return m_fileMenu;
}
QByteArray LocalGitRepository::GetFileNameInternal(QString const &fId) {
QRegularExpressionMatch match;
static const QRegularExpression re("(master|[0-9]+)");
if (fId.lastIndexOf(re, -1, &match) != -1) {
int idx = fId.indexOf("/");
if (idx != -1) {
QString path = fId.mid(idx);
idx = path.indexOf(":");
if (idx != -1) {
path = path.mid(0, idx);
QString s = match.captured(match.lastCapturedIndex());
if (s != "master") {
if (fId.contains("psa_tariff")) {
QString fn(QDir::cleanPath(
repoRootDirectory + QDir::separator() +
QString(m_localRepository) + QDir::separator()
+ path + QDir::separator()
+ QString("tariff%1.json").arg(s.toUInt(), 2, 10, QChar('0'))));
return fn.toUtf8();
}
}
}
}
}
return QByteArray();
}
QByteArray LocalGitRepository::GetFileInternal(QString const &fId) {
QByteArray a = GetFileNameInternal(fId);
if (a.isValidUtf8()) {
QFile fn(a);
if (fn.exists()) {
if (fn.open(QIODevice::ReadOnly)) {
return fn.readAll();
}
}
}
return QByteArray("{}");
}
int32_t LocalGitRepository::GetFileSize(QString const &fId) {
QByteArray a = GetFileNameInternal(fId);
if (a.isValidUtf8()) {
QFile fn(a);
if (fn.exists()) {
return fn.size();
}
}
return -1;
}
bool LocalGitRepository::SetFileInternal(QString const &fId, QByteArray const &json) {
QByteArray a = GetFileNameInternal(fId);
if (a.isValidUtf8()) {
QFile fn(a);
if (fn.exists()) {
if (fn.open(QIODevice::WriteOnly)) {
qint64 bytesWritten = 0;
qint64 bytesToWrite = json.size();
while (bytesToWrite > 0 &&
(bytesWritten = fn.write(json.constData(), bytesToWrite)) != -1) {
bytesToWrite -= bytesWritten;
}
fn.flush();
return (bytesToWrite == 0);
}
}
}
return false;
}

View File

@ -0,0 +1,58 @@
#ifndef LOCAL_GIT_REPOSITORY_H_INCLUDED
#define LOCAL_GIT_REPOSITORY_H_INCLUDED
#include <QByteArray>
#include <QString>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QDir>
#include <QMap>
#include <git2.h>
class GitLibrary;
class LocalGitRepository {
friend class GitLibrary;
QString m_localRepository;
mutable QByteArray m_fileMenu;
mutable int32_t m_fileMenuSize;
git_repository *m_git_repository;
static QString repoRootDirectory;
static QMap<QString, LocalGitRepository *> localGitRepos;
protected: // force heap-based objects
LocalGitRepository(QString const &localRepository);
~LocalGitRepository();
public:
static void SetReposRootDirectory(QString s);
static QString GetReposRootDirectory();
static LocalGitRepository *GetInstance(QString const &localRepository);
static bool DestroyInstance(QString const &localRepository);
static void DestroyAllRepositories();
static QMap<QString, LocalGitRepository *> &GetLocalGitRepos();
QString localRepositoryName() const;
QString localRepositoryPath() const;
void SetGitRepository(git_repository *git_repo);
git_repository const *GetGitRepository() const;
git_repository *GetGitRepository();
static QString localRepositoryPath(QString const &localRepository);
QByteArray GetFileMenuInternal();
int32_t GetFileMenuSizeInternal() const;
QByteArray GetFileNameInternal(QString const &fileId);
int32_t GetFileSize(QString const &fileId);
QByteArray GetFileInternal(QString const &fileId);
bool SetFileInternal(QString const &fileId, QByteArray const &json);
};
#endif // LOCAL_GIT_REPOSITORY_H_INCLUDED

View File

@ -0,0 +1,430 @@
#include "tariff_calculator.h"
#include <QDebug>
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
#if 0
QByteArray TariffCalculator::readJson(QString const &filename) {
QFile f(filename);
if (f.exists()) {
if (f.open(QFile::ReadOnly | QFile::Text)) {
QTextStream in(&f);
return in.readAll().toUtf8();
} else {
qCritical() << filename << "not readable";
}
} else {
qCritical() << filename << "does not exist";
}
return QByteArray();
}
#endif
TariffCalculator::~TariffCalculator() {
qCritical() << __func__;
}
TariffCalculator::TariffCalculator() {
// QByteArray ba = readJson("/opt/ptu5/opt/ATBTariffCalculator/Utilities/tariff.template.json");
//QJsonParseError pe;
//m_jsonDoc = QJsonDocument::fromJson(ba, &pe);
//if (pe.error == QJsonParseError::NoError) {
// qCritical().noquote() << m_jsonDoc.toJson(QJsonDocument::JsonFormat::Indented);
//} else {
// qCritical() << __func__ << pe.errorString();
//
//}
m_o = QJsonObject();
createJsonValue("Tariffhead");
createJsonValue("Products");
createJsonValue("Accuracy");
createJsonValue("Type");
createJsonValue("Price");
createJsonValue("Config");
createJsonValue("TimeRanges");
//createJsonValue("Periods");
//createJsonValue("DayConfigs");
//createJsonValue("Days");
m_jsonDoc.setObject(m_o);
qCritical().noquote() << m_jsonDoc.toJson(QJsonDocument::JsonFormat::Indented);
}
void TariffCalculator::createJsonValue(QString const &key, QString const &value) {
if (key.compare("Tariffhead", Qt::CaseInsensitive) == 0) {
QJsonObject o({
QPair(QString("Project"), QJsonValue(QString("Szeged"))),
QPair(QString("Version"), QJsonValue(QString("1.0.0"))),
QPair(QString("Date"), QJsonValue("01.01.1970")),
QPair(QString("Committer"), QJsonValue("")),
QPair(QString("Info"), QJsonValue(QString("")))});
m_o.insert(key, o);
} else
if (key.compare("Accuracy", Qt::CaseInsensitive) == 0) {
QJsonObject o({
QPair(QString("accuracy_id"), QJsonValue(1)),
QPair(QString("accuracy_label"), QJsonValue(QString("computation-to-the-minute"))),
QPair(QString("accuracy_value"), QJsonValue(1)),
QPair(QString("comment"), QJsonValue(QString("accuracy of tariff computation is individual minutes")))});
m_o.insert(key, o);
} else
if (key.compare("Type", Qt::CaseInsensitive) == 0) {
QJsonObject o({
QPair(QString("type_id"), QJsonValue(1)),
QPair(QString("type_label"), QJsonValue(QString("uniform-minutes"))),
QPair(QString("comment"), QJsonValue(QString("same price for all minutes")))});
m_o.insert(key, o);
} else
if (key.compare("Price", Qt::CaseInsensitive) == 0) {
QJsonObject o1({
QPair(QString("price_id"), QJsonValue(1)),
QPair(QString("price"), QJsonValue(165)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue(QString("price per hour as provided by customer")))});
QJsonObject o2({
QPair(QString("price_id"), QJsonValue(2)),
QPair(QString("price"), QJsonValue(990)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue(QString("price for dayticket as provided by customer")))});
QJsonArray a;
a.push_back(o1);
a.push_back(o2);
m_o.insert(key, a);
} else
if (key.compare("Config", Qt::CaseInsensitive) == 0) {
QJsonObject o1({
QPair(QString("value"), QJsonValue(15)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue(QString("minimal parking time in minutes (net)")))});
QJsonObject o2({
QPair(QString("value"), QJsonValue(360)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue(QString("maximal parking time in minutes (net)")))});
QJsonObject o3({
QPair(QString("value"), QJsonValue(1)),
QPair(QString("comment"), QJsonValue(QString("price-id of customer entered price (for hour) expressed in minimal time: 15*(165/60) = 41.25")))});
QJsonObject o4({
QPair(QString("value"), QJsonValue(1)),
QPair(QString("comment"), QJsonValue(QString("price-id of customer entered price (for hour) expressed in maximal time: 360*(165/60) = 990")))});
QJsonObject o5({
QPair(QString("comment"), QJsonValue(QString("general tariff config"))),
QPair(QString("config_id"), QJsonValue(1)),
QPair(QString("config_label"), QJsonValue("Tariff Config 1")),
QPair(QString("config_tariff_accuracy"), QJsonValue(1)),
QPair(QString("config_tariff_type"), QJsonValue(1)),
QPair(QString("config_carry_over"), QJsonValue(true)),
QPair(QString("config_prepaid"), QJsonValue(true)),
QPair(QString("MinimalTime"), QJsonValue(o1)),
QPair(QString("MaximalTime"), QJsonValue(o2)),
QPair(QString("MinimalPrice"), QJsonValue(o3)),
QPair(QString("MinimalPrice"), QJsonValue(o4))});
m_o.insert(key, o5);
} else
if (key.compare("Products", Qt::CaseInsensitive) == 0) {
QJsonObject o1({
QPair(QString("product_id"), QJsonValue(1)),
QPair(QString("product_price_id"), QJsonValue(1)),
QPair(QString("product_label"), QJsonValue(QString("SHORT_TIME_PARKING")))});
QJsonObject o2({
QPair(QString("product_id"), QJsonValue(2)),
QPair(QString("product_price_id"), QJsonValue(2)),
QPair(QString("product_time_ranges"), QJsonArray({QJsonValue(100001)})),
QPair(QString("product_label"), QJsonValue(QString("DAY_TICKET")))});
QJsonArray a;
a.push_back(o1);
a.push_back(o2);
m_o.insert(key, a);
} else
if (key.compare("TimeRanges", Qt::CaseInsensitive) == 0) {
QJsonObject o1({
QPair(QString("range_id"), QJsonValue(1)),
QPair(QString("range_price_id"), QJsonValue(0)),
QPair(QString("range_start"), QJsonValue(QString("00:00:00"))),
QPair(QString("range_end"), QJsonValue(QString("00:00:00"))),
QPair(QString("comment"), QJsonValue(QString("[ 00:00-00:00 [ = [ 00:00-24:00 [")))});
QJsonObject o2({
QPair(QString("range_id"), QJsonValue(1)),
QPair(QString("range_price_id"), QJsonValue(1)),
QPair(QString("range_start"), QJsonValue(QString("00:00:00"))),
QPair(QString("range_end"), QJsonValue(QString("08:00:00"))),
QPair(QString("comment"), QJsonValue(QString("[ 00:00-08:00 [")))});
QJsonObject o3({
QPair(QString("range_id"), QJsonValue(1)),
QPair(QString("range_price_id"), QJsonValue(2)),
QPair(QString("range_start"), QJsonValue(QString("18:00:00"))),
QPair(QString("range_end"), QJsonValue(QString("00:00:00"))),
QPair(QString("comment"), QJsonValue(QString("[ 18:00-00:00 [")))});
QJsonObject o4({
QPair(QString("range_id"), QJsonValue(1)),
QPair(QString("range_price_id"), QJsonValue(3)),
QPair(QString("range_start"), QJsonValue(QString("12:00:00"))),
QPair(QString("range_end"), QJsonValue(QString("00:00:00"))),
QPair(QString("comment"), QJsonValue(QString("[ 12:00-00:00 [")))});
QJsonArray a;
a.push_back(o1);
a.push_back(o2);
a.push_back(o3);
a.push_back(o4);
QTime const t(8,0,0);
QJsonArray b;
for (int i=0; i<600; ++i) {
QTime const &start = t.addSecs(i*60);
QTime const &end = t.addSecs((i+1)*60);
QJsonObject o({
QPair(QString("range_id"), QJsonValue(i)),
QPair(QString("range_price_id"), QJsonValue(0)),
QPair(QString("range_start"), QJsonValue(start.toString(Qt::ISODate))),
QPair(QString("range_end"), QJsonValue(end.toString(Qt::ISODate)))});
b.push_back(o);
}
a.push_back(b);
m_o.insert(key, a);
} else
if (key.compare("Periods", Qt::CaseInsensitive) == 0) {
QJsonObject o1({
QPair(QString("period_id"), QJsonValue(1)),
QPair(QString("period_label"), QJsonValue("1st quarter")),
QPair(QString("period_from"), QJsonValue(QString("1970-01-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-03-31")))});
QJsonObject o2({
QPair(QString("period_id"), QJsonValue(2)),
QPair(QString("period_label"), QJsonValue("2nd quarter")),
QPair(QString("period_from"), QJsonValue(QString("1970-04-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-06-30")))});
QJsonObject o3({
QPair(QString("period_id"), QJsonValue(3)),
QPair(QString("period_label"), QJsonValue("3rd quarter")),
QPair(QString("period_from"), QJsonValue(QString("1970-07-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-09-30")))});
QJsonObject o4({
QPair(QString("period_id"), QJsonValue(4)),
QPair(QString("period_label"), QJsonValue("4th quarter")),
QPair(QString("period_from"), QJsonValue(QString("1970-10-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-12-31")))});
QJsonObject o5({
QPair(QString("period_id"), QJsonValue(5)),
QPair(QString("period_label"), QJsonValue("1st half-year")),
QPair(QString("period_from"), QJsonValue(QString("1970-01-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-06-30")))});
QJsonObject o6({
QPair(QString("period_id"), QJsonValue(6)),
QPair(QString("period_label"), QJsonValue("2nd half-year")),
QPair(QString("period_from"), QJsonValue(QString("1970-07-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-12-31")))});
QJsonArray a;
a.push_back(o1);
a.push_back(o2);
a.push_back(o3);
a.push_back(o4);
a.push_back(o5);
a.push_back(o6);
m_o.insert(key, a);
} else
if (key.compare("DayConfigs", Qt::CaseInsensitive) == 0) {
QJsonArray b;
b.push_back(QJsonValue(100002));
for (int i=0; i<600; ++i) {
b.push_back(QJsonValue(i));
}
b.push_back(QJsonValue(100003));
QJsonArray c;
c.push_back(QJsonValue(100001));
QJsonObject o1({
QPair(QString("day_config_id"), QJsonValue(1)),
QPair(QString("day_config_range"), QJsonValue(6)),
QPair(QString("day_config_product_ids"), QJsonArray({QJsonValue(0), QJsonValue(1)})),
QPair(QString("day_config_short_time_parking"), b),
QPair(QString("day_config_day_ticket"), c)});
QJsonObject o2({QPair(QString("DayConfig_1"), QJsonValue(o1))});
QJsonObject o3({
QPair(QString("day_config_id"), QJsonValue(2)),
QPair(QString("day_config_range"), QJsonValue(6)),
QPair(QString("day_config_product_ids"), QJsonArray({QJsonValue(1)})),
QPair(QString("day_config_day_ticket"), c)});
QJsonObject o4({QPair(QString("DayConfig_2"), QJsonValue(o3))});
QJsonArray a;
a.push_back(o2);
a.push_back(o4);
m_o.insert(key, a);
} else
if (key.compare("Days", Qt::CaseInsensitive) == 0) {
QJsonArray b;
for (int i=1; i < 8; ++i) {
QJsonObject o1({
QPair(QString("day_id"), QJsonValue(1)),
QPair(QString("day_config_id"), QJsonValue(0))});
switch(i) {
case Qt::Monday: {
QJsonObject o2({QPair(QString("Mon"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Tuesday: {
QJsonObject o2({QPair(QString("Tue"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Wednesday: {
QJsonObject o2({QPair(QString("Wed"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Thursday: {
QJsonObject o2({QPair(QString("Thu"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Friday: {
QJsonObject o2({QPair(QString("Fri"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Saturday: {
QJsonObject o2({QPair(QString("Sat"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Sunday: {
QJsonObject o2({QPair(QString("Sun"), QJsonValue(o1))});
b.push_back(o2);
} break;
}
}
QJsonArray c;
QJsonObject o1({
QPair(QString("day_id"), QJsonValue(1)),
QPair(QString("day_config_id"), QJsonValue(1)),
QPair(QString("day_date"), QJsonValue(QString("2024-12-25"))),
QPair(QString("day_movable"), QJsonValue(false))});
QJsonObject o2({
QPair(QString("day_id"), QJsonValue(2)),
QPair(QString("day_config_id"), QJsonValue(1)),
QPair(QString("day_date"), QJsonValue(QString("2024-12-26"))),
QPair(QString("day_movable"), QJsonValue(false))});
c.push_back(o1);
c.push_back(o2);
QJsonObject o3({QPair(QString("Weekdays"), b),
QPair(QString("Holidays"), c)});
//"Christmas_1st_day": {
// "day_id": 8,
// "day_config_id": 1,
// "day_date": "2024-12-25",
// "day_moveable": false
//},
//"Christmas_2nd_day": {
// "day_id": 9,
// "day_config_id": 1,
// "day_date": "2024-12-26",
// "day_moveable": false
//}
//m_a.push_back(QJsonObject({QPair(key, QJsonValue(o3))}));
m_o.insert(key, o3);
}
#if 0
"TariffDays": [
"Mon": {
"day_id": 1,
"day_config_id": 0
},
"Tue": {
"day_id": 2,
"day_config_id": 0
},
"Wed": {
"day_id": 3,
"day_config_id": 0
},
"Thu": {
"day_id": 4,
"day_config_id": 0
},
"Fri": {
"day_id": 5,
"day_config_id": 0
},
"Sat": {
"day_id": 6,
"day_config_id": 0
},
"Sun": {
"day_id": 7,
"day_config_id": 0
},
"Christmas_1st_day": {
"day_id": 8,
"day_config_id": 1,
"day_date": "2024-12-25",
"day_moveable": false
},
"Christmas_2nd_day": {
"day_id": 9,
"day_config_id": 1,
"day_date": "2024-12-26",
"day_moveable": false
}
// usw. die anderen Feiertage un
"DayConfig_1": {
"day_config_id": 0,
"day_config_date_range": 6,
"comment_1": "day config is valid for the whole year",
"day_config_product_ids": [0, 1],
"comment_2": "short-time-parking or day-ticket on this day",
#endif
}

View File

@ -0,0 +1,24 @@
#ifndef TARIFF_CALCULATOR_H_INCLUDED
#define TARIFF_CALCULATOR_H_INCLUDED
#include <QByteArray>
#include <QString>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <git2.h>
class TariffCalculator {
QJsonObject m_o;
QJsonDocument m_jsonDoc;
void createJsonValue(QString const &key, QString const &value = "");
public:
explicit TariffCalculator();
~TariffCalculator();
static QByteArray readJson(QString const &filename);
};
#endif // TARIFF_CALCULATOR_H_INCLUDED

BIN
E52461.pdf Normal file

Binary file not shown.

Binary file not shown.

BIN
StartProgUsingPascal.pdf Normal file

Binary file not shown.

View File

@ -1,82 +0,0 @@
QT += core
TARGET = util
VERSION="0.1.0"
win32 {
BUILD_DATE=$$system("date /t")
BUILD_TIME=$$system("time /t")
} else {
BUILD_DATE=$$system("date +%d-%m-%y")
BUILD_TIME=$$system("date +%H:%M:%S")
}
GIT_COMMIT=$$system("git log -1 --format=oneline | cut -d' ' -f1")
EXTENDED_VERSION="$${VERSION}-$${GIT_COMMIT}"
CONFIG += c++17
DEFINES+=APP_VERSION=\\\"$$VERSION\\\"
DEFINES+=APP_BUILD_DATE=\\\"$$BUILD_DATE\\\"
DEFINES+=APP_BUILD_TIME=\\\"$$BUILD_TIME\\\"
DEFINES+=APP_EXTENDED_VERSION=\\\"$$EXTENDED_VERSION\\\"
# keep comments, as /* fall through */
QMAKE_CXXFLAGS += -C
QMAKE_CXXFLAGS += -g
QMAKE_CXXFLAGS += -Wno-deprecated-copy -O
contains( CONFIG, PTU5 ) {
greaterThan(QT_MAJOR_VERSION, 4): QT += serialport
CONFIG += link_pkgconfig
lessThan(QT_MAJOR_VERSION, 5): PKGCONFIG += qextserialport
QMAKE_CXXFLAGS += -O2 -std=c++17 # for GCC >= 4.7
# QMAKE_CXXFLAGS += -Wno-deprecated-copy
ARCH = PTU5
DEFINES+=PTU5
}
contains( CONFIG, PTU5_YOCTO ) {
greaterThan(QT_MAJOR_VERSION, 4): QT += serialport
QMAKE_CXXFLAGS += -std=c++17 # for GCC >= 4.7
# QMAKE_CXXFLAGS += -Wno-deprecated-copy
PTU5BASEPATH = /opt/devel/ptu5
ARCH = PTU5
DEFINES+=PTU5
# add qmqtt lib
#LIBS += -lQt5Qmqtt
}
contains( CONFIG, DesktopLinux ) {
greaterThan(QT_MAJOR_VERSION, 4): QT += serialport
lessThan(QT_MAJOR_VERSION, 5): CONFIG += extserialport
# QMAKE_CC = ccache $$QMAKE_CC
# QMAKE_CXX = ccache $$QMAKE_CXX
QMAKE_CXXFLAGS += -std=c++17
# QMAKE_CXXFLAGS += -Wno-deprecated-copy
linux-clang { QMAKE_CXXFLAGS += -Qunused-arguments }
ARCH = DesktopLinux
DEFINES+=DesktopLinux
}
SOURCES += \
main.cpp \
tariff_json_template.cpp \
tariff_editor.cpp
HEADERS += \
tariff_json_template.h \
tariff_editor.h
OTHER_FILES += \
tariff.json \
tariff.template.json
##########################################################################################
# for running program on target through QtCreator
contains( CONFIG, PTU5 ) {
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/app/tools/atbupdate/
!isEmpty(target.path): INSTALLS += target
}

View File

@ -1,8 +1,5 @@
#include <QtGlobal>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QDebug>
#include "tariff_editor.h"
@ -12,39 +9,6 @@ int main(int argc, char **argv) {
Q_UNUSED(argv);
TariffEditor editor;
editor.writeToDocument("Project", "Szeged");
editor.writeToDocument("Version", "1.0.0");
editor.writeToDocument("Date", "01.01.1970");
editor.writeToDocument("Commiter" , "");
editor.writeToDocument("Info", "");
editor.writeToDocument(editor.create("TariffType"));
editor.writeToDocument(editor.create("TariffAccuracy"));
editor.writeToDocument(editor.create("TariffPrice"));
editor.writeToDocument(editor.create("TariffProducts"));
editor.writeToDocument(editor.create("TariffConfig"));
editor.writeToDocument(editor.create("TimeRanges"));
qCritical().noquote() << editor.document().toJson();
return 0;
QFile currentFile("/home/linux/ATBTariffCalculator/Utilities/tariff.template.json");
if (currentFile.open(QIODevice::ReadOnly)) {
qCritical() << __LINE__;
QByteArray json = currentFile.readAll();
QJsonParseError e;
QJsonDocument doc = QJsonDocument::fromJson(json, &e);
if (e.error == QJsonParseError::NoError) {
qCritical().noquote() << doc.toJson(QJsonDocument::JsonFormat::Indented);
} else {
qCritical() << e.errorString();
}
}
return 0;

View File

@ -6,22 +6,6 @@ Tarif-Datei Szeged in Zone 1 (expandiert, Vorschlag):
"Commiter":"",
"Info":"",
"TariffType": [
{
"tariff_type_id": 1,
"tariff_type_label": "uniform-to-the-minute",
"comment": "same price for all computational units (minutes)"
}
],
"TariffAccuracy": [
{
"tariff_accuracy_id": 1,
"tariff_accuracy_label": "computation per minute",
"tariff_accuracy_value": 1,
"comment": "accuracy of tariff computation is individual minutes"
}
],
"Products" : [
{
"tariff_product_id": 0,
@ -34,17 +18,44 @@ Tarif-Datei Szeged in Zone 1 (expandiert, Vorschlag):
"tariff_product_time_ranges" : [100001]
}
],
"TariffPriceCustomer": [
"TariffAccuracy": [
{
"tariff_accuracy_id": 1,
"tariff_accuracy_label": "computation per minute",
"tariff_accuracy_value": 1,
"comment": "accuracy of tariff computation is individual minutes"
}
],
"TariffType": [
{
"tariff_type_id": 1,
"tariff_type_label": "linear",
"comment": "same price for all computational units, typically minutes"
}
],
"TariffTimeBase": [
{
"tariff_timebase_id": 1,
"tariff_timebase_label": "dynamic-timebase",
"comment": "computation starts at minute 0 (can be any minute during the day)"
},
{
"tariff_timebase_id": 2,
"tariff_timebase_label": "wall-clock-timebase",
"comment": "computation starts at fixed wall-clock time"
}
],
"TariffPriceCustomer": [
{
"tariff_price_customer_id": 1,
"tariff_price_customer": 165,
"editable": true,
"editable": true,
"comment": "price per hour as entered by customer"
},
{
{
"tariff_price_customer_id": 2,
"tariff_price_customer": 990,
"editable": true,
"editable": true,
"comment": "price for dayticket as entered by customer"
}
],
@ -81,12 +92,10 @@ Tarif-Datei Szeged in Zone 1 (expandiert, Vorschlag):
},
"MinimalPrice": {
"value" : 1,
"editable": true,
"comment": "price-id of customer entered price (for hour) expressed in minimal time: 15*(165/60) = 41.25"
},
"MaximalPrice": {
"value" : 1,
"editable": true,
"comment": "price-id of customer entered price (for hour) expressed in maximal time: 360*(165/60) = 990"
},
"tariff_config_time_base": 1,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,181 +1,423 @@
#include "tariff_editor.h"
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>
#include <QPair>
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
#include <initializer_list>
QByteArray TariffEditor::readJson(QString const &filename) {
QFile f(filename);
if (f.exists()) {
if (f.open(QFile::ReadOnly | QFile::Text)) {
QTextStream in(&f);
return in.readAll().toUtf8();
} else {
qCritical() << filename << "not readable";
}
} else {
qCritical() << filename << "does not exist";
}
TariffEditor::TariffEditor() {
m_doc = QJsonDocument();
// m_doc.setObject(QJsonObject());
return QByteArray();
}
QJsonObject TariffEditor::create(QString const &key) {
QJsonArray a;
if (key.compare("TariffType", Qt::CaseInsensitive) == 0) {
a.push_back(QJsonObject({
QPair(QString("tariff_type_id"), QJsonValue(1)),
QPair(QString("tariff_type_label"), QJsonValue("uniform-to-the-minute")),
QPair(QString("comment"), QJsonValue("same price for all computational units, typically minutes"))}));
TariffEditor::TariffEditor() {
// QByteArray ba = readJson("/opt/ptu5/opt/ATBTariffCalculator/Utilities/tariff.template.json");
//QJsonParseError pe;
//m_jsonDoc = QJsonDocument::fromJson(ba, &pe);
//if (pe.error == QJsonParseError::NoError) {
// qCritical().noquote() << m_jsonDoc.toJson(QJsonDocument::JsonFormat::Indented);
//} else {
// qCritical() << __func__ << pe.errorString();
//
//}
m_a = QJsonArray();
createJsonValue("Project", "Szeged");
createJsonValue("Version", "1.0.0");
createJsonValue("Date", "01.01.1970");
createJsonValue("Committer", "");
createJsonValue("Info", "");
createJsonValue("Products");
createJsonValue("Accuracy");
createJsonValue("Type");
createJsonValue("Price");
createJsonValue("Config");
createJsonValue("TimeRanges");
createJsonValue("Periods");
createJsonValue("DayConfigs");
createJsonValue("Days");
m_jsonDoc.setArray(m_a);
qCritical().noquote() << m_jsonDoc.toJson(QJsonDocument::JsonFormat::Indented);
}
void TariffEditor::createJsonValue(QString const &key, QString const &value) {
if ((key.compare("Project", Qt::CaseInsensitive) == 0)
|| (key.compare("Version", Qt::CaseInsensitive) == 0)
|| (key.compare("Date", Qt::CaseInsensitive) == 0)
|| (key.compare("Committer", Qt::CaseInsensitive) == 0)
|| (key.compare("Info", Qt::CaseInsensitive) == 0)) {
m_a.push_back(QJsonValue({QPair(key, QJsonValue(value))}));
} else
if (key.compare("TariffAccuracy", Qt::CaseInsensitive) == 0) {
a.push_back(QJsonObject({
QPair(QString("tariff_accuracy_id"), QJsonValue(1)),
QPair(QString("tariff_accuracy_label"), QJsonValue("computation per minute")),
QPair(QString("tariff_accuracy_value"), QJsonValue(1)),
QPair(QString("comment"), QJsonValue("accuracy of tariff computation is individual minutes"))
}));
if (key.compare("Accuracy", Qt::CaseInsensitive) == 0) {
QJsonObject o({
QPair(QString("accuracy_id"), QJsonValue(1)),
QPair(QString("accuracy_label"), QJsonValue(QString("computation-to-the-minute"))),
QPair(QString("accuracy_value"), QJsonValue(1)),
QPair(QString("comment"), QJsonValue(QString("accuracy of tariff computation is individual minutes")))});
m_a.push_back(QJsonObject({QPair(key, QJsonValue(o))}));
} else
if (key.compare("TariffPrice", Qt::CaseInsensitive) == 0) {
a.push_back(QJsonObject({
QPair(QString("tariff_price_id"), QJsonValue(1)),
QPair(QString("tariff_price"), QJsonValue(165)),
if (key.compare("Type", Qt::CaseInsensitive) == 0) {
QJsonObject o({
QPair(QString("type_id"), QJsonValue(1)),
QPair(QString("type_label"), QJsonValue(QString("uniform-minutes"))),
QPair(QString("comment"), QJsonValue(QString("same price for all minutes")))});
m_a.push_back(QJsonObject({QPair(key, QJsonValue(o))}));
} else
if (key.compare("Price", Qt::CaseInsensitive) == 0) {
QJsonObject o1({
QPair(QString("price_id"), QJsonValue(1)),
QPair(QString("price"), QJsonValue(165)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue("price per hour as entered by customer"))
}));
a.push_back(QJsonObject({
QPair(QString("tariff_price_id"), QJsonValue(2)),
QPair(QString("tariff_price"), QJsonValue(990)),
QPair(QString("comment"), QJsonValue(QString("price per hour as provided by customer")))});
QJsonObject o2({
QPair(QString("price_id"), QJsonValue(2)),
QPair(QString("price"), QJsonValue(990)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue("price for dayticket as entered by customer"))
}));
QPair(QString("comment"), QJsonValue(QString("price for dayticket as provided by customer")))});
QJsonArray a;
a.push_back(o1);
a.push_back(o2);
m_a.push_back(QJsonObject({QPair(key, QJsonValue(a))}));
} else
if (key.compare("TariffConfig", Qt::CaseInsensitive) == 0) {
a.push_back(QJsonObject({
QPair(QString("tariff_config_id"), QJsonValue(1)),
QPair(QString("tariff_config_label"), QJsonValue("Tariff-Config")),
QPair(QString("tariff_config_accuracy"), QJsonValue(1)),
QPair(QString("tariff_config_type"), QJsonValue(1)),
QPair(QString("tariff_config_carry_over"), QJsonValue(true)),
QPair(QString("tariff_config_prepaid"), QJsonValue(true))
}));
a.push_back(QJsonObject({
QPair(QString("MinimalTime"),
QJsonValue(QJsonObject({
QPair(QString("value"), QJsonValue(15)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue("minimal parking time in minutes (net)"))})))}));
a.push_back(QJsonObject({
QPair(QString("MaximalTime"),
QJsonValue(QJsonObject({
QPair(QString("value"), QJsonValue(360)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue("maximal parking time in minutes (net)"))})))}));
a.push_back(QJsonObject({
QPair(QString("MinimalPrice"),
QJsonValue(QJsonObject({
QPair(QString("value"), QJsonValue(15)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue("customer entered price (for hour) expressed in minimal time: 15*(165/60) = 41.25"))})))}));
a.push_back(QJsonObject({
QPair(QString("MaximalPrice"),
QJsonValue(QJsonObject({
QPair(QString("value"), QJsonValue(990)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue("customer entered price (for hour) expressed in maximal time: 15*(165/60) = 41.25"))})))}));
if (key.compare("Config", Qt::CaseInsensitive) == 0) {
QJsonObject o1({
QPair(QString("value"), QJsonValue(15)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue(QString("minimal parking time in minutes (net)")))});
QJsonObject o2({
QPair(QString("value"), QJsonValue(360)),
QPair(QString("editable"), QJsonValue(true)),
QPair(QString("comment"), QJsonValue(QString("maximal parking time in minutes (net)")))});
QJsonObject o3({
QPair(QString("value"), QJsonValue(1)),
QPair(QString("comment"), QJsonValue(QString("price-id of customer entered price (for hour) expressed in minimal time: 15*(165/60) = 41.25")))});
QJsonObject o4({
QPair(QString("value"), QJsonValue(1)),
QPair(QString("comment"), QJsonValue(QString("price-id of customer entered price (for hour) expressed in maximal time: 360*(165/60) = 990")))});
QJsonObject o5({
QPair(QString("comment"), QJsonValue(QString("general tariff config"))),
QPair(QString("config_id"), QJsonValue(1)),
QPair(QString("config_label"), QJsonValue("Tariff Config 1")),
QPair(QString("config_tariff_accuracy"), QJsonValue(1)),
QPair(QString("config_tariff_type"), QJsonValue(1)),
QPair(QString("config_carry_over"), QJsonValue(true)),
QPair(QString("config_prepaid"), QJsonValue(true)),
QPair(QString("MinimalTime"), QJsonValue(o1)),
QPair(QString("MaximalTime"), QJsonValue(o2)),
QPair(QString("MinimalPrice"), QJsonValue(o3)),
QPair(QString("MinimalPrice"), QJsonValue(o4))});
m_a.push_back(QJsonObject({QPair(key, QJsonValue(o5))}));
} else
if (key.compare("TariffProducts", Qt::CaseInsensitive) == 0) {
a.push_back(QJsonObject({
QPair(QString("ShortTimeParking"),
QJsonValue(QJsonObject({
QPair(QString("tariff_product_id"), QJsonValue(1)),
QPair(QString("tariff_product_price_id"), QJsonValue(1))})))}));
a.push_back(QJsonObject({
QPair(QString("DayTicket"),
QJsonValue(QJsonObject({
QPair(QString("tariff_product_id"), QJsonValue(2)),
QPair(QString("tariff_product_price_id"), QJsonValue(2))})))}));
if (key.compare("Products", Qt::CaseInsensitive) == 0) {
QJsonObject o1({
QPair(QString("product_id"), QJsonValue(1)),
QPair(QString("product_price_id"), QJsonValue(1)),
QPair(QString("product_label"), QJsonValue(QString("SHORT_TIME_PARKING")))});
QJsonObject o2({
QPair(QString("product_id"), QJsonValue(2)),
QPair(QString("product_price_id"), QJsonValue(2)),
QPair(QString("product_time_ranges"), QJsonArray({QJsonValue(100001)})),
QPair(QString("product_label"), QJsonValue(QString("DAY_TICKET")))});
QJsonArray a;
a.push_back(o1);
a.push_back(o2);
m_a.push_back(QJsonObject({QPair(key, QJsonValue(a))}));
} else
if (key.compare("TimeRanges", Qt::CaseInsensitive) == 0) {
// if prepaid, unrestricted
QJsonObject o1({
QPair(QString("range_id"), QJsonValue(1)),
QPair(QString("range_price_id"), QJsonValue(0)),
QPair(QString("range_start"), QJsonValue(QString("00:00:00"))),
QPair(QString("range_end"), QJsonValue(QString("00:00:00"))),
QPair(QString("comment"), QJsonValue(QString("[ 00:00-00:00 [ = [ 00:00-24:00 [")))});
QJsonObject o2({
QPair(QString("range_id"), QJsonValue(1)),
QPair(QString("range_price_id"), QJsonValue(1)),
QPair(QString("range_start"), QJsonValue(QString("00:00:00"))),
QPair(QString("range_end"), QJsonValue(QString("08:00:00"))),
QPair(QString("comment"), QJsonValue(QString("[ 00:00-08:00 [")))});
QJsonObject o3({
QPair(QString("range_id"), QJsonValue(1)),
QPair(QString("range_price_id"), QJsonValue(2)),
QPair(QString("range_start"), QJsonValue(QString("18:00:00"))),
QPair(QString("range_end"), QJsonValue(QString("00:00:00"))),
QPair(QString("comment"), QJsonValue(QString("[ 18:00-00:00 [")))});
QJsonObject o4({
QPair(QString("range_id"), QJsonValue(1)),
QPair(QString("range_price_id"), QJsonValue(3)),
QPair(QString("range_start"), QJsonValue(QString("12:00:00"))),
QPair(QString("range_end"), QJsonValue(QString("00:00:00"))),
QPair(QString("comment"), QJsonValue(QString("[ 12:00-00:00 [")))});
QJsonArray a;
a.push_back(o1);
a.push_back(o2);
a.push_back(o3);
a.push_back(o4);
QTime const t(8,0,0);
QJsonArray b;
for (int i=0; i<600; ++i) {
QJsonValue v;
QTime const &start = t.addSecs(i*60);
QTime const &end = t.addSecs((i+1)*60);
v = QJsonObject({
QPair(QString("tariff_range_id"), QJsonValue(100001)),
QPair(QString("tariff_range_start"), QJsonValue("00:00:00")),
QPair(QString("tariff_range_end"), QJsonValue("00:00:00")),
QPair(QString("tariff_range_price_id"), QJsonValue(0)),
QPair(QString("comment"), QJsonValue(QString("start block is free of charge")))});
QJsonObject o({
QPair(QString("range_id"), QJsonValue(i)),
QPair(QString("range_price_id"), QJsonValue(0)),
QPair(QString("range_start"), QJsonValue(start.toString(Qt::ISODate))),
QPair(QString("range_end"), QJsonValue(end.toString(Qt::ISODate)))});
v = QJsonObject({QPair(QString("Block-Start-0"), v)});
b.append(v);
b.push_back(o);
}
v = QJsonObject({
QPair(QString("tariff_range_id"), QJsonValue(100002)),
QPair(QString("tariff_range_start"), QJsonValue("00:00:00")),
QPair(QString("tariff_range_end"), QJsonValue("00:00:00")),
QPair(QString("tariff_range_price_id"), QJsonValue(0)),
QPair(QString("comment"), QJsonValue(QString("end block is free of charge")))}),
v = QJsonObject({QPair(QString("Block-End-0"), v)});
b.append(v);
a.push_back(b);
m_a.push_back(QJsonObject({QPair(key, QJsonValue(a))}));
} else
if (key.compare("Periods", Qt::CaseInsensitive) == 0) {
QJsonObject o1({
QPair(QString("period_id"), QJsonValue(1)),
QPair(QString("period_label"), QJsonValue("1st quarter")),
QPair(QString("period_from"), QJsonValue(QString("1970-01-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-03-31")))});
v = QJsonObject({
QPair(QString("tariff_range_id"), QJsonValue(100003)),
QPair(QString("tariff_range_start"), QJsonValue("00:00:00")),
QPair(QString("tariff_range_end"), QJsonValue("08:00:00")),
QPair(QString("tariff_range_price_id"), QJsonValue(0)),
QPair(QString("comment"), QJsonValue(QString("start block is free of charge")))});
v = QJsonObject({QPair(QString("Block-Start-1"), v)});
b.append(v);
QJsonObject o2({
QPair(QString("period_id"), QJsonValue(2)),
QPair(QString("period_label"), QJsonValue("2nd quarter")),
QPair(QString("period_from"), QJsonValue(QString("1970-04-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-06-30")))});
v = QJsonObject({
QPair(QString("tariff_range_id"), QJsonValue(100004)),
QPair(QString("tariff_range_start"), QJsonValue("18:00:00")),
QPair(QString("tariff_range_end"), QJsonValue("00:00:00")),
QPair(QString("tariff_range_price_id"), QJsonValue(0)),
QPair(QString("comment"), QJsonValue(QString("end block is free of charge")))});
v = QJsonObject({QPair(QString("Block-End-1"), v)});
b.append(v);
QJsonObject o3({
QPair(QString("period_id"), QJsonValue(3)),
QPair(QString("period_label"), QJsonValue("3rd quarter")),
QPair(QString("period_from"), QJsonValue(QString("1970-07-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-09-30")))});
v = QJsonObject({
QPair(QString("tariff_range_id"), QJsonValue(100005)),
QPair(QString("tariff_range_start"), QJsonValue("00:00:00")),
QPair(QString("tariff_range_end"), QJsonValue("08:00:00")),
QPair(QString("tariff_range_price_id"), QJsonValue(0)),
QPair(QString("comment"), QJsonValue(QString("start block is free of charge")))});
v = QJsonObject({QPair(QString("Block-Start-1"), v)});
b.append(v);
QJsonObject o4({
QPair(QString("period_id"), QJsonValue(4)),
QPair(QString("period_label"), QJsonValue("4th quarter")),
QPair(QString("period_from"), QJsonValue(QString("1970-10-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-12-31")))});
v = QJsonObject({
QPair(QString("tariff_range_id"), QJsonValue(100006)),
QPair(QString("tariff_range_start"), QJsonValue("12:00:00")),
QPair(QString("tariff_range_end"), QJsonValue("00:00:00")),
QPair(QString("tariff_range_price_id"), QJsonValue(0)),
QPair(QString("comment"), QJsonValue(QString("end block is free of charge")))});
v = QJsonObject({QPair(QString("Block-End-1"), v)});
b.append(v);
QJsonObject o5({
QPair(QString("period_id"), QJsonValue(5)),
QPair(QString("period_label"), QJsonValue("1st half-year")),
QPair(QString("period_from"), QJsonValue(QString("1970-01-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-06-30")))});
a.push_back(QJsonObject({QPair(QString("OperationTimes"), b)}));
QJsonObject o6({
QPair(QString("period_id"), QJsonValue(6)),
QPair(QString("period_label"), QJsonValue("2nd half-year")),
QPair(QString("period_from"), QJsonValue(QString("1970-07-01"))),
QPair(QString("period_until"), QJsonValue(QString("1970-12-31")))});
QJsonArray a;
a.push_back(o1);
a.push_back(o2);
a.push_back(o3);
a.push_back(o4);
a.push_back(o5);
a.push_back(o6);
m_a.push_back(QJsonObject({QPair(key, QJsonValue(a))}));
} else
if (key.compare("DayConfigs", Qt::CaseInsensitive) == 0) {
QJsonArray b;
b.push_back(QJsonValue(100002));
for (int i=0; i<600; ++i) {
b.push_back(QJsonValue(i));
}
b.push_back(QJsonValue(100003));
QJsonArray c;
c.push_back(QJsonValue(100001));
QJsonObject o1({
QPair(QString("day_config_id"), QJsonValue(1)),
QPair(QString("day_config_range"), QJsonValue(6)),
QPair(QString("day_config_product_ids"), QJsonArray({QJsonValue(0), QJsonValue(1)})),
QPair(QString("day_config_short_time_parking"), b),
QPair(QString("day_config_day_ticket"), c)});
QJsonObject o2({QPair(QString("DayConfig_1"), QJsonValue(o1))});
QJsonObject o3({
QPair(QString("day_config_id"), QJsonValue(2)),
QPair(QString("day_config_range"), QJsonValue(6)),
QPair(QString("day_config_product_ids"), QJsonArray({QJsonValue(1)})),
QPair(QString("day_config_day_ticket"), c)});
QJsonObject o4({QPair(QString("DayConfig_2"), QJsonValue(o3))});
QJsonArray a;
a.push_back(o2);
a.push_back(o4);
m_a.push_back(QJsonObject({QPair(key, QJsonValue(a))}));
} else
if (key.compare("Days", Qt::CaseInsensitive) == 0) {
QJsonArray b;
for (int i=1; i < 8; ++i) {
QJsonObject o1({
QPair(QString("day_id"), QJsonValue(1)),
QPair(QString("day_config_id"), QJsonValue(0))});
switch(i) {
case Qt::Monday: {
QJsonObject o2({QPair(QString("Mon"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Tuesday: {
QJsonObject o2({QPair(QString("Tue"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Wednesday: {
QJsonObject o2({QPair(QString("Wed"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Thursday: {
QJsonObject o2({QPair(QString("Thu"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Friday: {
QJsonObject o2({QPair(QString("Fri"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Saturday: {
QJsonObject o2({QPair(QString("Sat"), QJsonValue(o1))});
b.push_back(o2);
} break;
case Qt::Sunday: {
QJsonObject o2({QPair(QString("Sun"), QJsonValue(o1))});
b.push_back(o2);
} break;
}
}
QJsonArray c;
QJsonObject o1({
QPair(QString("day_id"), QJsonValue(1)),
QPair(QString("day_config_id"), QJsonValue(1)),
QPair(QString("day_date"), QJsonValue(QString("2024-12-25"))),
QPair(QString("day_movable"), QJsonValue(false))});
QJsonObject o2({
QPair(QString("day_id"), QJsonValue(2)),
QPair(QString("day_config_id"), QJsonValue(1)),
QPair(QString("day_date"), QJsonValue(QString("2024-12-26"))),
QPair(QString("day_movable"), QJsonValue(false))});
c.push_back(o1);
c.push_back(o2);
QJsonObject o3({QPair(QString("Weekdays"), b),
QPair(QString("Holidays"), c)});
//"Christmas_1st_day": {
// "day_id": 8,
// "day_config_id": 1,
// "day_date": "2024-12-25",
// "day_moveable": false
//},
//"Christmas_2nd_day": {
// "day_id": 9,
// "day_config_id": 1,
// "day_date": "2024-12-26",
// "day_moveable": false
//}
m_a.push_back(QJsonObject({QPair(key, QJsonValue(o3))}));
}
#if 0
{
"time_range_id": 100001,
"time_range_start": "00:00:00",
"time_range_end": "00:00:00",
"time_range_start_minute": 0,
"time_range_end_minute": 1440,
"time_range_price_id": 2,
"comment": "[ 00:00-00:00 [ = [ 00:00-24:00 ["
"TariffDays": [
"Mon": {
"day_id": 1,
"day_config_id": 0
},
"Tue": {
"day_id": 2,
"day_config_id": 0
},
"Wed": {
"day_id": 3,
"day_config_id": 0
},
"Thu": {
"day_id": 4,
"day_config_id": 0
},
"Fri": {
"day_id": 5,
"day_config_id": 0
},
"Sat": {
"day_id": 6,
"day_config_id": 0
},
"Sun": {
"day_id": 7,
"day_config_id": 0
},
"Christmas_1st_day": {
"day_id": 8,
"day_config_id": 1,
"day_date": "2024-12-25",
"day_moveable": false
},
"Christmas_2nd_day": {
"day_id": 9,
"day_config_id": 1,
"day_date": "2024-12-26",
"day_moveable": false
}
// usw. die anderen Feiertage un
"DayConfig_1": {
"day_config_id": 0,
"day_config_date_range": 6,
"comment_1": "day config is valid for the whole year",
"day_config_product_ids": [0, 1],
"comment_2": "short-time-parking or day-ticket on this day",
#endif
return QJsonObject({QPair(key, QJsonValue(a))});
}
QJsonDocument &TariffEditor::writeToDocument(QJsonObject const &object) {
QJsonArray a = m_doc.array();
a.push_back(object);
//a.push_back(object);
//a.push_back(QJsonObject(std::initializer_list{QPair(key, value)}));
m_doc.setArray(a);
return m_doc;
}
QJsonDocument &TariffEditor::writeToDocument(QString const &key, QString const &value) {
return writeToDocument(std::initializer_list{QPair(key, QJsonValue(value))});
}

View File

@ -1,22 +1,20 @@
#ifndef TARIFF_EDITOR_H_INCLUDED
#define TARIFF_EDITOR_H_INCLUDED
#include <QJsonDocument>
#include <QByteArray>
#include <QString>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonArray>
class TariffEditor {
QJsonDocument m_doc;
QJsonArray m_a;
QJsonDocument m_jsonDoc;
void createJsonValue(QString const &key, QString const &value = "");
public:
explicit TariffEditor();
QJsonObject create(QString const &key);
QJsonDocument &document() { return m_doc; }
QJsonDocument const &document() const { return m_doc; }
QJsonDocument &writeToDocument(QString const &key, QString const &value);
QJsonDocument &writeToDocument(QJsonObject const &value);
static QByteArray readJson(QString const &filename);
};
#endif // TARIFF_EDITOR_H_INCLUDED

View File

@ -8,7 +8,7 @@
#include <QJsonValue>
struct TariffTemplate : public QJsonObject {
struct Tariff : public QJsonObject {
QJsonValue m_project;
QJsonValue m_version;
QJsonValue m_date;

Binary file not shown.

1693
au-porting2-pdf.pdf Normal file

File diff suppressed because it is too large Load Diff

BIN
cobjs.zip Normal file

Binary file not shown.

Binary file not shown.

BIN
cppobjs.zip Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

985
l-solar-pdf.pdf Normal file
View File

@ -0,0 +1,985 @@
%PDF-1.3
%ª«¬­
4 0 obj
<< /Type /Info
/Producer (FOP 0.20.5) >>
endobj
5 0 obj
<< /Length 1668 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gau`T92jk1&AI=/p]sm<=Rn7p>%!b$[W\P#8XPsHaW)!bE<N`3Q0\MNIbIAL>/l<@?FDh$.oLS@rV0R`bLu+W"*(:&HHp=agAX`8Ss,.ij1ugW@a@cCaGBuXH4spl38[Lq2Iad(SM?*;fRHdlo3=jeM_['r.jYSp2O-:$6MI,N>EmBrH'P4OIS->5kD(kjCMPMYG1Lh2,X2.(3u^D@9X,L=q(*J=lr<PIVmS_B:i)+ea63aR2%%>2;'RO!(LO=]YZhYZ_o#&Z$pWSV[+>[o(q[]sG/C*e,0uC,q1e(IRJ32Vk,R?4Z1ZUInkPLG1?Xp113''*_&)k4)1,"/&*H[P&=U,N,dC.j:PL_=T>H/p5+m]9n\:"1'oTq'gF0b`7/_r]GAWkB%_18OOG@SZ>%&\WqN34k2qMUf9$UGOXC+AS_OJ_Ek1n!^/f=0XPcKd7\NVfBQ`SD5/epUg+b=;8kR)]I2k?<l(DY(Yl?V@(GqV"_^.NABSB=_sM(?<YM27ZGOj!#IqB=+[jr0N#.VB^"FT9b#cSsbD1lU;LK/rT2EmLJrZ>o7HgO^5Y^%?mM+]&F,<K4"^43oGl39hq[FgjV#/B)?-4%kAThG?FW?4Qb+IRKjIcn7jM2W1Ha(K*C,i.<P9TGFW/J:0"O+EhJ&@BYrtDA5jp*-/>n))=lE<QjZ>@;\N5A-L\7hr*EK'J'/B5BY6JClK+rco-1n7\L,oB(qljCiCMIjH9.I>B'O?=olpsDH,7?<b-%=Y;5_iBGl)^Q)JBI4Kl?Yog0(DM.0CMl06n7A/WmdK7f#gCe7u7"YUGp?>bFZV7gPVA1ClC)L>qh\3"*+n!Usr'GA%,1>uLO5lUXl@_r/^Q23Bl]a>u>5nEU%+"eUi-nRDh$nda4FfmoE."s@$!/ld&XqX[l"k+;2'Ql%V4guGA^P,on]]I,KipooEdEfDd`H]KT%QT>D,F,e(E(D`jJq?*Tf7?Pi%i@Q1]lVFb]PtR#4K9]ZAYjes(7LoaD_ZL;"P\DO$.isII'@Zb5G*%nR*n:o^X2c7SQ5LlWpW:oUFV:hR"9D!;m?u"+K/O-i9f9\A'unr.<M[Qq=`^7`W1#*cng6Y4$d(=Bl9'(:)g=G'c*t0UI0s_hWb_mTrcu?!+tK!Y"m"TjDaCZM`1c;2VHeFepghJZS9UTC-)<n1Q\-A1OJ&Mli?DV6[]WAc:IN'.8StLlIUoNqub6A4k(YSg;i+A'm<9+/Fg0Pcpk-YaT,FpqO!O-3=JAlaRD-&\'OE+KI&f9<-D'h9#,">=D>l89]U#P%pWjm^@+E[-E)"%ljKYaV<TrW%3l4i$k8$A]BM0SI.R1%)kuV@HE:ppSSgl`G;Q-uNr=S&reXbn9C7FrTSD"=b_mnW^>D^m?\8AW+tttu91l2=43A1(M!t13#]jol9Uo#go@Q%mM<cIlG]N])=3n"3le1LZ;%gLt<gb&F_qslBnD#.\:0NV%D[PM%+\2Qk/n_d0T(?sor<Jip*k'OS)[):%30@jWj:6/3&j)0"'M0FP[oZ1+m=E%Pg+nN@n=Z$f['lSR-Ed#Q+pdoj>S>NcrtA;VLPO5L>X(n5'5*1SH,7utpU7>^'*?<!IL1$cN2eC24Y)Ys;-$nn#-K51T3_FdF$'B,&]2o_e'QNdCUI?A(gegc?kVWMC(&@B~>
endstream
endobj
6 0 obj
<</Type /XObject
/Subtype /Image
/Name /Im1
/Length 654
/Width 87
/Height 34
/BitsPerComponent 8
/ColorSpace /DeviceRGB
/Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gb"/(m?*&E%,FZ0_%J04&hLj3.)?NI_%J04&hLj3]JmkN_\!2p=Zg;Vp[=Js)0e_2GFf6Q%32b+0**1"@AT2V)!JO@_UC@/qgQ`E\uqB>cL]71)ImMT!nA$s)i!<,:1TVkbXhkRap;B.FPA^10SS:&>[5::FE&;@gIZq,(;PC?Z7HVs`e)."+a49R,dd^1h1@7T#E-=bL$mkF#VsMU<urB$\OljX5o>;N+rl6jSKB!\,#O3eW8S3T2o5s_OX.%4Qc6V<E?#iXN73/NU</+'`i-;<Ft'l:fSlLLhPqXm?s6c4Qr5\RNGl>8jmaq16lj??65$Yd-`7HQn,ao!O@'6oQZF9F#6:"O"\R,bV_Bkk"tmqV=r8D32d<472OkMp"Ged%kgWR9Mr`jkI0W2U!Y-qja"3kr5#;pl]K;YRSqqIA/8As_+.3dOMUqPY8][S-I@8SgEajuu>;hm>kYO;H_./9I!P^HE'q\(7^I;0"";d?S3cKME((79/\C)Nr6<0L$s(^>_q`7=S+6KK33;M4dR_mR]@rtT,2X)AKOO:I9f6Wk"iVlNFWbjO$bb$N_+-fmT)K@#XZ6\Z)FRY&ihOPaU?)RI'eHkAH]U+/U#R?3,8Po0]!u8bOIWn%K&l*ArC9,s@L5$tf!2YnGc2~>
endstream
endobj
7 0 obj
<</Type /XObject
/Subtype /Image
/Name /Im2
/Length 1455
/Width 170
/Height 27
/BitsPerComponent 8
/ColorSpace /DeviceRGB
/Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gb"/)4)Q#m$nZLR]g@b;2Plm+5]Ql-BjIT-+63KSqc)ug#OhoVhT_A@DR$V$P=Ic.6V3dY`p8UK+pNT],Df3D,Xol?\gC.?1hkC68WtLi>ompe%[Z@>pNLOFOX&V?W;cajK_5!LhW(SJ*56pBZU!("f/IoiQRT/\_l"$L_jaNab/9R,G`%hq$BPD@m</,2]>;[ElsH>omUD\6Q?U4FiTF8cA\YQ)i=DUV@D.73f_9=hJQh/m=c-NLqthC9?kW0)iIIaul.k(D^7t",6BQg[piUh-^Wi7K1<)\3"-ki2Sed\,XA[TSh=ta%0"Be!m(;sON<fpX'f2GOHJE3ii-r^#d:^-b(1TbB@?OsN`Ja47fnUc=h,Dfl)e*asp#7OoJRP(=/l*H0TD#ku4Ri\sF:>K8F<uEu%@S<ZE=c7dG[ZXQJ6?0s4u(u&SH<)?[G7.q/P6d0H$bN@[Rp?a;@">B`'<:4A6;-(KLsge9d?m'/<5<3OIJ7b<>8KRFAW11i*80t#_P-?#)'Nfof,_Fb&+ut)3l"N,Y5tKY2c_%0mZ?dT*2lA0'EI*fb(3BMi`A4'h(&_SRk$sG>EW(YGe1DQCT\P7#\cbof37=%B`6"SF[3m9YFuIech7%ctI^8b7-48>4rhORHGe*)qS!aU>>\1_8=Y\R6'nBN`e"%h#\/.Lra`/TLd=='#(58_ME#?>0&n+O7$:k_.GoR,%7HL#YS<QVi(ZiP$8j(dE!G/7ri4*p76gn\"qi,m6t=K.S?<R@),Rt9GD#FR&I-Z7j@R>#ijBji)]i-e7SukT4dVWG+?,8H,MlTEq2R^SQ"379+(9mpEW*tKH_CfW99PTn';F]CIKP^W<"HW9]@$A]qdar@)Q()0"T-'I_sm%6X4\8)"%B^X[ih*o\3>3e:Gr@8tKNO7l/h"mJ2sOT;K>)8+kCE%t0u.olPrCZ.U583Q/Y%ojJ$tHJ.;V1&*1.m:GWW.mZPQ=%r@4ngW'K7=L?`!Y>$W+,X9Y-]4DhR=oG>+6mVcG\*;B5420q*BqFXA:BG)onG:bM0"K$`P>$jTdDknTB9^6Q[S[dV+B,sg82/YN<:"HrH%=W:t1J(I<@9amKjcTS5ZMC/6O1(<M&Npg*i>hfUl=>3=TI(LIn"g9m7kiFrmboEj(s2oaS36Q%_-CZIMYE_9RX\jjDb*3^1H1QPqRu8aN8DY0CFY\`We'UPZa_XZ;9Y4$KP9f^[XL@N=RPPm\>W-aFe(H!`S0iu;DkfgI>4G)1,q]dU+%//q\TlrB)up;187[`?"B@.s1&[J[I'pe#`T?GFr>JkbObSe0r\q.T*T;4JltCB/[89m6k1k0fc,h=f?V=I_;LQ`CjNp;3]b!";Q:Gdb=om/"(F2lMW79\bP0iD"6E`1EQ190EaIHo\?qEVmNis5u&/01K9ahb'>"Rl'irZb3I@,LN;YP9s"m1hlLnj<(iH9@a~>
endstream
endobj
8 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 5 0 R
/Annots 9 0 R
>>
endobj
9 0 obj
[
10 0 R
12 0 R
13 0 R
14 0 R
]
endobj
10 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 70.866 528.25 125.562 516.25 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A 11 0 R
/H /I
>>
endobj
12 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 132.894 528.25 239.766 516.25 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (mailto:r1sood@in.ibm.com)
/S /URI >>
/H /I
>>
endobj
13 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
14 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
15 0 obj
<< /Length 1358 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
GatU39lK&M&A@7.kZ.pj.j?:^Ec9Vf.CSH76"=:59b4TfQAJ/.5Y>qlmn:VA*6OGRM^!q4Pkb%9lco4rlK7Mk"GDM,YhIl#6$YhLaSsjU&r1JHJjj5MP@^tuK>2$%Pd9%OT#Dt6Z8`/&^VC=/e^P^G]2'62"e("t$*C#<q)Z]!h1uEFq;c^7rW[8j[A";9!;m"eKj,DUSs=]:]aarN<khpZ:,<MpPFV)a^(i6\D5Ug&n2.^hDd'+&"Z.>0c\t2,2P<@u@#gS'3&!KTn3ge!KisiKBu7_8=WDZK='S?@98Bpk=12>oLdpVE_p`UMP.Ar@[U9Yu&asD\6=US<<]a0OO1BW(K2b-p?>@H;RPtne9p]'cQq^YUTScY=<[`gMBN;[pMlO9&Ae;Y><Dhb-LG<,,n,Ic#%R[er]9(i1:(?sqSu&,bIG)-n^$:(#+[^)rCHhrP;NEb2-1VSQb`lC*+un+<mtEs`@qN"mEPX`tgUM**.[qCRPF!b*W%XmWk3HcCX/<d'[,JDE1Tl3K&6gbS8nc"Bm/0Y*h[r>aOJJ37lrc]n:Ve&79i4[6_<Jup@IOW:f7T%t$'^NU/k[&Db3??j3j/#2[YLX7+Nqb$'N25=38VaWBa(C,.bE]c^q)&>b<V\])%n/PoI"<V:,TM,K&YP,Bf)8>T'6fGkAS#G_Gln'MfjflGP;eIa\*78NqeN,1'^3D8KC\1^+WRXJpDCu+PpKjT)1F4)m:Z0qOKNu)*_rkY1S)$1Ekdk+9ZG%D2Z'*JYNad):m*4o>JbYcLWe>o:/n40H\V31qM+ZT57sI7Dj3Vl5N)Q]$.<2qoWbOPVC\YE`Kmh-8(_pbgk9jXglU9o4c4I0nNSC'L(9'VHcRMj9gkgEOr9V/!M)d+`%[um;?1W$'t4%>>N98aEWF'V'B_-8E\T,j?!h2Bb#1QDTgdkCG]"pj3i9+F>:6^ea=f$Z6;DYV"r@R>V[;Vb]d;k[e8Q*-mtt#>aKts1_jqU,t,W@K]e;]cI\d2oba89F1\fS%6>n6a2\0Yis/.Q1.g\b)m1RLkqM<p`!$TMC#Y>cK8-YLOfeAC;94[tEc45?B.L2+jVOHs?eh&b!>r54+f52LOnlneYNBV<n>J12`_HLn:1^#X$[ChX@F=brkN%3`qe_9ge9:aJ7ZgFFIl?OqhpSE1kPq-jJu'VrdK>3_n<41N2l5EU.qRrf.#At[iad"#XR"4OIHR6:3-gmaQQ]KOci)RCM<$PGTd3>@ks%@N+))`d"hG,f$s@,]6^E!3=.0q%o1=#Udf#!-mNV)!#M&1K.(:U6?TrtYn$P#n0J:^#@V:9=@V4)B1@MYa.sC,!Z58?)8WIJFX.+S>'8j1m~>
endstream
endobj
16 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 15 0 R
/Annots 17 0 R
>>
endobj
17 0 obj
[
18 0 R
19 0 R
]
endobj
18 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
19 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
20 0 obj
<< /Length 2078 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gatm=?#SIU'Re<2n68ha;(Pl@#PKjY7D!,E[\30;LLh"'7+jsR;BmJLrqE1(a#_fr*=j"XON81jmlC..OSL`J])<NW_C-62k5!PHYe1;J6i.N,-Gs4P*Y0T+(lZ>b?sX?B]"XBs#<1%@C>Zb.=2K&TVWQEamW#:rG=;O>o=B9^.^[()LQ&E^TrO8KGalmacq:_g_?QKp86=WBOD3*Qgn:cKA3qo\:R$#$n%nq2;hX2a,ac:iK\a5)CSh8>'\n3@-$puidhS'>FJ)[qAY'9EJB=m>W4:-</r<"D\)=nF8pgK.`a+7";00usTd7,lH-2+THL(9b_uL&K\kbQAhU_d^b5LS@QCR(BI(<-L!G3,&"18%*$<2)4H19J22#+[r6pWWFm]M-(W[^EJj"0\9*%)cEo3U9`SA?Mrs(R,jY)H(nc(HP>,?>1i'7gg(hr4/Egne3G$R..t9C9PU$9NiDA?UC9IN9GU`9E`L\Du_6YVC_4qQ.i^(4[e2G9K$8(&IVrVN:d7,qi$%NPN8mM\df#]oS6n>\g1@BF>uUcb;YP&_[W_b^kj7e&W8sA3B+trdXKs!WI[,faGsM(`96Zb*nQ-(Z\(!6Vc&,Lli0bC(H4??Soq6Os>WJr0Z(Q-5$T_G;hS3Ui!ljS"eP53cG/N`+&gt>CrPT)d/)^T;E#^IoQ2#ZNYe57@]c"N&k,MV4O@g2a1U8d)6Q5&^ZAeM3/Rjc@B-:obsg:78c&7^`UpcZ'sM<Qi.aHqj4C%/&[,cT$Fp7m4>%_6Q_Q"Ri@g4D'?GrJPEO%+e0;m_Hq%o::I3iIr[J:/R3(^E$e-mPb$2XoA0aWoVaN=XgDAT5u#>?d+<=P8?@T[W*hC"T\JDH$d'oYiXX0#C?$b?9'MdW(_.f,X3)30m--7&9fp(UW#)LdeL_>_G-@^?0srMZ<_r8(W+ie!%HdV=J9TW[5[s!KQ\q\aohW@.#UHCRS%/E8-t@jB3hCI'p]TMg$Agb"5X$id_?$K4!B0O.).esG>D%BdT&Io'4)%kBco.kW59@1H`N]rs,jKu(klu;rXT^]q^mlX)&Y`DW*S:Uu1#'b?m2PuUII0#q1I?=]*M[0!L$7q"KR\IbZ?_"1pe'82eL-N4#`+'eReb;XhOS&m-dsV`2^>0GP')pK:7S8RX5/LUVo^i6Gm0Nqa9i"M@V[<Jp5nE.kO607q1aL]l2$OW[dh&K"2,Zo]cYMY?oFKPpV1cZ:C_*.<ekhREB-dW?p'G4!ocMVdp5_/:j3;XT:+R*>K.(98_W+erS(gljHo.A*#gGWB$6C5.-`NK\?o?pHOo#&,8"\a+%1Ji?+sd^_om$a?^''rZr<E``^udlCV,5+q&-aK1]X:IdBkh<g`;%G$.9R3#UOfIVm>CV9)8=,KOT4.k3#oO:[`5Sf$hA,NposINg9bM=<.fO/BlpDmBBp$U@8H$.%5<q(gc8^6JCI&6$n,bEH53HC/Nr/,^'$(+-<B.]%6u]NG[8?(VSQX>MI`%I;UUVL$/4GKqO8@KAH$%Ist?#e**<-MMJ1o--Jn(h,K<dS-e3sOnPSLM"5l+U92hO(s`n<;:eQFOnZkYV63g2BXth=,#Ig"^HDf@s6akRN!CSBmS)\%f-J*&/3nuZ`C(`]`,CfZ2`G,K1MJBX,deX5^tIZ?DE7fY63"Ij7bcuJX9T=0q#:-*,E\FK/Q8]pYeBP]3f^\$Ii:?oY`\)@L.K3ll8gZ>+GT+UN^W5Oh`Mr]K&bAa)70))/9j<5!4o)o]>sf(G#!3JJm:Ck\ei&T0#e0+kl`_maknIrV-4bLLp<-L$F&5ieW?rDlV&-;SAL`(2__tG[;dD!HD13=);Q,oV?dB(b9%d=>rqXtKl9I4n;+PG%;H^A-i7.gSl0imFoZi!7cfGkA\3G),i^#970fg"-j.*MmEt/?8jAsAR<Ub"U2WG#dM5PT1-T!/*<*DYKTj<B?Q.l:-,"QNY17<B\Fr<;+GVW!Z!ZH:6T^a#.<0@1=iO+s+CPd.Z)#C'rOWhefPU:a<Eh&@/*OWiTC25rD*aa=9/IV8%OmqWD';=Sg$O?L]odY^L%3"5Qhf1Hi&%KS~>
endstream
endobj
21 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 20 0 R
/Annots 22 0 R
>>
endobj
22 0 obj
[
23 0 R
25 0 R
26 0 R
]
endobj
23 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 394.998 353.935 452.346 341.935 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A 24 0 R
/H /I
>>
endobj
25 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
26 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
27 0 obj
<< /Length 1773 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
GatU4D/\/e&H;*)+eTpCTWo\<U0dPqERu=#)e?"-%9W<i[V/m'/@q'V-i^n.>8E8Tohl2a!7B4XGC8g=o#SH=jS"dSfUcdpo@:c7ee?fBi6O</b7$MZn3VB_qSmnur,_Onm9.SU>F$#U`g$6!QsHt5T*V#g5N^S;^W-3G'.,_J[dh#WFR8LMpW*jX-Y:7M3>ur;,"E5cR.Dnn,JK>e`<O#3PLYNsQ7Wt@9sUq*LSq$@pm%b>8C$gEc]qBa36sJ)@VPNrai`3S*7cksj!7iQ7(;/iaq+"@f9Rf=G"a9VL.@&qopH?u[XhqX<oCL-eX,KRXcepVj(teK9*T]N4lb9;(^lQ;4I7nH?LUV%.h\Fr\Y=Q*'Bfi5PF.3*L<uc6bP)?@/&A]8j:F^&Qd;6RT,.f3WmdeD8ps:RrSohN?dU;mHRA;=f187,I&J`tK/34P,kf5N3@Jr,k\3lZ3A8>aNH])9XLQp>F?%M^MtO/h3E4\$@YU,OX_"DbUoP2E#EijT@]UsD:RQZ-:,n^=Z.;T/So(3-JK8tuMb0HsEfi6"Klf=ii#a$>QKIhGI"((L:c*N+K$&EsiR5M`6<Akj^<5-^kk(8df#@lY(6prWPFZ`b2eI)]\"W(8<PJbRTIO#Yr:sNVf?#);W\H"JaE*:R>m]du`qlbF0@^G2*#Rus.1Y,QY$i,IRte]X[>soZY"N'Bi!2)kC>T!sbR9=sRP8`VAU/P=i#[-&(9+SSLmGLB"MY.3f6EESb3".26`'>;]ZoZ@e90.sJKYc)jCeY7olL2UVeE2_>)rLBhXI_>\KZd3h]C1<J=RCV)7/)NqtIcL@hm(bDblu"1<]$2RI$\JBbl.A?;1b2Q#,-:qme0_)l9dq';br*[`"kt\VKif5ekPkh^=^-3^07AFO[QTTl8Wp2$f-a7/.SB=AAd^gs+Rhd-XgK@;t$"X%u;(RQg,IE*V^A9mjoh6r`>p^m"r*#VQXIj_hI]iLHtNC5/s3*]'KiSrPkd)t_f7baugO>;CLXKT>amW5d"NQ7k\44"]38$@idWV19Wb1L"0n'!$bZ^)J2-(q(SX_;,XK0oXl6JT2d;]Fa0;2uf616Xr\N8`XGkiAO00*HVEi3%d)eEs1Os;*Bs"RdN2-S`";"nr?XB%g[/#*N)ILK/%`75s3ck`lS=oO!_s4]6=>Y)$/LuA/t/C+sW0g:,)6D6qZ(Z9dL*O/X9V6#=Q`!O;&X?U4k\NpAF#mUMc$=>A>S/hMMbi4-26XTT(Jdb"39"oI_e))U!]E%>1;EVP<g92lR`#Dg9+VZNs`rG3X$*fL7F"rXHCh:(#iTk3<Zcc`6D'NsMk4UF;sUW))g*8M&Rr9p6WO=AiL?Z?S7%rf#T,3&]e46+(eN^Hii,.3F,tU`@9:_^;aJb-\+m)guEBiLlkK46Tkt7qCHdD+X9mbTAX@#DD\?UITa8AQY&AS9G"M[Y5&pD.p6k9%4#2I7_mRZ)\@^>t;0l[0t=R,[I=fZ<raQ@+S9adO"u-jF+cULJcAa<+5Am,arK6&E,<d6O(PZ&j.e3I01L`'YbG<[Z<CRr5Y+:<tGrh7QGQY?/(9STsbIlYA63lS&MCBKgW1h4`SF0U#R:>3FUDRW(d-.`Cp2(W7UV,JnN,@=XB!.$%(X5C40Mn?U^Hm?ea*I.(\-e[4bb6$c7fp1Mf-pT'j1:Tba.]BV:"aSO(K.;<N%7-nj/&/fU?`q<gs&lOD#'_qc.,?GIgj9d-bmWk%4O?LNDTZ+$WENOV=lUUV\Y?)d`D@?Q[W~>
endstream
endobj
28 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 27 0 R
/Annots 29 0 R
>>
endobj
29 0 obj
[
30 0 R
31 0 R
32 0 R
]
endobj
30 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 70.866 513.935 128.214 501.935 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A 24 0 R
/H /I
>>
endobj
31 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
32 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
33 0 obj
<< /Length 2041 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
GatU59lo&I&A@C2nE=sFKE):,>j\>$icL^1R`V8k!L=i7;gtYjQ*L5P$VDVQO9boVNlN3iikBhcG[0U`GDk.p`U'4"LbbD1(2RSSLse6m&eZB^=[:JZ(h!#BMdS^F@s3&.&SHk)Oti2ulu6l2(fHu/6YI0?*Kuj6*lRoOK_Q+@3<O5JD$4:mM"e[D!-`p!XCkt.,RDp:%LAi-ckL&M"cFT"o-TgchdZ72R$/dq+ZJC\/GC`GaTZu,r"Ucs=On>L(r^SRJ"JASVMd6h89d`cIk=()F1Ea?d<e/Ai,Ll6IfuC1]\V1%^E(YKMs-;"(X:%lZkH*CQD,7=CU`;flQS++#.Y-@.Z8^`]/<>\dO4!JZS17f.-7K*bneG7'_PT=)AJo^LL=Gk]Z<S4YfmogjZd<V%tW9b(.TUR8D+t"5k6G^Ea()g@+EGsBH#8l]8q*.j6f-U?cWF\o@HK[4)e)a`4VnTB,j\q/;j^ilFt=JA(,&`@&qOgd!^R]9WjFug=dT.[JhlCj0"Z$r"iO`=fhf\;JXrT6R*)X\!:2*dmO*&\bIWE`WhgY_:#B4/^"SK<U=8A>?R64(7u0-aB"".[futbWV4o^W3%!q+k(=f<,KEW[?*fke>e:BTC8\Kj+5uIa+Rc'TmME:5\i(soI!LnR^^/FCD7<%mA`X!>;V].9'h6-;-F]9kJ+HdBt6)P62Lk6,"ikYQjqnd[_.@&.$lSEYGH@J;3h^XID3gK]`C,$`@ZRgkHG(\&bRVM;&Tp<k79YbFBHD>gfqXK?<a,2-/?jN+pdSA7&1_ZXlgFbLt%iiXn9@[&ZMO")sh<4:c>ELq5.#+7Xh0[BUX6JM$PKeZmj^C6[7O(6Q!VNG$>?gReDC>]%..]h]M,>4@Y8>Uh`&o>)2X@[B\,u5&]PF[9-S+WG:#kX<Wa2TtYq+9gFIkrsi3O=m*)1m?0P,^Ir15+#uIWlQ'oQ\":/'*kHE.ojI4"^!'Pc#?Pgi06@f:#`V.9G^Q+>L=eubHFY'!]62bV)!E8WfiDaFlfG'S",]?R\X'C\L1IQ%c)/Em.ZZ*Lg3jKF^&&"WZ/"a*rYP95rGHuCdK76i<t.#$K4_=S%S/Qp.#tSJ9/V<(j$V2Jag,XHrN\L"TOHQ']++op3=`EB-VfRoe/4^p8"@QG$U"QB<nZS>V6N!o-.cp0MfO)dNh!SXUSj0(FFW/@MV9S`B)kn9kPSsmT,5Uuh+Sj>rOQE-rDf0\f0MB2'oip=E+o%FK9iD)dftsQ=(CM-<#l7\jGK9h3)i@H&`(-f7*+C/ckR^\)<(T&#cF\_`^I3gPHSWEl3^B9BLk]ZM02PC@:C)n8QD`Y8U@tWH#$S\=DACZ/kW\ZiUi;RK;_G*T97KE65BeV9G^#;'(LbpTC20o)8ma\9JG\uo41,'&K*d3,OOLS$a3L&0@;s'fU*$-hGR,Y"tut\[*h!:@l:2@lG5CM="G:fm)t0>EsC<?HM%f4HIf^KDh>dhTtj5^!'bo1plme1#rcnnF9@u)f\pl^i-9o27I&')?oN2rb;7FeB]dQCS&g7`H=ikg7NUL@#]GYG7"1O^#fA'[G%be*Q44&srnGJs(.GSrgrS1l&=T95@1Wt-G_@kA`+]cAZo3`^=b/XCiW7:n==]"lDM*1aB-Y&"#+>/iN=KfZLHcuA8.,9'gW&(lDIi,F#jj5e*l.:OB@U$ErS`L^r\->_n@?^c*oLjfpT]CM?58U5lAhs_CU89Ha[R');b`KOSo,]n3(]aBSCd>+?U*AGg@0ZGj[%7jEYHfsE\l(OH;TL32:2&L'^.po$,'E<m0B?,7-.oRei"ImONBu5^m`_0oU4CY7n<3)`JA'&&G]3H2$L[#Fo>(3Ren1,IIRdu8sOib0dFr!B>W["W+.l2^uD/.(&&?T082&VG#d?:rs2cZ<A@`m(QHBT`_/#PJO/c_m:dS4"na4h%%5gHb#3lOU?3t'n.?8bkoWMGN0;X?=2HYY/$%K1/N6lf/UtM3*I_=q7<8!R!XV5k$#T`!L8aYGbk@%6(]J5u\Ab+-r<G83/62~>
endstream
endobj
34 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 33 0 R
/Annots 35 0 R
>>
endobj
35 0 obj
[
36 0 R
37 0 R
]
endobj
36 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
37 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
38 0 obj
<< /Length 2040 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gatm=bBDVu&Dd46\8+u4N;/R7mUFd^SN:I[U3#%[\dO=I,h+*UJu!5_I>>+=>YosPKo\0iVuc%#kKZF2o<\05,;0?$Yr?$]NP3kFi/QtSn>9\[SP6\1&GT*VoB)nDpR<hAjipS>]mm]j-P?iZ"nt=aI639p;sMCB;0<E@[Gi`UhKkr9RZc/>!WQ6,eIPAUf2B"=f,rh,G-.Cj2:iA&GdJ#)^#>t'ZI0i9V*jhMij4+/o^d"t+n/u+gmL1la(.+$e%K<cWO1%'9"5X9GXs3rIep`-*ZZ_Yq)Z91S(;I_.&rR3W"9?UPi1ImVYF"q)G5Kg)s045SVB1[+,WP%K@k`N+(_>l(7cjoiuMBJH%$6<eo`,kel&Rf]@XdS>^`5q5QqDU]Ip#E`R94X[pQ=VicbKIXnF*@NpOG-$@jKo#I[P1h_j1$b"S*YCPS#RQ"u]AYn\>()M_pEU*K2MmYHm=g,qG]+%=R*ngRP5Gj7f5L^7dr/cfn^25])(079\mJ"9E7dXl,UYjij*X9qIKG%E:l9<NMn^>Kr:f['J7EBVfO/4:Z87oZM%kPR`DCuZ&_pgYl_mM&sLU6,,P3!?4@K+[I>mha%d&L:aWg+\dNmfk7Em^1up31B'^EjYkjaO(#5mo3(pToR2?V4>W;)CD)m%&M_r9X@\21+WbU*25m`+Zh%@n6=2\Z.F%PeLmFdLJNF^>RE79eYH&KD1n'PBg<<]AnZ`oG/u-0LGdg/-eq?VR$&`C&Re,O<CI+/FFD[s2=dM!nWIjm?#ps>$!i]lU5`)$\8OR;4!Ru`qs0odaFYP^qo!f/49Kml\GkcEpfOn@'o'2/XCg5"2JSSb<jtc)3/H/iCC./?h7)ng;"RV`#(slF[O>C^D+>B(`G+7LO:g:PkI+J&&:j]#RkM;"CAA!/oh%DkoET@=Cj<?B$sUnmj_EG&l"Fu<._:u^fI3^/6R"!29%?N'Gqs=EKgX'fXUSc2f,%;)&i?ibMR)^"(qr24]o=S(<FT7QWP0E#o%jpoc.fX&q5@m4bA44jhIXdmAiE,#7tI,7hGt9]U,YIqV9BO2M[nV*&cmM-_-5>A^r^2(K['@20Q:ZVJG:.,CNAqu-_EA=+i7Q2cs`/J2>#5\'cV@0Re)JQ4N%A]h+\%_m%3WOm$LS@]6<tdkfU%^RSIZ"/+QudF(jO8iT,^2aj>=r@IOM5>+4&Ic,DU=H*DnAYeH/SLeYup$.e*)!d!#`qpRf<!6$K1]]ikcJm^:]_0DesHn6tkE><u=Gd\TtPqAuE0j%/9L183g=Yu]M>O=HcJAPZ\$q#.n)MONK;+0i_E#'ddpT-q2R=c^YWD9i=&n1r\p\'1P*0BT8Sorr1+1TH]_]<t-NDA3+o<K."h*_WPfuru+)Aq.+km4%E2F3b,<:)]jC(p<b"?B4u$r)lr?`ZB.$jaMW>?D<EV+f/7&IdN%Y$#UL2mRd)2\#4?L'No:PQq+tR[VBK\GfFM-a<4<.L.^.V;'Gn97p.[_fS_2``W'/?J-Ch,iYeg#Q6eC2JHhGn;TB4;]0MFjn*"9TNW.$k4`fOqP`DlWa[ZOq+3^)3C%.kd8ER''F4+EK\&>L)<IfrWK\tHZMTo=<q(oXH@8`*_7U#i/pR6q`4M-%%TIH@hsAlmf9nj.BZPcSiE/GMa\7'<\FoV(')-TM<cmINEP\m0bZP=58c)V2>[TD$m6U#@*Sf$nMu+O[03QCGPPR):(/\Ynbr*'kk;BG`UMC&E)QeB>=B4n2cuU-0/-n[Q]GIW+)5#RK[d"idN[PlOe,&K#gn.4S00L`pC%tF9oD>h;%IShQlXF!ir!.5`ei^S1\\^dNArMl)ZeYrp.]_7qk0g=Ti/<$kK=%2;=kc<;s4nidpf'%n/&ZmDfZtFb89NP>L<3s;PF/j;M?d$g;>SdX]JlYt,^4$PT6T?eDTB7FZg/brRs"3\D/HT!PLGMLA5%&fOr>gq(!CmESE:AMN;$"=mL#Vaanek3%g4UGIL!EJMMrO6[c)J$=:gjYW?D`bj0l.-KcQ9r=[B\^m:q+D5HS^LNW~>
endstream
endobj
39 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 38 0 R
/Annots 40 0 R
>>
endobj
40 0 obj
[
41 0 R
42 0 R
43 0 R
44 0 R
]
endobj
41 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 114.882 248.935 172.23 236.935 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A 24 0 R
/H /I
>>
endobj
42 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 70.866 115.435 128.214 103.435 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A 24 0 R
/H /I
>>
endobj
43 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
44 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
45 0 obj
<< /Length 2128 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gat=nD/\/e&BE]*;s7eN/uhI"PdGX+p4*PhOKA``@MoBhVJW$4j@OC?m*h$(7-Z0ni[$"1<]9Em]DM+i4Pq\+T78"*TmkoO2iGK+/r1=B5K&H]58M+o#k8d(]]J#IlbfEtR]P.joWDjA/!CM7]<#%9/cCaehqmo_-,tnr5Y/iKO1!>/>0C5`SMk3^e@Zj<GA4;d%sbT8p9J@*G@\!@&bLN*GHughn=b+VJLB,_URIc8cl]C\['!urIo(%F49l>Ek;:B2V]9eZ(?"NX^\)BuaSh1u#>^BXe6N-16&22\Z'Dl-XKlKLT%30Nd`JRg0H+1-lPW;_iLrB@"YD?@Sg3j>QCFt+Ys#dP[QC.-4#*mU5CMf=o!I$jdk*8S%s!qPZ;oUhA`6F\5)B'b05]t_N2CWF:gqpn6EM=gA^s$#B>sE<prN:QMhs^6P^-GDosi\AL[.0C&Moiq'MPVpW'8;f3EBq/(cX\I)g2kl]NkBH#lK?EPcFs]HPo8d@,.OB=ZN\b<mo_Rr`Ir,LDD'o>HiXL/P^.s,j$X[(qeBEZ7QW*ks3,<-d%#K2.Pc##`X3uk"X.-0c8,((:86Op`\fPf`A.oe$+/r31b1(1S;A*=3;._3.09Ud?(eRTmp[e=OYYSjkQb"fCZ<ggJcsQM%6<-kt/fs-7nF&Z.Hg8q\i1,7gIM(+Taa:]7441&?fe="cTq9rfcH`"FSUcKRUd4l`>VpB-V1.B2f/ABZC5aiVl,r6_AH^3s'3&]=Sj;eW_)5jg8X$V]#c`O)tWoQ<R^.W,!A"[.el-T=T/=T^V)ll:HNJV]"0j+^l:`L4j:>c65IeDU"c7?`\%?X!GEL4X22g[)3'?>@.Rgh@:$Jg!KB&TW#(3[4[,aooZA"C#rG'&B]=A>11>D4YaNokTY,n0Lb3jnV#?@A#IdEN#dkYk/QEP<f>q6HL@,SSU/P#J3ujHE)<#b^gV=B3/"F8LX7p:0Y/0-Vi(S2OO`9fqA20N'G*(bmg9jhKWr8sPsYd7N3:0Tco'Ge\cs*C=(CQ<1"[&C)Ojo4OlrW=SNtHB^<+RJ"V)\m^d2fR3/k!ELX7p:&@r&c7TY6.F>;\bZML+;k1C-'_.->KT&/ks\7(UZ2bVl@%Ahg!ZZP5QDAZ[(%HFYSVKEL+0^`[n,/S5:9V'JQl?aqcU61JB#tE^CKBb(2(gW+2lFP=cF:C9a^BRuAMa<,;=/--:lk[W@S&Cn=k,QQe!>58IMQii^pC0QMY,7$%2&$Y6L*B)g;s\T\'G7X>,,<d2O/W-(EkF#ck?G8qEX6ML%Z7m>@<=@eKWZJRco'l<\scm%M]mk;2:lg2ZO3I<FNYU]KDR5-n/KY0Q4Lq(&qL\HKIpWk5l?@8%8L"]`ZK!9F_;%IVkm:EU,D_WPMfd-U7@Ji%XE9C&+?3'o-,cu4Dcuf[>4M?eP(<ZYF`%3in@Uip6YYs/aFLuM[WR(TBKB`b@>Hj86>k+5Y8"J^Ob-2[IJn<dab?[_IAj3/^_PAQ(1JOW6(HRM/5q4*A<,+`l1Nq#i7\'q?)&,`H,(FkO.[+nC-PU>=7IoSQQ\c[G4gIqTKqV$(/g!"?TV/QpB;i-:S)9n&GXbWiW5\@A\cIeIXWQ(_g";OPX:=;GZ@eKZ8)%+!JIYS%X"\Qk4Ba&k@B>_f.l3kh>Fq`-p^Y$=bm(!f>I\>L5=YN"WPY&:/44LSn/"=Ydiu7$[kf?pm!I',<rVBeWTcl1QbC&YI(MV=i;.7=K@%&^E$+MXO)#"'0Wt=-j(#D5XrP(tI6MkDSfN4)'^uMfP%dQZpr,e?.2:[c9DOD00E`1JVX0C+hG.h3;L=JD_2$ab7f8Qa7Y`CQa71eQF$BH)`$n5XV10%,Xh;W=-);aT>FbA\fs6Z@J&(kB;Lt$A%[kS_9?.A`98\.l2aA2JI]q;fBPnX(npoVKuEq&psE\gEU*J3`IG3oB^2[YKHh,[="9cWA`\<AbBnBkmc0_Q]fFuZn3=J(IP73410I"W3c<mR'#KFl/CWT\>dXLbYK"I/SZABSare_B0>6@ln]\e/hYZd7IJWe,dcNLQ..MQ(*RghJj7+3]N3^/#<(2GS)<3!PmVPNr1QElNItHn)>BO;%^<DIl^'BSps5`A(fgS<\2@2L~>
endstream
endobj
46 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 45 0 R
/Annots 47 0 R
>>
endobj
47 0 obj
[
48 0 R
49 0 R
]
endobj
48 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
49 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
50 0 obj
<< /Length 2245 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gatm>?'Ca9'RekG_;m'0e-%$B+E,rqA(!s&mAsssd-Yq^7^e]bU4BT9r;$a>`"`J%B0)G$)k21rm^Yh#]$B^>k5G/=h]'n$EJTFW]*UVZU=9L3kPCQ*87$Y'0E3NiCiB<_\\3flnL9(.JK%&=FK^b(/&.P__1?fQ9W3_K&F39br)6"2)=[KTn+c:jlg9ZZ,CIOqs*Q34?"E$9KK/;Qq<MTq1p<FaSb92H@=2f0VoSJp"E6%(Mhj5A,5/73-o;9+oj'iM7%ggR,-M*^hi#W"K*?9KK*I=$A[$^PA[$aQAY@PlbMr4NaOd*:2A='TTRn%`W;r%iB!?ec.R;X"=bRu=WLXn4EC3N#@>2QhL=g0K*_'iFa-e*S1bllt9e9\!9sA9!G.f4^*+n#^9JFou0dA1d+LK6/Alp@3"`,iEO)<JT\RVR@pJ)\L1N(RU%'=W%fHqW_YY#-+]5.]b'AJ5X6fWlpT-B,G.M`+8<T$Ea:Wp%Gi$qkPY"q.7f,q6PUX+:`9"DiW?XnBlpe<UCNJd6Z@XLshi"YEADmOOejLj;XPut][78aX<1j_DkCd_U,)6\cjlDM#Blo>>rj=+(.;"MUG0%]Z#^(e9n78o&E94aVK$!l>mf9k+QGAnk:1C:^]ZGm8ko<I@;gYj?q&KS#V=_?oQ25quhmV0M;,7#_:?>\@"&hWo+h55QNnRT33*f?e,fEeGNn33_29iM'#7Ma,gnYJGom)k)GIE5D0;[KaE79aKTBZad$@5l+c69=;*KQ#NeCS4YEH]2!Gf\nk-$*;8cH!(k<P0*B!3J:D%IG40bF/Ybg%kmCIkL2d.W`^Ub7DYU@p$c_ki(4nDn9nI0/Xuo4;pEgL[F:0adl0%T8$n^Veu+/M!\j30lLEMWTcV1H8>J+oMP%ZaXK'nb-j6g?VE0YNP`p2>Wa)%WOM"WZ\$quYL0m5BN0Gn^UJ!J4[>0MMQ_LW].5sfa*Y:?X[\H<V/PH9-al?409YrMb\W<I8joK1o;P[ebV-,^Vr/V_O9oBWPnR.((nq0`RqiW7^?HR&L9Y#cDVet2*[d,.?R?+9>G?tU-][m<D(ppq?ed]r,EY1jW_<I/fL?V?V]hkRI)+S(%KF="V*@tO)<Zhi=D@tdaehf7lVKXZlSCW[#Qq%?>cS!*aA0FTJbr>lh6->*::RFL8d,d_?TDN+/kqN-578Ou6nkY%t5Y(2ZPVPh>EZN^P?Zb&3>@n>fd6?<\lG,4l`qR;a>0KYFSsPj)c6q<5<P\&6(QO8^U-\YsghO3U8/lg"WoT"&YETo?g1=C:CQsp.?5[iiZdYr)`tG&n?9A7RC6@758_MWt_#QJ[Vo@U4U,&C%QJb/^\!>$CXJfcT$2G]-?-R_YYpuk-(*+BJoD4"IkM6YAd;bR'Ij`a_q$75H%=N=e^CY\]&1TWK;st7?F1F`Sn=#_@&$bR>@MH>'N!RKn!:1M^NdVcA0#?aVU>PEP%XC5m%A?f]5J"ehV9(rVmXbm)SY4c@(3A.!N,4E3]F!<R4RN,mC'.0WBHJ"_@sces"R@F\At$X*bpA-!5kk!AjcLhROO[mjQ](9,H2:P]5(1/_BUFS.ZE5\A-sJu$k16(417cMY:t4=C6;(>7$ZhkOdJM7AL%:jAI_G\rONBn>$coS9kP-OP^%Wq_oH&kk9CF&"Wp9-MNm>#cPi'\!HG=/6N'F/k!7Qec%!L+JRjFc`AgYp;bq;(h2@EnJOki-=CsP)TL2h,h*84SuD6Wc=n>TiD?P$HnEf3[K1Jgi!']ohOh[=.c?"lTV:?Z)+V%j<u8i$e88k?hc8df$9T:NRF0"]b"]@ajCl<YtRlA77$FZZ=@DO2uiAm$u):^2X_9P0&2b\"=,5pp1sRGEaR1:rs-1-6ai2S0,HZ-Q2$CR8=CT3Z8?B6EZ"M1su$gN&?BI#`IObjmO<cACK?S[6R)/bnVd_9`\1)gR#hGI`)FPO?KfE^h!,7O7?cN&K5;.QC5^))p(b,d8r0@5Y7G>g*G#qBa@Pk5pqA"%$iL,*E020>`;3nfr(Aq,V%^Yg$7rrt)*c=$ZJaSpYL[GY"ck@aoV7^@=m]]_YQ+?g@qbk_Nmp?%mo.<;Muo)j.ndUG!h'rs7T[@2JZ8Ss3i9[4+P@VlI3a/m8?2G18j0/VWAd:ZtKpWHO;28>Pu7M):+UMBtAtZfr#MC(U+3,5s:G0;:R0l#%$eq!%J[r4\=cNd`0>SjsL2*FM?A/E\H%m>gRaG1#s3nA2F0+6OYDpA~>
endstream
endobj
51 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 50 0 R
/Annots 52 0 R
>>
endobj
52 0 obj
[
53 0 R
54 0 R
]
endobj
53 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
54 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
55 0 obj
<< /Length 1831 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gau0DD3(/G&H88._*qNb]?5FS`WgbSLUOdr>4q9#,Me-PMF^&H</=Hq]:1n<J%l!m*XJRpdrk7jZ10WA):-K9?;1V_\(%&d0oa:i?lJ>32,*e]*+af6gi,s^:H`2#)dc'5bMnl.[EBsQ?"P%NQ^NfM"\`'Z$Sk26>^QpglV$9=0mQjDE_PI"@0i24[hA?\aKf8d"jJrV*i,4=pnig.)/cc'd1^Q$TAPFYrT!RG/+h?.8+5V3DA_i:+:^Zh;G[/RF/ABN/ZYGi<h9]dL\G62<1Xa$r)5-seGF)<pc^Bga5@JgWd8tIW-'qR@,0\;$1M_s(UH\@bQkln?;395YrLZ';/ig$@b$;H?@h$d&P%)b>1]`3l%X/bb>U)H8=*dE\";Qd%a#q9[g^)H@[4t:Xp&Hq!^9cmfrT/lFEB1RV1*E,FdGmRcB@F'4)gHUM\9WY;X!#?26KTBHk"#Rc.0hA7(pbOrFl2a/V8=-ED3tY0q7uQ4I^'7Cj%HV57=4dcV@!J=PcPoio2.QG@NHfLX5X,p`^bg0XeWc]fa^R8jKPO,JY>B%7uZKPO3I&*\UT$irXhb<?Ct6c7mt=@@VV]EQdI9:_qi;fh%QkEC,@.as]JMC6\X:M+2q.aTo3L+SSEgeB\[J:J0:rC'LRoZ.tq6@JuFRTq$7;_;M1`\0n;.61Yq:h&f[V-L@7[_)tJkkn\%`GX_"?\n!o0eA@_Y1FQclKieN+KF1m('hO$H()C5a/X87?$QcW_/'r(=j2!`;$LL@B3lb-PFaHt4YpiVMFX6-6b2`7N;s3!H(6h)$-ua@^jmb[n-?a3JB-u+W+p9R8e`,b?45!Ga4lr,>["<N$I@s)1N2iS3;)OJQ'"M@foE7lcD;P)F*sVtB>6eaRO"(AN5ZX./.!ArMV"qD/BaJ8&lq%$*1>_CSCd@b3)Te7n?KJc_@CXk6AJ)l@F<>(=gnmEG?IXOVoBKKtorWjGZTNA0l$f4nDCX+:]5_^P=Pj3mSk!UtNp>'0.P0m.R?#@225iUpM)rm$OBsZ8:Mm\;LVR+jc#2%e#!^k?\6S&T*^a2jG?[JhdKb8W9&M<mI$M#Y[CrGc8=3kh>ssrtLPX)>7;5W,^6PYl#*24M)0_OrDG@M[/R;F[ifi^ml2DaiCg3N=02lb1TU!a5.!X^0VT5X9STiTV)"Q_Qs4bmB[6"RBH^Z$Ta!S\$0gT]oc=qKe3C"ESZ:fa+WEi9.]-i/5R&<elbHm!S.<?r5)6-d\%Pr5Y0=T+d3.gDYm71FZd+YO+Q6<'X]1ti=F-^ZqLHYcW!<X'b"MCaXQ@Sj-73M?Z'Y876B`;K$UOE=l[nU(B3AtgWeM1sE1utFMr?C"k8G=rSoTC=iouPaGcfU!6G_SnX)4$(H4NIY4;/Z5PL!'t,3;2$,L:/dE(]<+kTg8!;@7/None*pQDNF!WKnK:7bWa#uin`X(Zc9HfCOAEDM)+ZQhm&uSIkT"Z+t26@>Z]$\>^a=FY!*Bte&sIphn0lhd<u^iod2<<$>LT"Ou-\`+cZ6[g&f%`)t+qiqDEfQTZfRM+:_kK*/;McZ79H7pB^B[/ad.QW"c$c-,MkG2HP8jZ?pM2B]AX,5@3CDg%qModFoQ,ZMrqW?U+OsH<tGjX*34Yf+`uJ+Cs"-L3ZIc?/I2cq]O#rrDP'#dZsuP-sd[Nf*8O;Qs./YXOVL@:oL-CDtY?gfj]Q>P=`+,XqDVEE&u"Ig*q3PDQTa57^=pe%J*dHj).6'8`DCUf^EcGBb#ffBfjkc6r#HSfH$,o]g3A"mAgcmI0)mH!Wf;'Y8(:ebrBf6hUq5%^IGs/OM*1C9Pr$"rWV3Ud#n~>
endstream
endobj
56 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 55 0 R
/Annots 57 0 R
>>
endobj
57 0 obj
[
58 0 R
59 0 R
]
endobj
58 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
59 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
60 0 obj
<< /Length 1888 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gau`TD/\/e&H;*)TbSE+?nj0(U0d[J.FP@dJnD-9%VprQQ=u&0/@lO\`;B5&??q^1f`&5l8OZ4s4hTs&GGMAWZaV$\KcO].Mq-%[eh_-qqB*-I)hl"E"W/I#8(M-ZI6Uqm1_n>!>JE8/ITVLm1t_32"/$_K'XkdrSgt73\)pEslIX?EA?ISNf^ROP;\;7f?5As>r[LeqH/A$t04mF]2Mtc<UZ^K?I@PGDYRu&87;Q1\kLas?O$-,kCH;95G-s".!f(FkUG/d!2.AG#n=p=V!eQ5\X*:gC>*a.:BkU6C%5;9jHi"tlU4+f#K+TGjjc]rRFY$A7@`9il4f>T+p')u>U>@`$mUJ,^j#:Y?no]f.%5s_CGo0!Hru/:?`KI)EAQZifGQ6GD\LNnDE7[O%&2nL8gG063m/d"!)8Llt,4ure3OW"a]=6ZlEFFIkWi9<"Rn:k]=*&fi<S0MgoH/&@Q[19t`S6>M5nc'Nc!9C):!q]ZnjoNoSsCi0NOYGN_XSQ<<]\%q2j;+;<kJJm,D=DH+c-7g_Bq+&W=jl:IGZL^m6Iti8/3,JF]("U`=[hQYabFLneA!JZntDuVio^I@A#F(p"D:KruGH#pLe0rNUG+'f.fTG,&SXVeP7hqQXmsDY>X2KYq4ijb?1><j*9"^j!2/nrfq+NYl==`o#lA9/8JR=^#\L)9k<\B68aC^clYcT>cErFi!XUU-OMZN(^%420\<SNEh;V$^%FjAfh#b.J2>:TQ4K<nKD*0tBQ61l"tHiZCk,o@ZP?Bc9UT,2%h)!.544+t4TP8CZP],IX,.YWG+8&i2DqjgK+@Lbodb!@.[$VB/tnlH.;*Vjg:L(Am4jHq;ZCVik44)fF;/MV0i@!cRd+%s7hG#=PBiS.O=[)_:<_V)9jD]b,[J;-a<jkYGi%JF+t6tdW$I?-\\f-jp8`bHjbC2DFX_mk1+2,2C_CO5=3ih1=u-=/YnD(E<R5>0Ut!(7h2V$i,eQ>H'(dqYBX'f>lZE6";or\_2G":TmAJ.<n!W,Dc\`MpHt5!Bl%F\#>AYB3E]-o95aDH>'"4OG#lpT`"UG2^GDCUgVK,Dl3F?f$$+0jA=6.'&0ime0<@o87&k=:+<KTb+lb"0^TG6j:H>GjB[;5TsEpidt+msNRXc\"dkkL=lYo-:,KWeEMp/3iERpK"pN-_No<?^&7piF-iJ/JATq*]L#Qg#XAa4,8=0u?p`nR@(n/W1*@j*[kMZoc[(a-(5][/5Y%*"H(8(:krS(Y-3f^QJZ:?nY%^43/q>gNT:)?%;*NBhhAD$'F[9rTV!5k4,C/*nY+I#Hab&cQJIu#=I0NJ,0'>`nT5c@i)[!Z!9@IDVR;`l#Ip#b5ptn>pTgSQuA3>T"L4H/X$j"b'PC4%s(gN9tifGaX8J5eAH)1[69\qF&-ue@Qq)-ST:7LSUq^7m!;E$f#_qGhp(V<+U:/@.B2)CY*:m_(6&nN?-3pcF^dM6[DZ!B)U4L+'fkWu0`<XhrRIsoqd1L3?@NM"Rpt`:]Oig=ZV=jg*q:iDO6j:DkmCOahKjojP!$bqYNYD!%`11FTI/uS?>Rg-3E<2^L`r]%CdB:0%B@qZ(L-,d:e<Q@n\_rm@uoc(54n`\dtaLDiqTPt^+Ds2%iu6jOn;+3$:L-FB>N\SCR=BjEd0RB:G8K$b4SFBHY9fCC9M6hHuH(=TCAiYnVF:^[NcHI"d9ms<SrD^h<\bceA:l0O47M[M3"1*Z&l1;Q3r%rq5031q7T/nJOgj07F<'Ipi;#ZM<\q"]n`](s$[1us4cD)3kS8UIu*NqXtJRMM@2uh[\8oQ&1smu[(V#u6hOc%GET-O^lnM8FUOg7mH!1*W]L1ug%pq?,i/%7,[e7MSJACmSj(d_T6(#7^0aZ7~>
endstream
endobj
61 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 60 0 R
/Annots 62 0 R
>>
endobj
62 0 obj
[
63 0 R
64 0 R
65 0 R
]
endobj
63 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 187.59 363.648 458.622 351.648 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/linux/library/l-pow-portsolaris)
/S /URI >>
/H /I
>>
endobj
64 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
65 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
66 0 obj
<< /Length 1987 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gat=->Ar7S'RnB30_/&9J0XB/=gnEKeeB"U-"oDW__Mq57+jsS;'7;LhQJ#446E4fb0#e^;psY#c?F.gb_Q#5m+.RaY%:Dkq1Ut7?8rU&r]-1`[c0!27#kc&:,86(PJ=<`/,XR2m7+AYr(:?t&usMfYU1(o".tZIrI1OG@YBB#i-.Z]*&Ch+odFI["Njb9o^D[F<6_bGemgH61R\9s2)\,P.t03rK`FA59<^!s((:5B";_ptJ>\\P,$&*Z+t6W3BqlFm!kX\[)F>sqLIQ@@!-V2(W<I.WmU`T4Z*/PuCQ(&e)86Mg7?#6*L3$6)*?<=2'dYkO7_X\0elfoDN)XN=A9bO*K$X.J\@%bDR+SD&29l^H%B!Va?AXDT!LOZeB=H_PbIZu06udQtIl%+PP]9AP5ls/m?aoY0BP<ArJJNrriu0_a/kNGRk0R'A?jl1kT'RH@ClS.+IbmC:p_f?>JZ&I,$"@*n,<uelYqVsT_jiV9"]$%sQ5IPn3QZ$S\RA]GlOj+=rUg!IqbJ<MpXC>?@9/,<^nnm*0N)d_;,R71%#)V:$GN9+qMJj!<Sp]C[/`PJDDhEhIdXF&?!Y`j7ap%O29C<]S>t12ZbWn+M^HcBhPphL7YIZQ.Qd(0e^3B9ZJbk2&nON[(O1qHAjHb4I+Ra+5SdH3".\=L:q#b8k@qI!3mVu7,>KCo=NIT)VWuYMDFWNq?=\b]XqJ[Kd6F3C=A]kb9\kTC7e0GI5l*fc/gtOJ.H6^j#=/0[/9HHH/!l85_!B0)(F>tuqtTpG6j9,NBBsRHF.9rLR2_ZX2GC<"-emQlS2N\aU\YJ-/>\O>4k1'+A^l&ur!K&s`r=i$=^g4m/VuAhd#BQE-\e`WWaW$U.6M"ODU2Y<"'`>$<7tZK)-+fuNX`L==ql''I5[h,qQ<&s[,1J@ei"lt*q+Qi]q<$<H#$Vg8^EYt01l#`Vc^b`=MU[<%-&,`:a.r/Cq2j5le0/p!9ZC[0)E-n`1pnl[`1]-.h"!Wkj5]A)Ce3lFr$8Xq5=,&)c5n/7gc^mn\[YT<O6V6r/4'i-k93e/BJg"%M!,LX4:f1%piq1l_0c]W[SagN'O#bnfVI&^hW[3c5\.<jpJtR<atQ-fA1`^o0^J;'^#N(dic-;^2qOiP`)YpTpPA;WZ+A]'JOPQZlNLD/^'^eA8Y^NBXqDGPIE\NH2C65#Z;ICF(Z((:aFYkBV8k=YQ%ZdR#`Jij?jYLiIC3f]f*dE8)N4VPhYgJ0iPW%55Kqd4A_SEC,Z8_mb*OT='%&[Jgf3Z>Fraj`3LT0@*teDZ)P2b'@dWfO*?)*0Gi00Lr!j5=qr//Ll#SGXU1b&C%Rl6J9cDlHh'Alb_.tQ4OE/4E'OBqmH4E6f8hl^Tt]PV<Y4KC0_m^EL88iq3*D<J=67q7ZWnl^JgApTN&Sq$6S%\S?+a\!']pOu>!:e!TO@J.QW8!*7GWdaV$]t63FQk>X(ZY3*IoFU<+5l$bL71EI'6o9AJCWR%N2hd/G1MLT]>V>E]9?Y1k_AWH8S'\>F]"0i09oG6L]#r_ZXGlVMuTpk@1qhUs`Ll,R=/V?FXZ_:Fc0Oc/eV%^JghUqWr7\@&.n*.&.7l;1:O\!i9"g7#3as<,;>9&(;8J`pf4T>4D.&f^WEir%[;Nn*\o7VDn9se(IK>l)Z>rc'cH0aUH`G%Q!"L2e#_-<b=b7+`Oi>B%CWoiCjV6D%aW7ZmM[I9a?\5YI\j@*P(7l#m9i/V1C2q>l_d,b4E8_]=Pq3dW)[iAZD*o$?%uL>6%4B3P#CkIt"a/,jp5o7;5=AZOF$W6#4^DT^7$7Pk_L2HX3F?l4QmUQEF2+q"KF&6jK,U%ETa?i4N,iVI)CV3iubtF1i%kflR&mCCb0sQBNQ1^m6]-7n*c(c;5jG>7V%ViKDp#rFl551tkg,DJ6^pA@Vc%]DM($^1YkbU_d4d[Y#g?,sWg?,hLGN4id`+&p/Y9Gd);f_fd-b(]OLd06^L~>
endstream
endobj
67 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 66 0 R
/Annots 68 0 R
>>
endobj
68 0 obj
[
69 0 R
70 0 R
]
endobj
69 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
70 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
71 0 obj
<< /Length 2197 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gatm=>Ar7S'Roe[&C?ajBP<OX[<l*/bHc8+\%((FAM=gVG)45&.S<9k@K1aGZ7^p<kW%4`#-_X0g\77[Gf[O#bi\An72`A4`Hl-#Ri/VMpn=!lPJHc@T2NO?BJ$[DT._kLB@[7X"'GMBQW:qU<2pSK@sNtR<nVX8V=BuHQaQShb_<a@c4m$3$+XqGe_31@Xu0Gm+,_[#HVO-/P91EalueU(c?tjjp%Z\fBi^LE<MJ[L&Z6Y=''_NhWE^H`cCk7F6=$5hVmH1AP@So1ZL"aE39%mbI1gX*&p^CK0@fAhlJ5qCF]P7Fs+&nmdt_)(-@dMSCUjne(Ru(u0rkl:c0UeMS&HN=1Df+"V'u7n`-P=u$hk9o:L)&3[G:#*9T-EOQ"S0s7&Cs)8IT`2I%Q'EZTQP\rZ4XKLR\k=QBu@SeAs]JBA7mkr#\thH)gJbl?"H]R+H)L[d?1Il^bUMP"8l_N"_O<D/#kn!oWp5"j6Tm_S1%"`K3TD85V,&7CEg9X^5Xo8T_VPM4Y4&J)K1gQ((ugk;Kol\XXPc+'OET`P0T+\_[c^.bc-^C/mei*;^Y>(nN3Coll$6U\.fl8qFb5R8>M(&sY4FeZI%ecQ+rak6B5Ih-4kP<rtaN`edAJW"Z#[d`q;/fU6]r!M]<W[N/?FqYe$e%bCUj'sU(sd^7-T;/GhLgR0g.Q)-!nO8<H19311H[CK,aNS:@0+>9`sgnU[T/>oIj*I!#@;X7Z/ieT+#\Z(JM-:)S1>oISA$GC*Q^Sp%!PZ="3=]$B8(0GiEU8^(Po5=%<)J[S!:7%GB-4$k+5O^R'P213]LjN"c`q_k.%bTV<hKrM4i\:L8EG(B1h0g7$m3NZ7VW%XP/ISMC%(eD&aQBb=1MsY^N#8r(>`2T#6';R<aeg8*6B32/FY=d^R"JX4mV$sNk1`9`qVE2b($2u^MJ8B&>5DLHOP0M)RLQ`PUU8=TaV\I1kul!UVCCfWT8;a^$04kO.E^2RC=G/LTLS"2d2XsULN5..cPuZ.]!5;bAVQm2,FKH$b7lk7D-NcIU.eE(JuE=5k2C_6'AZB]<FdR_Q_H0emBV;kBHiG-g//jP&%MQdMGt]O@5EtQ!fS4j:HM!!fM7GA='6.N;ONF<mYK-%AObo@F@qdb14tFk`7R!$\5+ZgNBB)c:SH*e?i]X["gWa)H\4hC8i:sSq=#%qi]0\V!MWb_aUt[8%g_i\""C@nl93(mR8!jm+,hQ:n^4jeHL+hQSu<,moXpb6CHCX*r5StT"H^5ZnS0JVO0u:ddDHe0Ul7@G<'((&#IOm,CBZ:E2B_).JV[np2ED820mb29,iOtdif'^Q'7@lY]+`m$k@g<qP++:#:?W!(O5"S!bf*#aOfE+F<MNS6X^o"8@,irkFgNX=BfPB=GWNhlMdU@%NUk(CdT/u=BdQu=7OClkDJr").3)IK@&iGmrufTq<h-h<YSlE9a9bi^eZ,\XN42hkEQ\V/2kCr]:25tkTli$mB[/Xb1s4c>@^D2)(YW91^@OU@RdW.pA3#:6d)5Si`]bsl?(rW>kB[*md&-uQ::snAodt^Ch6'Sp,9]05FhOM@ST;>/D,(/aCXuB2k_pLr??qj`8EP3l/$.u@/nY#t\3Lq.%dK4+/^%NSicHjNpLm8,@rT,9EoOXs%F4m!d(Smd_fKn'(.Cq^Ac#QloBH,k#5a#pn@d*`EZL)2TP(h5EqO>Gq:!mUmkbH`*DZK#6^NILHUh/6LG;\?X1VaU_!K(sko_FU0,e72U`]9n@?b+uZfebm')?hGmIKQ5_r]555G@Prn2\`I&Y_Ap9^`33*=H&XQV68?Klr6;7EbDl2b#Y_E@CiO_`9^YW%XLH]X0&k<lOaTF)\h=am1b\Pt[ZW_N;;#f`FZlNkX*;SmS*1!7?qt0]I@0q>V9eM0%[3'Oe`McNJ9X`0<8-Ub,S"#&bWPALaS0Jp6#<P5N*(_$_V";E2<Lr"Odnn^??o8Q1Q2N7pH07SDnPOXPd(Ti"=#h#1S;>`Z+Nm7#rd-^$"s`G[FsWGCXB,<Lq/$$Sj:nn(NqfljMk+%Wi,oe<JVEZZbK)pY_]m&=i$C[K^@?kU>^U[\QWB9,=pd,$4PfN>hBXrTbC#+CI.,)X>t158_7/37WK!F4hHq7A38(&B6%jdVn3pB:[[3fHG:]"N_8j;HGPURJU:d0=#L)%%5:Jl$+4T)St![oQT~>
endstream
endobj
72 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 71 0 R
/Annots 73 0 R
>>
endobj
73 0 obj
[
74 0 R
75 0 R
]
endobj
74 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
75 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
76 0 obj
<< /Length 2007 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gat%$HZ.Xs&HCX[6Gn<t#o[!36p3GM^m_)gL,AE=%kUToL+L_1&Qs/I8/&*'mQ9aRP:X^KJfkcH]DLF]W417'j`L-3U_D(-+)TQ2hN&YI\@/M"L/+\h1oBS,f?Pg&Lul3Ob-f4PT@$l]^bHZ[(aPmG#8G?I$JR'[Cu$GHjcjC,[2LL31oqJa,,-.'&@Csh:\.t,\fBs"5rB[3WTJJZ0gg#(QS?J.VAnpGaaB\:e_6)%Lo9kB<'.Q^IOCOJYBPI\e\5eI^KW=N6Tj:9"#m.;nLKYfZ0WL3L"S(1O-^*lB2ZO;@46/Y`.!AmEeGQ<U).8B#;`oQ-ZZoYBH8D84V%kc:nu`*)_7"1-IEhMR/t8#9X+&nqnE%=3F`19Ceq7H/IqtbC)QiJlmP,b9e9mX/4J>_;K>W#0jFcTh8f)KB6fXao@,BU$4V]>2X;c:844l:bYHF`;-G\MB;bOLmc<`A&(Cc5,u4g,>/?iURINA=5rt=Zg;[50j30B:c"b5#@ZY(ZDJA/Wnl([aQ94o2b6RO5+7+ReD<5IDj@+r$77hNlTgs+K0gCg!eflr9#an%nKCE&T\VO=MM+q<68aIs1K/cih(o,$$XDTMXCI/n!=Q$bi`tUM^[Ya0M<NU:E/`ca(p(Ef8aas$6.n\$=PGVElUG?bcLpS5%\,P^4.5`N`'DNCKTf.6`.^kSk,_ef>as):8=p%r`MGK^F.[D5bUAUP-K5FRu]>)'NgEIuk>95$51)652Pk!GkCo>C(DUp3e(]'!U2&/9s\4R_P3$(.JS6D6G'$m5sFH?,<n?o'+UaRp[Lj:r^qcnTA?JaICh;6r3kI;B-pjnRp:>S_F\sUh*m^ZTfEr"i,g;XP.]g<-?M?'k'USq+<iti#CEdN$'H%%K_]D_Ka`MJGD,5?OI\\)X;.hu"BYRCfUg7N`_-%eGCdSL69TI0-0H$O9e2GC&1L,([@%'5*OFXK1<]M*;E4[ZEb][##hAQ[<mSr9]$5*QZ6WC,u!n@"d=>8D4_c1g@lQ4O6R=0EWlo[H^t1HkMOG\o^d<O15`oBV6M.E%Z-PWYfk8^NA;^)13W6=#sfh':@mF=8kdB<OUJWqL(/0LP*+[70+BARhVbBV?A._PRj<DX?Dd#_87(je^Dueq+-UO`_R#HAIL(JuA1MS0aZ->AUc?Re*c4S*TSW9CH&_<nMreW57<,6>_1_k"kOsn7)l0Y*V]l,657@O,GP0M`?NMOH12%cc-\^ZGtrr\SDcnNsL*)nXprQQM0c<baqFX4&7=PerpD#4<GH40'tN%Vq_eE'2n3+"o>:A`ShufYaJI%MPFQ`/0Y]$h4Y4[GG70<Q>*X%)AZ7HDEhEU<1n-l[PeJU#G,Ob:i1e4i;NZ3kQ_Qn2;s/Mh`2bs&gd.?OY[0LZ3rd9)!fgQIs/+lP6V]Z`*#2O[(;Z!Y8->iY&m_j(9*oibta,T0_i<2r<!\P+1F?I40-K:[>u#)FKC_1I2$1#WBfih\,-2YNU'(rHQa@teqp#/bWDUJofQrQ".,L:=J\0:j_]7pCH[20^RQtT$p-3$:J7d1as.Jl^nW7\Fr9E\.cnBHX`Gm,hu,B"L%-2XHR6CQiI^!>'ZeS+2&'DNDH#Wo;:uh[C*VR5#@Bmu,2umdG>.U3TnQuI%s1\r?Pf`t*Q[l7pFOq$1r<GI[T5s@^t^KH9r@R<[W5<m0Z]\SE8T"<5t.1lh%_2TobBq/5(H+.'.TJRd0ZR29-;P&W/8NERpCQ/?VVN)r-26:.t"U?g;Tb_5]m>+*NjG1(>(.[?i0sbcX,L5L\X``FrV?;\rA+F-gc%mVf_CuCU*/7-*q%>Y<TFO`J+N;AfPj4g]WMrV^/tEG8SMWb:;:04-X$.RDJ5R<@,rai1<lr]IsDr.ZX*&4a+SiWG<CFcD0.0W^(:_8o#"oh1b0NgOV=YrK(sq!@(S/0MgO^6"qf;>pS1&FB?sgo"P'Qhl!,XY9_"sK!bS[#anF]\G9TJP>4eKF*MMtc,JU]3r0pU5BGl~>
endstream
endobj
77 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 76 0 R
/Annots 78 0 R
>>
endobj
78 0 obj
[
79 0 R
80 0 R
]
endobj
79 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
80 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
81 0 obj
<< /Length 1122 /Filter [ /ASCII85Decode /FlateDecode ]
>>
stream
Gatm:9lnc;&A@7.pfM.,l]:fca#5M+$o#mN$tXsA@`u1u9/;[#2ZFgY8Y_Pd#7aE[QD32`qqga52lk'N45]Q1f5k!3`,j(Xms+]l4,N-tEU4sbmtUhc=]+A&"^u>>b90CLl&1UU[Eid9RLA_h._IR<N43qIQB/.IB!oY@Rj![*_422C(7;(IkF14&*1HK9MJ<nacVTUtfg%*DOE,<K6"P92Qa?P8:HtEsDE=$]P1N59i4hT_%&95/r4=7Z%>Fo=kEo3`Dp-9d!nurR+8"fMM\=X2-3nL2cEb$HKJR9Y$laqm&Tn7kCUd2oPlQ2/kUj+n"K,m7:qW,2O:%f]SArHO:eTUQ8LP`j>@)7,Na5:k6pj]+8OJ%b:)d)`S71MW_Vd2M&1_T'Y_`"5`)TOa"p6CO6r[2qksD*mA@Y0%dn29)K/6DeC]q6a)O\l;Yt?)EN5.I+,.]9_>$b$A'N6VLZVo:DWtr+LgbuDu8b-;D.0<7A%?GW`5Ep&McCdqDCBVo`LYm@bi`>bPOfHZM,D<]<P&,4]BL0YjCom2_orZWL)'1M2":F"R%AoZ67c>t_eb/07o1"2mc@#Y"F1p_<)QSKk:D33lBeW7k2i<Y=Xrj?V9@!-mKCG-.5>2S/')fj8G^'Z@n2,kVYWWOj-K#7f!kWNq$h^<rh<`q%Ot[;k&HR%j2kPiZk=2orWk#p<aqlTVaR.)m8iTEPAbQ0i"ZpX^0aOM/68a@kYXT0?<`)-er6Ti[0G8E-/^NA=:WZO1e&Y(Aj"7EZ".=hu/_^]pdKm!;!>'[dVUh$10EO2RiEh(%KC@Qa?jpT0)rbdu6MckuN3][6=COS#]UUY;9/&s*@>3\'VE8<a#LZnTn;ZqU`PsO%@=2A0^>Mok0o7YS+Ea,(*D,t%0Zio)GI9OoB6R6^C:PbsU=?cU@@XNn(Ct!u]r<1FjXu^8oZZYSeWmCh$V%B?b^s/TI+-<\T0X1cU.lk\HVJifA5-?XDdM,JY:P`Q0@s![G4/XupZC`(PN>"m;>.4(TH$fi-\RVK\m^h,&6AqpR%huMU7$;.BtA[*C<i<>+D!DgWodRM,`uA&H?)J&J0dGr\7lLXdD"i=/XR^1iO;+^^NXn2Rf!1KjQ^p~>
endstream
endobj
82 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 595 792 ]
/Resources 3 0 R
/Contents 81 0 R
/Annots 83 0 R
>>
endobj
83 0 obj
[
84 0 R
85 0 R
]
endobj
84 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 508.358 75.634 556.364 66.634 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/developerworks/ibm/trademarks/)
/S /URI >>
/H /I
>>
endobj
85 0 obj
<< /Type /Annot
/Subtype /Link
/Rect [ 45.866 65.509 184.052 56.509 ]
/C [ 0 0 0 ]
/Border [ 0 0 0 ]
/A << /URI (http://www.ibm.com/legal/copytrade.shtml)
/S /URI >>
/H /I
>>
endobj
88 0 obj
<<
/Title (\376\377\0\124\0\141\0\142\0\154\0\145\0\40\0\157\0\146\0\40\0\103\0\157\0\156\0\164\0\145\0\156\0\164\0\163)
/Parent 86 0 R
/Next 90 0 R
/A 87 0 R
>> endobj
90 0 obj
<<
/Title (\376\377\0\120\0\154\0\141\0\156\0\156\0\151\0\156\0\147\0\40\0\146\0\157\0\162\0\40\0\164\0\150\0\145\0\40\0\160\0\157\0\162\0\164)
/Parent 86 0 R
/Prev 88 0 R
/Next 92 0 R
/A 89 0 R
>> endobj
92 0 obj
<<
/Title (\376\377\0\104\0\145\0\166\0\145\0\154\0\157\0\160\0\155\0\145\0\156\0\164\0\40\0\145\0\156\0\166\0\151\0\162\0\157\0\156\0\155\0\145\0\156\0\164\0\163)
/Parent 86 0 R
/Prev 90 0 R
/Next 94 0 R
/A 91 0 R
>> endobj
94 0 obj
<<
/Title (\376\377\0\101\0\162\0\143\0\150\0\151\0\164\0\145\0\143\0\164\0\165\0\162\0\145\0\55\0\40\0\141\0\156\0\144\0\40\0\163\0\171\0\163\0\164\0\145\0\155\0\55\0\163\0\160\0\145\0\143\0\151\0\146\0\151\0\143\0\40\0\144\0\151\0\146\0\146\0\145\0\162\0\145\0\156\0\143\0\145\0\163)
/Parent 86 0 R
/Prev 92 0 R
/Next 96 0 R
/A 93 0 R
>> endobj
96 0 obj
<<
/Title (\376\377\0\103\0\157\0\156\0\143\0\154\0\165\0\163\0\151\0\157\0\156)
/Parent 86 0 R
/Prev 94 0 R
/Next 97 0 R
/A 95 0 R
>> endobj
97 0 obj
<<
/Title (\376\377\0\101\0\142\0\157\0\165\0\164\0\40\0\164\0\150\0\145\0\40\0\141\0\165\0\164\0\150\0\157\0\162)
/Parent 86 0 R
/Prev 96 0 R
/A 11 0 R
>> endobj
98 0 obj
<< /Type /Font
/Subtype /Type1
/Name /F9
/BaseFont /Courier
/Encoding /WinAnsiEncoding >>
endobj
99 0 obj
<< /Type /Font
/Subtype /Type1
/Name /F1
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding >>
endobj
100 0 obj
<< /Type /Font
/Subtype /Type1
/Name /F2
/BaseFont /Helvetica-Oblique
/Encoding /WinAnsiEncoding >>
endobj
101 0 obj
<< /Type /Font
/Subtype /Type1
/Name /F3
/BaseFont /Helvetica-Bold
/Encoding /WinAnsiEncoding >>
endobj
1 0 obj
<< /Type /Pages
/Count 14
/Kids [8 0 R 16 0 R 21 0 R 28 0 R 34 0 R 39 0 R 46 0 R 51 0 R 56 0 R 61 0 R 67 0 R 72 0 R 77 0 R 82 0 R ] >>
endobj
2 0 obj
<< /Type /Catalog
/Pages 1 0 R
/Outlines 86 0 R
/PageMode /UseOutlines
>>
endobj
3 0 obj
<<
/Font << /F9 98 0 R /F1 99 0 R /F2 100 0 R /F3 101 0 R >>
/ProcSet [ /PDF /ImageC /Text ] /XObject <</Im1 6 0 R
/Im2 7 0 R
>>
>>
endobj
11 0 obj
<<
/S /GoTo
/D [82 0 R /XYZ 65.866 533.635 null]
>>
endobj
24 0 obj
<<
/S /GoTo
/D [null /XYZ 0.0 0.0 null]
>>
endobj
86 0 obj
<<
/First 88 0 R
/Last 97 0 R
>> endobj
87 0 obj
<<
/S /GoTo
/D [null /XYZ 0.0 0.0 null]
>>
endobj
89 0 obj
<<
/S /GoTo
/D [16 0 R /XYZ 65.866 663.135 null]
>>
endobj
91 0 obj
<<
/S /GoTo
/D [28 0 R /XYZ 65.866 714.135 null]
>>
endobj
93 0 obj
<<
/S /GoTo
/D [39 0 R /XYZ 65.866 217.635 null]
>>
endobj
95 0 obj
<<
/S /GoTo
/D [82 0 R /XYZ 65.866 675.135 null]
>>
endobj
xref
0 102
0000000000 65535 f
0000040830 00000 n
0000040980 00000 n
0000041072 00000 n
0000000015 00000 n
0000000071 00000 n
0000001831 00000 n
0000002681 00000 n
0000004334 00000 n
0000004454 00000 n
0000004501 00000 n
0000041225 00000 n
0000004637 00000 n
0000004813 00000 n
0000005014 00000 n
0000005205 00000 n
0000006656 00000 n
0000006779 00000 n
0000006813 00000 n
0000007014 00000 n
0000007205 00000 n
0000009376 00000 n
0000009499 00000 n
0000009540 00000 n
0000041293 00000 n
0000009679 00000 n
0000009880 00000 n
0000010071 00000 n
0000011937 00000 n
0000012060 00000 n
0000012101 00000 n
0000012239 00000 n
0000012440 00000 n
0000012631 00000 n
0000014765 00000 n
0000014888 00000 n
0000014922 00000 n
0000015123 00000 n
0000015314 00000 n
0000017447 00000 n
0000017570 00000 n
0000017618 00000 n
0000017756 00000 n
0000017894 00000 n
0000018095 00000 n
0000018286 00000 n
0000020507 00000 n
0000020630 00000 n
0000020664 00000 n
0000020865 00000 n
0000021056 00000 n
0000023394 00000 n
0000023517 00000 n
0000023551 00000 n
0000023752 00000 n
0000023943 00000 n
0000025867 00000 n
0000025990 00000 n
0000026024 00000 n
0000026225 00000 n
0000026416 00000 n
0000028397 00000 n
0000028520 00000 n
0000028561 00000 n
0000028779 00000 n
0000028980 00000 n
0000029171 00000 n
0000031251 00000 n
0000031374 00000 n
0000031408 00000 n
0000031609 00000 n
0000031800 00000 n
0000034090 00000 n
0000034213 00000 n
0000034247 00000 n
0000034448 00000 n
0000034639 00000 n
0000036739 00000 n
0000036862 00000 n
0000036896 00000 n
0000037097 00000 n
0000037288 00000 n
0000038503 00000 n
0000038626 00000 n
0000038660 00000 n
0000038861 00000 n
0000041352 00000 n
0000041403 00000 n
0000039052 00000 n
0000041462 00000 n
0000039234 00000 n
0000041530 00000 n
0000039453 00000 n
0000041598 00000 n
0000039692 00000 n
0000041666 00000 n
0000040053 00000 n
0000040209 00000 n
0000040385 00000 n
0000040491 00000 n
0000040599 00000 n
0000040716 00000 n
trailer
<<
/Size 102
/Root 2 0 R
/Info 4 0 R
>>
startxref
41734
%%EOF

97
message_handler.cpp Executable file
View File

@ -0,0 +1,97 @@
#include "message_handler.h"
#include <QDateTime>
#include <cstring>
#include <QString>
#include <QFileInfo>
#include <QMessageLogContext>
static char const *DBG_NAME[] = { "DBG ", "WARN ", "CRIT ", "FATAL", "INFO " };
static bool installedMsgHandler = false;
static int debugLevel = LOG_NOTICE;
int getDebugLevel() { return debugLevel; }
void setDebugLevel(int newDebugLevel) {
debugLevel = newDebugLevel;
}
bool messageHandlerInstalled() {
return installedMsgHandler;
}
QtMessageHandler atbInstallMessageHandler(QtMessageHandler handler) {
installedMsgHandler = (handler != 0);
static QtMessageHandler prevHandler = nullptr;
if (handler) {
prevHandler = qInstallMessageHandler(handler);
return prevHandler;
} else {
return qInstallMessageHandler(prevHandler);
}
}
///
/// \brief Print message according to given debug level.
///
/// \note Install this function using qInstallMsgHandler().
///
/// int main(int argc, char **argv) {
/// installMsgHandler(atbDebugOutput);
/// QApplication app(argc, argv);
/// ...
/// return app.exec();
/// }
///
#if (QT_VERSION > QT_VERSION_CHECK(5, 0, 0) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
void atbDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) {
Q_UNUSED(context);
QString const localMsg = QString(DBG_NAME[type]) + msg.toLocal8Bit();
switch (debugLevel) {
case LOG_DEBUG: { // debug-level message
syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
} break;
case LOG_INFO: { // informational message
if (type != QtDebugMsg) {
syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
}
} break;
case LOG_NOTICE: { // normal, but significant, condition
if (type != QtDebugMsg) {
syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
}
} break;
case LOG_WARNING: { // warning conditions
if (type != QtInfoMsg && type != QtDebugMsg) {
syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
}
} break;
case LOG_ERR: { // error conditions
if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) {
syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
}
} break;
case LOG_CRIT: { // critical conditions
if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) {
syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
}
} break;
case LOG_ALERT: { // action must be taken immediately
if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) {
syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
}
} break;
case LOG_EMERG: { // system is unusable
if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) {
syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
}
} break;
default: {
//fprintf(stderr, "%s No ErrorLevel defined! %s\n",
// datetime.toStdString().c_str(), msg.toStdString().c_str());
}
}
}
#endif

23
message_handler.h Executable file
View File

@ -0,0 +1,23 @@
#ifndef MESSAGE_HANDLER_H_INCLUDED
#define MESSAGE_HANDLER_H_INCLUDED
#include <QtGlobal>
#ifdef __linux__
#include <syslog.h>
#endif
int getDebugLevel();
void setDebugLevel(int newDebugLevel);
bool messageHandlerInstalled();
QtMessageHandler atbInstallMessageHandler(QtMessageHandler handler);
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
// typedef void (*QtMessageHandler)(QtMsgType, const char *);
void atbDebugOutput(QtMsgType type, const char *msg);
#elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
// typedef void (*QtMessageHandler)(QtMsgType, const QMessageLogContext &, const QString &);
void atbDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg);
#endif
#endif // MESSAGE_HANDLER_H_INCLUDED

Binary file not shown.

BIN
openarr.zip Normal file

Binary file not shown.

BIN
pchars.zip Normal file

Binary file not shown.

Binary file not shown.

BIN
poscomparisons.zip Normal file

Binary file not shown.

Binary file not shown.

BIN
shtrees.zip Normal file

Binary file not shown.

4433
tariff.json Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

BIN
windows/git2.dll Normal file

Binary file not shown.

BIN
windows/git2.exp Normal file

Binary file not shown.

BIN
windows/git2.lib Normal file

Binary file not shown.

BIN
windows/git2.pdb Normal file

Binary file not shown.

35
windows/helloworld.lpr Normal file
View File

@ -0,0 +1,35 @@
{%RunFlags MESSAGES+}
{$mode ObjFPC}{$H-}
program helloworld(output);
uses
TariffCalculator, CTypes;
var
TariffCalc: TariffCalculatorHandle;
CustomerRepo: array[0..100] of char;
LocalCustomerRepo: array[0..100] of char;
begin
writeLn('Hello, World!') ;
// TariffCalc := NewTariffCalculator;
// DeleteTariffCalculator(TariffCalc);
if InitGitLibrary() > 0 then
begin
writeLn('init OK!') ;
CustomerRepo := 'https://git.mimbach49.de/GerhardHoffmann/customer_999.git';
LocalCustomerRepo := 'C:\\tmp\\customer_999';
CloneRepository(CustomerRepo, LocalCustomerRepo);
ShutdownGitLibrary();
end
else
begin
writeLn('init NOT OK!') ;
Readln;
end;
end.

View File

@ -0,0 +1,35 @@
unit TariffCalculator;
{$mode ObjFPC}{$H-}
interface
uses
SysUtils, CTypes;
type
// Can't use the class directly, so it is treated as an opaque handle.
// THandle is guaranteed to have the right size, even on other platforms.
TariffCalculatorHandle = THandle;
function NewTariffCalculator: TariffCalculatorHandle; stdcall;
procedure DeleteTariffCalculator(handle: TariffCalculatorHandle); stdcall;
function InitGitLibrary: cint32; stdcall;
function ShutdownGitLibrary: cint32; stdcall;
function CloneRepository(var url; var local_path) : cint32; stdcall;
implementation
const
DLLName = 'CalculatorCInterface.dll';
function NewTariffCalculator: TariffCalculatorHandle; stdcall; external DLLName;
procedure DeleteTariffCalculator(handle: TariffCalculatorHandle); stdcall; external DLLName;
function InitGitLibrary: cint32; stdcall; external DLLName;
function ShutdownGitLibrary: cint32; stdcall; external DLLName;
function CloneRepository(var url; var local_path) : cint32; stdcall; external DLLName;
end.