File: System\Reflection\TypeLoading\Assemblies\Ecma\EcmaAssembly.ManifestResources.cs
Web Access
Project: src\src\libraries\System.Reflection.MetadataLoadContext\src\System.Reflection.MetadataLoadContext.csproj (System.Reflection.MetadataLoadContext)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection.Metadata;
 
namespace System.Reflection.TypeLoading.Ecma
{
    /// <summary>
    /// Base class for all Assembly objects created by a MetadataLoadContext and get its metadata from a PEReader.
    /// </summary>
    internal sealed partial class EcmaAssembly
    {
        public sealed override ManifestResourceInfo? GetManifestResourceInfo(string resourceName)
        {
            if (resourceName is null)
                throw new ArgumentNullException(nameof(resourceName));
            if (resourceName.Length == 0)
                throw new ArgumentException(null, nameof(resourceName));
 
            InternalManifestResourceInfo internalManifestResourceInfo = GetEcmaManifestModule().GetInternalManifestResourceInfo(resourceName);
 
            if (!internalManifestResourceInfo.Found)
            {
                return null;
            }
 
            if (internalManifestResourceInfo.ResourceLocation == ResourceLocation.ContainedInAnotherAssembly)
            {
                // Must get resource info from other assembly, and OR in the contained in another assembly information
                ManifestResourceInfo underlyingManifestResourceInfo = internalManifestResourceInfo.ReferencedAssembly.GetManifestResourceInfo(resourceName)!;
                internalManifestResourceInfo.FileName = underlyingManifestResourceInfo.FileName ?? string.Empty;
                internalManifestResourceInfo.ResourceLocation = underlyingManifestResourceInfo.ResourceLocation | ResourceLocation.ContainedInAnotherAssembly;
                if (underlyingManifestResourceInfo.ReferencedAssembly != null)
                    internalManifestResourceInfo.ReferencedAssembly = underlyingManifestResourceInfo.ReferencedAssembly;
            }
 
            return new ManifestResourceInfo(internalManifestResourceInfo.ReferencedAssembly, internalManifestResourceInfo.FileName, internalManifestResourceInfo.ResourceLocation);
        }
 
        public sealed override string[] GetManifestResourceNames()
        {
            MetadataReader reader = Reader;
 
            ManifestResourceHandleCollection manifestResources = reader.ManifestResources;
            string[] resourceNames = new string[manifestResources.Count];
 
            int iResource = 0;
            foreach (ManifestResourceHandle resourceHandle in manifestResources)
            {
                ManifestResource resource = resourceHandle.GetManifestResource(reader);
                resourceNames[iResource] = resource.Name.GetString(reader);
                iResource++;
            }
 
            return resourceNames;
        }
 
        [UnconditionalSuppressMessage("SingleFile", "IL3002:RequiresAssemblyFiles on Module.GetFile",
            Justification = "ResourceLocation should never be ContainedInAnotherAssembly if embedded in a single-file")]
        public sealed override Stream? GetManifestResourceStream(string name)
        {
            if (name is null)
                throw new ArgumentNullException(nameof(name));
            if (name.Length == 0)
                throw new ArgumentException(null, nameof(name));
 
            InternalManifestResourceInfo internalManifestResourceInfo = GetEcmaManifestModule().GetInternalManifestResourceInfo(name);
 
            if (!internalManifestResourceInfo.Found)
            {
                return null;
            }
 
            if ((internalManifestResourceInfo.ResourceLocation & ResourceLocation.Embedded) != 0)
            {
                unsafe
                {
                    return new UnmanagedMemoryStream(internalManifestResourceInfo.PointerToResource, internalManifestResourceInfo.SizeOfResource);
                }
            }
            else
            {
                if (internalManifestResourceInfo.ResourceLocation == ResourceLocation.ContainedInAnotherAssembly)
                {
                    return internalManifestResourceInfo.ReferencedAssembly.GetManifestResourceStream(name);
                }
                else
                {
                    return GetFile(internalManifestResourceInfo.FileName);
                }
            }
        }
    }
}