void initialize()

in src/library/impl/meta_reader/database.h [229:482]


        void initialize()
        {
            auto dos = m_view.as<impl::image_dos_header>();

            if (dos.e_signature != 0x5A4D) // IMAGE_DOS_SIGNATURE
            {
                throw_invalid("Invalid DOS signature");
            }

            auto pe = m_view.as<impl::image_nt_headers32>(dos.e_lfanew);

            if (pe.FileHeader.NumberOfSections == 0 || pe.FileHeader.NumberOfSections > 100)
            {
                throw_invalid("Invalid PE section count");
            }

            impl::image_section_header const* sections{};
            uint32_t com_virtual_address{};
            if (pe.OptionalHeader.Magic == 0x10B) // PE32
            {
                com_virtual_address = pe.OptionalHeader.DataDirectory[14].VirtualAddress; // IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
                sections = &m_view.as<impl::image_section_header>(dos.e_lfanew + sizeof(impl::image_nt_headers32));
            }
            else if (pe.OptionalHeader.Magic == 0x20B) // PE32+
            {
                auto pe_plus = m_view.as<impl::image_nt_headers32plus>(dos.e_lfanew);
                com_virtual_address = pe_plus.OptionalHeader.DataDirectory[14].VirtualAddress; // IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
                sections = &m_view.as<impl::image_section_header>(dos.e_lfanew + sizeof(impl::image_nt_headers32plus));
            }
            else
            {
                throw_invalid("Invalid optional header magic value");
            }
            auto sections_end = sections + pe.FileHeader.NumberOfSections;
            auto section = section_from_rva(sections, sections_end, com_virtual_address);

            if (section == sections_end)
            {
                throw_invalid("PE section containing CLI header not found");
            }

            auto offset = offset_from_rva(*section, com_virtual_address);

            auto cli = m_view.as<impl::image_cor20_header>(offset);

            if (cli.cb != sizeof(impl::image_cor20_header))
            {
                throw_invalid("Invalid CLI header");
            }

            section = section_from_rva(sections, sections_end, cli.MetaData.VirtualAddress);

            if (section == sections_end)
            {
                throw_invalid("PE section containing CLI metadata not found");
            }

            offset = offset_from_rva(*section, cli.MetaData.VirtualAddress);

            if (m_view.as<uint32_t>(offset) != 0x424a5342)
            {
                throw_invalid("CLI metadata magic signature not found");
            }

            auto version_length = m_view.as<uint32_t>(offset + 12);
            auto stream_count = m_view.as<uint16_t>(offset + version_length + 18);
            auto view = m_view.seek(offset + version_length + 20);
            byte_view tables;

            for (uint16_t i{}; i < stream_count; ++i)
            {
                auto stream = view.as<stream_range>();
                auto name = view.as<std::array<char, 12>>(8);

                if (name.data() == "#Strings"sv)
                {
                    m_strings = m_view.sub(offset + stream.offset, stream.size);
                }
                else if (name.data() == "#Blob"sv)
                {
                    m_blobs = m_view.sub(offset + stream.offset, stream.size);
                }
                else if (name.data() == "#GUID"sv)
                {
                    m_guids = m_view.sub(offset + stream.offset, stream.size);
                }
                else if (name.data() == "#~"sv)
                {
                    tables = m_view.sub(offset + stream.offset, stream.size);
                }
                else if (name.data() != "#US"sv)
                {
                    throw_invalid("Unknown metadata stream");
                }

                view = view.seek(stream_offset(name.data()));
            }

            std::bitset<8> const heap_sizes{ tables.as<uint8_t>(6) };
            uint8_t const string_index_size = heap_sizes.test(0) ? 4 : 2;
            uint8_t const guid_index_size = heap_sizes.test(1) ? 4 : 2;
            uint8_t const blob_index_size = heap_sizes.test(2) ? 4 : 2;

            std::bitset<64> const valid_bits{ tables.as<uint64_t>(8) };
            view = tables.seek(24);

            for (uint32_t i{}; i < 64; ++i)
            {
                if (!valid_bits.test(i))
                {
                    continue;
                }

                auto row_count = view.as<uint32_t>();
                view = view.seek(4);

                switch (i)
                {
                case 0x00: Module.set_row_count(row_count); break;
                case 0x01: TypeRef.set_row_count(row_count); break;
                case 0x02: TypeDef.set_row_count(row_count); break;
                case 0x04: Field.set_row_count(row_count); break;
                case 0x06: MethodDef.set_row_count(row_count); break;
                case 0x08: Param.set_row_count(row_count); break;
                case 0x09: InterfaceImpl.set_row_count(row_count); break;
                case 0x0a: MemberRef.set_row_count(row_count); break;
                case 0x0b: Constant.set_row_count(row_count); break;
                case 0x0c: CustomAttribute.set_row_count(row_count); break;
                case 0x0d: FieldMarshal.set_row_count(row_count); break;
                case 0x0e: DeclSecurity.set_row_count(row_count); break;
                case 0x0f: ClassLayout.set_row_count(row_count); break;
                case 0x10: FieldLayout.set_row_count(row_count); break;
                case 0x11: StandAloneSig.set_row_count(row_count); break;
                case 0x12: EventMap.set_row_count(row_count); break;
                case 0x14: Event.set_row_count(row_count); break;
                case 0x15: PropertyMap.set_row_count(row_count); break;
                case 0x17: Property.set_row_count(row_count); break;
                case 0x18: MethodSemantics.set_row_count(row_count); break;
                case 0x19: MethodImpl.set_row_count(row_count); break;
                case 0x1a: ModuleRef.set_row_count(row_count); break;
                case 0x1b: TypeSpec.set_row_count(row_count); break;
                case 0x1c: ImplMap.set_row_count(row_count); break;
                case 0x1d: FieldRVA.set_row_count(row_count); break;
                case 0x20: Assembly.set_row_count(row_count); break;
                case 0x21: AssemblyProcessor.set_row_count(row_count); break;
                case 0x22: AssemblyOS.set_row_count(row_count); break;
                case 0x23: AssemblyRef.set_row_count(row_count); break;
                case 0x24: AssemblyRefProcessor.set_row_count(row_count); break;
                case 0x25: AssemblyRefOS.set_row_count(row_count); break;
                case 0x26: File.set_row_count(row_count); break;
                case 0x27: ExportedType.set_row_count(row_count); break;
                case 0x28: ManifestResource.set_row_count(row_count); break;
                case 0x29: NestedClass.set_row_count(row_count); break;
                case 0x2a: GenericParam.set_row_count(row_count); break;
                case 0x2b: MethodSpec.set_row_count(row_count); break;
                case 0x2c: GenericParamConstraint.set_row_count(row_count); break;
                default: throw_invalid("Unknown metadata table");
                };
            }

            table_base const empty_table{ nullptr };

            auto const TypeDefOrRef = composite_index_size(TypeDef, TypeRef, TypeSpec);
            auto const HasConstant = composite_index_size(Field, Param, Property);
            auto const HasCustomAttribute = composite_index_size(MethodDef, Field, TypeRef, TypeDef, Param, InterfaceImpl, MemberRef, Module, Property, Event, StandAloneSig, ModuleRef, TypeSpec, Assembly, AssemblyRef, File, ExportedType, ManifestResource, GenericParam, GenericParamConstraint, MethodSpec);
            auto const HasFieldMarshal = composite_index_size(Field, Param);
            auto const HasDeclSecurity = composite_index_size(TypeDef, MethodDef, Assembly);
            auto const MemberRefParent = composite_index_size(TypeDef, TypeRef, ModuleRef, MethodDef, TypeSpec);
            auto const HasSemantics = composite_index_size(Event, Property);
            auto const MethodDefOrRef = composite_index_size(MethodDef, MemberRef);
            auto const MemberForwarded = composite_index_size(Field, MethodDef);
            auto const Implementation = composite_index_size(File, AssemblyRef, ExportedType);
            auto const CustomAttributeType = composite_index_size(MethodDef, MemberRef, empty_table, empty_table, empty_table);
            auto const ResolutionScope = composite_index_size(Module, ModuleRef, AssemblyRef, TypeRef);
            auto const TypeOrMethodDef = composite_index_size(TypeDef, MethodDef);

            Assembly.set_columns(4, 8, 4, blob_index_size, string_index_size, string_index_size);
            AssemblyOS.set_columns(4, 4, 4);
            AssemblyProcessor.set_columns(4);
            AssemblyRef.set_columns(8, 4, blob_index_size, string_index_size, string_index_size, blob_index_size);
            AssemblyRefOS.set_columns(4, 4, 4, AssemblyRef.index_size());
            AssemblyRefProcessor.set_columns(4, AssemblyRef.index_size());
            ClassLayout.set_columns(2, 4, TypeDef.index_size());
            Constant.set_columns(2, HasConstant, blob_index_size);
            CustomAttribute.set_columns(HasCustomAttribute, CustomAttributeType, blob_index_size);
            DeclSecurity.set_columns(2, HasDeclSecurity, blob_index_size);
            EventMap.set_columns(TypeDef.index_size(), Event.index_size());
            Event.set_columns(2, string_index_size, TypeDefOrRef);
            ExportedType.set_columns(4, 4, string_index_size, string_index_size, Implementation);
            Field.set_columns(2, string_index_size, blob_index_size);
            FieldLayout.set_columns(4, Field.index_size());
            FieldMarshal.set_columns(HasFieldMarshal, blob_index_size);
            FieldRVA.set_columns(4, Field.index_size());
            File.set_columns(4, string_index_size, blob_index_size);
            GenericParam.set_columns(2, 2, TypeOrMethodDef, string_index_size);
            GenericParamConstraint.set_columns(GenericParam.index_size(), TypeDefOrRef);
            ImplMap.set_columns(2, MemberForwarded, string_index_size, ModuleRef.index_size());
            InterfaceImpl.set_columns(TypeDef.index_size(), TypeDefOrRef);
            ManifestResource.set_columns(4, 4, string_index_size, Implementation);
            MemberRef.set_columns(MemberRefParent, string_index_size, blob_index_size);
            MethodDef.set_columns(4, 2, 2, string_index_size, blob_index_size, Param.index_size());
            MethodImpl.set_columns(TypeDef.index_size(), MethodDefOrRef, MethodDefOrRef);
            MethodSemantics.set_columns(2, MethodDef.index_size(), HasSemantics);
            MethodSpec.set_columns(MethodDefOrRef, blob_index_size);
            Module.set_columns(2, string_index_size, guid_index_size, guid_index_size, guid_index_size);
            ModuleRef.set_columns(string_index_size);
            NestedClass.set_columns(TypeDef.index_size(), TypeDef.index_size());
            Param.set_columns(2, 2, string_index_size);
            Property.set_columns(2, string_index_size, blob_index_size);
            PropertyMap.set_columns(TypeDef.index_size(), Property.index_size());
            StandAloneSig.set_columns(blob_index_size);
            TypeDef.set_columns(4, string_index_size, string_index_size, TypeDefOrRef, Field.index_size(), MethodDef.index_size());
            TypeRef.set_columns(ResolutionScope, string_index_size, string_index_size);
            TypeSpec.set_columns(blob_index_size);

            Module.set_data(view);
            TypeRef.set_data(view);
            TypeDef.set_data(view);
            Field.set_data(view);
            MethodDef.set_data(view);
            Param.set_data(view);
            InterfaceImpl.set_data(view);
            MemberRef.set_data(view);
            Constant.set_data(view);
            CustomAttribute.set_data(view);
            FieldMarshal.set_data(view);
            DeclSecurity.set_data(view);
            ClassLayout.set_data(view);
            FieldLayout.set_data(view);
            StandAloneSig.set_data(view);
            EventMap.set_data(view);
            Event.set_data(view);
            PropertyMap.set_data(view);
            Property.set_data(view);
            MethodSemantics.set_data(view);
            MethodImpl.set_data(view);
            ModuleRef.set_data(view);
            TypeSpec.set_data(view);
            ImplMap.set_data(view);
            FieldRVA.set_data(view);
            Assembly.set_data(view);
            AssemblyProcessor.set_data(view);
            AssemblyOS.set_data(view);
            AssemblyRef.set_data(view);
            AssemblyRefProcessor.set_data(view);
            AssemblyRefOS.set_data(view);
            File.set_data(view);
            ExportedType.set_data(view);
            ManifestResource.set_data(view);
            NestedClass.set_data(view);
            GenericParam.set_data(view);
            MethodSpec.set_data(view);
            GenericParamConstraint.set_data(view);
        }