diff options
| author | saturneric <[email protected]> | 2026-09-19 11:57:16 +0200 |
|---|---|---|
| committer | saturneric <[email protected]> | 2026-09-19 11:57:16 +0200 |
| commit | cf2eebe9eea1cad1d12dd789fea13d511a63b4b0 (patch) | |
| tree | e25c9cf4f21a4c0d11d7b4be3888bd60b6fed52b /include/GFModuleCommonUtils.hpp | |
| parent | feat(modules): package modules as signed gfmodule files (diff) | |
| download | modules-cf2eebe9eea1cad1d12dd789fea13d511a63b4b0.tar.gz modules-cf2eebe9eea1cad1d12dd789fea13d511a63b4b0.zip | |
refactor(module): centralize module headers and identity
- split common utilities into focused logging, event, i18n, memory,
and conversion headers
- add GFModule.h as the unified module include
- derive bootstrap identity and translation context from generated metadata
- replace parameterized bootstrap macros with GF_MODULE_BOOTSTRAP()
- retain deprecated compatibility headers and allocation helper names
- remove the obsolete GFModuleDeclare.h interface
- correct non-debug logging macros to use their intended levels
Diffstat (limited to 'include/GFModuleCommonUtils.hpp')
| -rw-r--r-- | include/GFModuleCommonUtils.hpp | 522 |
1 files changed, 5 insertions, 517 deletions
diff --git a/include/GFModuleCommonUtils.hpp b/include/GFModuleCommonUtils.hpp index 8a4c1a7..ca224fa 100644 --- a/include/GFModuleCommonUtils.hpp +++ b/include/GFModuleCommonUtils.hpp @@ -28,522 +28,10 @@ #pragma once -#include <GFSDKBasic.h> -#include <GFSDKLog.h> -#include <GFSDKModule.h> -#include <GFSDKUI.h> -#include <GFSDKUIModel.h> - -#include <QByteArray> -#include <QMap> -#include <QSharedPointer> -#include <QString> -#include <QVariant> -#include <cstring> - -// OWNERSHIP, in one place. -// -// SDK ARGUMENTS ARE BORROWED. Pass a pointer straight through -- -// `s.toUtf8().constData()` for a QString -- and keep owning it. Do NOT -// pre-allocate one to hand over: nothing on the other side will free it. -// That is what DUP()/QDUP() used to be for, and why they are gone. +// DEPRECATED. This header's contents were split by concern into GFModule.h and +// the five headers it pulls in. It remains for one cycle so that a module can +// be ported without being rewritten in the same commit. // -// The one exception, and it is a struct rather than an argument: the few -// aggregates a module builds and hands over whole (GFModuleEvent, -// GFModuleEventParam, GFModuleMetaData, GFCommandExecuteContext) still -// transfer, so their char* members are still allocated with GFModuleStrDup. -// -// SDK RETURN VALUES ARE OWNED. Reclaim them, which is what the UDUP family -// is for -- that half of the old convention was always right. -#define DUP(v) GFModuleStrDup(v) -#define SECDUP(v) GFModuleSecStrDup(v) -#define UDUP(v) UnStrDup(v) -#define USECDUP(v) UnSecStrDup(v) -#define UDUPN(v, n) UnBytesDup(v, n) - -// No DUP: SDK arguments are borrowed now, so pre-allocating here would leak. -#define LISTEN(event) GFModuleListenEvent(GFGetModuleID(), (event)) - -#define DEFINE_TRANSLATIONS_STRUCTURE(name) \ - class GTrC { \ - Q_DECLARE_TR_FUNCTIONS(GTrC) \ - }; \ - auto TranslatorDataReader(const char* p_l, char** p_d)->int { \ - auto locale = QString::fromUtf8(p_l == nullptr ? "" : p_l); \ - QFile f(QString(":/i18n/%2.%1.qm").arg(locale).arg(#name)); \ - if (f.exists() && f.open(QIODevice::ReadOnly)) { \ - auto b = f.readAll(); \ - *p_d = AllocBufferAndCopy(b); \ - return b.size(); \ - } \ - FLOG_WARN("%3 loading, locale: %1, not found", locale, f.fileName(), \ - QString::fromUtf8(GFGetModuleID())); \ - *p_d = nullptr; \ - return 0; \ - } - -#define REGISTER_TRANS_READER() \ - GFAppRegisterTranslatorReader(GFGetModuleID(), TranslatorDataReader) - -#define GC_TR(text) QT_TRANSLATE_NOOP("GTrC", text) - -#define CONCATENATE_DETAIL(x, y) x##y -#define CONCATENATE(x, y) CONCATENATE_DETAIL(x, y) -#define GTRC_TR(name, src) CONCATENATE(GTrC_, name)::tr(src) - -#define STRINGIFY(x) #x -#define TOSTRING(x) STRINGIFY(x) -#define GTRC_AS_STRING(name) TOSTRING(GTrC_##name) - -#define EXECUTE_MODULE() \ - auto GFExecuteModule(GFModuleEvent* p_event)->int { \ - auto event = ConvertEventToMap(p_event); - -#define END_EXECUTE_MODULE() } - -#undef CB_SUCC -#define CB_SUCC(event) \ - { \ - CB(event, GFGetModuleID(), {{"ret", "0"}}); \ - return 0; \ - } - -#undef CB_ERR -#define CB_ERR(event, ret, err) \ - { \ - CB(event, GFGetModuleID(), \ - {{"ret", QString::number(ret)}, {"err", QString(err)}}); \ - return ret; \ - } - -#undef CB_ERR_NO_RET -#define CB_ERR_NO_RET(event, ret, err) \ - { \ - CB(event, GFGetModuleID(), \ - {{"ret", QString::number(ret)}, {"err", QString(err)}}); \ - } - -#define DEFINE_EXECUTE_API_USING_STANDARD_EVEN_HANDLE_MODEL \ - EXECUTE_MODULE() { \ - auto event_id = event["event_id"]; \ - auto it = _gr_module_event_handlers.find(event_id); \ - if (it != _gr_module_event_handlers.end()) { \ - return it.value()(event); \ - } \ - CB_ERR(event, -1, QString("unsupported event id: %1").arg(event_id)); \ - } \ - END_EXECUTE_MODULE() - -#define REGISTER_EVENT_HANDLER(event_id, handler) \ - namespace { \ - auto _gv_register_event_handler_by_id_##event_id = []() -> const bool { \ - _gr_module_event_handlers[#event_id] = handler; \ - return true; \ - }(); \ - } - -inline void MLogDebug(const QString& s) { GFModuleLogDebug(s.toUtf8()); } -inline void MLogInfo(const QString& s) { GFModuleLogInfo(s.toUtf8()); } -inline void MLogWarn(const QString& s) { GFModuleLogWarn(s.toUtf8()); } -inline void MLogError(const QString& s) { GFModuleLogError(s.toUtf8()); } - -#define LOG_DEBUG(format) MLogDebug(FormatString(QString(format))) -#define LOG_INFO(format) MLogDebug(FormatString(QString(format))) -#define LOG_WARN(format) MLogDebug(FormatString(QString(format))) -#define LOG_ERROR(format) MLogDebug(FormatString(QString(format))) - -#define FLOG_DEBUG(format, ...) \ - MLogDebug(FormatString(QString(format), __VA_ARGS__)) -#define FLOG_INFO(format, ...) \ - MLogInfo(FormatString(QString(format), __VA_ARGS__)) -#define FLOG_WARN(format, ...) \ - MLogWarn(FormatString(QString(format), __VA_ARGS__)) -#define FLOG_ERROR(format, ...) \ - MLogError(FormatString(QString(format), __VA_ARGS__)) - -inline auto QStrDup(const QString& str) -> char* { return DUP(str.toUtf8()); } - -inline auto QSecStrDup(const QString& str) -> char* { - return SECDUP(str.toUtf8()); -} - -/// Takes ownership of a sized SDK buffer and returns its octets verbatim. -/// -/// The QString forms below decode UTF-8 and stop at the first NUL, which is -/// right for identifiers and error strings and wrong for message data: a MIME -/// entity may be 8bit or binary, and a signature covers exact octets. Anything -/// that crosses the crypto boundary must use this and the matching @c *N SDK -/// entry points instead. -inline auto UnBytesDup(const char* s, size_t size) -> QByteArray { - if (s == nullptr) return {}; - QByteArray bytes(s, static_cast<qsizetype>(size)); - GFFreeMemory(static_cast<void*>(const_cast<char*>(s))); - return bytes; -} - -inline auto UnStrDup(const char* s) -> QString { - auto q_s = QString::fromUtf8(s == nullptr ? "" : s); - if (s != nullptr) GFFreeMemory(static_cast<void*>(const_cast<char*>(s))); - return q_s; -} - -inline auto UnSecStrDup(const char* s) -> QString { - auto q_s = QString::fromUtf8(s == nullptr ? "" : s); - if (s != nullptr) GFSecFreeMemory(static_cast<void*>(const_cast<char*>(s))); - return q_s; -} - -inline auto FormatStringHelper(const QString& format, const std::string& arg) - -> QString { - return format.arg(QString::fromStdString(arg)); -} - -template <typename T> -auto FormatStringHelper(const QString& format, T arg) -> QString { - return format.arg(arg); -} - -template <typename... Args> -auto FormatStringHelper(const QString& format, const std::string& arg, - Args... args) -> QString { - return FormatStringHelper(format.arg(QString::fromStdString(arg)), args...); -} - -template <typename T, typename... Args> -auto FormatStringHelper(const QString& format, T arg, Args... args) -> QString { - return FormatStringHelper(format.arg(arg), args...); -} - -inline auto FormatStringHelper(const QString& format) -> QString { - return format; -} - -template <typename T> -inline auto FormatStringHelper(const T& format) -> - typename std::enable_if<std::is_same<T, std::string>::value, - QString>::type { - return FormatStringHelper(QString::fromStdString(format)); -} - -template <typename... Args> -auto FormatString(const QString& format, Args... args) -> QString { - return FormatStringHelper(format, args...); -} - -inline auto QMapToMetaDataArray(const QMap<QString, QString>& map) - -> MetaData** { - auto** meta_data_array = - static_cast<MetaData**>(GFAllocateMemory(sizeof(MetaData*) * map.size())); - - int index = 0; - for (auto it = map.begin(); it != map.end(); ++it) { - meta_data_array[index] = - static_cast<MetaData*>(GFAllocateMemory(sizeof(MetaData))); - - QByteArray const key = it.key().toUtf8(); - QByteArray const value = it.value().toUtf8(); - - meta_data_array[index]->key = GFModuleStrDup(key); - - meta_data_array[index]->value = GFModuleStrDup(value); - - ++index; - } - - return meta_data_array; -} - -inline auto QMapToGFModuleMetaDataList(const QMap<QString, QString>& map) - -> GFModuleMetaData* { - GFModuleMetaData* head = nullptr; - GFModuleMetaData* tail = nullptr; - - for (auto it = map.begin(); it != map.end(); ++it) { - auto* new_node = static_cast<GFModuleMetaData*>( - GFAllocateMemory(sizeof(GFModuleMetaData))); - - QByteArray const key = it.key().toUtf8(); - QByteArray const value = it.value().toUtf8(); - - new_node->key = DUP(key); - new_node->value = SECDUP(value); - - new_node->next = nullptr; - - if (tail != nullptr) { - tail->next = new_node; - } else { - head = new_node; - } - tail = new_node; - } - - return head; -} - -inline auto ConvertEventParamsToMap(GFModuleEventParam* params) - -> QMap<QString, QString> { - QMap<QString, QString> param_map; - GFModuleEventParam* current = params; - GFModuleEventParam* last; - - while (current != nullptr) { - const auto name = UDUP(current->name); - const auto value = USECDUP(current->value); - - if (!name.isEmpty()) param_map[name] = value; - - last = current; - current = current->next; - GFFreeMemory(last); - } - - return param_map; -} - -inline auto ConvertMapToParams(const QMap<QString, QString>& param_map) - -> GFModuleEventParam* { - GFModuleEventParam* head = nullptr; - GFModuleEventParam* prev = nullptr; -#if QT_VERSION >= QT_VERSION_CHECK(6, 4, 0) - for (const auto& [key, value] : param_map.asKeyValueRange()) { - auto* param = static_cast<GFModuleEventParam*>( - GFAllocateMemory(sizeof(GFModuleEventParam))); - - param->name = DUP(key.toUtf8()); - param->value = SECDUP(value.toUtf8()); - param->next = nullptr; - - if (prev == nullptr) { - head = param; - } else { - prev->next = param; - } - prev = param; - } -#else - for (auto it = param_map.keyValueBegin(); it != param_map.keyValueEnd(); - ++it) { - auto* param = static_cast<GFModuleEventParam*>( - GFAllocateMemory(sizeof(GFModuleEventParam))); - - param->name = DUP(it->first.toUtf8()); - param->value = SECDUP(it->second.toUtf8()); - param->next = nullptr; - - if (prev == nullptr) { - head = param; - } else { - prev->next = param; - } - prev = param; - } -#endif - - return head; -} - -inline auto ConvertEventToMap(GFModuleEvent* event) -> QMap<QString, QString> { - QMap<QString, QString> event_map; - - event_map["event_id"] = UDUP(event->id); - event_map["trigger_id"] = UDUP(event->trigger_id); - event_map.insert(ConvertEventParamsToMap(event->params)); - - GFFreeMemory(event); - - return event_map; -} - -inline auto ConvertMapToEvent(QMap<QString, QString> event_map) - -> GFModuleEvent* { - auto* event = - static_cast<GFModuleEvent*>(GFAllocateMemory(sizeof(GFModuleEvent))); - - event->id = DUP(event_map["event_id"].toUtf8()); - event->trigger_id = DUP(event_map["trigger_id"].toUtf8()); - event->params = nullptr; - - return event; -} - -inline void CB(const QMap<QString, QString>& event, const char* module, - const QMap<QString, QString>& params) { - GFModuleTriggerModuleEventCallback(ConvertMapToEvent(event), module, - ConvertMapToParams(params)); -} - -/// Copies @p b into an SDK buffer, NUL-terminated one past the end. -/// -/// The terminator is not optional politeness: the buffer is handed to the -/// host, and a caller that treats it as a C string would otherwise read past -/// the allocation. @p b .size() stays authoritative for the byte count. -inline auto AllocBufferAndCopy(const QByteArray& b) -> char* { - auto* p = static_cast<char*>(GFAllocateMemory(sizeof(char) * (b.size() + 1))); - if (p == nullptr) return nullptr; - memcpy(p, b.constData(), b.size()); - p[b.size()] = '\0'; - return p; -} - -/// NOTE ON NAMING: the four helpers below say "Secure" but allocate from the -/// ORDINARY arena (GFAllocateMemory), not the wiping one (GFSecAllocateMemory). -/// They are named for the SDK allocator generally, not for the secure tier. -/// For anything that must actually be erased, use the secure tier explicitly -/// or a GFBuf handle -- do not rely on these names. -template <typename T, typename... Args> -auto SecureCreateSharedObject(Args&&... args) -> std::shared_ptr<T> { - void* mem = GFAllocateMemory(sizeof(T)); - if (!mem) throw std::bad_alloc(); - - try { - T* obj = new (mem) T(std::forward<Args>(args)...); - return std::shared_ptr<T>(obj, [](T* ptr) { - ptr->~T(); - GFFreeMemory(ptr); - }); - } catch (...) { - GFFreeMemory(mem); - throw; - } -} - -template <typename T> -class PointerConverter { - public: - explicit PointerConverter(void* ptr) : ptr_(ptr) {} - - auto AsType() const -> T* { return static_cast<T*>(ptr_); } - - private: - void* ptr_; -}; - -/** - * @brief - * - * @tparam T - * @return T* - */ -template <typename T> -auto SecureMallocAsType(std::size_t size) -> T* { - return PointerConverter<T>(GFAllocateMemory(size)).AsType(); -} - -/** - * @brief - * - * @return void* - */ -template <typename T> -auto SecureReallocAsType(T* ptr, std::size_t size) -> T* { - return PointerConverter<T>(GFReallocateMemory(ptr, size)).AsType(); -} - -template <typename T, typename... Args> -auto SecureCreateQSharedObject(Args&&... args) -> QSharedPointer<T> { - void* mem = GFAllocateMemory(sizeof(T)); - if (!mem) throw std::bad_alloc(); - - try { - T* obj = new (mem) T(std::forward<Args>(args)...); - return QSharedPointer<T>(obj, [](T* ptr) { - ptr->~T(); - GFFreeMemory(ptr); - }); - } catch (...) { - GFFreeMemory(mem); - throw; - } -} - -inline auto CharArrayToQStringList(char** pl_components, int size) - -> QStringList { - QStringList list; - for (int i = 0; i < size; ++i) { - list.append(UDUP(pl_components[i])); - } - GFFreeMemory(static_cast<void*>(pl_components)); - return list; -} - -inline auto QStringListToCharArray(const QStringList& list) -> char** { - char** char_array = - static_cast<char**>(GFAllocateMemory(list.size() * sizeof(char*))); - - int index = 0; - for (const QString& item : list) { - QByteArray value = item.toUtf8(); - char_array[index] = static_cast<char*>(GFAllocateMemory(value.size() + 1)); - std::strcpy(char_array[index], value.constData()); - index++; - } - - return char_array; -} - -template <typename T> -inline auto ArrayToQList(T** pl_components, int size) -> QList<T> { - if (pl_components == nullptr || size <= 0) { - return QList<T>(); - } - - QList<T> list; - for (int i = 0; i < size; ++i) { - list.append(*pl_components[i]); - GFFreeMemory(pl_components[i]); - } - GFFreeMemory(pl_components); - return list; -} - -template <typename T> -inline auto QListToArray(const QList<T>& list) -> T** { - T** array = static_cast<T**>(GFAllocateMemory(list.size() * sizeof(T*))); - int index = 0; - for (const T& item : list) { - auto mem = static_cast<T*>(GFAllocateMemory(sizeof(T))); - array[index] = new (mem) T(item); - index++; - } - - return array; -} - -inline auto ConvertQVariantToVoidPtr(const QVariant& variant) -> void* { - void* mem = GFAllocateMemory(sizeof(QVariant)); - auto* variant_ptr = new (mem) QVariant(variant); - return static_cast<void*>(variant_ptr); -} - -inline auto ConvertVoidPtrToQVariant(void* ptr) -> QVariant { - if (ptr == nullptr) return {}; - - auto* variant_ptr = static_cast<QVariant*>(ptr); - QVariant variant = *variant_ptr; - - GFFreeMemory(variant_ptr); - return variant; -} - -template <typename T> -auto GFUIGetGUIObjectAs(const QString& handle) -> T* { - auto* obj = static_cast<QObject*>( - GFUIGetGUIObject(handle.toUtf8().constData())); - if (!obj) { - return nullptr; - } - return qobject_cast<T*>(obj); -} - -#define Q_VARIANT_Q_OBJECT_FACTORY_DECLARE(name) \ - auto name(void* data_raw_ptr)->void*; - -#define Q_VARIANT_Q_OBJECT_FACTORY_DEFINE(name, func) \ - auto name(void* data_raw_ptr)->void* { \ - auto data = ConvertVoidPtrToQVariant(data_raw_ptr); \ - return func(data); \ - } +// Include "GFModule.h" instead. -#define GUI_OBJECT(factory, data) \ - GFUICreateGUIObject(factory, ConvertQVariantToVoidPtr(data)) +#include "GFModule.h" |
