From 7c5bc44724f0a3138720ef86f0ace0ab38b9d30f Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Wed, 7 Aug 2024 11:40:18 +0800 Subject: [PATCH] refactor: refactor project - finish document export function. - add lost database validation code in export function. - add assistant macros for convenient utilize functions located in utilities namespace. - update sqlite database open function. --- materializer/DataTypes.hpp | 2 +- materializer/Database.cpp | 18 ++++--- materializer/ExportDocument.cpp | 64 +++++++++++++++++++++++- materializer/ExportEnvironment.cpp | 80 ++++++++++++++++-------------- materializer/Utilities.cpp | 20 ++++---- materializer/Utilities.hpp | 16 +++++- 6 files changed, 141 insertions(+), 59 deletions(-) diff --git a/materializer/DataTypes.hpp b/materializer/DataTypes.hpp index bf99a44..637bef9 100644 --- a/materializer/DataTypes.hpp +++ b/materializer/DataTypes.hpp @@ -175,7 +175,7 @@ namespace VSW::Materializer::DataTypes { CK_ID id; YYCC::yycc_u8string name; CK_CLASSID classid; - YYCC::yycc_u8string classtype; + YYCC::yycc_u8string classid_name; }; class DataCache { diff --git a/materializer/Database.cpp b/materializer/Database.cpp index b4a0a50..d23691f 100644 --- a/materializer/Database.cpp +++ b/materializer/Database.cpp @@ -48,7 +48,7 @@ failed: throw std::runtime_error("fail to bind value for prepared statement."); // connect to database (the argument of sqlite3 open function is UTF8) int errcode; if (file.empty()) goto failed; - errcode = sqlite3_open(YYCC::EncodingHelper::ToOrdinary(file.data()), &m_Db); + errcode = sqlite3_open_v2(YYCC::EncodingHelper::ToOrdinary(file.data()), &m_Db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr); if (errcode != SQLITE_OK) goto failed; // disable synchronous to accelerate speed. @@ -312,26 +312,32 @@ failed: throw std::runtime_error("fail to bind value for prepared statement."); // initialize table BEGIN_CTOR; CTOR_SQL_EXEC("CREATE TABLE [msg] ([index] INTEGER, [name] TEXT);"); - CTOR_SQL_EXEC("CREATE TABLE [obj] ([id] INTEGER, [name] TEXT, [classid] INTEGER, [classtype] TEXT);"); + CTOR_SQL_EXEC("CREATE TABLE [obj] ([id] INTEGER, [name] TEXT, [classid] INTEGER, [classid_name] TEXT);"); END_CTOR; } DocumentDatabase::~DocumentDatabase() { - // do nothing + // create index for quick select in following process + BEGIN_DTOR; + DTOR_SQL_EXEC("begin;"); + DTOR_SQL_EXEC("CREATE INDEX [quick_where1] ON [msg] ([index])"); + DTOR_SQL_EXEC("CREATE INDEX [quick_where2] ON [obj] ([id])"); + DTOR_SQL_EXEC("commit;"); + END_DTOR; } void DocumentDatabase::Write(const DataTypes::Document::Table_msg& data) { BEGIN_WRITER("INSERT INTO [msg] VALUES (?, ?);"); WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.index)); - WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.name.c_str(), -1, SQLITE_TRANSIENT)); + WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.name), -1, SQLITE_TRANSIENT)); END_WRITER; } void DocumentDatabase::Write(const DataTypes::Document::Table_obj& data) { BEGIN_WRITER("INSERT INTO [obj] VALUES (?, ?, ?, ?);"); WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.id)); - WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.name.c_str(), -1, SQLITE_TRANSIENT)); + WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.name), -1, SQLITE_TRANSIENT)); WRITER_BIND(sqlite3_bind_int(WRITER_STMT, WRITER_INDEX, data.classid)); - WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, data.classtype.c_str(), -1, SQLITE_TRANSIENT)); + WRITER_BIND(sqlite3_bind_text(WRITER_STMT, WRITER_INDEX, REVEAL_U8STR(data.classid_name), -1, SQLITE_TRANSIENT)); END_WRITER; } diff --git a/materializer/ExportDocument.cpp b/materializer/ExportDocument.cpp index de722bf..1423eb8 100644 --- a/materializer/ExportDocument.cpp +++ b/materializer/ExportDocument.cpp @@ -1,12 +1,74 @@ #include "ExportCore.hpp" +#include "Database.hpp" +#include "DataTypes.hpp" +#include "Utilities.hpp" +#include namespace VSW::Materializer::ExportDocument { + struct ExportContext { + ExportContext(CKContext* ctx, const YYCC::yycc_u8string_view& db_path, UINT code_page) : + db(db_path), cache(), reporter(ctx), cp(code_page) {} + Database::DocumentDatabase db; + DataTypes::Document::DataCache cache; + Utilities::EnhancedReporter reporter; + UINT cp; + }; + static void IterateMessage(ExportContext& expctx, CKMessageManager* msg_mgr) { + int count = msg_mgr->GetMessageTypeCount(); + for (int i = 0; i < count; i++) { + expctx.cache.msg.index = i; + CP_CKSTR(expctx.cache.msg.name, msg_mgr->GetMessageTypeName(i)); - void Export(CKContext* ctx, const YYCC::yycc_u8string_view& db_path, UINT code_page) { + expctx.db.Write(expctx.cache.msg); + } + } + + /// @brief The common parents list which exported objects belong to. + static const std::vector g_CommonClassIds { + // Export CKSceneObject will export almost objects in scene + // That's enough + CKCID_SCENEOBJECT + }; + static void IterateObject(ExportContext& expctx, CKContext* ctx) { + // Get CKParameterManager to resolve Class ID name + CKParameterManager* param_mgr = ctx->GetParameterManager(); + // prepare variables + CK_CLASSID classid_cache; + + for (const auto& cid : g_CommonClassIds) { + XObjectPointerArray obj_array = ctx->GetObjectListByType(cid, TRUE); + int obj_count = obj_array.Size(); + for (int i = 0; i < obj_count; i++) { + CKSceneObject* scene_obj = static_cast(obj_array.GetObjectA(i)); + + // basic infos + expctx.cache.obj.id = scene_obj->GetID(); + CP_CKSTR(expctx.cache.obj.name, scene_obj->GetName()); + classid_cache = scene_obj->GetClassID(); + expctx.cache.obj.classid = classid_cache; + // resolve class id name + CP_CKSTR(expctx.cache.obj.classid_name, param_mgr->ParameterGuidToName(param_mgr->ClassIDToGuid(classid_cache))); + + expctx.db.Write(expctx.cache.obj); + } + } } + void Export(CKContext* ctx, const YYCC::yycc_u8string_view& db_path, UINT code_page) { + // create export context + ExportContext expctx(ctx, db_path, code_page); + if (!expctx.db.IsValid()) { + expctx.reporter.Err(YYCC_U8("Fail to open database. Export process aborted.")); + return; + } + + // export document + IterateMessage(expctx, ctx->GetMessageManager()); + IterateObject(expctx, ctx); + } + } diff --git a/materializer/ExportEnvironment.cpp b/materializer/ExportEnvironment.cpp index 167ba37..e2ea9a0 100644 --- a/materializer/ExportEnvironment.cpp +++ b/materializer/ExportEnvironment.cpp @@ -27,8 +27,8 @@ namespace VSW::Materializer::ExportEnvironment { // fill the shared data part. expctx.cache.op.op_code = i; guid = param_mgr->OperationCodeToGuid(i); - Utilities::CopyGuid(expctx.reporter, expctx.cache.op.op_guid, guid); - Utilities::CopyCKString(expctx.reporter, expctx.cache.op.op_name, param_mgr->OperationCodeToName(i), expctx.cp); + CP_GUID(expctx.cache.op.op_guid, guid); + CP_CKSTR(expctx.cache.op.op_name, param_mgr->OperationCodeToName(i)); // get all sub-operation of this parameter operation. // each sub-operation can have different in out parameter type @@ -37,10 +37,10 @@ namespace VSW::Materializer::ExportEnvironment { op_list.resize(static_cast(op_list_count)); param_mgr->GetAvailableOperationsDesc(guid, nullptr, nullptr, nullptr, op_list.data()); for (const auto& op : op_list) { - Utilities::CopyGuid(expctx.reporter, expctx.cache.op.in1_guid, op.P1Guid); - Utilities::CopyGuid(expctx.reporter, expctx.cache.op.in2_guid, op.P2Guid); - Utilities::CopyGuid(expctx.reporter, expctx.cache.op.out_guid, op.ResGuid); - expctx.cache.op.func_ptr = Utilities::RelativeAddress(expctx.reporter, op.Fct); + CP_GUID(expctx.cache.op.in1_guid, op.P1Guid); + CP_GUID(expctx.cache.op.in2_guid, op.P2Guid); + CP_GUID(expctx.cache.op.out_guid, op.ResGuid); + CP_ADDR(expctx.cache.op.func_ptr, op.Fct); expctx.db.Write(expctx.cache.op); } @@ -58,17 +58,17 @@ namespace VSW::Materializer::ExportEnvironment { // Parameter basic infos expctx.cache.param.index = desc->Index; - Utilities::CopyGuid(expctx.reporter, expctx.cache.param.guid, desc->Guid); - Utilities::CopyGuid(expctx.reporter, expctx.cache.param.derived_from, desc->DerivedFrom); - Utilities::CopyCKString(expctx.reporter, expctx.cache.param.name, desc->TypeName.CStr(), expctx.cp); + CP_GUID(expctx.cache.param.guid, desc->Guid); + CP_GUID(expctx.cache.param.derived_from, desc->DerivedFrom); + CP_CKSTR(expctx.cache.param.name, desc->TypeName.CStr()); expctx.cache.param.default_size = desc->DefaultSize; - expctx.cache.param.func_CreateDefault = Utilities::RelativeAddress(expctx.reporter, desc->CreateDefaultFunction); - expctx.cache.param.func_Delete = Utilities::RelativeAddress(expctx.reporter, desc->DeleteFunction); - expctx.cache.param.func_SaveLoad = Utilities::RelativeAddress(expctx.reporter, desc->SaveLoadFunction); - expctx.cache.param.func_Check = Utilities::RelativeAddress(expctx.reporter, desc->CheckFunction); - expctx.cache.param.func_Copy = Utilities::RelativeAddress(expctx.reporter, desc->CopyFunction); - expctx.cache.param.func_String = Utilities::RelativeAddress(expctx.reporter, desc->StringFunction); - expctx.cache.param.func_UICreator = Utilities::RelativeAddress(expctx.reporter, desc->UICreatorFunction); + CP_ADDR(expctx.cache.param.func_CreateDefault, desc->CreateDefaultFunction); + CP_ADDR(expctx.cache.param.func_Delete, desc->DeleteFunction); + CP_ADDR(expctx.cache.param.func_SaveLoad, desc->SaveLoadFunction); + CP_ADDR(expctx.cache.param.func_Check, desc->CheckFunction); + CP_ADDR(expctx.cache.param.func_Copy, desc->CopyFunction); + CP_ADDR(expctx.cache.param.func_String, desc->StringFunction); + CP_ADDR(expctx.cache.param.func_UICreator, desc->UICreatorFunction); // Creator dll infos // This is different with plugin. @@ -76,7 +76,7 @@ namespace VSW::Materializer::ExportEnvironment { CKPluginEntry* plugin_entry = desc->CreatorDll; CKPluginDll* plugin_dll = plugin_mgr->GetPluginDllInfo(plugin_entry->m_PluginDllIndex); if (plugin_entry != nullptr) { - Utilities::CopyCKString(expctx.reporter, expctx.cache.param.dll_name, plugin_dll->m_DllFileName.CStr(), expctx.cp); + CP_CKSTR(expctx.cache.param.dll_name, plugin_dll->m_DllFileName.CStr()); expctx.cache.param.dll_index = plugin_entry->m_PluginDllIndex; expctx.cache.param.position_in_dll = plugin_entry->m_PositionInDll; } else { @@ -89,7 +89,7 @@ namespace VSW::Materializer::ExportEnvironment { expctx.cache.param.flags = desc->dwFlags; expctx.cache.param.dw_param = desc->dwParam; expctx.cache.param.cid = desc->Cid; - Utilities::CopyGuid(expctx.reporter, expctx.cache.param.saver_manager, desc->Saver_Manager); + CP_GUID(expctx.cache.param.saver_manager, desc->Saver_Manager); expctx.db.Write(expctx.cache.param); } @@ -100,14 +100,14 @@ namespace VSW::Materializer::ExportEnvironment { int count = attr_mgr->GetAttributeCount(); for (int i = 0; i < count; i++) { expctx.cache.attr.index = i; - Utilities::CopyCKString(expctx.reporter, expctx.cache.attr.name, attr_mgr->GetAttributeNameByType(i), expctx.cp); + CP_CKSTR(expctx.cache.attr.name, attr_mgr->GetAttributeNameByType(i)); expctx.cache.attr.category_index = attr_mgr->GetAttributeCategoryIndex(i); - Utilities::CopyCKString(expctx.reporter, expctx.cache.attr.category_name, attr_mgr->GetAttributeCategory(i), expctx.cp); + CP_CKSTR(expctx.cache.attr.category_name, attr_mgr->GetAttributeCategory(i)); expctx.cache.attr.flags = attr_mgr->GetAttributeFlags(i); expctx.cache.attr.param_index = attr_mgr->GetAttributeParameterType(i); - Utilities::CopyGuid(expctx.reporter, expctx.cache.attr.param_guid, attr_mgr->GetAttributeParameterGUID(i)); + CP_GUID(expctx.cache.attr.param_guid, attr_mgr->GetAttributeParameterGUID(i)); expctx.cache.attr.compatible_classid = attr_mgr->GetAttributeCompatibleClassId(i); - Utilities::CopyCKString(expctx.reporter, expctx.cache.attr.default_value, attr_mgr->GetAttributeDefaultValue(i), expctx.cp); + CP_CKSTR(expctx.cache.attr.default_value, attr_mgr->GetAttributeDefaultValue(i)); expctx.db.Write(expctx.cache.attr); } @@ -121,7 +121,7 @@ namespace VSW::Materializer::ExportEnvironment { int category_count = plugin_mgr->GetCategoryCount(); for (int i = 0; i < category_count; ++i) { // category name and its index - Utilities::CopyCKString(expctx.reporter, expctx.cache.plugin.category_name, plugin_mgr->GetCategoryName(i), expctx.cp); + CP_CKSTR(expctx.cache.plugin.category_name, plugin_mgr->GetCategoryName(i)); expctx.cache.plugin.category_index = i; // iterate plugin within this category @@ -132,21 +132,21 @@ namespace VSW::Materializer::ExportEnvironment { CKPluginDll* plugin_dll = plugin_mgr->GetPluginDllInfo(plugin_entry->m_PluginDllIndex); // dll infomation (name + index + position in dll) - Utilities::CopyCKString(expctx.reporter, expctx.cache.plugin.dll_name, plugin_dll->m_DllFileName.CStr(), expctx.cp); + CP_CKSTR(expctx.cache.plugin.dll_name, plugin_dll->m_DllFileName.CStr()); expctx.cache.plugin.dll_index = plugin_entry->m_PluginDllIndex; expctx.cache.plugin.position_in_dll = plugin_entry->m_PositionInDll; // plugin info expctx.cache.plugin.index = j; - Utilities::CopyGuid(expctx.reporter, expctx.cache.plugin.guid, plugin_info->m_GUID); - Utilities::CopyCKString(expctx.reporter, expctx.cache.plugin.desc, plugin_info->m_Description.CStr(), expctx.cp); - Utilities::CopyCKString(expctx.reporter, expctx.cache.plugin.author, plugin_info->m_Author.CStr(), expctx.cp); - Utilities::CopyCKString(expctx.reporter, expctx.cache.plugin.summary, plugin_info->m_Summary.CStr(), expctx.cp); + CP_GUID(expctx.cache.plugin.guid, plugin_info->m_GUID); + CP_CKSTR(expctx.cache.plugin.desc, plugin_info->m_Description.CStr()); + CP_CKSTR(expctx.cache.plugin.author, plugin_info->m_Author.CStr()); + CP_CKSTR(expctx.cache.plugin.summary, plugin_info->m_Summary.CStr()); expctx.cache.plugin.version = plugin_info->m_Version; plugin_type = plugin_info->m_Type; expctx.cache.plugin.type = plugin_type; - expctx.cache.plugin.func_init = Utilities::RelativeAddress(expctx.reporter, plugin_info->m_InitInstanceFct); - expctx.cache.plugin.func_exit = Utilities::RelativeAddress(expctx.reporter, plugin_info->m_ExitInstanceFct); + CP_ADDR(expctx.cache.plugin.func_init, plugin_info->m_InitInstanceFct); + CP_ADDR(expctx.cache.plugin.func_exit, plugin_info->m_ExitInstanceFct); // extra fields according to plugin type // first reset these specific fields @@ -165,11 +165,11 @@ namespace VSW::Materializer::ExportEnvironment { case CKPLUGIN_MOVIE_READER: { // Reader specific - expctx.cache.plugin.reader_fct = Utilities::RelativeAddress(expctx.reporter, plugin_entry->m_ReadersInfo->m_GetReaderFct); + CP_ADDR(expctx.cache.plugin.reader_fct, plugin_entry->m_ReadersInfo->m_GetReaderFct); expctx.cache.plugin.reader_opt_count = plugin_entry->m_ReadersInfo->m_OptionCount; expctx.cache.plugin.reader_flags = plugin_entry->m_ReadersInfo->m_ReaderFlags; - Utilities::CopyGuid(expctx.reporter, expctx.cache.plugin.reader_setting_param_guid, plugin_entry->m_ReadersInfo->m_SettingsParameterGuid); - Utilities::CopyCKString(expctx.reporter, expctx.cache.plugin.reader_file_ext, static_cast(plugin_info->m_Extension), expctx.cp, YYCC_U8("")); + CP_GUID(expctx.cache.plugin.reader_setting_param_guid, plugin_entry->m_ReadersInfo->m_SettingsParameterGuid); + CP_CKSTR(expctx.cache.plugin.reader_file_ext, static_cast(plugin_info->m_Extension), YYCC_U8("")); break; } case CKPLUGIN_BEHAVIOR_DLL: @@ -178,7 +178,7 @@ namespace VSW::Materializer::ExportEnvironment { std::vector guids; YYCC::yycc_u8string guid_cache; for (int i = 0; i < plugin_entry->m_BehaviorsInfo->m_BehaviorsGUID.Size(); ++i) { - Utilities::CopyStrGuid(expctx.reporter, guid_cache, plugin_entry->m_BehaviorsInfo->m_BehaviorsGUID[i]); + CP_STR_GUID(guid_cache, plugin_entry->m_BehaviorsInfo->m_BehaviorsGUID[i]); guids.emplace_back(guid_cache); } expctx.cache.plugin.behavior_guids = YYCC::StringHelper::Join(guids, YYCC_U8(", ")); @@ -215,9 +215,9 @@ namespace VSW::Materializer::ExportEnvironment { varobj = it.GetVariable(); // variable name var_name = it.GetName(); - Utilities::CopyCKString(expctx.reporter, expctx.cache.variable.name, var_name, expctx.cp); + CP_CKSTR(expctx.cache.variable.name, var_name); // variable description - Utilities::CopyCKString(expctx.reporter, expctx.cache.variable.desciption, varobj->GetDescription(), expctx.cp); + CP_CKSTR(expctx.cache.variable.desciption, varobj->GetDescription()); // variable flags expctx.cache.variable.flags = varobj->GetFlags(); // variable type @@ -228,7 +228,7 @@ namespace VSW::Materializer::ExportEnvironment { // Because it is not a name. // So we should record it as empty string if it is nullptr, instead of default var_representation = varobj->GetRepresentation(); - Utilities::CopyCKString(expctx.reporter, expctx.cache.variable.representation, var_representation, expctx.cp, YYCC_U8("")); + CP_CKSTR(expctx.cache.variable.representation, var_representation, YYCC_U8("")); // We output variable stored value in different way // according to its type. switch (var_type) { @@ -242,7 +242,7 @@ namespace VSW::Materializer::ExportEnvironment { break; case CKVariableManager::Variable::Type::STRING: var_mgr->GetValue(var_name, xstring_cache); - Utilities::CopyCKString(expctx.reporter, expctx.cache.variable.data, xstring_cache.CStr(), expctx.cp); + CP_CKSTR(expctx.cache.variable.data, xstring_cache.CStr()); break; default: throw std::runtime_error("invalid variable type!"); @@ -256,6 +256,10 @@ namespace VSW::Materializer::ExportEnvironment { void Export(CKContext* ctx, const YYCC::yycc_u8string_view& db_path, UINT code_page) { // create database and data cache in context ExportContext expctx(ctx, db_path, code_page); + if (!expctx.db.IsValid()) { + expctx.reporter.Err(YYCC_U8("Fail to open database. Export process aborted.")); + return; + } // export environment one by one IterateParameterOperation(expctx, ctx->GetParameterManager()); diff --git a/materializer/Utilities.cpp b/materializer/Utilities.cpp index 2440522..b506efc 100644 --- a/materializer/Utilities.cpp +++ b/materializer/Utilities.cpp @@ -16,14 +16,11 @@ namespace VSW::Materializer::Utilities { #pragma endregion - YYCC::yycc_u8string RelativeAddress(const EnhancedReporter& reporter, const void* absolute_addr) { - // prepare return value - YYCC::yycc_u8string ret; - + void RelativeAddress(const EnhancedReporter& reporter, YYCC::yycc_u8string& relative_addr_str, const void* absolute_addr) { // If address is nullptr, return directly if (absolute_addr == nullptr) { - ret = YYCC_U8(""); - return ret; + relative_addr_str = YYCC_U8(""); + return; } // Get the module handle which given function address belongs to @@ -35,14 +32,16 @@ namespace VSW::Materializer::Utilities { &hModule); if (hModule == NULL) { reporter.ErrF(YYCC_U8("Fail to get module of given absolute address 0x%" PRI_XPTR_LEFT_PADDING PRIXPTR ". Some relative address may be empty."), absolute_addr); - return ret; + relative_addr_str.clear(); + return; } // Get full path to module YYCC::yycc_u8string u8_module_path; if (!YYCC::WinFctHelper::GetModuleFileName(hModule, u8_module_path)) { reporter.ErrF(YYCC_U8("Fail to get file name of given module 0x%" PRI_XPTR_LEFT_PADDING PRIXPTR ". Some relative address may be empty."), hModule); - return ret; + relative_addr_str.clear(); + return; } // Then get its file name part auto module_path = YYCC::FsPathPatch::FromUTF8Path(u8_module_path.c_str()); @@ -54,11 +53,10 @@ namespace VSW::Materializer::Utilities { uintptr_t relative_addr = reinterpret_cast(absolute_addr) - reinterpret_cast(hModule); // get final result - if (!YYCC::StringHelper::Printf(ret, YYCC_U8("%s+0x%" PRI_XPTR_LEFT_PADDING PRIXPTR), u8_module_name.c_str(), relative_addr)) { + if (!YYCC::StringHelper::Printf(relative_addr_str, YYCC_U8("%s+0x%" PRI_XPTR_LEFT_PADDING PRIXPTR), u8_module_name.c_str(), relative_addr)) { reporter.Err(YYCC_U8("Fail to format relative address. Some relative address may be empty.")); - ret.clear(); + relative_addr_str.clear(); } - return ret; } void CopyStrGuid(const EnhancedReporter& reporter, YYCC::yycc_u8string& dst, const CKGUID& src) { diff --git a/materializer/Utilities.hpp b/materializer/Utilities.hpp index 3237566..4473b8e 100644 --- a/materializer/Utilities.hpp +++ b/materializer/Utilities.hpp @@ -23,10 +23,12 @@ namespace VSW::Materializer::Utilities { /** * @brief Get relative address from given absolute address * @details This function is used when exporting function pointer into database. + * @param[out] relative_addr_str + * The variable holding relative address result. + * The result is module based relative address like \c xxx.dll+0x00000000. * @param[in] absolute_addr The absolute address - * @return Module based relative address like \c xxx.dll+0x00000000. */ - YYCC::yycc_u8string RelativeAddress(const EnhancedReporter& reporter, const void* absolute_addr); + void RelativeAddress(const EnhancedReporter& reporter, YYCC::yycc_u8string& relative_addr_str, const void* absolute_addr); void CopyStrGuid(const EnhancedReporter& reporter, YYCC::yycc_u8string& dst, const CKGUID& src); void CopyGuid(const EnhancedReporter& reporter, int64_t& dst, const CKGUID& src); void CopyCKString( @@ -37,4 +39,14 @@ namespace VSW::Materializer::Utilities { const YYCC::yycc_char8_t* fallback = YYCC::EncodingHelper::ToUTF8(NULLPTR_CKSTRING) ); +#pragma region Convenient Macros + +#define CP_ADDR(dst, src) ::VSW::Materializer::Utilities::RelativeAddress(expctx.reporter, (dst), (src)) +#define CP_STR_GUID(dst, src) ::VSW::Materializer::Utilities::CopyStrGuid(expctx.reporter, (dst), (src)) +#define CP_GUID(dst, src) ::VSW::Materializer::Utilities::CopyGuid(expctx.reporter, (dst), (src)) +#define CP_CKSTR(dst, src, ...) ::VSW::Materializer::Utilities::CopyCKString(expctx.reporter, (dst), (src), expctx.cp, ##__VA_ARGS__) + +#pragma endregion + + }