aboutsummaryrefslogtreecommitdiffstats
path: root/include/GFModuleCommonUtils.hpp
diff options
context:
space:
mode:
authorsaturneric <[email protected]>2026-09-19 11:57:16 +0200
committersaturneric <[email protected]>2026-09-19 11:57:16 +0200
commitcf2eebe9eea1cad1d12dd789fea13d511a63b4b0 (patch)
treee25c9cf4f21a4c0d11d7b4be3888bd60b6fed52b /include/GFModuleCommonUtils.hpp
parentfeat(modules): package modules as signed gfmodule files (diff)
downloadmodules-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.hpp522
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"