diff options
author | saturneric <[email protected]> | 2023-10-16 20:19:26 +0000 |
---|---|---|
committer | saturneric <[email protected]> | 2023-10-16 20:19:26 +0000 |
commit | 5175b3ae6687839afa2cdfe01f2fd70d714024ed (patch) | |
tree | 96eef7e087749c9118d5da7a838fdd81b0e96354 | |
parent | feat: using piml tech on plugin system (diff) | |
download | GpgFrontend-5175b3ae6687839afa2cdfe01f2fd70d714024ed.tar.gz GpgFrontend-5175b3ae6687839afa2cdfe01f2fd70d714024ed.zip |
refactor: use c++17 features and piml tech to rewrite DataObject and Task
Diffstat (limited to '')
24 files changed, 697 insertions, 676 deletions
diff --git a/src/core/GpgConstants.h b/src/core/GpgConstants.h index 6183cfaa..48fa37e6 100644 --- a/src/core/GpgConstants.h +++ b/src/core/GpgConstants.h @@ -29,6 +29,8 @@ #ifndef GPG_CONSTANTS_H #define GPG_CONSTANTS_H +#include <memory> + #include "GpgFrontendCore.h" const int RESTART_CODE = 1000; ///< only refresh ui @@ -36,8 +38,8 @@ const int DEEP_RESTART_CODE = 1001; // refresh core and ui namespace GpgFrontend { using ByteArray = std::string; ///< -using ByteArrayPtr = std::unique_ptr<ByteArray>; ///< -using StdBypeArrayPtr = std::unique_ptr<ByteArray>; ///< +using ByteArrayPtr = std::shared_ptr<ByteArray>; ///< +using StdBypeArrayPtr = std::shared_ptr<ByteArray>; ///< using BypeArrayRef = ByteArray&; ///< using BypeArrayConstRef = const ByteArray&; ///< using StringArgsPtr = std::unique_ptr<std::vector<std::string>>; ///< diff --git a/src/core/GpgContext.cpp b/src/core/GpgContext.cpp index 039c520c..e6c4d322 100644 --- a/src/core/GpgContext.cpp +++ b/src/core/GpgContext.cpp @@ -191,7 +191,7 @@ GpgContext::GpgContext(const GpgContextInitArgs &args) : args_(args) { Thread::TaskRunnerGetter::GetInstance() .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_GPG) ->PostTask(new Thread::Task( - [=](Thread::Task::DataObjectPtr) -> int { + [=](Thread::DataObjectPtr) -> int { post_init_ctx(); return 0; }, diff --git a/src/core/GpgCoreInit.cpp b/src/core/GpgCoreInit.cpp index 1799472f..0441b7d8 100644 --- a/src/core/GpgCoreInit.cpp +++ b/src/core/GpgCoreInit.cpp @@ -206,37 +206,36 @@ void init_gpgfrontend_core() { // async init no-ascii channel Thread::TaskRunnerGetter::GetInstance() .GetTaskRunner(Thread::TaskRunnerGetter::kTaskRunnerType_GPG) - ->PostTask( - new Thread::Task([=](Thread::Task::DataObjectPtr data_obj) -> int { - // init non-ascii channel - auto& ctx = GpgFrontend::GpgContext::CreateInstance( - GPGFRONTEND_NON_ASCII_CHANNEL, - [=]() -> std::unique_ptr<ChannelObject> { - GpgFrontend::GpgContextInitArgs args; - args.ascii = false; - - // set key database path - if (use_custom_key_database_path && - !custom_key_database_path.empty()) { - args.db_path = custom_key_database_path; - } - - if (use_custom_gnupg_install_path) { - args.custom_gpgconf = true; - args.custom_gpgconf_path = - custom_gnupg_install_fs_path.u8string(); - } - - args.offline_mode = forbid_all_gnupg_connection; - args.auto_import_missing_key = auto_import_missing_key; - args.use_pinentry = use_pinentry_as_password_input_dialog; - - return std::unique_ptr<ChannelObject>(new GpgContext(args)); - }); - - if (!ctx.good()) SPDLOG_ERROR("no-ascii channel init error"); - return ctx.good() ? 0 : -1; - })); + ->PostTask(new Thread::Task([=](Thread::DataObjectPtr data_obj) -> int { + // init non-ascii channel + auto& ctx = GpgFrontend::GpgContext::CreateInstance( + GPGFRONTEND_NON_ASCII_CHANNEL, + [=]() -> std::unique_ptr<ChannelObject> { + GpgFrontend::GpgContextInitArgs args; + args.ascii = false; + + // set key database path + if (use_custom_key_database_path && + !custom_key_database_path.empty()) { + args.db_path = custom_key_database_path; + } + + if (use_custom_gnupg_install_path) { + args.custom_gpgconf = true; + args.custom_gpgconf_path = + custom_gnupg_install_fs_path.u8string(); + } + + args.offline_mode = forbid_all_gnupg_connection; + args.auto_import_missing_key = auto_import_missing_key; + args.use_pinentry = use_pinentry_as_password_input_dialog; + + return std::unique_ptr<ChannelObject>(new GpgContext(args)); + }); + + if (!ctx.good()) SPDLOG_ERROR("no-ascii channel init error"); + return ctx.good() ? 0 : -1; + })); // try to restart all components GpgFrontend::GpgAdvancedOperator::GetInstance().RestartGpgComponents(); diff --git a/src/core/GpgModel.h b/src/core/GpgModel.h index 7cd45a80..a5f7d8cc 100644 --- a/src/core/GpgModel.h +++ b/src/core/GpgModel.h @@ -46,7 +46,7 @@ using SignIdArgsList = std::vector<std::pair<std::string, std::string>>; ///< using SignIdArgsListPtr = std::unique_ptr<SignIdArgsList>; ///< using KeyFprArgsListPtr = std::unique_ptr<std::vector<std::string>>; ///< using KeyArgsList = std::vector<GpgKey>; ///< -using KeyListPtr = std::unique_ptr<KeyArgsList>; ///< +using KeyListPtr = std::shared_ptr<KeyArgsList>; ///< using GpgKeyLinkList = std::list<GpgFrontend::GpgKey>; ///< using KeyLinkListPtr = std::unique_ptr<GpgKeyLinkList>; ///< using KeyPtr = std::unique_ptr<GpgKey>; ///< diff --git a/src/core/function/gpg/GpgCommandExecutor.cpp b/src/core/function/gpg/GpgCommandExecutor.cpp index dcb188ec..7d5ecc24 100644 --- a/src/core/function/gpg/GpgCommandExecutor.cpp +++ b/src/core/function/gpg/GpgCommandExecutor.cpp @@ -27,48 +27,56 @@ */ #include "GpgCommandExecutor.h" +#include <memory> +#include <string> + #include "GpgFunctionObject.h" #include "core/thread/TaskRunnerGetter.h" +#include "thread/DataObject.h" GpgFrontend::GpgCommandExecutor::GpgCommandExecutor(int channel) : SingletonFunctionObject<GpgCommandExecutor>(channel) {} void GpgFrontend::GpgCommandExecutor::Execute( std::string cmd, std::vector<std::string> arguments, - std::function<void(int, std::string, std::string)> callback, - std::function<void(QProcess *)> interact_func) { + GpgCommandExecutorCallback callback, + GpgCommandExecutorInteractor interact_func) { SPDLOG_DEBUG("called cmd {} arguments size: {}", cmd, arguments.size()); Thread::Task::TaskCallback result_callback = - [](int rtn, Thread::Task::DataObjectPtr data_object) { + [](int rtn, Thread::DataObjectPtr data_object) { SPDLOG_DEBUG("data object use count: {}", data_object.use_count()); - if (data_object->GetObjectSize() != 4) + if (!data_object->Check<int, std::string, std::string>()) throw std::runtime_error("invalid data object size"); - auto exit_code = data_object->PopObject<int>(); - auto process_stdout = data_object->PopObject<std::string>(); - auto process_stderr = data_object->PopObject<std::string>(); - auto callback = data_object->PopObject< - std::function<void(int, std::string, std::string)>>(); + auto exit_code = Thread::ExtractParams<int>(data_object, 0); + auto process_stdout = + Thread::ExtractParams<std::string>(data_object, 1); + auto process_stderr = + Thread::ExtractParams<std::string>(data_object, 2); + auto callback = + Thread::ExtractParams<GpgCommandExecutorCallback>(data_object, 3); // call callback callback(exit_code, process_stdout, process_stderr); }; Thread::Task::TaskRunnable runner = - [](GpgFrontend::Thread::Task::DataObjectPtr data_object) -> int { + [](Thread::DataObjectPtr data_object) -> int { SPDLOG_DEBUG("process runner called, data object size: {}", data_object->GetObjectSize()); - if (data_object->GetObjectSize() != 4) + if (!data_object + ->Check<std::string, std::string, GpgCommandExecutorInteractor>()) throw std::runtime_error("invalid data object size"); // get arguments - auto cmd = data_object->PopObject<std::string>(); + auto cmd = Thread::ExtractParams<std::string>(data_object, 0); SPDLOG_DEBUG("get cmd: {}", cmd); - auto arguments = data_object->PopObject<std::vector<std::string>>(); + auto arguments = + Thread::ExtractParams<std::vector<std::string>>(data_object, 1); auto interact_func = - data_object->PopObject<std::function<void(QProcess *)>>(); + Thread::ExtractParams<GpgCommandExecutorInteractor>(data_object, 2); auto *cmd_process = new QProcess(); cmd_process->setProcessChannelMode(QProcess::MergedChannels); @@ -120,27 +128,13 @@ void GpgFrontend::GpgCommandExecutor::Execute( cmd_process->close(); cmd_process->deleteLater(); - // transfer result - SPDLOG_DEBUG("runner append object"); - data_object->AppendObject(std::move(process_stderr)); - data_object->AppendObject(std::move(process_stdout)); - data_object->AppendObject(std::move(exit_code)); - SPDLOG_DEBUG("runner append object done"); - + data_object->Swap({exit_code, process_stdout, process_stderr}); return 0; }; - // data transfer into task - auto data_object = std::make_shared<Thread::Task::DataObject>(); - SPDLOG_DEBUG("executor append object"); - data_object->AppendObject(std::move(callback)); - data_object->AppendObject(std::move(interact_func)); - data_object->AppendObject(std::move(arguments)); - data_object->AppendObject(std::move(std::string{cmd})); - SPDLOG_DEBUG("executor append object done"); - auto *process_task = new GpgFrontend::Thread::Task( - std::move(runner), fmt::format("Execute/{}", cmd), data_object, + std::move(runner), fmt::format("Execute/{}", cmd), + Thread::TransferParams(cmd, arguments, interact_func, callback), std::move(result_callback)); QEventLoop looper; @@ -158,40 +152,43 @@ void GpgFrontend::GpgCommandExecutor::Execute( void GpgFrontend::GpgCommandExecutor::ExecuteConcurrently( std::string cmd, std::vector<std::string> arguments, - std::function<void(int, std::string, std::string)> callback, - std::function<void(QProcess *)> interact_func) { + GpgCommandExecutorCallback callback, + GpgCommandExecutorInteractor interact_func) { SPDLOG_DEBUG("called cmd {} arguments size: {}", cmd, arguments.size()); Thread::Task::TaskCallback result_callback = - [](int rtn, Thread::Task::DataObjectPtr data_object) { - if (data_object->GetObjectSize() != 4) + [](int rtn, Thread::DataObjectPtr data_object) { + if (!data_object->Check<int, std::string, std::string, + GpgCommandExecutorCallback>()) throw std::runtime_error("invalid data object size"); - auto exit_code = data_object->PopObject<int>(); - auto process_stdout = data_object->PopObject<std::string>(); - auto process_stderr = data_object->PopObject<std::string>(); - auto callback = data_object->PopObject< - std::function<void(int, std::string, std::string)>>(); + auto exit_code = Thread::ExtractParams<int>(data_object, 0); + auto process_stdout = + Thread::ExtractParams<std::string>(data_object, 1); + auto process_stderr = + Thread::ExtractParams<std::string>(data_object, 2); + auto callback = + Thread::ExtractParams<GpgCommandExecutorCallback>(data_object, 3); // call callback callback(exit_code, process_stdout, process_stderr); }; Thread::Task::TaskRunnable runner = - [](GpgFrontend::Thread::Task::DataObjectPtr data_object) -> int { + [](GpgFrontend::Thread::DataObjectPtr data_object) -> int { SPDLOG_DEBUG("process runner called, data object size: {}", data_object->GetObjectSize()); - if (data_object->GetObjectSize() != 4) + if (!data_object + ->Check<std::string, std::string, GpgCommandExecutorInteractor>()) throw std::runtime_error("invalid data object size"); - SPDLOG_DEBUG("runner pop object"); // get arguments - auto cmd = data_object->PopObject<std::string>(); - auto arguments = data_object->PopObject<std::vector<std::string>>(); + auto cmd = Thread::ExtractParams<std::string>(data_object, 0); + auto arguments = + Thread::ExtractParams<std::vector<std::string>>(data_object, 1); auto interact_func = - data_object->PopObject<std::function<void(QProcess *)>>(); - SPDLOG_DEBUG("runner pop object done"); + Thread::ExtractParams<std::function<void(QProcess *)>>(data_object, 2); auto *cmd_process = new QProcess(); cmd_process->setProcessChannelMode(QProcess::MergedChannels); @@ -244,22 +241,13 @@ void GpgFrontend::GpgCommandExecutor::ExecuteConcurrently( cmd_process->close(); cmd_process->deleteLater(); - // transfer result - SPDLOG_DEBUG("runner append object"); - data_object->AppendObject(std::move(process_stderr)); - data_object->AppendObject(std::move(process_stdout)); - data_object->AppendObject(std::move(exit_code)); - SPDLOG_DEBUG("runner append object done"); - + data_object->Swap({exit_code, process_stdout, process_stderr}); return 0; }; // data transfer into task - auto data_object = std::make_shared<Thread::Task::DataObject>(); - data_object->AppendObject(std::move(callback)); - data_object->AppendObject(std::move(interact_func)); - data_object->AppendObject(std::move(arguments)); - data_object->AppendObject(std::move(std::string{cmd})); + auto data_object = + Thread::TransferParams(cmd, arguments, interact_func, callback); auto *process_task = new GpgFrontend::Thread::Task( std::move(runner), fmt::format("ExecuteConcurrently/{}", cmd), diff --git a/src/core/function/gpg/GpgCommandExecutor.h b/src/core/function/gpg/GpgCommandExecutor.h index a7259df8..1bad6d40 100644 --- a/src/core/function/gpg/GpgCommandExecutor.h +++ b/src/core/function/gpg/GpgCommandExecutor.h @@ -39,6 +39,10 @@ namespace GpgFrontend { +using GpgCommandExecutorCallback = + std::function<void(int, std::string, std::string)>; +using GpgCommandExecutorInteractor = std::function<void(QProcess *)>; + /** * @brief Extra commands related to GPG * @@ -62,14 +66,14 @@ class GPGFRONTEND_CORE_EXPORT GpgCommandExecutor */ void Execute( std::string cmd, std::vector<std::string> arguments, - std::function<void(int, std::string, std::string)> callback = - [](int, std::string, std::string) {}, - std::function<void(QProcess *)> interact_func = [](QProcess *) {}); + GpgCommandExecutorCallback callback = [](int, std::string, + std::string) {}, + GpgCommandExecutorInteractor interact_func = [](QProcess *) {}); void ExecuteConcurrently( std::string cmd, std::vector<std::string> arguments, - std::function<void(int, std::string, std::string)> callback, - std::function<void(QProcess *)> interact_func = [](QProcess *) {}); + GpgCommandExecutorCallback callback, + GpgCommandExecutorInteractor interact_func = [](QProcess *) {}); private: GpgContext &ctx_ = GpgContext::GetInstance( diff --git a/src/core/function/gpg/GpgFileOpera.cpp b/src/core/function/gpg/GpgFileOpera.cpp index cb919042..de50de62 100644 --- a/src/core/function/gpg/GpgFileOpera.cpp +++ b/src/core/function/gpg/GpgFileOpera.cpp @@ -55,7 +55,7 @@ GpgFrontend::GpgError GpgFrontend::GpgFileOpera::EncryptFile( throw std::runtime_error("read file error"); } - std::unique_ptr<std::string> out_buffer = nullptr; + ByteArrayPtr out_buffer = nullptr; auto err = GpgBasicOperator::GetInstance(_channel).Encrypt( std::move(keys), in_buffer, out_buffer, result); @@ -85,7 +85,7 @@ GpgFrontend::GpgError GpgFrontend::GpgFileOpera::DecryptFile( if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) { throw std::runtime_error("read file error"); } - std::unique_ptr<std::string> out_buffer; + ByteArrayPtr out_buffer; auto err = GpgBasicOperator::GetInstance().Decrypt(in_buffer, out_buffer, result); @@ -119,7 +119,7 @@ gpgme_error_t GpgFrontend::GpgFileOpera::SignFile(KeyListPtr keys, if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) { throw std::runtime_error("read file error"); } - std::unique_ptr<std::string> out_buffer; + ByteArrayPtr out_buffer; auto err = GpgBasicOperator::GetInstance(_channel).Sign( std::move(keys), in_buffer, out_buffer, GPGME_SIG_MODE_DETACH, result); @@ -149,7 +149,7 @@ gpgme_error_t GpgFrontend::GpgFileOpera::VerifyFile( if (!FileOperator::ReadFileStd(data_path_std, in_buffer)) { throw std::runtime_error("read file error"); } - std::unique_ptr<std::string> sign_buffer = nullptr; + ByteArrayPtr sign_buffer = nullptr; if (!sign_path.empty()) { std::string sign_buffer_str; if (!FileOperator::ReadFileStd(sign_path_std, sign_buffer_str)) { @@ -180,7 +180,7 @@ gpg_error_t GpgFrontend::GpgFileOpera::EncryptSignFile( if (!FileOperator::ReadFileStd(in_path_std, in_buffer)) { throw std::runtime_error("read file error"); } - std::unique_ptr<std::string> out_buffer = nullptr; + ByteArrayPtr out_buffer = nullptr; auto err = GpgBasicOperator::GetInstance(_channel).EncryptSign( std::move(keys), std::move(signer_keys), in_buffer, out_buffer, encr_res, @@ -212,7 +212,7 @@ gpg_error_t GpgFrontend::GpgFileOpera::DecryptVerifyFile( throw std::runtime_error("read file error"); } - std::unique_ptr<std::string> out_buffer = nullptr; + ByteArrayPtr out_buffer = nullptr; auto err = GpgBasicOperator::GetInstance().DecryptVerify( in_buffer, out_buffer, decr_res, verify_res); @@ -241,7 +241,7 @@ unsigned int GpgFrontend::GpgFileOpera::EncryptFileSymmetric( throw std::runtime_error("read file error"); } - std::unique_ptr<std::string> out_buffer; + ByteArrayPtr out_buffer; auto err = GpgBasicOperator::GetInstance(_channel).EncryptSymmetric( in_buffer, out_buffer, result); diff --git a/src/core/thread/DataObject.cpp b/src/core/thread/DataObject.cpp index c99e0bfd..b21db7cb 100644 --- a/src/core/thread/DataObject.cpp +++ b/src/core/thread/DataObject.cpp @@ -26,4 +26,59 @@ * */ -#include "DataObject.h"
\ No newline at end of file +#include "DataObject.h" + +#include <memory> +#include <stack> + +#include "function/DataObjectOperator.h" + +namespace GpgFrontend::Thread { + +class DataObject::Impl { + public: + Impl() {} + + Impl(std::initializer_list<std::any> init_list) : params_(init_list) {} + + void AppendObject(std::any obj) { params_.push_back(obj); } + + std::any GetParameter(size_t index) { + if (index >= params_.size()) { + throw std::out_of_range("index out of range"); + } + return params_[index]; + } + + size_t GetObjectSize() { return params_.size(); } + + private: + std::vector<std::any> params_; +}; + +DataObject::DataObject() : p_(std::make_unique<Impl>()) {} + +DataObject::DataObject(std::initializer_list<std::any> i) + : p_(std::make_unique<Impl>(i)) {} + +DataObject::~DataObject() = default; + +DataObject::DataObject(GpgFrontend::Thread::DataObject&&) noexcept = default; + +std::any DataObject::operator[](size_t index) const { + return p_->GetParameter(index); +} + +std::any DataObject::GetParameter(size_t index) const { + return p_->GetParameter(index); +} + +size_t DataObject::GetObjectSize() const { return p_->GetObjectSize(); } + +void DataObject::Swap(DataObject& other) noexcept { std::swap(p_, other.p_); } + +void DataObject::Swap(DataObject&& other) noexcept { p_ = std::move(other.p_); } + +void swap(DataObject& a, DataObject& b) noexcept { a.Swap(b); } + +} // namespace GpgFrontend::Thread
\ No newline at end of file diff --git a/src/core/thread/DataObject.h b/src/core/thread/DataObject.h index 885b09ec..af5f0f5f 100644 --- a/src/core/thread/DataObject.h +++ b/src/core/thread/DataObject.h @@ -28,110 +28,66 @@ #pragma once -/** - * @brief DataObject to be passed to the callback function. - * - */ - class GPGFRONTEND_CORE_EXPORT DataObject { - public: - struct Destructor { - const void *p_obj; - void (*destroy)(const void *); - }; - - /** - * @brief Get the Objects Size - * - * @return size_t - */ - size_t GetObjectSize(); - - /** - * @brief - * - * @tparam T - * @param ptr - */ - template <typename T> - void AppendObject(T &&obj) { - SPDLOG_TRACE("append object: {}", static_cast<void *>(this)); - auto *obj_dstr = this->get_heap_ptr(sizeof(T)); - new ((void *)obj_dstr->p_obj) T(std::forward<T>(obj)); - - if (std::is_class_v<T>) { - auto destructor = [](const void *x) { - static_cast<const T *>(x)->~T(); - }; - obj_dstr->destroy = destructor; - } else { - obj_dstr->destroy = nullptr; - } - - data_objects_.push(obj_dstr); - } +#include <stack> - /** - * @brief - * - * @tparam T - * @param ptr - */ - template <typename T> - void AppendObject(T *obj) { - SPDLOG_TRACE("called: {}", static_cast<void *>(this)); - auto *obj_dstr = this->get_heap_ptr(sizeof(T)); - auto *ptr_heap = new ((void *)obj_dstr->p_obj) T(std::move(*obj)); - if (std::is_class_v<T>) { - SPDLOG_TRACE("is class"); - auto destructor = [](const void *x) { - static_cast<const T *>(x)->~T(); - }; - obj_dstr->destroy = destructor; - } else { - obj_dstr->destroy = nullptr; - } - data_objects_.push(std::move(obj_dstr)); - } +#include "core/GpgFrontendCoreExport.h" + +namespace GpgFrontend::Thread { + +class DataObject; +using DataObjectPtr = std::shared_ptr<DataObject>; ///< + +class GPGFRONTEND_CORE_EXPORT DataObject { + public: + DataObject(); + + DataObject(std::initializer_list<std::any>); + + ~DataObject(); + + DataObject(GpgFrontend::Thread::DataObject&&) noexcept; + + std::any operator[](size_t index) const; - /** - * @brief - * - * @tparam T - * @return std::shared_ptr<T> - */ - template <typename T> - T PopObject() { - SPDLOG_TRACE("pop object: {}", static_cast<void *>(this)); - if (data_objects_.empty()) throw std::runtime_error("No object to pop"); - auto *obj_dstr = data_objects_.top(); - auto *heap_ptr = (T *)obj_dstr->p_obj; - auto obj = std::move(*(T *)(heap_ptr)); - this->free_heap_ptr(obj_dstr); - data_objects_.pop(); - return obj; + void AppendObject(std::any); + + std::any GetParameter(size_t index) const; + + size_t GetObjectSize() const; + + void Swap(DataObject& other) noexcept; + + void Swap(DataObject&& other) noexcept; + + template <typename... Args> + bool Check() { + if (sizeof...(Args) != GetObjectSize()) return false; + + std::vector<std::type_info const*> type_list = {&typeid(Args)...}; + for (size_t i = 0; i < type_list.size(); ++i) { + if (type_list[i] != &((*this)[i]).type()) return false; } + return true; + } + + private: + class Impl; + std::unique_ptr<Impl> p_; +}; + +template <typename... Args> +std::shared_ptr<DataObject> TransferParams(Args&&... args) { + return std::make_shared<DataObject>(DataObject{std::forward<Args>(args)...}); +} + +template <typename T> +T ExtractParams(const std::shared_ptr<DataObject>& d_o, int index) { + if (!d_o) { + throw std::invalid_argument("nullptr provided for DataObjectPtr"); + } + return std::any_cast<T>(d_o->GetParameter(index)); +} + +void swap(DataObject& a, DataObject& b) noexcept; - /** - * @brief Destroy the Data Object object - * - */ - ~DataObject(); - - private: - std::stack<Destructor *> data_objects_; ///< - - /** - * @brief Get the heap ptr object - * - * @param bytes_size - * @return void* - */ - Destructor *get_heap_ptr(size_t bytes_size); - - /** - * @brief - * - * @param heap_ptr - */ - void free_heap_ptr(Destructor *); - };
\ No newline at end of file +} // namespace GpgFrontend::Thread
\ No newline at end of file diff --git a/src/core/thread/Task.cpp b/src/core/thread/Task.cpp index c508531d..cc6a38b8 100644 --- a/src/core/thread/Task.cpp +++ b/src/core/thread/Task.cpp @@ -28,200 +28,46 @@ #include "core/thread/Task.h" -#include <boost/uuid/uuid.hpp> -#include <boost/uuid/uuid_generators.hpp> -#include <boost/uuid/uuid_io.hpp> -#include <functional> -#include <string> -#include <utility> - -#include "core/thread/TaskRunner.h" - -const std::string GpgFrontend::Thread::Task::DEFAULT_TASK_NAME = "default-task"; - -GpgFrontend::Thread::Task::Task(std::string name) - : uuid_(generate_uuid()), name_(name) { - SPDLOG_TRACE("task {}/ created", GetFullID()); - init(); -} - -GpgFrontend::Thread::Task::Task(TaskRunnable runnable, std::string name, - DataObjectPtr data_object, bool sequency) - : uuid_(generate_uuid()), - name_(name), - runnable_(std::move(runnable)), - callback_(std::move([](int, const std::shared_ptr<DataObject> &) {})), - callback_thread_(QThread::currentThread()), - data_object_(data_object), - sequency_(sequency) { - SPDLOG_TRACE("task {} created with runnable, callback_thread_: {}", - GetFullID(), static_cast<void *>(callback_thread_)); - init(); -} - -GpgFrontend::Thread::Task::Task(TaskRunnable runnable, std::string name, - DataObjectPtr data_object, - TaskCallback callback, bool sequency) - : uuid_(generate_uuid()), - name_(name), - runnable_(std::move(runnable)), - callback_(std::move(callback)), - callback_thread_(QThread::currentThread()), - data_object_(data_object), - sequency_(sequency) { - init(); - SPDLOG_TRACE( - "task {} created with runnable and callback, callback_thread_: {}", - GetFullID(), static_cast<void *>(callback_thread_)); -} - -GpgFrontend::Thread::Task::~Task() { - SPDLOG_TRACE("task {} destroyed", GetFullID()); -} +#include <memory> + +#include "TaskImpl.hpp" + +namespace GpgFrontend::Thread { + +const std::string DEFAULT_TASK_NAME = "unnamed-task"; + +Task::Task(std::string name) : p_(std::make_unique<Impl>(this, name)) {} + +Task::Task(TaskRunnable runnable, std::string name, DataObjectPtr data_object, + bool sequency) + : p_(std::make_unique<Impl>(this, runnable, name, data_object, sequency)) {} + +Task::Task(TaskRunnable runnable, std::string name, DataObjectPtr data_object, + TaskCallback callback, bool sequency) + : p_(std::make_unique<Impl>(this, runnable, name, data_object, callback, + sequency)) {} + +Task::~Task() = default; /** * @brief * * @return std::string */ -std::string GpgFrontend::Thread::Task::GetFullID() const { - return uuid_ + "/" + name_; -} - -std::string GpgFrontend::Thread::Task::GetUUID() const { return uuid_; } - -bool GpgFrontend::Thread::Task::GetSequency() const { return sequency_; } - -void GpgFrontend::Thread::Task::HoldOnLifeCycle(bool hold_on) { - this->run_callback_after_runnable_finished_ = !hold_on; -} - -void GpgFrontend::Thread::Task::SetRTN(int rtn) { this->rtn_ = rtn; } - -void GpgFrontend::Thread::Task::init() { - // after runnable finished, running callback - connect(this, &Task::SignalTaskRunnableEnd, this, - &Task::slot_task_run_callback); -} - -void GpgFrontend::Thread::Task::slot_task_run_callback(int rtn) { - SPDLOG_TRACE("task runnable {} finished, rtn: {}", GetFullID(), rtn); - // set return value - this->SetRTN(rtn); - - try { - if (callback_) { - if (callback_thread_ == QThread::currentThread()) { - SPDLOG_DEBUG("callback thread is the same thread"); - if (!QMetaObject::invokeMethod(callback_thread_, - [callback = callback_, rtn = rtn_, - data_object = data_object_, this]() { - callback(rtn, data_object); - // do cleaning work - emit SignalTaskEnd(); - })) { - SPDLOG_ERROR("failed to invoke callback"); - } - // just finished, let callack thread to raise SignalTaskEnd - return; - } else { - // waiting for callback to finish - if (!QMetaObject::invokeMethod( - callback_thread_, - [callback = callback_, rtn = rtn_, - data_object = data_object_]() { callback(rtn, data_object); }, - Qt::BlockingQueuedConnection)) { - SPDLOG_ERROR("failed to invoke callback"); - } - } - } - } catch (std::exception &e) { - SPDLOG_ERROR("exception caught: {}", e.what()); - } catch (...) { - SPDLOG_ERROR("unknown exception caught"); - } - - // raise signal, announcing this task come to an end - SPDLOG_DEBUG("task {}, starting calling signal SignalTaskEnd", GetFullID()); - emit SignalTaskEnd(); -} - -void GpgFrontend::Thread::Task::run() { - SPDLOG_TRACE("task {} starting", GetFullID()); - - // build runnable package for running - auto runnable_package = [=, id = GetFullID()]() { - SPDLOG_DEBUG("task {} runnable start runing", id); - // Run() will set rtn by itself - Run(); - // raise signal to anounce after runnable returned - if (run_callback_after_runnable_finished_) emit SignalTaskRunnableEnd(rtn_); - }; - - if (thread() != QThread::currentThread()) { - SPDLOG_DEBUG("task running thread is not object living thread"); - // if running sequently - if (sequency_) { - // running in another thread, blocking until returned - if (!QMetaObject::invokeMethod(thread(), runnable_package, - Qt::BlockingQueuedConnection)) { - SPDLOG_ERROR("qt invoke method failed"); - } - } else { - // running in another thread, non-blocking - if (!QMetaObject::invokeMethod(thread(), runnable_package)) { - SPDLOG_ERROR("qt invoke method failed"); - } - } - } else { - if (!QMetaObject::invokeMethod(this, runnable_package)) { - SPDLOG_ERROR("qt invoke method failed"); - } - } -} - -void GpgFrontend::Thread::Task::SlotRun() { run(); } - -void GpgFrontend::Thread::Task::Run() { - if (runnable_) { - SetRTN(runnable_(data_object_)); - } else { - SPDLOG_WARN("no runnable in task, do callback operation"); - } -} - -GpgFrontend::Thread::Task::DataObject::Destructor * -GpgFrontend::Thread::Task::DataObject::get_heap_ptr(size_t bytes_size) { - Destructor *dstr_ptr = new Destructor(); - dstr_ptr->p_obj = malloc(bytes_size); - return dstr_ptr; -} - -GpgFrontend::Thread::Task::DataObject::~DataObject() { - if (!data_objects_.empty()) - SPDLOG_WARN("data_objects_ is not empty", - "address:", static_cast<void *>(this)); - while (!data_objects_.empty()) { - free_heap_ptr(data_objects_.top()); - data_objects_.pop(); - } -} - -size_t GpgFrontend::Thread::Task::DataObject::GetObjectSize() { - return data_objects_.size(); -} - -void GpgFrontend::Thread::Task::DataObject::free_heap_ptr(Destructor *ptr) { - SPDLOG_TRACE("p_obj: {} data object: {}", - static_cast<const void *>(ptr->p_obj), - static_cast<void *>(this)); - if (ptr->destroy != nullptr) { - ptr->destroy(ptr->p_obj); - } - free(const_cast<void *>(ptr->p_obj)); - delete ptr; -} - -std::string GpgFrontend::Thread::Task::generate_uuid() { - return boost::uuids::to_string(boost::uuids::random_generator()()); -} +std::string Task::GetFullID() const { return p_->GetFullID(); } + +std::string Task::GetUUID() const { return p_->GetUUID(); } + +bool Task::GetSequency() const { return p_->GetSequency(); } + +void Task::HoldOnLifeCycle(bool hold_on) { p_->HoldOnLifeCycle(hold_on); } + +void Task::SetRTN(int rtn) { p_->SetRTN(rtn); } + +void Task::SlotRun() { p_->SlotRun(); } + +void Task::Run() { p_->Run(); } + +void Task::run() { p_->RunnableInterfaceRun(); } + +} // namespace GpgFrontend::Thread
\ No newline at end of file diff --git a/src/core/thread/Task.h b/src/core/thread/Task.h index 2e812c3f..d4e4df05 100644 --- a/src/core/thread/Task.h +++ b/src/core/thread/Task.h @@ -26,34 +26,27 @@ * */ -#ifndef GPGFRONTEND_TASK_H -#define GPGFRONTEND_TASK_H - -#include <functional> -#include <memory> -#include <stack> -#include <string> -#include <type_traits> -#include <utility> +#pragma once #include "core/GpgFrontendCore.h" +#include "core/thread/DataObject.h" namespace GpgFrontend::Thread { class TaskRunner; +extern const std::string DEFAULT_TASK_NAME; + +class DataObject; +using DataObjectPtr = std::shared_ptr<DataObject>; ///< class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable { Q_OBJECT public: - class DataObject; - using DataObjectPtr = std::shared_ptr<DataObject>; ///< + friend class TaskRunner; + using TaskRunnable = std::function<int(DataObjectPtr)>; ///< using TaskCallback = std::function<void(int, DataObjectPtr)>; ///< - static const std::string DEFAULT_TASK_NAME; - - friend class TaskRunner; - /** * @brief Construct a new Task object * @@ -148,44 +141,9 @@ class GPGFRONTEND_CORE_EXPORT Task : public QObject, public QRunnable { void SetRTN(int rtn); private: - class Impl; - std::unique_ptr<Impl>; - const std::string uuid_; - const std::string name_; - const bool sequency_ = true; ///< must run in the same thread - TaskCallback callback_; ///< - TaskRunnable runnable_; ///< - bool run_callback_after_runnable_finished_ = true; ///< - int rtn_ = 0; ///< - QThread *callback_thread_ = nullptr; ///< - DataObjectPtr data_object_ = nullptr; ///< + class Impl; + std::unique_ptr<Impl> p_; - /** - * @brief - * - */ - void init(); - - /** - * @brief - * - */ virtual void run() override; - - /** - * @brief - * - * @return std::string - */ - static std::string generate_uuid(); - - private slots: - /** - * @brief - * - */ - void slot_task_run_callback(int rtn); }; } // namespace GpgFrontend::Thread - -#endif // GPGFRONTEND_TASK_H
\ No newline at end of file diff --git a/src/core/thread/TaskImpl.hpp b/src/core/thread/TaskImpl.hpp new file mode 100644 index 00000000..c196c981 --- /dev/null +++ b/src/core/thread/TaskImpl.hpp @@ -0,0 +1,242 @@ +/** + * Copyright (C) 2021 Saturneric <[email protected]> + * + * This file is part of GpgFrontend. + * + * GpgFrontend is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GpgFrontend is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GpgFrontend. If not, see <https://www.gnu.org/licenses/>. + * + * The initial version of the source code is inherited from + * the gpg4usb project, which is under GPL-3.0-or-later. + * + * All the source code of GpgFrontend was modified and released by + * Saturneric <[email protected]> starting on May 12, 2021. + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#pragma once + +#include <boost/uuid/uuid.hpp> +#include <boost/uuid/uuid_generators.hpp> +#include <boost/uuid/uuid_io.hpp> +#include <memory> + +#include "Task.h" + +namespace GpgFrontend::Thread { + +class Task::Impl : public QObject { + Q_OBJECT + + public: + Impl(Task *parent, std::string name) + : parent_(parent), uuid_(generate_uuid()), name_(name) { + SPDLOG_TRACE("task {} created", GetFullID()); + init(); + } + + Impl(Task *parent, TaskRunnable runnable, std::string name, + DataObjectPtr data_object, bool sequency) + : parent_(parent), + uuid_(generate_uuid()), + name_(name), + runnable_(std::move(runnable)), + callback_(std::move([](int, const DataObjectPtr &) {})), + callback_thread_(QThread::currentThread()), + data_object_(data_object), + sequency_(sequency) { + SPDLOG_TRACE("task {} created with runnable, callback_thread_: {}", + GetFullID(), static_cast<void *>(callback_thread_)); + init(); + } + + Impl(Task *parent, TaskRunnable runnable, std::string name, + DataObjectPtr data_object, TaskCallback callback, bool sequency) + : parent_(parent), + uuid_(generate_uuid()), + name_(name), + runnable_(std::move(runnable)), + callback_(std::move(callback)), + callback_thread_(QThread::currentThread()), + data_object_(data_object), + sequency_(sequency) { + init(); + SPDLOG_TRACE( + "task {} created with runnable and callback, callback_thread_: {}", + GetFullID(), static_cast<void *>(callback_thread_)); + } + + ~Impl() { SPDLOG_TRACE("task {} destroyed", GetFullID()); } + + /** + * @brief + * + * @return std::string + */ + std::string GetFullID() const { return uuid_ + "/" + name_; } + + std::string GetUUID() const { return uuid_; } + + bool GetSequency() const { return sequency_; } + + void Run() { + if (runnable_) { + SetRTN(runnable_(data_object_)); + } else { + SPDLOG_WARN("no runnable in task, do callback operation"); + } + } + + /** + * @brief Set the Finish After Run object + * + * @param finish_after_run + */ + void HoldOnLifeCycle(bool hold_on) { + this->run_callback_after_runnable_finished_ = !hold_on; + } + + /** + * @brief + * + * @param rtn + */ + void SetRTN(int rtn) { this->rtn_ = rtn; } + + /** + * @brief + * + */ + void RunnableInterfaceRun() { + SPDLOG_TRACE("task {} starting", GetFullID()); + + // build runnable package for running + auto runnable_package = [=, id = GetFullID()]() { + SPDLOG_DEBUG("task {} runnable start runing", id); + // Run() will set rtn by itself + Run(); + // raise signal to anounce after runnable returned + if (run_callback_after_runnable_finished_) + emit parent_->SignalTaskRunnableEnd(rtn_); + }; + + if (thread() != QThread::currentThread()) { + SPDLOG_DEBUG("task running thread is not object living thread"); + // if running sequently + if (sequency_) { + // running in another thread, blocking until returned + if (!QMetaObject::invokeMethod(thread(), runnable_package, + Qt::BlockingQueuedConnection)) { + SPDLOG_ERROR("qt invoke method failed"); + } + } else { + // running in another thread, non-blocking + if (!QMetaObject::invokeMethod(thread(), runnable_package)) { + SPDLOG_ERROR("qt invoke method failed"); + } + } + } else { + if (!QMetaObject::invokeMethod(this, runnable_package)) { + SPDLOG_ERROR("qt invoke method failed"); + } + } + } + + public slots: + + /** + * @brief + * + */ + void SlotRun() { RunnableInterfaceRun(); } + + private: + Task *parent_; + const std::string uuid_; + const std::string name_; + const bool sequency_ = true; ///< must run in the same thread + TaskCallback callback_; ///< + TaskRunnable runnable_; ///< + bool run_callback_after_runnable_finished_ = true; ///< + int rtn_ = 0; ///< + QThread *callback_thread_ = nullptr; ///< + DataObjectPtr data_object_ = nullptr; ///< + + void init() { + // after runnable finished, running callback + connect(parent_, &Task::SignalTaskRunnableEnd, this, + &Impl::slot_task_run_callback); + } + + /** + * @brief + * + * @return std::string + */ + std::string generate_uuid() { + return boost::uuids::to_string(boost::uuids::random_generator()()); + } + + private slots: + + /** + * @brief + * + */ + void slot_task_run_callback(int rtn) { + SPDLOG_TRACE("task runnable {} finished, rtn: {}", GetFullID(), rtn); + // set return value + this->SetRTN(rtn); + + try { + if (callback_) { + if (callback_thread_ == QThread::currentThread()) { + SPDLOG_DEBUG("callback thread is the same thread"); + if (!QMetaObject::invokeMethod(callback_thread_, + [callback = callback_, rtn = rtn_, + &data_object = data_object_, this]() { + callback(rtn, data_object); + // do cleaning work + emit parent_->SignalTaskEnd(); + })) { + SPDLOG_ERROR("failed to invoke callback"); + } + // just finished, let callack thread to raise SignalTaskEnd + return; + } else { + // waiting for callback to finish + if (!QMetaObject::invokeMethod( + callback_thread_, + [callback = callback_, rtn = rtn_, + data_object = data_object_]() { + callback(rtn, data_object); + }, + Qt::BlockingQueuedConnection)) { + SPDLOG_ERROR("failed to invoke callback"); + } + } + } + } catch (std::exception &e) { + SPDLOG_ERROR("exception caught: {}", e.what()); + } catch (...) { + SPDLOG_ERROR("unknown exception caught"); + } + + // raise signal, announcing this task come to an end + SPDLOG_DEBUG("task {}, starting calling signal SignalTaskEnd", GetFullID()); + emit parent_->SignalTaskEnd(); + } +}; +} // namespace GpgFrontend::Thread
\ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 050c9d3e..8c8030d6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -39,7 +39,7 @@ #include "core/GpgConstants.h" #include "core/GpgCoreInit.h" #include "core/function/GlobalSettingStation.h" -// #include "plugin/GpgFrontendPluginInit.h" +#include "plugin/GpgFrontendPluginInit.h" #include "spdlog/spdlog.h" #include "ui/GpgFrontendApplication.h" #include "ui/GpgFrontendUIInit.h" diff --git a/src/plugin/GpgFrontendPluginInit.cpp b/src/plugin/GpgFrontendPluginInit.cpp index 74eb04f1..a21432c7 100644 --- a/src/plugin/GpgFrontendPluginInit.cpp +++ b/src/plugin/GpgFrontendPluginInit.cpp @@ -36,18 +36,16 @@ #include <memory> #include "core/function/GlobalSettingStation.h" -#include "core/plugin/Plugin.h" -#include "core/plugin/PluginManager.h" +#include "plugin/system/PluginManager.h" // integrated plugins -#include "integrated_plugins/version_checking_plugin/VersionCheckingPlugin.h" +#include "module/version_checking_plugin/VersionCheckingPlugin.h" namespace GpgFrontend::Plugin { void LoadGpgFrontendIntegratedPlugins() { PluginManager::GetInstance()->RegisterPlugin( - std::make_shared< - IntegradedPlugin::VersionCheckingPlugin::VersionCheckingPlugin>()); + std::make_shared<Module::VersionCheckingPlugin::VersionCheckingPlugin>()); } void InitPluginLoggingSystem() { diff --git a/src/plugin/system/Plugin.cpp b/src/plugin/system/Plugin.cpp index 9f975925..479ee75c 100644 --- a/src/plugin/system/Plugin.cpp +++ b/src/plugin/system/Plugin.cpp @@ -83,6 +83,8 @@ Plugin::Plugin(PluginIdentifier id, PluginVersion version, PluginMetaData meta_data) : s_(this) {} +Plugin::~Plugin() = default; + int Plugin::getChannel() { return p_->GetChannel(); } int Plugin::getDefaultChannel() { return p_->GetDefaultChannel(); } diff --git a/src/plugin/system/Plugin.h b/src/plugin/system/Plugin.h index 7c538b3f..68484c1e 100644 --- a/src/plugin/system/Plugin.h +++ b/src/plugin/system/Plugin.h @@ -55,6 +55,8 @@ class GPGFRONTEND_PLUGIN_SYSTEM_EXPORT Plugin : public QObject { public: Plugin(PluginIdentifier, PluginVersion, PluginMetaData); + ~Plugin(); + virtual bool Register() = 0; virtual bool Active() = 0; diff --git a/src/plugin/system/PluginManager.cpp b/src/plugin/system/PluginManager.cpp index c1348948..c4623c32 100644 --- a/src/plugin/system/PluginManager.cpp +++ b/src/plugin/system/PluginManager.cpp @@ -45,7 +45,7 @@ class PluginManager::Impl { void RegisterPlugin(PluginPtr plugin) { task_runner_->PostTask(new Thread::Task( - std::move([=](GpgFrontend::Thread::Task::DataObjectPtr) -> int { + std::move([=](GpgFrontend::Thread::DataObjectPtr) -> int { global_plugin_context_->RegisterPlugin(plugin); return 0; }), @@ -54,7 +54,7 @@ class PluginManager::Impl { void TriggerEvent(EventRefrernce event) { task_runner_->PostTask(new Thread::Task( - std::move([=](GpgFrontend::Thread::Task::DataObjectPtr) -> int { + std::move([=](GpgFrontend::Thread::DataObjectPtr) -> int { global_plugin_context_->TriggerEvent(event); return 0; }), @@ -63,7 +63,7 @@ class PluginManager::Impl { void ActivePlugin(PluginIdentifier identifier) { task_runner_->PostTask(new Thread::Task( - std::move([=](GpgFrontend::Thread::Task::DataObjectPtr) -> int { + std::move([=](GpgFrontend::Thread::DataObjectPtr) -> int { global_plugin_context_->ActivePlugin(identifier); return 0; }), diff --git a/src/plugin/system/PluginManager.h b/src/plugin/system/PluginManager.h index cad0d93c..5fc36291 100644 --- a/src/plugin/system/PluginManager.h +++ b/src/plugin/system/PluginManager.h @@ -58,6 +58,8 @@ using GlobalPluginContextPtr = std::shared_ptr<GlobalPluginContext>; class GPGFRONTEND_PLUGIN_SYSTEM_EXPORT PluginManager : public QObject { Q_OBJECT public: + ~PluginManager(); + static PluginMangerPtr GetInstance(); void RegisterPlugin(PluginPtr); @@ -76,8 +78,6 @@ class GPGFRONTEND_PLUGIN_SYSTEM_EXPORT PluginManager : public QObject { static PluginMangerPtr g_; PluginManager(); - - ~PluginManager(); }; } // namespace GpgFrontend::Plugin diff --git a/src/ui/GpgFrontendUI.h b/src/ui/GpgFrontendUI.h index 09204b6b..3d3d74bb 100644 --- a/src/ui/GpgFrontendUI.h +++ b/src/ui/GpgFrontendUI.h @@ -26,8 +26,7 @@ * */ -#ifndef GPGFRONTEND_GPGFRONTENDUI_H -#define GPGFRONTEND_GPGFRONTENDUI_H +#pragma once /** * Basic dependency @@ -48,5 +47,3 @@ */ #include <qt-aes/qaesencryption.h> - -#endif // GPGFRONTEND_GPGFRONTENDUI_H diff --git a/src/ui/UserInterfaceUtils.cpp b/src/ui/UserInterfaceUtils.cpp index 0e01155b..954ee42f 100644 --- a/src/ui/UserInterfaceUtils.cpp +++ b/src/ui/UserInterfaceUtils.cpp @@ -120,7 +120,7 @@ void process_result_analyse(TextEdit *edit, InfoBoardWidget *info_board, void process_operation(QWidget *parent, const std::string &waiting_title, const Thread::Task::TaskRunnable func, const Thread::Task::TaskCallback callback, - Thread::Task::DataObjectPtr data_object) { + Thread::DataObjectPtr data_object) { auto *dialog = new WaitingDialog(QString::fromStdString(waiting_title), parent); @@ -435,7 +435,7 @@ void CommonUtils::SlotImportKeyFromKeyServer( void CommonUtils::slot_update_key_status() { auto refresh_task = new Thread::Task( - [](Thread::Task::DataObjectPtr) -> int { + [](Thread::DataObjectPtr) -> int { // flush key cache for all GpgKeyGetter Intances. for (const auto &channel_id : GpgKeyGetter::GetAllChannelId()) { GpgKeyGetter::GetInstance(channel_id).FlushKeyCache(); diff --git a/src/ui/UserInterfaceUtils.h b/src/ui/UserInterfaceUtils.h index 7f59c7ae..e54cee59 100644 --- a/src/ui/UserInterfaceUtils.h +++ b/src/ui/UserInterfaceUtils.h @@ -106,7 +106,7 @@ void process_operation( QWidget* parent, const std::string& waiting_title, GpgFrontend::Thread::Task::TaskRunnable func, GpgFrontend::Thread::Task::TaskCallback callback = nullptr, - Thread::Task::DataObjectPtr data_object = nullptr); + Thread::DataObjectPtr data_object = nullptr); /** * @brief diff --git a/src/ui/dialog/import_export/KeyUploadDialog.cpp b/src/ui/dialog/import_export/KeyUploadDialog.cpp index 03bf0871..4e9c78c9 100644 --- a/src/ui/dialog/import_export/KeyUploadDialog.cpp +++ b/src/ui/dialog/import_export/KeyUploadDialog.cpp @@ -60,7 +60,7 @@ KeyUploadDialog::KeyUploadDialog(const KeyIdArgsListPtr& keys_ids, } void KeyUploadDialog::SlotUpload() { - auto out_data = std::make_unique<ByteArray>(); + auto out_data = std::make_shared<ByteArray>(); GpgKeyImportExporter::GetInstance().ExportKeys(*m_keys_, out_data); slot_upload_key_to_server(*out_data); diff --git a/src/ui/main_window/MainWindowFileSlotFunction.cpp b/src/ui/main_window/MainWindowFileSlotFunction.cpp index daeddbac..325cc348 100644 --- a/src/ui/main_window/MainWindowFileSlotFunction.cpp +++ b/src/ui/main_window/MainWindowFileSlotFunction.cpp @@ -86,7 +86,7 @@ bool process_tarball_into_directory(QWidget* parent, bool if_error = false; process_operation(parent, _("Extracting Tarball"), - [&](Thread::Task::DataObjectPtr) -> int { + [&](Thread::DataObjectPtr) -> int { try { GpgFrontend::ArchiveFileOperator::ExtractArchive( target_path, base_path); @@ -131,7 +131,7 @@ bool process_directory_into_tarball(QWidget* parent, QString& path) { bool if_error = false; process_operation(parent, _("Making Tarball"), - [&](Thread::Task::DataObjectPtr) -> int { + [&](Thread::DataObjectPtr) -> int { try { GpgFrontend::ArchiveFileOperator::CreateArchive( base_path, target_path, 0, {selected_dir_path}); @@ -223,8 +223,7 @@ void MainWindow::SlotFileEncrypt() { if (ret == QMessageBox::Cancel) return; process_operation( - this, _("Symmetrically Encrypting"), - [&](Thread::Task::DataObjectPtr) -> int { + this, _("Symmetrically Encrypting"), [&](Thread::DataObjectPtr) -> int { try { error = GpgFrontend::GpgFileOpera::EncryptFileSymmetric( path.toStdString(), out_path.toStdString(), result, _channel); @@ -250,17 +249,16 @@ void MainWindow::SlotFileEncrypt() { } } - process_operation(this, _("Encrypting"), - [&](Thread::Task::DataObjectPtr) -> int { - try { - error = GpgFileOpera::EncryptFile( - std::move(p_keys), path.toStdString(), - out_path.toStdString(), result, _channel); - } catch (const std::runtime_error& e) { - if_error = true; - } - return 0; - }); + process_operation(this, _("Encrypting"), [&](Thread::DataObjectPtr) -> int { + try { + error = + GpgFileOpera::EncryptFile(std::move(p_keys), path.toStdString(), + out_path.toStdString(), result, _channel); + } catch (const std::runtime_error& e) { + if_error = true; + } + return 0; + }); } // remove xxx.tar and only left xxx.tar.gpg @@ -314,16 +312,15 @@ void MainWindow::SlotFileDecrypt() { GpgDecrResult result = nullptr; gpgme_error_t error; bool if_error = false; - process_operation(this, _("Decrypting"), - [&](Thread::Task::DataObjectPtr) -> int { - try { - error = GpgFileOpera::DecryptFile( - path.toStdString(), out_path.u8string(), result); - } catch (const std::runtime_error& e) { - if_error = true; - } - return 0; - }); + process_operation(this, _("Decrypting"), [&](Thread::DataObjectPtr) -> int { + try { + error = GpgFileOpera::DecryptFile(path.toStdString(), out_path.u8string(), + result); + } catch (const std::runtime_error& e) { + if_error = true; + } + return 0; + }); if (!if_error) { auto resultAnalyse = GpgDecryptResultAnalyse(error, std::move(result)); @@ -419,17 +416,16 @@ void MainWindow::SlotFileSign() { gpgme_error_t error; bool if_error = false; - process_operation( - this, _("Signing"), [&](Thread::Task::DataObjectPtr) -> int { - try { - error = GpgFileOpera::SignFile(std::move(keys), in_path.u8string(), - sig_file_path.u8string(), result, - _channel); - } catch (const std::runtime_error& e) { - if_error = true; - } - return 0; - }); + process_operation(this, _("Signing"), [&](Thread::DataObjectPtr) -> int { + try { + error = + GpgFileOpera::SignFile(std::move(keys), in_path.u8string(), + sig_file_path.u8string(), result, _channel); + } catch (const std::runtime_error& e) { + if_error = true; + } + return 0; + }); if (!if_error) { auto resultAnalyse = GpgSignResultAnalyse(error, std::move(result)); @@ -504,17 +500,16 @@ void MainWindow::SlotFileVerify() { GpgVerifyResult result = nullptr; gpgme_error_t error; bool if_error = false; - process_operation( - this, _("Verifying"), [&](Thread::Task::DataObjectPtr) -> int { - try { - error = GpgFileOpera::VerifyFile(data_file_path.u8string(), - sign_file_path.u8string(), result, - _channel); - } catch (const std::runtime_error& e) { - if_error = true; - } - return 0; - }); + process_operation(this, _("Verifying"), [&](Thread::DataObjectPtr) -> int { + try { + error = + GpgFileOpera::VerifyFile(data_file_path.u8string(), + sign_file_path.u8string(), result, _channel); + } catch (const std::runtime_error& e) { + if_error = true; + } + return 0; + }); if (!if_error) { auto result_analyse = GpgVerifyResultAnalyse(error, result); @@ -622,18 +617,17 @@ void MainWindow::SlotFileEncryptSign() { gpgme_error_t error; bool if_error = false; - process_operation(this, _("Encrypting and Signing"), - [&](Thread::Task::DataObjectPtr) -> int { - try { - error = GpgFileOpera::EncryptSignFile( - std::move(p_keys), std::move(p_signer_keys), - path.toStdString(), out_path.toStdString(), - encr_result, sign_result, _channel); - } catch (const std::runtime_error& e) { - if_error = true; - } - return 0; - }); + process_operation( + this, _("Encrypting and Signing"), [&](Thread::DataObjectPtr) -> int { + try { + error = GpgFileOpera::EncryptSignFile( + std::move(p_keys), std::move(p_signer_keys), path.toStdString(), + out_path.toStdString(), encr_result, sign_result, _channel); + } catch (const std::runtime_error& e) { + if_error = true; + } + return 0; + }); if (!if_error) { auto encrypt_result = @@ -696,17 +690,16 @@ void MainWindow::SlotFileDecryptVerify() { GpgVerifyResult v_result = nullptr; gpgme_error_t error; bool if_error = false; - process_operation(this, _("Decrypting and Verifying"), - [&](Thread::Task::DataObjectPtr) -> int { - try { - error = GpgFileOpera::DecryptVerifyFile( - path.toStdString(), out_path.u8string(), d_result, - v_result); - } catch (const std::runtime_error& e) { - if_error = true; - } - return 0; - }); + process_operation( + this, _("Decrypting and Verifying"), [&](Thread::DataObjectPtr) -> int { + try { + error = GpgFileOpera::DecryptVerifyFile( + path.toStdString(), out_path.u8string(), d_result, v_result); + } catch (const std::runtime_error& e) { + if_error = true; + } + return 0; + }); if (!if_error) { auto decrypt_res = GpgDecryptResultAnalyse(error, std::move(d_result)); diff --git a/src/ui/main_window/MainWindowSlotFunction.cpp b/src/ui/main_window/MainWindowSlotFunction.cpp index 068668d3..02088de1 100644 --- a/src/ui/main_window/MainWindowSlotFunction.cpp +++ b/src/ui/main_window/MainWindowSlotFunction.cpp @@ -40,6 +40,7 @@ #include "core/function/gpg/GpgKeyGetter.h" #include "core/function/gpg/GpgKeyImportExporter.h" #include "core/function/gpg/GpgKeyManager.h" +#include "core/thread/DataObject.h" #include "dialog/SignersPicker.h" #include "spdlog/spdlog.h" #include "ui/UserInterfaceUtils.h" @@ -58,22 +59,17 @@ void MainWindow::slot_encrypt() { auto key_ids = m_key_list_->GetChecked(); // data to transfer into task - auto data_object = std::make_shared<Thread::Task::DataObject>(); - - // set input buffer - auto buffer = - edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString(); - data_object->AppendObject(std::move(buffer)); + auto data_object = Thread::TransferParams(std::move( + edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString())); // the callback function - auto result_callback = [this](int rtn, - Thread::Task::DataObjectPtr data_object) { + auto result_callback = [this](int rtn, Thread::DataObjectPtr data_object) { if (!rtn) { - if (data_object->GetObjectSize() != 3) - throw std::runtime_error("Invalid data object size"); - auto error = data_object->PopObject<GpgError>(); - auto result = data_object->PopObject<GpgEncrResult>(); - auto tmp = data_object->PopObject<std::unique_ptr<ByteArray>>(); + if (!data_object->Check<GpgError, GpgEncrResult, ByteArrayPtr>()) + throw std::runtime_error("data object doesn't pass checking"); + auto error = Thread::ExtractParams<GpgError>(data_object, 0); + auto result = Thread::ExtractParams<GpgEncrResult>(data_object, 1); + auto tmp = Thread::ExtractParams<ByteArrayPtr>(data_object, 2); auto resultAnalyse = GpgEncryptResultAnalyse(error, std::move(result)); resultAnalyse.Analyse(); @@ -104,19 +100,19 @@ void MainWindow::slot_encrypt() { if (ret == QMessageBox::Cancel) return; encrypt_type = _("Symmetrically Encrypting"); - encrypt_runner = [](Thread::Task::DataObjectPtr data_object) -> int { - if (data_object == nullptr || data_object->GetObjectSize() != 1) - throw std::runtime_error("Invalid data object size"); - auto buffer = data_object->PopObject<std::string>(); + encrypt_runner = [](Thread::DataObjectPtr data_object) -> int { + if (data_object == nullptr || !data_object->Check<std::string>()) + throw std::runtime_error("data object doesn't pass checking"); + auto buffer = Thread::ExtractParams<std::string>(data_object, 0); try { GpgEncrResult result = nullptr; - auto tmp = std::make_unique<ByteArray>(); + auto tmp = std::make_shared<ByteArray>(); GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().EncryptSymmetric( buffer, tmp, result); - data_object->AppendObject(std::move(tmp)); - data_object->AppendObject(std::move(result)); - data_object->AppendObject(std::move(error)); + + data_object->Swap(Thread::DataObject{ + std::move(error), std::move(result), std::move(tmp)}); } catch (const std::runtime_error& e) { return -1; } @@ -144,22 +140,21 @@ void MainWindow::slot_encrypt() { // Asymmetric Encrypt encrypt_type = _("Encrypting"); - encrypt_runner = [](Thread::Task::DataObjectPtr data_object) -> int { + encrypt_runner = [](Thread::DataObjectPtr data_object) -> int { // check the size of the data object - if (data_object == nullptr || data_object->GetObjectSize() != 2) - throw std::runtime_error("Invalid data object size"); + if (data_object == nullptr || + !data_object->Check<std::string, KeyListPtr>()) + throw std::runtime_error("data object doesn't pass checking"); - auto keys = data_object->PopObject<KeyListPtr>(); - auto buffer = data_object->PopObject<std::string>(); + auto buffer = Thread::ExtractParams<std::string>(data_object, 0); + auto keys = Thread::ExtractParams<KeyListPtr>(data_object, 1); try { GpgEncrResult result = nullptr; - auto tmp = std::make_unique<ByteArray>(); + auto tmp = std::make_shared<ByteArray>(); GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().Encrypt( std::move(keys), buffer, tmp, result); - data_object->AppendObject(std::move(tmp)); - data_object->AppendObject(std::move(result)); - data_object->AppendObject(std::move(error)); + data_object->Swap({error, result, tmp}); } catch (const std::runtime_error& e) { return -1; } @@ -201,7 +196,7 @@ void MainWindow::slot_sign() { } // data to transfer into task - auto data_object = std::make_shared<Thread::Task::DataObject>(); + auto data_object = Thread::TransferParams(); // set input buffer auto buffer = @@ -211,35 +206,34 @@ void MainWindow::slot_sign() { // push the keys into data object data_object->AppendObject(std::move(keys)); - auto sign_ruunner = [](Thread::Task::DataObjectPtr data_object) -> int { + auto sign_ruunner = [](Thread::DataObjectPtr data_object) -> int { // check the size of the data object if (data_object == nullptr || data_object->GetObjectSize() != 2) - throw std::runtime_error("Invalid data object size"); + throw std::runtime_error("data object doesn't pass checking"); + + auto buffer = Thread::ExtractParams<std::string>(data_object, 0); + auto keys = Thread::ExtractParams<KeyListPtr>(data_object, 1); - auto keys = data_object->PopObject<KeyListPtr>(); - auto buffer = data_object->PopObject<std::string>(); try { GpgSignResult result = nullptr; - auto tmp = std::make_unique<ByteArray>(); + auto tmp = std::make_shared<ByteArray>(); GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().Sign( std::move(keys), buffer, tmp, GPGME_SIG_MODE_CLEAR, result); - data_object->AppendObject(std::move(tmp)); - data_object->AppendObject(std::move(result)); - data_object->AppendObject(std::move(error)); + + data_object->Swap({error, result, tmp}); } catch (const std::runtime_error& e) { return -1; } return 0; }; - auto result_callback = [this](int rtn, - Thread::Task::DataObjectPtr data_object) { + auto result_callback = [this](int rtn, Thread::DataObjectPtr data_object) { if (!rtn) { if (data_object == nullptr || data_object->GetObjectSize() != 3) - throw std::runtime_error("Invalid data object size"); - auto error = data_object->PopObject<GpgError>(); - auto result = data_object->PopObject<GpgSignResult>(); - auto tmp = data_object->PopObject<std::unique_ptr<ByteArray>>(); + throw std::runtime_error("data object doesn't pass checking"); + auto error = Thread::ExtractParams<GpgError>(data_object, 0); + auto result = Thread::ExtractParams<GpgSignResult>(data_object, 1); + auto tmp = Thread::ExtractParams<ByteArrayPtr>(data_object, 2); auto resultAnalyse = GpgSignResultAnalyse(error, std::move(result)); resultAnalyse.Analyse(); process_result_analyse(edit_, info_board_, resultAnalyse); @@ -273,41 +267,36 @@ void MainWindow::slot_decrypt() { } // data to transfer into task - auto data_object = std::make_shared<Thread::Task::DataObject>(); + auto data_object = Thread::TransferParams( + edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString()); - // set input buffer - auto buffer = - edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString(); - data_object->AppendObject(std::move(buffer)); - - auto decrypt_runner = [](Thread::Task::DataObjectPtr data_object) -> int { + auto decrypt_runner = [](Thread::DataObjectPtr data_object) -> int { // check the size of the data object if (data_object == nullptr || data_object->GetObjectSize() != 1) - throw std::runtime_error("Invalid data object size"); + throw std::runtime_error("data object doesn't pass checking"); - auto buffer = data_object->PopObject<std::string>(); + auto buffer = Thread::ExtractParams<std::string>(data_object, 0); try { GpgDecrResult result = nullptr; - auto decrypted = std::make_unique<ByteArray>(); + auto decrypted = std::make_shared<ByteArray>(); GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().Decrypt( buffer, decrypted, result); - data_object->AppendObject(std::move(decrypted)); - data_object->AppendObject(std::move(result)); - data_object->AppendObject(std::move(error)); + + data_object->Swap({error, result, decrypted}); } catch (const std::runtime_error& e) { return -1; } return 0; }; - auto result_callback = [this](int rtn, - Thread::Task::DataObjectPtr data_object) { + auto result_callback = [this](int rtn, Thread::DataObjectPtr data_object) { if (!rtn) { - if (data_object == nullptr || data_object->GetObjectSize() != 3) - throw std::runtime_error("Invalid data object size"); - auto error = data_object->PopObject<GpgError>(); - auto result = data_object->PopObject<GpgDecrResult>(); - auto decrypted = data_object->PopObject<std::unique_ptr<ByteArray>>(); + if (data_object == nullptr || + !data_object->Check<GpgError, GpgDecrResult, ByteArrayPtr>()) + throw std::runtime_error("data object doesn't pass checking"); + auto error = Thread::ExtractParams<GpgError>(data_object, 0); + auto result = Thread::ExtractParams<GpgDecrResult>(data_object, 1); + auto decrypted = Thread::ExtractParams<ByteArrayPtr>(data_object, 2); auto resultAnalyse = GpgDecryptResultAnalyse(error, std::move(result)); resultAnalyse.Analyse(); process_result_analyse(edit_, info_board_, resultAnalyse); @@ -332,43 +321,43 @@ void MainWindow::slot_verify() { } // data to transfer into task - auto data_object = std::make_shared<Thread::Task::DataObject>(); + auto data_object = Thread::TransferParams(); // set input buffer auto buffer = edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString(); data_object->AppendObject(std::move(buffer)); - auto verify_runner = [](Thread::Task::DataObjectPtr data_object) -> int { + auto verify_runner = [](Thread::DataObjectPtr data_object) -> int { // check the size of the data object - if (data_object == nullptr || data_object->GetObjectSize() != 1) - throw std::runtime_error("Invalid data object size"); + if (data_object == nullptr || !data_object->Check<std::string>()) + throw std::runtime_error("data object doesn't pass checking"); - auto buffer = data_object->PopObject<std::string>(); + auto buffer = Thread::ExtractParams<std::string>(data_object, 0); SPDLOG_DEBUG("verify buffer size: {}", buffer.size()); try { GpgVerifyResult verify_result = nullptr; - auto sig_buffer = std::unique_ptr<ByteArray>(nullptr); + auto sig_buffer = ByteArrayPtr(nullptr); GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().Verify( buffer, sig_buffer, verify_result); - data_object->AppendObject(std::move(verify_result)); - data_object->AppendObject(std::move(error)); + data_object->Swap({error, verify_result}); } catch (const std::runtime_error& e) { return -1; } return 0; }; - auto result_callback = [this](int rtn, - Thread::Task::DataObjectPtr data_object) { + auto result_callback = [this](int rtn, Thread::DataObjectPtr data_object) { if (!rtn) { - if (data_object == nullptr || data_object->GetObjectSize() != 2) - throw std::runtime_error("Invalid data object size"); - auto error = data_object->PopObject<GpgError>(); - auto verify_result = data_object->PopObject<GpgVerifyResult>(); + if (data_object == nullptr || + !data_object->Check<GpgError, GpgVerifyResult>()) + throw std::runtime_error("data object doesn't pass checking"); + auto error = Thread::ExtractParams<GpgError>(data_object, 0); + auto verify_result = + Thread::ExtractParams<GpgVerifyResult>(data_object, 1); auto result_analyse = GpgVerifyResultAnalyse(error, verify_result); result_analyse.Analyse(); @@ -443,37 +432,29 @@ void MainWindow::slot_encrypt_sign() { } // data to transfer into task - auto data_object = std::make_shared<Thread::Task::DataObject>(); - - // set input buffer - auto buffer = - edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString(); - data_object->AppendObject(std::move(buffer)); - // push the keys into data object - data_object->AppendObject(std::move(keys)); - data_object->AppendObject(std::move(signer_keys)); + auto data_object = Thread::TransferParams( + std::move(signer_keys), std::move(keys), + std::move( + edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString())); - auto encrypt_sign_runner = - [](Thread::Task::DataObjectPtr data_object) -> int { + auto encrypt_sign_runner = [](Thread::DataObjectPtr data_object) -> int { // check the size of the data object - if (data_object == nullptr || data_object->GetObjectSize() != 3) - throw std::runtime_error("Invalid data object size"); + if (data_object == nullptr || + !data_object->Check<KeyListPtr, KeyListPtr, std::string>()) + throw std::runtime_error("data object doesn't pass checking"); - auto signer_keys = data_object->PopObject<KeyListPtr>(); - auto keys = data_object->PopObject<KeyListPtr>(); - auto buffer = data_object->PopObject<std::string>(); + auto signer_keys = Thread::ExtractParams<KeyListPtr>(data_object, 0); + auto keys = Thread::ExtractParams<KeyListPtr>(data_object, 1); + auto buffer = Thread::ExtractParams<std::string>(data_object, 2); try { GpgEncrResult encr_result = nullptr; GpgSignResult sign_result = nullptr; - auto tmp = std::make_unique<ByteArray>(); + auto tmp = std::make_shared<ByteArray>(); GpgError error = GpgFrontend::GpgBasicOperator::GetInstance().EncryptSign( std::move(keys), std::move(signer_keys), buffer, tmp, encr_result, sign_result); - data_object->AppendObject(std::move(tmp)); - data_object->AppendObject(std::move(sign_result)); - data_object->AppendObject(std::move(encr_result)); - data_object->AppendObject(std::move(error)); + data_object->Swap({error, encr_result, sign_result, tmp}); } catch (const std::runtime_error& e) { return -1; @@ -481,15 +462,17 @@ void MainWindow::slot_encrypt_sign() { return 0; }; - auto result_callback = [this](int rtn, - Thread::Task::DataObjectPtr data_object) { + auto result_callback = [this](int rtn, Thread::DataObjectPtr data_object) { if (!rtn) { - if (data_object == nullptr || data_object->GetObjectSize() != 4) - throw std::runtime_error("Invalid data object size"); - auto error = data_object->PopObject<GpgError>(); - auto encrypt_result = data_object->PopObject<GpgEncrResult>(); - auto sign_result = data_object->PopObject<GpgSignResult>(); - auto tmp = data_object->PopObject<std::unique_ptr<ByteArray>>(); + if (data_object == nullptr || + !data_object + ->Check<GpgError, GpgEncrResult, GpgSignResult, ByteArrayPtr>()) + throw std::runtime_error("data object doesn't pass checking"); + auto error = Thread::ExtractParams<GpgError>(data_object, 0); + auto encrypt_result = + Thread::ExtractParams<GpgEncrResult>(data_object, 1); + auto sign_result = Thread::ExtractParams<GpgSignResult>(data_object, 2); + auto tmp = Thread::ExtractParams<ByteArrayPtr>(data_object, 3); auto encrypt_result_analyse = GpgEncryptResultAnalyse(error, std::move(encrypt_result)); @@ -522,31 +505,24 @@ void MainWindow::slot_decrypt_verify() { } // data to transfer into task - auto data_object = std::make_shared<Thread::Task::DataObject>(); + auto data_object = Thread::TransferParams(std::move( + edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString())); - // set input buffer - auto buffer = - edit_->CurTextPage()->GetTextPage()->toPlainText().toStdString(); - data_object->AppendObject(std::move(buffer)); - - auto decrypt_verify_runner = - [](Thread::Task::DataObjectPtr data_object) -> int { + auto decrypt_verify_runner = [](Thread::DataObjectPtr data_object) -> int { // check the size of the data object - if (data_object == nullptr || data_object->GetObjectSize() != 1) - throw std::runtime_error("Invalid data object size"); + if (data_object == nullptr || !data_object->Check<std::string>()) + throw std::runtime_error("data object doesn't pass checking"); - auto buffer = data_object->PopObject<std::string>(); + auto buffer = Thread::ExtractParams<std::string>(data_object, 0); try { GpgDecrResult decrypt_result = nullptr; GpgVerifyResult verify_result = nullptr; - auto decrypted_buffer = std::make_unique<ByteArray>(); + auto decrypted_buffer = std::make_shared<ByteArray>(); GpgError error = GpgBasicOperator::GetInstance().DecryptVerify( buffer, decrypted_buffer, decrypt_result, verify_result); - data_object->AppendObject(std::move(decrypted_buffer)); - data_object->AppendObject(std::move(verify_result)); - data_object->AppendObject(std::move(decrypt_result)); - data_object->AppendObject(std::move(error)); + data_object->Swap( + {error, decrypt_result, verify_result, decrypted_buffer}); } catch (const std::runtime_error& e) { SPDLOG_ERROR(e.what()); return -1; @@ -554,16 +530,19 @@ void MainWindow::slot_decrypt_verify() { return 0; }; - auto result_callback = [this](int rtn, - Thread::Task::DataObjectPtr data_object) { + auto result_callback = [this](int rtn, Thread::DataObjectPtr data_object) { if (!rtn) { - if (data_object == nullptr || data_object->GetObjectSize() != 4) - throw std::runtime_error("Invalid data object size"); - - auto error = data_object->PopObject<GpgError>(); - auto decrypt_result = data_object->PopObject<GpgDecrResult>(); - auto verify_result = data_object->PopObject<GpgVerifyResult>(); - auto decrypted = data_object->PopObject<std::unique_ptr<ByteArray>>(); + if (data_object == nullptr || + !data_object->Check<GpgError, GpgDecrResult, GpgVerifyResult, + ByteArrayPtr>()) + throw std::runtime_error("data object doesn't pass checking"); + + auto error = Thread::ExtractParams<GpgError>(data_object, 0); + auto decrypt_result = + Thread::ExtractParams<GpgDecrResult>(data_object, 1); + auto verify_result = + Thread::ExtractParams<GpgVerifyResult>(data_object, 2); + auto decrypted = Thread::ExtractParams<ByteArrayPtr>(data_object, 3); auto decrypt_result_analyse = GpgDecryptResultAnalyse(error, std::move(decrypt_result)); @@ -612,7 +591,7 @@ void MainWindow::slot_append_selected_keys() { return; } - auto exported = std::make_unique<ByteArray>(); + auto exported = std::make_shared<ByteArray>(); auto key_ids = m_key_list_->GetSelected(); if (key_ids->empty()) { |