mirror of
https://github.com/QuasarApp/Patronum.git
synced 2025-04-27 16:14:32 +00:00
Merge pull request #4 from QuasarApp/HanoiTowersPatch
[WIP] Hanoi Towers Patch
This commit is contained in:
commit
f7ea0538ee
15
.gitignore
vendored
15
.gitignore
vendored
@ -53,3 +53,18 @@ compile_commands.json
|
||||
|
||||
# QtCreator local machine specific files for imported projects
|
||||
*creator.user*
|
||||
|
||||
#cmake
|
||||
|
||||
CMakeLists.txt.user
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
CMakeScripts
|
||||
Testing
|
||||
Makefile
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
*_autogen
|
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -1,6 +1,4 @@
|
||||
[submodule "Patronum/QuasarAppLib"]
|
||||
path = Patronum/QuasarAppLib
|
||||
url = https://github.com/QuasarApp/QuasarAppLib.git
|
||||
[submodule "res/DoxyStyle"]
|
||||
path = res/DoxyStyle
|
||||
url = https://github.com/QuasarApp/DoxyStyle.git
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2018-2020 QuasarApp.
|
||||
# Copyright (C) 2018-2021 QuasarApp.
|
||||
# Distributed under the lgplv3 software license, see the accompanying
|
||||
# Everyone is permitted to copy and distribute verbatim copies
|
||||
# of this license document, but changing it is not allowed.
|
||||
@ -12,10 +12,31 @@ if(TARGET ${PROJECT_NAME})
|
||||
return()
|
||||
endif()
|
||||
|
||||
|
||||
include(Patronum/QuasarAppLib/CMake/ccache.cmake)
|
||||
# Add sub directories
|
||||
add_subdirectory(Patronum)
|
||||
add_subdirectory(Tests)
|
||||
|
||||
if (NOT DEFINED PATRONUM_TESTS)
|
||||
set(PATRONUM_TESTS ON)
|
||||
|
||||
if (DEFINED TARGET_PLATFORM_TOOLCHAIN)
|
||||
if (${TARGET_PLATFORM_TOOLCHAIN} STREQUAL "wasm32")
|
||||
set(PATRONUM_TESTS OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (ANDROID)
|
||||
set(PATRONUM_TESTS OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
if (PATRONUM_TESTS)
|
||||
add_subdirectory(Tests)
|
||||
else()
|
||||
message("The ${PROJECT_NAME} tests is disabled.")
|
||||
endif()
|
||||
|
||||
include(Patronum/QuasarAppLib/CMake/QuasarAppCITargets.cmake)
|
||||
initAll()
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2018-2020 QuasarApp.
|
||||
# Copyright (C) 2018-2021 QuasarApp.
|
||||
# Distributed under the lgplv3 software license, see the accompanying
|
||||
# Everyone is permitted to copy and distribute verbatim copies
|
||||
# of this license document, but changing it is not allowed.
|
||||
@ -8,21 +8,23 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
set(CURRENT_PROJECT ${PROJECT_NAME})
|
||||
|
||||
add_subdirectory(QuasarAppLib)
|
||||
|
||||
include(QuasarAppLib/CMake/ProjectOut.cmake)
|
||||
include(QuasarAppLib/CMake/Version.cmake)
|
||||
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
add_definitions(-DPATRONUM_LIBRARY)
|
||||
|
||||
find_package(Qt5 COMPONENTS Core Network REQUIRED)
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Network REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Network REQUIRED)
|
||||
|
||||
add_subdirectory(QuasarAppLib)
|
||||
|
||||
add_definitions(-DPATRONUM_LIBRARY)
|
||||
|
||||
file(GLOB SOURCE_CPP
|
||||
"src/*.cpp"
|
||||
@ -32,8 +34,8 @@ file(GLOB SOURCE_CPP
|
||||
|
||||
)
|
||||
|
||||
add_library(${CURRENT_PROJECT} SHARED ${SOURCE_CPP})
|
||||
target_link_libraries(${CURRENT_PROJECT} PUBLIC Qt5::Core Qt5::Network QuasarApp)
|
||||
add_library(${CURRENT_PROJECT} ${SOURCE_CPP})
|
||||
target_link_libraries(${CURRENT_PROJECT} PUBLIC Qt::Core Qt::Network QuasarApp)
|
||||
target_include_directories(${CURRENT_PROJECT} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src")
|
||||
target_include_directories(${CURRENT_PROJECT} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src/Private")
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit c65aba63291c5b93b4457c5a14672a552b7f915f
|
||||
Subproject commit 693e0e99481bcbc0ffb00d384867880eae14bbf8
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
#include <QList>
|
||||
#include <QVariantMap>
|
||||
#include "Patronum_global.h"
|
||||
|
||||
namespace Patronum {
|
||||
|
||||
@ -34,7 +35,7 @@ enum class ControllerError {
|
||||
/**
|
||||
* @brief The IController class
|
||||
*/
|
||||
class IController
|
||||
class PATRONUM_LIBRARYSHARED_EXPORT IController
|
||||
{
|
||||
public:
|
||||
IController() = default;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
@ -9,22 +9,61 @@
|
||||
#define ISERVICE_H
|
||||
|
||||
#include <QList>
|
||||
#include "Patronum_global.h"
|
||||
|
||||
namespace Patronum {
|
||||
|
||||
class Feature;
|
||||
|
||||
class IService
|
||||
/**
|
||||
* @brief The IService class is base interface of the service.
|
||||
*/
|
||||
class PATRONUM_LIBRARYSHARED_EXPORT IService
|
||||
{
|
||||
public:
|
||||
IService();
|
||||
virtual ~IService() = default;
|
||||
|
||||
virtual void handleReceive(const QList<Feature>& data) = 0;
|
||||
virtual QList<Feature> supportedFeatures() = 0;
|
||||
/**
|
||||
* @brief handleReceiveData This method get all received comnads and proccess its.
|
||||
* For each command will invoke the handleReceive method.
|
||||
* @param data
|
||||
*/
|
||||
virtual void handleReceiveData(const QSet<Feature>& data) = 0;
|
||||
|
||||
/**
|
||||
* @brief handleReceive This method invoked when service receive a request from terminal.
|
||||
* Override this method for wor service.
|
||||
* @param data This is input data.
|
||||
* @return This method showld be return true if the @a data command is supported and processed succesful.
|
||||
* IF you return false then a negative message will be sent to a terminal app.
|
||||
*/
|
||||
virtual bool handleReceive(const Feature &data) = 0;
|
||||
|
||||
/**
|
||||
* @brief supportedFeatures Override this method for add your featores for the service.
|
||||
* @return should be return a set of supported Features.
|
||||
*/
|
||||
virtual QSet<Feature> supportedFeatures() = 0;
|
||||
|
||||
/**
|
||||
* @brief onStart This method invoked when service is started successful
|
||||
*/
|
||||
virtual void onStart() = 0;
|
||||
|
||||
/**
|
||||
* @brief onStop This method invoked when service receive stop command from the terminal
|
||||
*/
|
||||
virtual void onStop() = 0;
|
||||
|
||||
/**
|
||||
* @brief onResume This method invoked when service receive resume command from the terminal
|
||||
*/
|
||||
virtual void onResume() = 0;
|
||||
|
||||
/**
|
||||
* @brief onPause This method invoked when service receive pause command from the terminal
|
||||
*/
|
||||
virtual void onPause() = 0;
|
||||
};
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
@ -76,14 +76,14 @@ bool Controller::send() {
|
||||
return d_ptr->pause();
|
||||
}
|
||||
|
||||
QList<Feature> sendData = {};
|
||||
QSet<Feature> sendData = {};
|
||||
auto userParams = QuasarAppUtils::Params::getUserParamsMap();
|
||||
for (auto val = userParams.begin(); val != userParams.end(); ++val) {
|
||||
if (val.key() == "verbose" || val.key() == "fileLog" || val.key() == "exec") {
|
||||
continue;
|
||||
}
|
||||
|
||||
sendData += {val.key(), val.value()};
|
||||
sendData.insert(Feature{val.key(), val.value()});
|
||||
}
|
||||
|
||||
return d_ptr->sendCmd(sendData);
|
||||
@ -148,12 +148,12 @@ void Controller::printDefaultHelp() const {
|
||||
auto quasarappHelp = QuasarAppUtils::Params::getparamsHelp();
|
||||
|
||||
QuasarAppUtils::Help::Charters help{{"General options of this controller",{
|
||||
{"start", QObject::tr("Start a service")},
|
||||
{"stop", QObject::tr("Stop a service")},
|
||||
{"pause", QObject::tr("Pause a service")},
|
||||
{"resume", QObject::tr("Resume a service")},
|
||||
{"install", QObject::tr("Install a service")},
|
||||
{"uninstall", QObject::tr("Uninstall a service")}
|
||||
{"start", QObject::tr("Start a service")},
|
||||
{"stop", QObject::tr("Stop a service")},
|
||||
{"pause", QObject::tr("Pause a service")},
|
||||
{"resume", QObject::tr("Resume a service")},
|
||||
{"install", QObject::tr("Install a service")},
|
||||
{"uninstall", QObject::tr("Uninstall a service")}
|
||||
}}};
|
||||
|
||||
QuasarAppUtils::Help::print(quasarappHelp.unite(help));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
@ -11,12 +11,12 @@
|
||||
|
||||
namespace Patronum {
|
||||
|
||||
Feature::Feature(const QString &cmd, const QVariant &arg,
|
||||
Feature::Feature(const QString &cmd, const QString &arg,
|
||||
const QString &description, const QString &example) {
|
||||
_cmd = cmd;
|
||||
_arg = arg;
|
||||
_description = description;
|
||||
_example = example;
|
||||
setCmd(cmd);
|
||||
setArg(arg);
|
||||
setDescription(description);
|
||||
setExample(example);
|
||||
}
|
||||
|
||||
QString Feature::cmd() const {
|
||||
@ -25,13 +25,14 @@ QString Feature::cmd() const {
|
||||
|
||||
void Feature::setCmd(const QString &cmd) {
|
||||
_cmd = cmd;
|
||||
_id = qHash(_cmd);
|
||||
}
|
||||
|
||||
QVariant Feature::arg() const {
|
||||
QString Feature::arg() const {
|
||||
return _arg;
|
||||
}
|
||||
|
||||
void Feature::setArg(const QVariantList &arg) {
|
||||
void Feature::setArg(const QString &arg) {
|
||||
_arg = arg;
|
||||
}
|
||||
|
||||
@ -58,6 +59,10 @@ QString Feature::toString() const {
|
||||
return _cmd;
|
||||
}
|
||||
|
||||
unsigned int Feature::id() const {
|
||||
return _id;
|
||||
}
|
||||
|
||||
QDataStream &operator<<(QDataStream &stream, const Feature &obj) {
|
||||
stream << obj._cmd << obj._arg;
|
||||
|
||||
@ -65,8 +70,22 @@ QDataStream &operator<<(QDataStream &stream, const Feature &obj) {
|
||||
}
|
||||
|
||||
QDataStream &operator>>(QDataStream &stream, Feature &obj) {
|
||||
stream >> obj._cmd >> obj._arg;
|
||||
decltype (obj._cmd) cmd;
|
||||
stream >> cmd >> obj._arg;
|
||||
obj.setCmd(cmd);
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
bool operator==(const Feature &left, const Feature &right) {
|
||||
return left.id() == right.id();
|
||||
}
|
||||
|
||||
|
||||
uint qHash(const Feature &feature) {
|
||||
return feature.id();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
@ -21,33 +21,83 @@ namespace Patronum {
|
||||
class PATRONUM_LIBRARYSHARED_EXPORT Feature
|
||||
{
|
||||
public:
|
||||
Feature() = default;
|
||||
Feature(const QString& cmd, const QVariant& arg = {},
|
||||
explicit Feature() = default;
|
||||
explicit Feature(const QString& cmd, const QString& arg = {},
|
||||
const QString& description = "", const QString& example = "");
|
||||
|
||||
/**
|
||||
* @brief cmd This method return command of the feature
|
||||
* @return command of the feature
|
||||
*/
|
||||
QString cmd() const;
|
||||
|
||||
/**
|
||||
* @brief setCmd This method set new value of the command.
|
||||
* @param cmd
|
||||
*/
|
||||
void setCmd(const QString &cmd);
|
||||
|
||||
QVariant arg() const;
|
||||
void setArg(const QVariantList &arg);
|
||||
/**
|
||||
* @brief arg This method return argument value.
|
||||
* The argument value has a qvariant type, so this object maybe have a list or array type.
|
||||
* @return argument value.
|
||||
*/
|
||||
QString arg() const;
|
||||
void setArg(const QString &arg);
|
||||
|
||||
friend QDataStream& operator<<(QDataStream& stream, const Feature& obj);
|
||||
friend QDataStream& operator>>(QDataStream& stream, Feature& obj);
|
||||
PATRONUM_LIBRARYSHARED_EXPORT friend QDataStream& operator<<(QDataStream& stream, const Feature& obj);
|
||||
PATRONUM_LIBRARYSHARED_EXPORT friend QDataStream& operator>>(QDataStream& stream, Feature& obj);
|
||||
PATRONUM_LIBRARYSHARED_EXPORT friend bool operator==(const Feature& left, const Feature& right);
|
||||
|
||||
/**
|
||||
* @brief description This method return description message of the command.
|
||||
* This string display in a teminal application in the help section.
|
||||
* @return description message of the command
|
||||
*/
|
||||
QString description() const;
|
||||
|
||||
/**
|
||||
* @brief setDescription This method sets description for command.
|
||||
* @param description tihs is new value of the description command.
|
||||
*/
|
||||
void setDescription(const QString &description);
|
||||
|
||||
/**
|
||||
* @brief example This is exmaple of using this command.
|
||||
* @return example of use.
|
||||
*/
|
||||
QString example() const;
|
||||
|
||||
/**
|
||||
* @brief setExample This method sets a new example
|
||||
* @param example This is a new example value.
|
||||
*/
|
||||
void setExample(const QString &example);
|
||||
|
||||
/**
|
||||
* @brief toString This is general method of the converting command to string.
|
||||
* @return string of all command.
|
||||
*/
|
||||
QString toString() const;
|
||||
|
||||
/**
|
||||
* @brief id This method retun id of the feature. The id is qHash from command string.
|
||||
* @return id of the feature.
|
||||
*/
|
||||
unsigned int id() const;
|
||||
|
||||
private:
|
||||
|
||||
unsigned int _id;
|
||||
QString _cmd;
|
||||
QString _description;
|
||||
QString _example;
|
||||
QVariant _arg;
|
||||
QString _arg;
|
||||
};
|
||||
|
||||
uint PATRONUM_LIBRARYSHARED_EXPORT qHash(const Feature& feature);
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif // FEaTURE_H
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
@ -22,7 +22,7 @@ template<class Application>
|
||||
* ###How to use :
|
||||
* - just inherit from the Service class and override the methods you need.
|
||||
*/
|
||||
class PATRONUM_LIBRARYSHARED_EXPORT Service : public ServiceBase
|
||||
class Service : public ServiceBase
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
@ -7,6 +7,7 @@
|
||||
|
||||
#include "PServiceBase.h"
|
||||
#include <QCoreApplication>
|
||||
#include <QLibraryInfo>
|
||||
#include <QTimer>
|
||||
#include "PController.h"
|
||||
#include "serviceprivate.h"
|
||||
@ -24,33 +25,42 @@ ServiceBase::~ServiceBase() {
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
void ServiceBase::handleReceive(const QList<Feature> &data) {
|
||||
|
||||
void ServiceBase::handleReceiveData(const QSet<Feature> &data) {
|
||||
auto list = supportedFeatures();
|
||||
|
||||
QStringList stringList;
|
||||
|
||||
for (const auto&i : list) {
|
||||
stringList += i.toString();
|
||||
}
|
||||
|
||||
QVariantMap result;
|
||||
|
||||
QString commandList;
|
||||
for (const auto&i : data ) {
|
||||
commandList += i.toString() + " ";
|
||||
|
||||
for (const auto& i: data) {
|
||||
if (list.contains(i)) {
|
||||
if (!handleReceive(i)) {
|
||||
sendResuylt(QString("The process of a command %0 with argumets: %1 is failed")
|
||||
.arg(i.cmd()).arg(i.arg()));
|
||||
}
|
||||
} else {
|
||||
commandList += i.toString() + " ";
|
||||
}
|
||||
}
|
||||
|
||||
result["Error"] = "Wrong command! The commands : " + commandList + " is not supported";
|
||||
result["Available commands"] = stringList;
|
||||
if (commandList.size()) {
|
||||
QStringList stringList;
|
||||
|
||||
for (const auto&i : list) {
|
||||
stringList += i.toString();
|
||||
}
|
||||
|
||||
QVariantMap result;
|
||||
|
||||
result["Error"] = "Wrong command! The commands : " + commandList + " is not supported";
|
||||
result["Available commands"] = stringList;
|
||||
|
||||
sendResuylt(result);
|
||||
}
|
||||
|
||||
sendResuylt(result);
|
||||
|
||||
}
|
||||
|
||||
QList<Feature> ServiceBase::supportedFeatures() {
|
||||
QList<Feature> result;
|
||||
return result;
|
||||
QSet<Feature> ServiceBase::supportedFeatures() {
|
||||
return {};
|
||||
}
|
||||
|
||||
bool ServiceBase::sendResuylt(const QVariantMap &result) {
|
||||
@ -61,6 +71,10 @@ bool ServiceBase::sendResuylt(const QString &result) {
|
||||
return d_ptr->sendCmdResult({{"Result", result}});
|
||||
}
|
||||
|
||||
bool ServiceBase::sendCloseeConnetion() {
|
||||
return d_ptr->sendCloseConnection();
|
||||
}
|
||||
|
||||
void ServiceBase::onStop() {
|
||||
sendResuylt("Success! Use default stop function");
|
||||
QCoreApplication::quit();
|
||||
@ -75,12 +89,14 @@ void ServiceBase::onPause() {
|
||||
sendResuylt("This function not supported");
|
||||
}
|
||||
|
||||
Controller *ServiceBase::controller() const {
|
||||
Controller *ServiceBase::controller() {
|
||||
if (_controller)
|
||||
return _controller;
|
||||
|
||||
return new Controller(_serviceName,
|
||||
QuasarAppUtils::Params::getCurrentExecutable());
|
||||
_controller = new Controller(_serviceName,
|
||||
QuasarAppUtils::Params::getCurrentExecutable());
|
||||
|
||||
return _controller;
|
||||
}
|
||||
|
||||
int ServiceBase::exec() {
|
||||
@ -88,24 +104,26 @@ int ServiceBase::exec() {
|
||||
createApplication();
|
||||
}
|
||||
|
||||
if (!QuasarAppUtils::Params::customParamasSize()) {
|
||||
bool fExec = QuasarAppUtils::Params::isEndable("exec") || QuasarAppUtils::Params::isDebugBuild();
|
||||
|
||||
if (!(QuasarAppUtils::Params::customParamasSize() || fExec)) {
|
||||
return controller()->startDetached();
|
||||
}
|
||||
|
||||
if (QuasarAppUtils::Params::isEndable("exec")) {
|
||||
QTimer::singleShot(0, [this](){
|
||||
if (fExec) {
|
||||
QTimer::singleShot(0, nullptr, [this](){
|
||||
onStart();
|
||||
d_ptr->listen();
|
||||
|
||||
});
|
||||
} else {
|
||||
QTimer::singleShot(0, nullptr, [this](){
|
||||
if (!controller()->send()) {
|
||||
_core->exit(static_cast<int>(ControllerError::ServiceUnavailable));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
QTimer::singleShot(0, [this](){
|
||||
if (!controller()->send()) {
|
||||
_core->exit(static_cast<int>(ControllerError::ServiceUnavailable));
|
||||
}
|
||||
});
|
||||
|
||||
return _core->exec();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
@ -42,17 +42,17 @@ public:
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief handleReceive - this method invoce when service receive new command from terminal of controller of this service
|
||||
* @brief handleReceiveData - this method invoce when service receive new command from terminal of controller of this service.
|
||||
* @param data - is list of commands from controller
|
||||
* Default inplementation send message abount error.
|
||||
* Default inplementation send message abount error, and invoke the .
|
||||
*/
|
||||
void handleReceive(const QList<Feature> &data) override;
|
||||
void handleReceiveData(const QSet<Feature> &data) override final;
|
||||
|
||||
/**
|
||||
* @brief supportedFeatures
|
||||
* @return list of supported features of this service. override this method for correctly work of your pair (service and controller)
|
||||
* @return a set supported features of this service. Override this method for correctly work of your pair (service and controller)
|
||||
*/
|
||||
QList<Feature> supportedFeatures() override;
|
||||
QSet<Feature> supportedFeatures() override;
|
||||
|
||||
/**
|
||||
* @brief sendResuylt - call this method for send responce from service to tour controller
|
||||
@ -68,6 +68,12 @@ protected:
|
||||
*/
|
||||
bool sendResuylt(const QString &result);
|
||||
|
||||
/**
|
||||
* @brief sendCloseeConnetion This method send signal that all request command processed.
|
||||
* @return return true if the message sent successul.
|
||||
*/
|
||||
bool sendCloseeConnetion();
|
||||
|
||||
/**
|
||||
* @brief createApplication default implementation create a Application object and parse argumnts.
|
||||
*/
|
||||
@ -97,11 +103,12 @@ protected:
|
||||
* @brief controller
|
||||
* @return own controller instance;
|
||||
*/
|
||||
Controller *controller() const;
|
||||
Controller *controller();
|
||||
|
||||
QCoreApplication *_core = nullptr;
|
||||
private:
|
||||
|
||||
|
||||
ServicePrivate *d_ptr = nullptr;
|
||||
Controller *_controller = nullptr;
|
||||
QString _serviceName = "";
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
@ -14,6 +14,7 @@
|
||||
#include <quasarapp.h>
|
||||
#include "package.h"
|
||||
#include "installersystemd.h"
|
||||
#include "parser.h"
|
||||
|
||||
namespace Patronum {
|
||||
|
||||
@ -23,6 +24,7 @@ ControllerPrivate::ControllerPrivate(const QString &name, const QString &service
|
||||
_socket = new LocalSocket(name, this);
|
||||
_serviceExe = servicePath;
|
||||
_controller = controller;
|
||||
_parser = new Parser();
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
_installer = new InstallerSystemD(name);
|
||||
@ -37,6 +39,7 @@ ControllerPrivate::~ControllerPrivate() {
|
||||
if (_installer) {
|
||||
delete _installer;
|
||||
}
|
||||
delete _parser;
|
||||
}
|
||||
|
||||
bool ControllerPrivate::sendFeaturesRequest() {
|
||||
@ -47,15 +50,10 @@ bool ControllerPrivate::sendFeaturesRequest() {
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray responce;
|
||||
QDataStream stream(&responce, QIODevice::WriteOnly);
|
||||
|
||||
stream << static_cast<quint8>(Command::FeaturesRequest);
|
||||
|
||||
return _socket->send(responce);
|
||||
return _socket->send(_parser->createPackage(Command::FeaturesRequest));
|
||||
}
|
||||
|
||||
bool ControllerPrivate::sendCmd(const QList<Feature> &result) {
|
||||
bool ControllerPrivate::sendCmd(const QSet<Feature> &result) {
|
||||
if (!_socket->isValid()) {
|
||||
QuasarAppUtils::Params::log("scoket is closed!",
|
||||
QuasarAppUtils::Debug);
|
||||
@ -64,13 +62,7 @@ bool ControllerPrivate::sendCmd(const QList<Feature> &result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray request;
|
||||
QDataStream stream(&request, QIODevice::WriteOnly);
|
||||
|
||||
stream << static_cast<quint8>(Command::Feature);
|
||||
stream << result;
|
||||
|
||||
if (_socket->send(request)) {
|
||||
if (_socket->send(_parser->createPackage(Command::Feature, result))) {
|
||||
_responce = false;
|
||||
return true;
|
||||
}
|
||||
@ -190,70 +182,68 @@ bool ControllerPrivate::connectToHost() const {
|
||||
|
||||
void ControllerPrivate::handleReceve(QByteArray data) {
|
||||
|
||||
const Package package = Package::parsePackage(data);
|
||||
|
||||
if (!package.isValid()) {
|
||||
|
||||
QuasarAppUtils::Params::log("Received invalid package!",
|
||||
QuasarAppUtils::Debug);
|
||||
|
||||
_controller->handleError(ControllerError::InvalidPackage);
|
||||
|
||||
if (!_controller) {
|
||||
QuasarAppUtils::Params::log("System error, controller is not inited!",
|
||||
QuasarAppUtils::Error);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (package.cmd()) {
|
||||
QList<Package> packages;
|
||||
if (!_parser->parse(data, packages)) {
|
||||
return;
|
||||
}
|
||||
|
||||
case Command::Features: {
|
||||
for (const auto& pkg: qAsConst(packages)) {
|
||||
if (!pkg.isValid()) {
|
||||
|
||||
if (!_controller) {
|
||||
QuasarAppUtils::Params::log("System error, controller is not inited!",
|
||||
QuasarAppUtils::Params::log("Received invalid package!",
|
||||
QuasarAppUtils::Debug);
|
||||
_controller->handleError(ControllerError::SystemError);
|
||||
|
||||
_controller->handleError(ControllerError::InvalidPackage);
|
||||
|
||||
continue;;
|
||||
}
|
||||
|
||||
switch (pkg.cmd()) {
|
||||
|
||||
case Command::Features: {
|
||||
|
||||
QDataStream stream(pkg.data());
|
||||
|
||||
QList<Feature> features;
|
||||
stream >> features;
|
||||
_features = features;
|
||||
|
||||
_controller->handleFeatures(features);
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case Command::CloseConnection: {
|
||||
_responce = true;
|
||||
break;
|
||||
}
|
||||
|
||||
QDataStream stream(package.data());
|
||||
case Command::FeatureResponce: {
|
||||
|
||||
QList<Feature> features;
|
||||
stream >> features;
|
||||
_features = features;
|
||||
QDataStream stream(pkg.data());
|
||||
|
||||
_responce = true;
|
||||
|
||||
_controller->handleFeatures(features);
|
||||
QVariantMap responce;
|
||||
stream >> responce;
|
||||
_controller->handleResponce(responce);
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case Command::FeatureResponce: {
|
||||
if (!_controller) {
|
||||
QuasarAppUtils::Params::log("System error, controller is not inited!",
|
||||
QuasarAppUtils::Error);
|
||||
_controller->handleError(ControllerError::SystemError);
|
||||
}
|
||||
default: {
|
||||
QuasarAppUtils::Params::log("Wrong command!",
|
||||
QuasarAppUtils::Debug);
|
||||
_controller->handleError(ControllerError::WrongCommand);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
QDataStream stream(package.data());
|
||||
|
||||
_responce = true;
|
||||
|
||||
QVariantMap responce;
|
||||
stream >> responce;
|
||||
_controller->handleResponce(responce);
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
default: {
|
||||
QuasarAppUtils::Params::log("Wrong command!",
|
||||
QuasarAppUtils::Debug);
|
||||
_controller->handleError(ControllerError::WrongCommand);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
@ -14,6 +14,7 @@ namespace Patronum {
|
||||
class IController;
|
||||
class LocalSocket;
|
||||
class Installer;
|
||||
class Parser;
|
||||
|
||||
class ControllerPrivate: public QObject
|
||||
{
|
||||
@ -23,7 +24,7 @@ public:
|
||||
IController* controller = nullptr, QObject *parent = nullptr);
|
||||
~ControllerPrivate();
|
||||
bool sendFeaturesRequest();
|
||||
bool sendCmd(const QList<Feature>& result);
|
||||
bool sendCmd(const QSet<Feature> &result);
|
||||
|
||||
int start() const;
|
||||
bool stop();
|
||||
@ -44,12 +45,14 @@ signals:
|
||||
void sigListFeatures(QList<Feature>);
|
||||
|
||||
private:
|
||||
|
||||
LocalSocket *_socket = nullptr;
|
||||
IController *_controller = nullptr;
|
||||
bool _responce = false;
|
||||
QList<Feature> _features;
|
||||
QString _serviceExe = "";
|
||||
Installer *_installer = nullptr;
|
||||
Parser * _parser;
|
||||
|
||||
private slots:
|
||||
void handleReceve(QByteArray data);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
@ -19,7 +19,15 @@ LocalSocket::LocalSocket(const QString &target, QObject *ptr):
|
||||
}
|
||||
|
||||
LocalSocket::~LocalSocket() {
|
||||
if (m_server) {
|
||||
m_server->close();
|
||||
delete m_server;
|
||||
}
|
||||
|
||||
if (m_socket) {
|
||||
m_socket->close();
|
||||
delete m_socket;
|
||||
}
|
||||
}
|
||||
|
||||
bool LocalSocket::registerSokcet(QLocalSocket *socket) {
|
||||
@ -34,7 +42,7 @@ bool LocalSocket::registerSokcet(QLocalSocket *socket) {
|
||||
connect(m_socket, &QLocalSocket::readyRead,
|
||||
this, &LocalSocket::handleReadyRead);
|
||||
|
||||
connect(m_socket, qOverload<QLocalSocket::LocalSocketError>(&QLocalSocket::error),
|
||||
connect(m_socket, qOverload<QLocalSocket::LocalSocketError>(&QLocalSocket::errorOccurred),
|
||||
this, &LocalSocket::handleSocketError);
|
||||
|
||||
handleStateChanged(m_socket->state());
|
||||
@ -105,10 +113,11 @@ void LocalSocket::handleReadyRead() {
|
||||
|
||||
void LocalSocket::handleIncomming() {
|
||||
if (m_socket) {
|
||||
m_socket->disconnect();
|
||||
m_socket->close();
|
||||
m_socket->deleteLater();
|
||||
m_socket = nullptr;
|
||||
}
|
||||
|
||||
registerSokcet(m_server->nextPendingConnection());
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
@ -10,29 +10,29 @@
|
||||
namespace Patronum {
|
||||
|
||||
Command Package::cmd() const {
|
||||
return static_cast<Command>(m_cmd);
|
||||
return static_cast<Command>(m_hdr.cmd);
|
||||
}
|
||||
|
||||
QByteArray Package::data() const {
|
||||
const QByteArray &Package::data() const {
|
||||
return m_data;
|
||||
}
|
||||
|
||||
bool Package::isValid() const {
|
||||
return m_cmd <= static_cast<int>(Command::FeatureResponce);
|
||||
return m_hdr.isValid() && m_hdr.size == m_data.size();
|
||||
}
|
||||
|
||||
void Package::reset() {
|
||||
m_hdr = {0, 0};
|
||||
m_data.clear();
|
||||
}
|
||||
|
||||
Package::Package() {
|
||||
reset();
|
||||
}
|
||||
|
||||
Package Package::parsePackage(const QByteArray &data) {
|
||||
if (!data.size()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
Package pkg;
|
||||
pkg.m_cmd = static_cast<unsigned char>(data.at(0));
|
||||
pkg.m_data = data.right(data.size() - sizeof (pkg.m_cmd));
|
||||
return pkg;
|
||||
bool Header::isValid() const {
|
||||
return cmd && cmd <= static_cast<int>(Command::CloseConnection);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
@ -11,16 +11,46 @@
|
||||
#include <QDataStream>
|
||||
#include <PFeature.h>
|
||||
#include <QVariantMap>
|
||||
#include <QIODevice>
|
||||
|
||||
namespace Patronum {
|
||||
|
||||
class Feature;
|
||||
|
||||
/**
|
||||
* @brief The Command enum This is base commands for sending
|
||||
*/
|
||||
enum class Command: quint8 {
|
||||
/// This is invalid command
|
||||
Undefined,
|
||||
/// This comand is request for the available command of the service
|
||||
FeaturesRequest,
|
||||
/// This comand is response of the FeaturesRequest command
|
||||
Features,
|
||||
/// This is request to execute command
|
||||
Feature,
|
||||
FeatureResponce
|
||||
/// This is response of the execute of command
|
||||
FeatureResponce,
|
||||
/// This command is finished command for the terminal. after receive this command terminal will closse connection.
|
||||
/// @note For Devs This commnad should be last in the enum. This commnad uses in te validation of header.
|
||||
CloseConnection
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The Header struct have as size 2 byte. maximus package size is 4095 bytes.
|
||||
*/
|
||||
struct Header {
|
||||
/**
|
||||
* @brief size This is size of package data (exclude header size).
|
||||
*/
|
||||
unsigned short size: 12;
|
||||
|
||||
/**
|
||||
* @brief cmd This is workCommand
|
||||
*/
|
||||
unsigned char cmd: 4;
|
||||
|
||||
bool isValid() const;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -30,27 +60,36 @@ enum class Command: quint8 {
|
||||
class Package
|
||||
{
|
||||
public:
|
||||
Package();
|
||||
/**
|
||||
* @brief cmd This method return command of the package.
|
||||
* @return command of the package.
|
||||
*/
|
||||
Command cmd() const;
|
||||
QByteArray data() const;
|
||||
|
||||
/**
|
||||
* @brief data This method return referense to the bytes array of the pacakge data.
|
||||
* @return bytes array of the pacakge data.
|
||||
*/
|
||||
const QByteArray& data() const;
|
||||
|
||||
/**
|
||||
* @brief isValid This method check this pacakge.
|
||||
* @return true if the package is valid.
|
||||
*/
|
||||
bool isValid() const;
|
||||
|
||||
template<class DATA>
|
||||
static QByteArray createPackage(Command cmd, const DATA &data) {
|
||||
QByteArray result;
|
||||
QDataStream stream(&result, QIODevice::WriteOnly);
|
||||
|
||||
stream << cmd;
|
||||
stream << data;
|
||||
|
||||
return result;
|
||||
}
|
||||
static Package parsePackage(const QByteArray& data);
|
||||
/**
|
||||
* @brief reset This method reset all fields of the package to default value.
|
||||
* @note after invoke this method package will be invalid.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
private:
|
||||
Package();
|
||||
|
||||
unsigned char m_cmd;
|
||||
Header m_hdr;
|
||||
QByteArray m_data;
|
||||
|
||||
friend class Parser;
|
||||
};
|
||||
|
||||
}
|
||||
|
72
Patronum/src/Private/parser.cpp
Normal file
72
Patronum/src/Private/parser.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
#include "parser.h"
|
||||
#include <quasarapp.h>
|
||||
namespace Patronum {
|
||||
|
||||
Parser::Parser() { }
|
||||
|
||||
bool Parser::parse(const QByteArray &array,
|
||||
QList<Package> &result) {
|
||||
|
||||
if (!array.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int workIndex = 0;
|
||||
const int headerSize = sizeof(Header);
|
||||
|
||||
const auto workArray = _hdrArray + array;
|
||||
const int arraySize = workArray.size();
|
||||
|
||||
while (arraySize > workIndex) {
|
||||
int offset = arraySize - workIndex;
|
||||
if (_data.m_hdr.isValid()) {
|
||||
// CASE 1: The Package data is still not collected, but the header is already collected. performs full or partial filling of packet data.
|
||||
|
||||
int dataLength = std::min(static_cast<int>(_data.m_hdr.size - _data.m_data.size()),
|
||||
arraySize - workIndex);
|
||||
_data.m_data.append(array.mid(workIndex + headerSize, dataLength));
|
||||
|
||||
workIndex += dataLength;
|
||||
|
||||
|
||||
} else if (offset >= headerSize) {
|
||||
|
||||
// CASE 2: The header and package still do not exist and the amount of data allows you to create a new header. A header is created and will fill in all or part of the package data.
|
||||
|
||||
_data.reset();
|
||||
|
||||
memcpy(&_data.m_hdr,
|
||||
array.data() + workIndex, headerSize);
|
||||
|
||||
int dataLength = std::min(static_cast<int>(_data.m_hdr.size),
|
||||
arraySize - headerSize - workIndex);
|
||||
|
||||
_data.m_data.append(array.mid(workIndex + headerSize, dataLength));
|
||||
workIndex += headerSize + dataLength;
|
||||
|
||||
} else {
|
||||
// CASE 3: There is not enough data to initialize the header. The data will be placed in temporary storage and will be processed the next time the data is received.
|
||||
|
||||
unsigned char dataLength = static_cast<unsigned char>(arraySize - workIndex);
|
||||
_hdrArray += array.mid(workIndex, dataLength);
|
||||
workIndex += dataLength;
|
||||
}
|
||||
|
||||
if (_data.isValid()) {
|
||||
result.push_back(_data);
|
||||
_data.reset();
|
||||
_hdrArray.clear();
|
||||
}
|
||||
|
||||
if (_data.m_data.size() > _data.m_hdr.size) {
|
||||
QuasarAppUtils::Params::log("Invalid Package received. ",
|
||||
QuasarAppUtils::Warning);
|
||||
_data.reset();
|
||||
_hdrArray.clear();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
52
Patronum/src/Private/parser.h
Normal file
52
Patronum/src/Private/parser.h
Normal file
@ -0,0 +1,52 @@
|
||||
#ifndef PARSER_H
|
||||
#define PARSER_H
|
||||
|
||||
#include <QByteArray>
|
||||
#include "package.h"
|
||||
|
||||
namespace Patronum {
|
||||
|
||||
/**
|
||||
* @brief The Parser class This is package parser of the Patronum packages.
|
||||
*/
|
||||
class Parser
|
||||
{
|
||||
public:
|
||||
Parser();
|
||||
|
||||
/**
|
||||
* @brief parse This method parse input data array @a array to the @result packages.
|
||||
* @param array This is input data.
|
||||
* @param result This is result packages.
|
||||
* @return return true if parse finished successful
|
||||
*/
|
||||
bool parse(const QByteArray& array, QList<Package>& result);
|
||||
|
||||
template<class DATA = QByteArray>
|
||||
/**
|
||||
* @brief createPackage This method create a custom package with @a cmd and @a data
|
||||
* @param cmd This is package command.
|
||||
* @param data This is data object.
|
||||
* @return bytes arra of the package.
|
||||
*/
|
||||
QByteArray createPackage(Command cmd, const DATA &data = {}) {
|
||||
QByteArray result;
|
||||
QDataStream stream(&result, QIODevice::WriteOnly);
|
||||
|
||||
Header hdr;
|
||||
hdr.cmd = static_cast<unsigned char>(cmd);
|
||||
|
||||
stream << data;
|
||||
hdr.size = result.size();
|
||||
result.insert(0, reinterpret_cast<char*>(&hdr), sizeof (hdr));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
Package _data;
|
||||
QByteArray _hdrArray;
|
||||
|
||||
};
|
||||
}
|
||||
#endif // PARSER_H
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
@ -13,6 +13,7 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QTimer>
|
||||
#include <quasarapp.h>
|
||||
#include "parser.h"
|
||||
|
||||
namespace Patronum {
|
||||
|
||||
@ -22,11 +23,16 @@ Patronum::ServicePrivate::ServicePrivate(const QString &name, IService *service,
|
||||
|
||||
_service = service;
|
||||
|
||||
_parser = new Parser();
|
||||
QObject::connect(_socket, &LocalSocket::sigReceve,
|
||||
this, &ServicePrivate::handleReceve);
|
||||
|
||||
}
|
||||
|
||||
ServicePrivate::~ServicePrivate() {
|
||||
delete _parser;
|
||||
}
|
||||
|
||||
bool ServicePrivate::sendCmdResult(const QVariantMap &result) {
|
||||
|
||||
if (!_socket->isValid()) {
|
||||
@ -35,7 +41,17 @@ bool ServicePrivate::sendCmdResult(const QVariantMap &result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return _socket->send(Package::createPackage(Command::FeatureResponce, result));
|
||||
return _socket->send(_parser->createPackage(Command::FeatureResponce, result));
|
||||
}
|
||||
|
||||
bool ServicePrivate::sendCloseConnection() {
|
||||
if (!_socket->isValid()) {
|
||||
QuasarAppUtils::Params::log("scoket is closed!",
|
||||
QuasarAppUtils::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
return _socket->send(_parser->createPackage(Command::CloseConnection));
|
||||
}
|
||||
|
||||
void ServicePrivate::listen() const {
|
||||
@ -45,7 +61,7 @@ void ServicePrivate::listen() const {
|
||||
};
|
||||
}
|
||||
|
||||
bool ServicePrivate::hendleStandartCmd(QList<Feature> *cmds) {
|
||||
bool ServicePrivate::handleStandartCmd(QSet<Feature> *cmds) {
|
||||
|
||||
if (!cmds)
|
||||
return false;
|
||||
@ -53,20 +69,17 @@ bool ServicePrivate::hendleStandartCmd(QList<Feature> *cmds) {
|
||||
if (!_service)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < cmds->size(); ++i) {
|
||||
if (cmds->value(i).cmd() == "stop") {
|
||||
_service->onStop();
|
||||
cmds->removeAt(i);
|
||||
i--;
|
||||
} else if (cmds->value(i).cmd() == "pause") {
|
||||
_service->onPause();
|
||||
cmds->removeAt(i);
|
||||
i--;
|
||||
} else if (cmds->value(i).cmd() == "resume") {
|
||||
_service->onResume();
|
||||
cmds->removeAt(i);
|
||||
i--;
|
||||
}
|
||||
if (cmds->contains(Feature{"stop"})) {
|
||||
_service->onStop();
|
||||
cmds->remove(Feature{"stop"});
|
||||
|
||||
} else if (cmds->contains(Feature{"pause"})) {
|
||||
_service->onPause();
|
||||
cmds->remove(Feature{"pause"});
|
||||
|
||||
} else if (cmds->contains(Feature{"resume"})) {
|
||||
_service->onResume();
|
||||
cmds->remove(Feature{"resume"});
|
||||
|
||||
}
|
||||
|
||||
@ -75,73 +88,69 @@ bool ServicePrivate::hendleStandartCmd(QList<Feature> *cmds) {
|
||||
|
||||
void ServicePrivate::handleReceve(QByteArray data) {
|
||||
|
||||
const Package package = Package::parsePackage(data);
|
||||
|
||||
if (!package.isValid()) {
|
||||
QuasarAppUtils::Params::log("receive package is not valid!",
|
||||
QuasarAppUtils::Warning);
|
||||
QList<Package> packages;
|
||||
if (!_parser->parse(data, packages)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (package.cmd()) {
|
||||
|
||||
case Command::FeaturesRequest: {
|
||||
for (const auto &pkg: qAsConst(packages)) {
|
||||
if (!pkg.isValid()) {
|
||||
QuasarAppUtils::Params::log("receive package is not valid!",
|
||||
QuasarAppUtils::Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_service) {
|
||||
QuasarAppUtils::Params::log("System error, service is not inited!",
|
||||
QuasarAppUtils::Error);
|
||||
break;
|
||||
return;;
|
||||
}
|
||||
|
||||
if (!_socket->isValid()) {
|
||||
QuasarAppUtils::Params::log("scoket is closed!",
|
||||
QuasarAppUtils::Error);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (pkg.cmd()) {
|
||||
|
||||
case Command::FeaturesRequest: {
|
||||
|
||||
if (!_socket->send(_parser->createPackage(Command::Features,
|
||||
_service->supportedFeatures()))) {
|
||||
QuasarAppUtils::Params::log("Fail to send ",
|
||||
QuasarAppUtils::Error);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
QList<Feature> features = _service->supportedFeatures();
|
||||
QByteArray sendData;
|
||||
QDataStream stream(&sendData, QIODevice::WriteOnly);
|
||||
case Command::Feature: {
|
||||
|
||||
stream << static_cast<quint8>(Command::Features);
|
||||
stream << features;
|
||||
QDataStream stream(pkg.data());
|
||||
|
||||
QSet<Feature> feature;
|
||||
stream >> feature;
|
||||
handleStandartCmd(&feature);
|
||||
|
||||
if (feature.size())
|
||||
_service->handleReceiveData(feature);
|
||||
|
||||
break;
|
||||
|
||||
if (!_socket->send(sendData)) {
|
||||
QuasarAppUtils::Params::log("scoket is closed!",
|
||||
QuasarAppUtils::Error);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case Command::Feature: {
|
||||
if (!_service) {
|
||||
QuasarAppUtils::Params::log("System error, service is not inited!",
|
||||
default: {
|
||||
QuasarAppUtils::Params::log("Wrong command!",
|
||||
QuasarAppUtils::Error);
|
||||
break;
|
||||
}
|
||||
|
||||
QDataStream stream(package.data());
|
||||
|
||||
QList<Feature> feature;
|
||||
stream >> feature;
|
||||
hendleStandartCmd(&feature);
|
||||
|
||||
if (feature.size())
|
||||
_service->handleReceive(feature);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
default: {
|
||||
QuasarAppUtils::Params::log("Wrong command!",
|
||||
QuasarAppUtils::Error);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
sendCloseConnection();
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
@ -14,6 +14,7 @@ namespace Patronum {
|
||||
|
||||
class LocalSocket;
|
||||
class IService;
|
||||
class Parser;
|
||||
|
||||
class ServicePrivate: public QObject
|
||||
{
|
||||
@ -21,8 +22,11 @@ class ServicePrivate: public QObject
|
||||
public:
|
||||
ServicePrivate(const QString& name,
|
||||
IService* service = nullptr, QObject *parent = nullptr);
|
||||
~ServicePrivate();
|
||||
|
||||
bool sendCmdResult(const QVariantMap& result);
|
||||
bool sendCloseConnection();
|
||||
|
||||
bool parseDefaultCmds();
|
||||
|
||||
void listen() const;
|
||||
@ -30,8 +34,9 @@ public:
|
||||
private:
|
||||
LocalSocket *_socket = nullptr;
|
||||
IService *_service = nullptr;
|
||||
Parser *_parser = nullptr;
|
||||
|
||||
bool hendleStandartCmd(QList<Feature> *cmds);
|
||||
bool handleStandartCmd(QSet<Feature> *cmds);
|
||||
|
||||
private slots:
|
||||
void handleReceve(QByteArray data);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2021 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2018-2020 QuasarApp.
|
||||
# Copyright (C) 2018-2021 QuasarApp.
|
||||
# Distributed under the lgplv3 software license, see the accompanying
|
||||
# Everyone is permitted to copy and distribute verbatim copies
|
||||
# of this license document, but changing it is not allowed.
|
||||
@ -17,14 +17,15 @@ set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
find_package(Qt5 COMPONENTS Core Test REQUIRED)
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Test REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Test REQUIRED)
|
||||
|
||||
file(GLOB SOURCE_CPP
|
||||
"*.cpp"
|
||||
)
|
||||
|
||||
add_executable(${CURRENT_PROJECT} ${SOURCE_CPP})
|
||||
target_link_libraries(${CURRENT_PROJECT} PRIVATE Qt5::Test Patronum)
|
||||
target_link_libraries(${CURRENT_PROJECT} PRIVATE Qt::Test Patronum )
|
||||
target_include_directories(${CURRENT_PROJECT} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
include(../Patronum/QuasarAppLib/CMake/QuasarAppCITargets.cmake)
|
||||
|
@ -16,22 +16,19 @@ void DefaultService::onStart() {
|
||||
QuasarAppUtils::Params::log("Server started!", QuasarAppUtils::Info);
|
||||
}
|
||||
|
||||
void DefaultService::handleReceive(const QList<Patronum::Feature> &data) {
|
||||
bool DefaultService::handleReceive(const Patronum::Feature &data) {
|
||||
|
||||
QList<Patronum::Feature> notSupportedList;
|
||||
for (const auto& i : data) {
|
||||
if (i.cmd() == "ping") {
|
||||
sendResuylt("pong");
|
||||
} else {
|
||||
notSupportedList += i;
|
||||
}
|
||||
if (data.cmd() == "ping") {
|
||||
sendResuylt("pong");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Patronum::Service<QCoreApplication>::handleReceive(notSupportedList);
|
||||
return false;
|
||||
}
|
||||
|
||||
QList<Patronum::Feature> DefaultService::supportedFeatures() {
|
||||
QList<Patronum::Feature> res;
|
||||
QSet<Patronum::Feature> DefaultService::supportedFeatures() {
|
||||
QSet<Patronum::Feature> res;
|
||||
res += Patronum::Feature("ping", {}, "test ping", "ping");
|
||||
|
||||
return res;
|
||||
|
@ -10,12 +10,12 @@ public:
|
||||
|
||||
// QtServiceBase interface
|
||||
protected:
|
||||
void onStart();
|
||||
void onStart() override;
|
||||
|
||||
// IService interface
|
||||
public:
|
||||
void handleReceive(const QList<Patronum::Feature> &data);
|
||||
QList<Patronum::Feature> supportedFeatures();
|
||||
bool handleReceive(const Patronum::Feature &data) override;
|
||||
QSet<Patronum::Feature> supportedFeatures() override;
|
||||
};
|
||||
|
||||
#endif // DEFAULTSERVICE_H
|
||||
|
@ -32,7 +32,9 @@ private slots:
|
||||
};
|
||||
|
||||
testPatronum::testPatronum() {
|
||||
QuasarAppUtils::Params::setArg("verbose", 3);
|
||||
QuasarAppUtils::Params::setArg("verbose", "3");
|
||||
|
||||
QFile::remove("/tmp/PTestPatronum");
|
||||
|
||||
}
|
||||
|
||||
@ -65,7 +67,7 @@ void testPatronum::testRandomCommad() {
|
||||
void testPatronum::connectTest() {
|
||||
DefaultService serv;
|
||||
|
||||
QTimer::singleShot(10, [this]() {
|
||||
QTimer::singleShot(10, this, [this]() {
|
||||
testRandomCommad();
|
||||
testPing();
|
||||
|
||||
|
@ -703,7 +703,7 @@ FILE_VERSION_FILTER =
|
||||
# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
|
||||
# tag is left empty.
|
||||
|
||||
LAYOUT_FILE = /res/DoxyStyle/DoxygenLayout.xml
|
||||
LAYOUT_FILE = /Patronum/QuasarAppLib/CMake/DoxyStyle/DoxygenLayout.xml
|
||||
|
||||
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
|
||||
# the reference definitions. This must be a list of .bib files. The .bib
|
||||
@ -790,7 +790,7 @@ WARN_LOGFILE =
|
||||
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
||||
# Note: If this tag is empty the current directory is searched.
|
||||
|
||||
INPUT = ./ \
|
||||
INPUT = ./README.md \
|
||||
Patronum/src
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
@ -1193,7 +1193,7 @@ HTML_STYLESHEET =
|
||||
# list). For an example see the documentation.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_EXTRA_STYLESHEET = res/DoxyStyle/doxygenStyles.css
|
||||
HTML_EXTRA_STYLESHEET = Patronum/QuasarAppLib/CMake/DoxyStyle/doxygenStyles.css
|
||||
|
||||
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
|
||||
# other source files which should be copied to the HTML output directory. Note
|
||||
|
@ -1 +0,0 @@
|
||||
Subproject commit 4592500f3efd49f6f404598523e09bc031368db0
|
Loading…
x
Reference in New Issue
Block a user