< Summary

Line coverage
0%
Covered lines: 0
Uncovered lines: 37
Coverable lines: 37
Total lines: 131
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 16
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.cctor()100%110%
.ctor(...)0%880%
Serialize(...)0%880%

File(s)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Ecma335/MetadataRootBuilder.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Collections.Immutable;
 5using System.Diagnostics;
 6using System.Text;
 7
 8namespace System.Reflection.Metadata.Ecma335
 9{
 10    /// <summary>
 11    /// Builder of a Metadata Root to be embedded in a Portable Executable image.
 12    /// </summary>
 13    /// <remarks>
 14    /// Metadata root constitutes of a metadata header followed by metadata streams (#~, #Strings, #US, #Guid and #Blob)
 15    /// </remarks>
 16    public sealed class MetadataRootBuilder
 17    {
 18        private const string DefaultMetadataVersionString = "v4.0.30319";
 19
 20        // internal for testing
 021        internal static readonly ImmutableArray<int> EmptyRowCounts = ImmutableArray.Create(new int[MetadataTokens.Table
 22
 23        private readonly MetadataBuilder _tablesAndHeaps;
 24        private readonly SerializedMetadata _serializedMetadata;
 25
 26        /// <summary>
 27        /// Metadata version string.
 28        /// </summary>
 029        public string MetadataVersion { get; }
 30
 31        /// <summary>
 32        /// True to suppresses basic validation of metadata tables.
 33        /// The validation verifies that entries in the tables were added in order required by the ECMA specification.
 34        /// It does not enforce all specification requirements on metadata tables.
 35        /// </summary>
 036        public bool SuppressValidation { get; }
 37
 38        /// <summary>
 39        /// Creates a builder of a metadata root.
 40        /// </summary>
 41        /// <param name="tablesAndHeaps">
 42        /// Builder populated with metadata entities stored in tables and values stored in heaps.
 43        /// The entities and values will be enumerated when serializing the metadata root.
 44        /// </param>
 45        /// <param name="metadataVersion">
 46        /// The version string written to the metadata header. The default value is "v4.0.30319".
 47        /// </param>
 48        /// <param name="suppressValidation">
 49        /// True to suppresses basic validation of metadata tables during serialization.
 50        /// The validation verifies that entries in the tables were added in order required by the ECMA specification.
 51        /// It does not enforce all specification requirements on metadata tables.
 52        /// </param>
 53        /// <exception cref="ArgumentNullException"><paramref name="tablesAndHeaps"/> is null.</exception>
 54        /// <exception cref="ArgumentException"><paramref name="metadataVersion"/> is too long (the number of bytes when
 055        public MetadataRootBuilder(MetadataBuilder tablesAndHeaps, string? metadataVersion = null, bool suppressValidati
 056        {
 057            if (tablesAndHeaps is null)
 058            {
 059                Throw.ArgumentNull(nameof(tablesAndHeaps));
 60            }
 61
 062            Debug.Assert(Encoding.UTF8.GetByteCount(DefaultMetadataVersionString) == DefaultMetadataVersionString.Length
 063            int metadataVersionByteCount = metadataVersion != null ? Encoding.UTF8.GetByteCount(metadataVersion) : Defau
 64
 065            if (metadataVersionByteCount > MetadataSizes.MaxMetadataVersionByteCount)
 066            {
 067                Throw.InvalidArgument(SR.MetadataVersionTooLong, nameof(metadataVersion));
 68            }
 69
 070            _tablesAndHeaps = tablesAndHeaps;
 071            MetadataVersion = metadataVersion ?? DefaultMetadataVersionString;
 072            SuppressValidation = suppressValidation;
 073            _serializedMetadata = tablesAndHeaps.GetSerializedMetadata(EmptyRowCounts, metadataVersionByteCount, isStand
 074        }
 75
 76        /// <summary>
 77        /// Returns sizes of various metadata structures.
 78        /// </summary>
 079        public MetadataSizes Sizes => _serializedMetadata.Sizes;
 80
 81        /// <summary>
 82        /// Serializes metadata root content into the given <see cref="BlobBuilder"/>.
 83        /// </summary>
 84        /// <param name="builder">Builder to write to.</param>
 85        /// <param name="methodBodyStreamRva">
 86        /// The relative virtual address of the start of the method body stream.
 87        /// Used to calculate the final value of RVA fields of MethodDef table.
 88        /// </param>
 89        /// <param name="mappedFieldDataStreamRva">
 90        /// The relative virtual address of the start of the field init data stream.
 91        /// Used to calculate the final value of RVA fields of FieldRVA table.
 92        /// </param>
 93        /// <exception cref="ArgumentNullException"><paramref name="builder"/> is null.</exception>
 94        /// <exception cref="ArgumentOutOfRangeException"><paramref name="methodBodyStreamRva"/> or <paramref name="mapp
 95        /// <exception cref="InvalidOperationException">
 96        /// A metadata table is not ordered as required by the specification and <see cref="SuppressValidation"/> is fal
 97        /// </exception>
 98        public void Serialize(BlobBuilder builder, int methodBodyStreamRva, int mappedFieldDataStreamRva)
 099        {
 0100            if (builder is null)
 0101            {
 0102                Throw.ArgumentNull(nameof(builder));
 103            }
 104
 0105            if (methodBodyStreamRva < 0)
 0106            {
 0107                Throw.ArgumentOutOfRange(nameof(methodBodyStreamRva));
 108            }
 109
 0110            if (mappedFieldDataStreamRva < 0)
 0111            {
 0112                Throw.ArgumentOutOfRange(nameof(mappedFieldDataStreamRva));
 113            }
 114
 0115            if (!SuppressValidation)
 0116            {
 0117                _tablesAndHeaps.ValidateOrder();
 0118            }
 119
 120            // header:
 0121            MetadataBuilder.SerializeMetadataHeader(builder, MetadataVersion, _serializedMetadata.Sizes);
 122
 123            // #~ or #- stream:
 0124            _tablesAndHeaps.SerializeMetadataTables(builder, _serializedMetadata.Sizes, _serializedMetadata.StringMap, m
 125
 126            // #Strings, #US, #Guid and #Blob streams:
 0127            _tablesAndHeaps.WriteHeapsTo(builder, _serializedMetadata.StringHeap);
 0128        }
 129    }
 130}
 131