diff --git a/src/dnmd/internal.h b/src/dnmd/internal.h index 3a31ebe..c322884 100644 --- a/src/dnmd/internal.h +++ b/src/dnmd/internal.h @@ -69,10 +69,6 @@ static_assert(MDTABLE_MAX_COUNT <= 64, "Specification sets max table count to 64 #define MDTABLE_MAX_COLUMN_COUNT 9 -// Macros for computing token types. -#define CreateTokenType(tk) (mdToken)(((uint32_t)tk << 24) & 0xff000000) -#define ExtractTokenType(tk) ((tk >> 24) & 0xff) - // Flags and masks used to embed column details for // interpreting table rows. typedef enum diff --git a/src/inc/dnmd.h b/src/inc/dnmd.h index bc156ab..ff5cd2d 100644 --- a/src/inc/dnmd.h +++ b/src/inc/dnmd.h @@ -139,6 +139,10 @@ typedef enum #endif // DNMD_PORTABLE_PDB } mdtable_id_t; +// Macros for computing token types. +#define CreateTokenType(tk) (mdToken)(((uint32_t)tk << 24) & 0xff000000) +#define ExtractTokenType(tk) ((tk >> 24) & 0xff) + // Table cursor definition typedef struct mdcursor__ { diff --git a/src/inc/dnmd.hpp b/src/inc/dnmd.hpp index 5a29937..e51ddc4 100644 --- a/src/inc/dnmd.hpp +++ b/src/inc/dnmd.hpp @@ -53,4 +53,506 @@ struct md_added_row_t final } }; +struct md_column_type_blob {}; +struct md_column_type_string {}; +struct md_column_type_guid {}; +struct md_column_type_userstring {}; +struct md_column_type_constant {}; + +template +struct mdcursor; + +template +struct mdcoded_index; + +template +struct mdcolumn final +{ + template + friend struct mdcursor; + + col_index_t column_index; + public: + explicit constexpr mdcolumn(col_index_t col) + : column_index{ col } + { + } +}; + +template +struct mdcursor_indirect; + +template +struct mdcursor final +{ + private: + mdcursor_t cursor; + public: + mdcursor() = default; + explicit mdcursor(mdcursor_t c) : cursor{ c } + { + mdtoken tk; + if (md_cursor_to_token(cursor, &tk)) + { + mdtable_id_t table_id = ExtractTokenType(tk); + assert(table_id == TableId); + } + } + + operator mdcursor_t() + { + return cursor; + } + + template + bool get_column_value(mdcolumn> column, mdcursor& target_cursor) + { + return md_get_column_value_as_cursor(cursor, column.column_index, &target_cursor.cursor); + } + + template + bool get_column_value(mdcolumn> column, mdcoded_index& target_coded_index) + { + return md_get_column_value_as_cursor(cursor, column.column_index, &target_coded_index.cursor); + } + + template + bool get_column_value(mdcolumn> column, mdToken& tk) + { + return md_get_column_value_as_token(cursor, column.column_index, &tk); + } + + template + bool get_column_value(mdcolumn> column, mdcursor_indirect& target_cursor) + { + return md_get_column_value_as_cursor(cursor, column.column_index, &target_cursor.cursor); + } + + bool get_column_value(mdcolumn column, uint8_t const** blob, uint32_t* blob_len) + { + return md_get_column_value_as_blob(cursor, column.column_index, blob, blob_len); + } + + bool get_column_value(mdcolumn column, mdguid_t* guid) + { + return md_get_column_value_as_guid(cursor, column.column_index, guid); + } + + bool get_column_value(mdcolumn column, mduserstring_t* userstring) + { + return md_get_column_value_as_userstring(cursor, column.column_index, userstring); + } + + bool get_column_value(mdcolumn column, char const** str) + { + return md_get_column_value_as_utf8(cursor, column.column_index, str); + } + + template + bool get_column_value_as_range(mdcolumn> column, mdcursor_indirect& range_cursor, uint32_t* count) + { + return md_get_column_value_as_range(cursor, column.column_index, &range_cursor.cursor, count) + } +}; + +template +struct mdcursor_indirect final +{ + private: + mdcursor_t cursor; + public: + mdcursor_indirect() = default; + explicit constexpr mdcursor_indirect(mdcursor_t c) : cursor{ c } + { + mdtoken tk; + if (md_cursor_to_token(cursor, &tk)) + { + mdtable_id_t table_id = ExtractTokenType(tk); + assert(table_id == DirectTableId || table_id == IndirectTableId); + } + } + + operator mdcursor_t() + { + return cursor; + } + + bool try_get(mdcursor& direct_cursor) + { + mdtoken tk; + if (!md_cursor_to_token(cursor, &tk)) + return false; + + mdcursor_t target_cursor; + if (!md_resolve_indirect_cursor(cursor, &target_cursor)) + return false; + + direct_cursor = mdcursor(target_cursor); + return true; + } +}; + +template +struct mdcoded_index final +{ + private: + mdcursor_t cursor; + public: + mdcoded_index() = default; + explicit constexpr mdcoded_index(mdcursor_t c) + : cursor{ c } + { + mdtoken tk; + if (md_cursor_to_token(cursor, &tk)) + { + mdtable_id_t table_id = ExtractTokenType(tk); + assert(((table_id == TableIds) || ...)); + } + } + + template + bool get_as(mdcursor& target_cursor) + { + static_assert(((CodedTableId == TableIds) || ...) , "CodedTableId must be one of the tables in the coded index."); + mdtoken tk; + if (!md_cursor_to_token(cursor, &tk)) + return false; + + if (ExtractTokenType(tk) != CodedTableId) + return false; + + target_cursor = mdcursor(cursor); + return true; + } + + template + void visit(TCallable&& callable) + { + (visit_impl(std::forward(callable)) || false ...); + } + + private: + template + bool visit_impl(TCallable&& callable) + { + mdtoken tk; + if (!md_cursor_to_token(cursor, &tk)) + return false; + if (ExtractTokenType(tk) != CodedTableId) + return false; + callable(mdcursor(cursor)); + return true; + } +}; + +template +inline bool md_cursor_next(mdcursor& cursor) +{ + mdcursor_t c = cursor; + if (!md_cursor_next(&c)) + return false; + cursor = mdcursor{c}; + return true; +} + +template +inline bool md_cursor_next(mdcursor_indirect& cursor) +{ + mdcursor_t c = cursor; + if (!md_cursor_next(&c)) + return false; + cursor = mdcursor_indirect{c}; + return true; +} + +// Strongly-typed overloads for md_find_row_from_cursor + +// Overload for constant columns +template +inline bool md_find_row_from_cursor(mdcursor begin, mdcolumn column, uint32_t value, mdcursor& cursor) +{ + mdcursor_t c; + bool result = ::md_find_row_from_cursor(begin, column.column_index, value, &c); + if (result) + cursor = mdcursor{c}; + return result; +} + +// Overload for cursor columns +template +inline bool md_find_row_from_cursor(mdcursor begin, mdcolumn> column, mdToken tk, mdcursor& cursor) +{ + mdToken tk; + if (!::md_cursor_to_token(value, &tk)) + return false; + + uint32_t rid = tk & 0x00FFFFFF; // Extract RID from token + mdcursor_t c; + bool result = ::md_find_row_from_cursor(begin, column.column_index, rid, &c); + if (result) + cursor = mdcursor{c}; + return result; +} + +// Overload for cursor columns +template +inline bool md_find_row_from_cursor(mdcursor begin, mdcolumn> column, mdcursor value, mdcursor& cursor) +{ + mdToken tk; + if (!::md_cursor_to_token(value, &tk)) + return false; + + return md_find_row_from_cursor(begin, column, tk, cursor); +} + +// Overload for indirect cursor columns +template +inline bool md_find_row_from_cursor(mdcursor begin, mdcolumn> column, mdcursor value, mdcursor& cursor) +{ + mdToken tk; + if (!::md_cursor_to_token(value, &tk)) + return false; + + uint32_t rid = tk & 0x00FFFFFF; // Extract RID from token + mdcursor_t c; + bool result = ::md_find_row_from_cursor(begin, column.column_index, rid, &c); + if (result) + cursor = mdcursor{c}; + return result; +} + +// Overload for coded index columns +template +inline bool md_find_row_from_cursor(mdcursor begin, mdcolumn> column, mdToken tk, mdcursor& cursor) +{ + mdcursor_t c; + bool result = ::md_find_row_from_cursor(begin, column.column_index, tk, &c); + if (result) + cursor = mdcursor{c}; + return result; +} + +// Overload for coded index columns +template +inline bool md_find_row_from_cursor(mdcursor begin, mdcolumn> column, mdcursor value, mdcursor& cursor) +{ + mdToken tk; + if (!::md_cursor_to_token(value, &tk)) + return false; + + return md_find_row_from_cursor(begin, column, tk, cursor); +} + +template +inline bool md_create_cursor(mdhandle_t handle, mdcursor& cursor, uint32_t* count) +{ + mdcursor_t c; + bool result = ::md_create_cursor(handle, TableId, &c, count); + if (result) + cursor = mdcursor{c}; + return result; +} + +namespace dnmd_columns +{ +inline constexpr mdcolumn Module_Generation{ mdtModule_Generation }; +inline constexpr mdcolumn Module_Name{ mdtModule_Name }; +inline constexpr mdcolumn Module_Mvid{ mdtModule_Mvid }; +inline constexpr mdcolumn Module_EncId{ mdtModule_EncId }; +inline constexpr mdcolumn Module_EncBaseId{ mdtModule_EncBaseId }; + +inline constexpr mdcolumn> TypeRef_ResolutionScope{ mdtTypeRef_ResolutionScope }; +inline constexpr mdcolumn TypeRef_TypeName{ mdtTypeRef_TypeName }; +inline constexpr mdcolumn TypeRef_TypeNamespace{ mdtTypeRef_TypeNamespace }; + +inline constexpr mdcolumn TypeDef_Flags{ mdtTypeDef_Flags }; +inline constexpr mdcolumn TypeDef_TypeName{ mdtTypeDef_TypeName }; +inline constexpr mdcolumn TypeDef_TypeNamespace{ mdtTypeDef_TypeNamespace }; +inline constexpr mdcolumn> TypeDef_Extends{ mdtTypeDef_Extends }; +inline constexpr mdcolumn> TypeDef_FieldList{ mdtTypeDef_FieldList }; +inline constexpr mdcolumn> TypeDef_MethodList{ mdtTypeDef_MethodList }; + +inline constexpr mdcolumn Field_Flags{ mdtField_Flags }; +inline constexpr mdcolumn Field_Name{ mdtField_Name }; +inline constexpr mdcolumn Field_Signature{ mdtField_Signature }; + +inline constexpr mdcolumn MethodDef_Rva{ mdtMethodDef_Rva }; +inline constexpr mdcolumn MethodDef_ImplFlags{ mdtMethodDef_ImplFlags }; +inline constexpr mdcolumn MethodDef_Flags{ mdtMethodDef_Flags }; +inline constexpr mdcolumn MethodDef_Name{ mdtMethodDef_Name }; +inline constexpr mdcolumn MethodDef_Signature{ mdtMethodDef_Signature }; +inline constexpr mdcolumn> MethodDef_ParamList{ mdtMethodDef_ParamList }; + +inline constexpr mdcolumn Param_Flags{ mdtParam_Flags }; +inline constexpr mdcolumn Param_Sequence{ mdtParam_Sequence }; +inline constexpr mdcolumn Param_Name{ mdtParam_Name }; + +inline constexpr mdcolumn> InterfaceImpl_Class{ mdtInterfaceImpl_Class }; +inline constexpr mdcolumn> InterfaceImpl_Interface{ mdtInterfaceImpl_Interface }; + +inline constexpr mdcolumn> MemberRef_Class{ mdtMemberRef_Class }; +inline constexpr mdcolumn MemberRef_Name{ mdtMemberRef_Name }; +inline constexpr mdcolumn MemberRef_Signature{ mdtMemberRef_Signature }; + +inline constexpr mdcolumn Constant_Type{ mdtConstant_Type }; +inline constexpr mdcolumn> Constant_Parent{ mdtConstant_Parent }; +inline constexpr mdcolumn Constant_Value{ mdtConstant_Value }; + +inline constexpr mdcolumn> CustomAttribute_Parent{ mdtCustomAttribute_Parent }; +inline constexpr mdcolumn> CustomAttribute_Type{ mdtCustomAttribute_Type }; +inline constexpr mdcolumn CustomAttribute_Value{ mdtCustomAttribute_Value }; + +inline constexpr mdcolumn> FieldMarshal_Parent{ mdtFieldMarshal_Parent }; +inline constexpr mdcolumn FieldMarshal_NativeType{ mdtFieldMarshal_NativeType }; + +inline constexpr mdcolumn DeclSecurity_Action{ mdtDeclSecurity_Action }; +inline constexpr mdcolumn> DeclSecurity_Parent{ mdtDeclSecurity_Parent }; +inline constexpr mdcolumn DeclSecurity_PermissionSet{ mdtDeclSecurity_PermissionSet }; + +inline constexpr mdcolumn ClassLayout_PackingSize{ mdtClassLayout_PackingSize }; +inline constexpr mdcolumn ClassLayout_ClassSize{ mdtClassLayout_ClassSize }; +inline constexpr mdcolumn> ClassLayout_Parent{ mdtClassLayout_Parent }; + +inline constexpr mdcolumn FieldLayout_Offset{ mdtFieldLayout_Offset }; +inline constexpr mdcolumn> FieldLayout_Field{ mdtFieldLayout_Field }; + +inline constexpr mdcolumn StandAloneSig_Signature{ mdtStandAloneSig_Signature }; + +inline constexpr mdcolumn> EventMap_Parent{ mdtEventMap_Parent }; +inline constexpr mdcolumn> EventMap_EventList{ mdtEventMap_EventList }; + +inline constexpr mdcolumn Event_EventFlags{ mdtEvent_EventFlags }; +inline constexpr mdcolumn Event_Name{ mdtEvent_Name }; +inline constexpr mdcolumn> Event_EventType{ mdtEvent_EventType }; + +inline constexpr mdcolumn> PropertyMap_Parent{ mdtPropertyMap_Parent }; +inline constexpr mdcolumn> PropertyMap_PropertyList{ mdtPropertyMap_PropertyList }; + +inline constexpr mdcolumn Property_Flags{ mdtProperty_Flags }; +inline constexpr mdcolumn Property_Name{ mdtProperty_Name }; +inline constexpr mdcolumn Property_Type{ mdtProperty_Type }; + +inline constexpr mdcolumn MethodSemantics_Semantics{ mdtMethodSemantics_Semantics }; +inline constexpr mdcolumn> MethodSemantics_Method{ mdtMethodSemantics_Method }; +inline constexpr mdcolumn> MethodSemantics_Association{ mdtMethodSemantics_Association }; + +inline constexpr mdcolumn> MethodImpl_Class{ mdtMethodImpl_Class }; +inline constexpr mdcolumn> MethodImpl_MethodBody{ mdtMethodImpl_MethodBody }; +inline constexpr mdcolumn> MethodImpl_MethodDeclaration{ mdtMethodImpl_MethodDeclaration }; + +inline constexpr mdcolumn ModuleRef_Name{ mdtModuleRef_Name }; + +inline constexpr mdcolumn TypeSpec_Signature{ mdtTypeSpec_Signature }; + +inline constexpr mdcolumn ImplMap_MappingFlags{ mdtImplMap_MappingFlags }; +inline constexpr mdcolumn> ImplMap_MemberForwarded{ mdtImplMap_MemberForwarded }; +inline constexpr mdcolumn ImplMap_ImportName{ mdtImplMap_ImportName }; +inline constexpr mdcolumn> ImplMap_ImportScope{ mdtImplMap_ImportScope }; + +inline constexpr mdcolumn FieldRva_Rva{ mdtFieldRva_Rva }; +inline constexpr mdcolumn> FieldRva_Field{ mdtFieldRva_Field }; + +inline constexpr mdcolumn ENCLog_Token{ mdtENCLog_Token }; +inline constexpr mdcolumn ENCLog_Op{ mdtENCLog_Op }; + +inline constexpr mdcolumn ENCMap_Token{ mdtENCMap_Token }; + +inline constexpr mdcolumn Assembly_HashAlgId{ mdtAssembly_HashAlgId }; +inline constexpr mdcolumn Assembly_MajorVersion{ mdtAssembly_MajorVersion }; +inline constexpr mdcolumn Assembly_MinorVersion{ mdtAssembly_MinorVersion }; +inline constexpr mdcolumn Assembly_BuildNumber{ mdtAssembly_BuildNumber }; +inline constexpr mdcolumn Assembly_RevisionNumber{ mdtAssembly_RevisionNumber }; +inline constexpr mdcolumn Assembly_Flags{ mdtAssembly_Flags }; +inline constexpr mdcolumn Assembly_PublicKey{ mdtAssembly_PublicKey }; +inline constexpr mdcolumn Assembly_Name{ mdtAssembly_Name }; +inline constexpr mdcolumn Assembly_Culture{ mdtAssembly_Culture }; + +inline constexpr mdcolumn AssemblyProcessor_Processor{ static_cast(0) }; + +inline constexpr mdcolumn AssemblyOS_OSPlatformId{ static_cast(0) }; +inline constexpr mdcolumn AssemblyOS_OSMajorVersion{ static_cast(1) }; +inline constexpr mdcolumn AssemblyOS_OSMinorVersion{ static_cast(2) }; + +inline constexpr mdcolumn AssemblyRef_MajorVersion{ mdtAssemblyRef_MajorVersion }; +inline constexpr mdcolumn AssemblyRef_MinorVersion{ mdtAssemblyRef_MinorVersion }; +inline constexpr mdcolumn AssemblyRef_BuildNumber{ mdtAssemblyRef_BuildNumber }; +inline constexpr mdcolumn AssemblyRef_RevisionNumber{ mdtAssemblyRef_RevisionNumber }; +inline constexpr mdcolumn AssemblyRef_Flags{ mdtAssemblyRef_Flags }; +inline constexpr mdcolumn AssemblyRef_PublicKeyOrToken{ mdtAssemblyRef_PublicKeyOrToken }; +inline constexpr mdcolumn AssemblyRef_Name{ mdtAssemblyRef_Name }; +inline constexpr mdcolumn AssemblyRef_Culture{ mdtAssemblyRef_Culture }; +inline constexpr mdcolumn AssemblyRef_HashValue{ mdtAssemblyRef_HashValue }; + +inline constexpr mdcolumn AssemblyRefProcessor_Processor{ static_cast(0) }; +inline constexpr mdcolumn> AssemblyRefProcessor_AssemblyRef{ static_cast(1) }; + +inline constexpr mdcolumn AssemblyRefOS_OSPlatformId{ static_cast(0) }; +inline constexpr mdcolumn AssemblyRefOS_OSMajorVersion{ static_cast(1) }; +inline constexpr mdcolumn AssemblyRefOS_OSMinorVersion{ static_cast(2) }; +inline constexpr mdcolumn> AssemblyRefOS_AssemblyRef{ static_cast(3) }; + +inline constexpr mdcolumn File_Flags{ mdtFile_Flags }; +inline constexpr mdcolumn File_Name{ mdtFile_Name }; +inline constexpr mdcolumn File_HashValue{ mdtFile_HashValue }; + +inline constexpr mdcolumn ExportedType_Flags{ mdtExportedType_Flags }; +inline constexpr mdcolumn ExportedType_TypeDefId{ mdtExportedType_TypeDefId }; +inline constexpr mdcolumn ExportedType_TypeName{ mdtExportedType_TypeName }; +inline constexpr mdcolumn ExportedType_TypeNamespace{ mdtExportedType_TypeNamespace }; +inline constexpr mdcolumn> ExportedType_Implementation{ mdtExportedType_Implementation }; + +inline constexpr mdcolumn ManifestResource_Offset{ mdtManifestResource_Offset }; +inline constexpr mdcolumn ManifestResource_Flags{ mdtManifestResource_Flags }; +inline constexpr mdcolumn ManifestResource_Name{ mdtManifestResource_Name }; +inline constexpr mdcolumn> ManifestResource_Implementation{ mdtManifestResource_Implementation }; + +inline constexpr mdcolumn> NestedClass_NestedClass{ mdtNestedClass_NestedClass }; +inline constexpr mdcolumn> NestedClass_EnclosingClass{ mdtNestedClass_EnclosingClass }; + +inline constexpr mdcolumn GenericParam_Number{ mdtGenericParam_Number }; +inline constexpr mdcolumn GenericParam_Flags{ mdtGenericParam_Flags }; +inline constexpr mdcolumn> GenericParam_Owner{ mdtGenericParam_Owner }; +inline constexpr mdcolumn GenericParam_Name{ mdtGenericParam_Name }; + +inline constexpr mdcolumn> MethodSpec_Method{ mdtMethodSpec_Method }; +inline constexpr mdcolumn MethodSpec_Instantiation{ mdtMethodSpec_Instantiation }; + +inline constexpr mdcolumn> GenericParamConstraint_Owner{ mdtGenericParamConstraint_Owner }; +inline constexpr mdcolumn> GenericParamConstraint_Constraint{ mdtGenericParamConstraint_Constraint }; + +#ifdef DNMD_PORTABLE_PDB +inline constexpr mdcolumn Document_Name{ mdtDocument_Name }; +inline constexpr mdcolumn Document_HashAlgorithm{ mdtDocument_HashAlgorithm }; +inline constexpr mdcolumn Document_Hash{ mdtDocument_Hash }; +inline constexpr mdcolumn Document_Language{ mdtDocument_Language }; + +inline constexpr mdcolumn> MethodDebugInformation_Document{ mdtMethodDebugInformation_Document }; +inline constexpr mdcolumn MethodDebugInformation_SequencePoints{ mdtMethodDebugInformation_SequencePoints }; + +inline constexpr mdcolumn> LocalScope_Method{ mdtLocalScope_Method }; +inline constexpr mdcolumn> LocalScope_ImportScope{ mdtLocalScope_ImportScope }; +inline constexpr mdcolumn> LocalScope_VariableList{ mdtLocalScope_VariableList }; +inline constexpr mdcolumn> LocalScope_ConstantList{ mdtLocalScope_ConstantList }; +inline constexpr mdcolumn LocalScope_StartOffset{ mdtLocalScope_StartOffset }; +inline constexpr mdcolumn LocalScope_Length{ mdtLocalScope_Length }; + +inline constexpr mdcolumn LocalVariable_Attributes{ mdtLocalVariable_Attributes }; +inline constexpr mdcolumn LocalVariable_Index{ mdtLocalVariable_Index }; +inline constexpr mdcolumn LocalVariable_Name{ mdtLocalVariable_Name }; + +inline constexpr mdcolumn LocalConstant_Name{ mdtLocalConstant_Name }; +inline constexpr mdcolumn LocalConstant_Signature{ mdtLocalConstant_Signature }; + +inline constexpr mdcolumn> ImportScope_Parent{ mdtImportScope_Parent }; +inline constexpr mdcolumn ImportScope_Imports{ mdtImportScope_Imports }; + +inline constexpr mdcolumn> StateMachineMethod_MoveNextMethod{ mdtStateMachineMethod_MoveNextMethod }; +inline constexpr mdcolumn> StateMachineMethod_KickoffMethod{ mdtStateMachineMethod_KickoffMethod }; + +inline constexpr mdcolumn> CustomDebugInformation_Parent{ mdtCustomDebugInformation_Parent }; +inline constexpr mdcolumn CustomDebugInformation_Kind{ mdtCustomDebugInformation_Kind }; +inline constexpr mdcolumn CustomDebugInformation_Value{ mdtCustomDebugInformation_Value }; +#endif // DNMD_PORTABLE_PDB +} + #endif // _SRC_INC_DNMD_HPP_ diff --git a/src/interfaces/metadataimport.cpp b/src/interfaces/metadataimport.cpp index 30c80ae..f877ef5 100644 --- a/src/interfaces/metadataimport.cpp +++ b/src/interfaces/metadataimport.cpp @@ -4,8 +4,11 @@ #include "metadataimportro.hpp" #include "hcorenum.hpp" #include "signatures.hpp" +#include "dnmd.hpp" #include +using namespace dnmd_columns; + #define MD_MODULE_TOKEN TokenFromRid(1, mdtModule) #define MD_GLOBAL_PARENT_TOKEN TokenFromRid(1, mdtTypeDef) @@ -755,16 +758,18 @@ HRESULT STDMETHODCALLTYPE MetadataImportRO::EnumMembersWithName( if (TypeFromToken(cl) != mdtTypeDef) return E_INVALIDARG; - mdcursor_t cursor; - if (!md_token_to_cursor(_md_ptr.get(), cl, &cursor)) + mdcursor_t raw_cursor; + if (!md_token_to_cursor(_md_ptr.get(), cl, &raw_cursor)) return CLDB_E_INDEX_NOTFOUND; + mdcursor cursor(raw_cursor); - mdcursor_t methodList; + mdcursor_indirect methodList; uint32_t methodListCount; - mdcursor_t fieldList; + mdcursor_indirect fieldList; uint32_t fieldListCount; - if (!md_get_column_value_as_range(cursor, mdtTypeDef_FieldList, &fieldList, &fieldListCount) - || !md_get_column_value_as_range(cursor, mdtTypeDef_MethodList, &methodList, &methodListCount)) + + if (!cursor.get_column_value_as_range(TypeDef_FieldList, fieldList, &fieldListCount) + || !cursor.get_column_value_as_range(TypeDef_MethodList, methodList, &methodListCount)) { return CLDB_E_FILE_CORRUPT; } @@ -783,10 +788,11 @@ HRESULT STDMETHODCALLTYPE MetadataImportRO::EnumMembersWithName( // Iterate the Type's methods for (uint32_t i = 0; i < methodListCount; ++i) { - mdcursor_t methodCursor; - if (!md_resolve_indirect_cursor(methodList, &methodCursor)) + mdcursor methodCursor; + if (!methodList.try_get(methodCursor)) return CLDB_E_FILE_CORRUPT; - if (!md_get_column_value_as_utf8(methodCursor, mdtMethodDef_Name, &toMatch)) + + if (!methodCursor.get_column_value(MethodDef_Name, &toMatch)) return CLDB_E_FILE_CORRUPT; if (0 == ::strcmp(toMatch, cvt)) @@ -794,16 +800,17 @@ HRESULT STDMETHODCALLTYPE MetadataImportRO::EnumMembersWithName( (void)md_cursor_to_token(methodCursor, &matchedTk); RETURN_IF_FAILED(HCORENUMImpl::AddToDynamicEnum(*enumImpl, matchedTk)); } - (void)md_cursor_next(&methodList); + (void)md_cursor_next(methodList); } // Iterate the Type's fields for (uint32_t i = 0; i < fieldListCount; ++i) { - mdcursor_t fieldCursor; - if (!md_resolve_indirect_cursor(fieldList, &fieldCursor)) + mdcursor fieldCursor; + if (!fieldList.try_get(fieldCursor)) return CLDB_E_FILE_CORRUPT; - if (!md_get_column_value_as_utf8(fieldCursor, mdtField_Name, &toMatch)) + + if (!fieldCursor.get_column_value(Field_Name, &toMatch)) return CLDB_E_FILE_CORRUPT; if (0 == ::strcmp(toMatch, cvt)) @@ -811,7 +818,7 @@ HRESULT STDMETHODCALLTYPE MetadataImportRO::EnumMembersWithName( (void)md_cursor_to_token(fieldCursor, &matchedTk); RETURN_IF_FAILED(HCORENUMImpl::AddToDynamicEnum(*enumImpl, matchedTk)); } - (void)md_cursor_next(&fieldList); + (void)md_cursor_next(fieldList); } *phEnum = cleanup.release(); @@ -2745,45 +2752,43 @@ HRESULT STDMETHODCALLTYPE MetadataImportRO::GetCustomAttributeByName( char const* nspace; char const* name; - mdcursor_t type; mdcursor_t tgtType; - mdToken typeTk; size_t len; char const* curr; - if (!md_get_column_value_as_cursor(custAttrCurr, mdtCustomAttribute_Type, &type)) + mdcursor custAttr(custAttrCurr); + mdcoded_index type; + if (!custAttr.get_column_value(CustomAttribute_Type, type)) { hr = CLDB_E_FILE_CORRUPT; return true; } - // Cursor was returned so must be valid. - (void)md_cursor_to_token(type, &typeTk); - - // Resolve the cursor based on its type. - switch (TypeFromToken(typeTk)) - { - case mdtMethodDef: - if (!md_find_cursor_of_range_element(type, &tgtType)) - { - hr = CLDB_E_FILE_CORRUPT; - return true; - } - break; - case mdtMemberRef: - if (!md_get_column_value_as_cursor(type, mdtMemberRef_Class, &tgtType)) + // Resolve the cursor based on its type using visit(). + type.visit([&](mdcursor typeCursor) { + if constexpr (TableId == mdtid_MethodDef) { - hr = CLDB_E_FILE_CORRUPT; - return true; + if (!md_find_cursor_of_range_element(typeCursor, &tgtType)) + { + hr = CLDB_E_FILE_CORRUPT; + } } - break; - default: - assert(!"Unexpected token in GetCustomAttributeByName"); + else if constexpr (TableId == mdtid_MemberRef) { - hr = COR_E_BADIMAGEFORMAT; - return true; + mdcursor_t raw_memberRefClass; + if (!md_get_column_value_as_cursor(typeCursor, mdtMemberRef_Class, &raw_memberRefClass)) + { + hr = CLDB_E_FILE_CORRUPT; + } + else + { + tgtType = raw_memberRefClass; + } } - } + }); + + if (FAILED(hr)) + return true; if (FAILED(hr = ResolveTypeDefRefSpecToName(tgtType, &nspace, &name))) { @@ -2810,7 +2815,7 @@ HRESULT STDMETHODCALLTYPE MetadataImportRO::GetCustomAttributeByName( { uint8_t const* data; uint32_t dataLen; - if (!md_get_column_value_as_blob(custAttrCurr, mdtCustomAttribute_Value, &data, &dataLen)) + if (!custAttr.get_column_value(CustomAttribute_Value, &data, &dataLen)) { hr = CLDB_E_FILE_CORRUPT; return true; @@ -2852,20 +2857,23 @@ HRESULT STDMETHODCALLTYPE MetadataImportRO::GetNestedClassProps( if (TypeFromToken(tdNestedClass) != mdtTypeDef) return E_INVALIDARG; - mdcursor_t cursor; + mdcursor cursor; uint32_t count; - mdcursor_t nestedClassRow; - if (!md_create_cursor(_md_ptr.get(), mdtid_NestedClass, &cursor, &count) - || !md_find_row_from_cursor(cursor, mdtNestedClass_NestedClass, RidFromToken(tdNestedClass), &nestedClassRow)) + if (!md_create_cursor(_md_ptr.get(), cursor, &count)) + return CLDB_E_RECORD_NOTFOUND; + + mdcursor nestedClassRow; + if (!md_find_row_from_cursor(cursor, NestedClass_NestedClass, tdNestedClass, nestedClassRow)) { return CLDB_E_RECORD_NOTFOUND; } - mdTypeDef enclosed; - if (!md_get_column_value_as_token(nestedClassRow, mdtNestedClass_EnclosingClass, &enclosed)) + mdcursor enclosingClass; + if (!nestedClassRow.get_column_value(NestedClass_EnclosingClass, enclosingClass)) return CLDB_E_FILE_CORRUPT; - *ptdEnclosingClass = enclosed; + if (!md_cursor_to_token(enclosingClass, ptdEnclosingClass)) + return CLDB_E_FILE_CORRUPT; return S_OK; }