From 6bda076a1d7b35e1fa133a52cd3b65d4c53d999f Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Thu, 9 Feb 2023 17:16:58 +0800 Subject: [PATCH] all prepare work done --- LibCmo/VTConstants.hpp | 19 +++++++++++++++++++ Unvirt/AccessibleValue.cpp | 27 +++++++++++--------------- Unvirt/AccessibleValue.hpp | 39 ++++++++++++++++++++++++++++++++++++-- Unvirt/Unvirt.cpp | 9 +++++++++ 4 files changed, 76 insertions(+), 18 deletions(-) diff --git a/LibCmo/VTConstants.hpp b/LibCmo/VTConstants.hpp index 6864cc1..8bf8842 100644 --- a/LibCmo/VTConstants.hpp +++ b/LibCmo/VTConstants.hpp @@ -2,9 +2,28 @@ #include #include +#include +#include namespace LibCmo { + namespace EnumHelper { + template + inline TEnum FlagEnumAdd(TEnum e, ...) { + TEnum result = e; + va_list argptr; + va_start(argptr, e); + result = static_cast(static_cast>(result) | static_cast>(va_arg(argptr, TEnum))); + va_end(argptr); + return result; + } + + template + inline bool FlagEnumHas(TEnum e, TEnum probe) { + return static_cast(static_cast>(e) & static_cast>(probe)); + } + } + using CK_ID = uint32_t; enum class CK_CLASSID : uint32_t { diff --git a/Unvirt/AccessibleValue.cpp b/Unvirt/AccessibleValue.cpp index b158471..96001ea 100644 --- a/Unvirt/AccessibleValue.cpp +++ b/Unvirt/AccessibleValue.cpp @@ -8,6 +8,8 @@ namespace Unvirt { #pragma region universal enum name + const char c_InvalidEnumName[] = "[undefined]"; + namespace EnumDesc { const EnumDescPairArray CK_FILE_WRITEMODE{ { LibCmo::CK_FILE_WRITEMODE::CKFILE_UNCOMPRESSED, "CKFILE_UNCOMPRESSED" }, @@ -36,18 +38,6 @@ namespace Unvirt { }; } - template - void GetEnumName(const EnumDescPairArray desc, std::string& strl, TEnum val) { - - - } - - template - void GetFlagEnumName(const EnumDescPairArray desc, std::string& strl, TEnum val) { - - - } - #pragma endregion #pragma region class id and ck error @@ -116,24 +106,26 @@ namespace Unvirt { }; void GetCkErrorName(std::string& strl, LibCmo::CKERROR err) { - strl.clear(); const std::array* pErrDesc = GetEnumData>( _CkErrorData, err ); if (pErrDesc != nullptr) { strl = pErrDesc->front(); + } else { + strl = c_InvalidEnumName; } } void GetCkErrorDescription(std::string& strl, LibCmo::CKERROR err) { - strl.clear(); const std::array* pErrDesc = GetEnumData>( _CkErrorData, err ); if (pErrDesc != nullptr) { strl = pErrDesc->back(); + } else { + strl = c_InvalidEnumName; } } @@ -209,27 +201,30 @@ namespace Unvirt { }; void GetClassIdName(std::string& strl, LibCmo::CK_CLASSID cls) { - strl.clear(); const std::vector* pHierarchy = GetEnumData>( _CkClassHierarchy, cls ); if (pHierarchy != nullptr) { strl = pHierarchy->back(); + } else { + strl = c_InvalidEnumName; } } void GetClassIdHierarchy(std::string& strl, LibCmo::CK_CLASSID cls) { - strl.clear(); const std::vector* pHierarchy = GetEnumData>( _CkClassHierarchy, cls ); if (pHierarchy != nullptr) { + strl.clear(); for (auto it = pHierarchy->begin(); it != pHierarchy->end(); ++it) { if (it != pHierarchy->begin()) strl += " -> "; strl += (*it); } + } else { + strl = c_InvalidEnumName; } } diff --git a/Unvirt/AccessibleValue.hpp b/Unvirt/AccessibleValue.hpp index e8c9b67..ac235b7 100644 --- a/Unvirt/AccessibleValue.hpp +++ b/Unvirt/AccessibleValue.hpp @@ -7,6 +7,10 @@ namespace Unvirt { namespace AccessibleValue { + extern const char c_InvalidEnumName[]; + +#pragma region universal enum name + template using EnumDescPairArray = std::vector>; @@ -17,9 +21,40 @@ namespace Unvirt { } template - void GetEnumName(const EnumDescPairArray desc, std::string& strl, TEnum val); + void GetEnumName(const EnumDescPairArray& desc, std::string& strl, TEnum val) { + for (auto it = desc.begin(); it != desc.end(); ++it) { + if ((*it).first == val) { + strl = (*it).second; + return; + } + } + strl = c_InvalidEnumName; + } template - void GetFlagEnumName(const EnumDescPairArray desc, std::string& strl, TEnum val); + void GetFlagEnumName(const EnumDescPairArray& desc, std::string& strl, TEnum val) { + strl.clear(); + for (auto it = desc.begin(); it != desc.end(); ++it) { + // if it have exacelt same entry, return directly + if ((*it).first == val) { + strl = (*it).second; + return; + } + + // check flag match + if (LibCmo::EnumHelper::FlagEnumHas(val, (*it).first)) { + // matched, add it + if (strl.size() != 0u) strl += ", "; + strl += (*it).second; + } + } + + if (strl.size() == 0u) { + // nothing was gotten. set to undefined + strl = c_InvalidEnumName; + } // otherwise return directly + } + +#pragma endregion void GetClassIdName(std::string& strl, LibCmo::CK_CLASSID cls); void GetCkErrorName(std::string& strl, LibCmo::CKERROR err); diff --git a/Unvirt/Unvirt.cpp b/Unvirt/Unvirt.cpp index a3b35c8..25f4db6 100644 --- a/Unvirt/Unvirt.cpp +++ b/Unvirt/Unvirt.cpp @@ -7,5 +7,14 @@ int main(int argc, char* argv[]) { printf("%s\n", test.c_str()); Unvirt::AccessibleValue::GetCkErrorDescription(test, LibCmo::CKERROR::CKERR_OBSOLETEVIRTOOLS); printf("%s\n", test.c_str()); + + Unvirt::AccessibleValue::GetEnumName(Unvirt::AccessibleValue::EnumDesc::CK_FO_OPTIONS, test, LibCmo::CK_FO_OPTIONS::CK_FO_RENAMEOBJECT); + printf("%s\n", test.c_str()); + + Unvirt::AccessibleValue::GetFlagEnumName(Unvirt::AccessibleValue::EnumDesc::CK_LOAD_FLAGS, test, LibCmo::CK_LOAD_FLAGS::CK_LOAD_DEFAULT); + printf("%s\n", test.c_str()); + auto v = LibCmo::EnumHelper::FlagEnumAdd(LibCmo::CK_LOAD_FLAGS::CK_LOAD_ANIMATION, LibCmo::CK_LOAD_FLAGS::CK_LOAD_ASCHARACTER); + Unvirt::AccessibleValue::GetFlagEnumName(Unvirt::AccessibleValue::EnumDesc::CK_LOAD_FLAGS, test, v); + printf("%s\n", test.c_str()); return 0; }