| File: System\Reflection\Internal\MemoryBlocks\MemoryBlockProvider.cs | Web Access |
| Project: src\runtime\src\libraries\System.Reflection.Metadata\src\System.Reflection.Metadata.csproj (System.Reflection.Metadata) |
// 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.PortableExecutable; namespace System.Reflection.Internal { internal abstract class MemoryBlockProvider : IDisposable { /// <summary> /// Creates and hydrates a memory block representing all data. /// </summary> /// <exception cref="IOException">Error while reading from the memory source.</exception> public AbstractMemoryBlock GetMemoryBlock() { return GetMemoryBlockImpl(0, Size); } /// <summary> /// Creates and hydrates a memory block representing data in the specified range. /// </summary> /// <param name="start">Starting offset relative to the beginning of the data represented by this provider.</param> /// <param name="size">Size of the resulting block.</param> /// <exception cref="IOException">Error while reading from the memory source.</exception> public AbstractMemoryBlock GetMemoryBlock(int start, int size) { // Add cannot overflow as it is the sum of two 32-bit values done in 64 bits. // Negative start or size is handle by overflow to greater than maximum size = int.MaxValue. if ((ulong)(unchecked((uint)start)) + unchecked((uint)size) > (ulong)this.Size) { Throw.ImageTooSmallOrContainsInvalidOffsetOrCount(); } return GetMemoryBlockImpl(start, size); } /// <exception cref="IOException">IO error while reading from the underlying stream.</exception> protected abstract AbstractMemoryBlock GetMemoryBlockImpl(int start, int size); /// <summary> /// Gets the <see cref="Stream"/> backing the <see cref="MemoryBlockProvider"/>, if there is one. /// </summary> /// <remarks> /// It is the caller's responsibility to use <paramref name="stream"/> only /// while locking on <paramref name="streamGuard"/>, and not read outside the /// bounds defined by <paramref name="imageStart"/> and <paramref name="imageSize"/>. /// </remarks> public virtual bool TryGetUnderlyingStream([NotNullWhen(true)] out Stream? stream, out long imageStart, out int imageSize, [NotNullWhen(true)] out object? streamGuard) { stream = null; imageStart = 0; imageSize = 0; streamGuard = null; return false; } /// <summary> /// The size of the data. /// </summary> public abstract int Size { get; } protected abstract void Dispose(bool disposing); public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } } }