Class MemoryRegion
- Namespace
- CStructSharp.Memory
- Assembly
- CStructSharp.dll
A finite byte range in one source: the source object, an unsigned start address, and a length in bytes.
public sealed record MemoryRegion : IEquatable<MemoryRegion>
- Inheritance
-
MemoryRegion
- Implements
- Inherited Members
Remarks
A region is the unit every session, walker, and patch operates on. It answers "which bytes may this operation touch?" and nothing more. It does not copy bytes, and it is not proof that the bytes exist: reading through the region still consults the source, which may report a hole or changed data.
The address is unsigned so that high 64-bit process addresses such as 0xffff800000000000 can be represented, while the length is a signed long because a single operation must always be finite and must fit in an allocation. Both constructor and Slice(long, long) check that the range does not wrap around the end of the address space, including the edge case where the final byte sits at MaxValue.
OpenRead(MemoryAccessContext?) is the bridge to the ordinary stream-based CStructSharp API: it exposes the region as a stream whose position zero is the region's start. The bridge does not rewrite any pointer bits stored in the bytes; stored process addresses remain meaningless as stream positions, and only MemorySession interprets them.
Constructors
MemoryRegion(IMemorySource, ulong, long)
Creates a region and rejects ranges that would wrap past the end of the unsigned address space.
public MemoryRegion(IMemorySource source, ulong address, long length)
Parameters
sourceIMemorySourceCaller-owned address space; the region does not take ownership or dispose it.
addressulongUnsigned starting coordinate in
source.lengthlongFinite byte extent; zero is allowed.
Properties
Address
Gets the unsigned address of the first byte.
public ulong Address { get; }
Property Value
Length
Gets the number of bytes in the region.
public long Length { get; }
Property Value
Source
Gets the caller-owned source whose coordinate system Address belongs to.
public IMemorySource Source { get; }
Property Value
Methods
DescribeBacking(MemoryAccessContext?)
Describes terminal backing fragments through optional static or dynamic mapping capabilities.
public IReadOnlyList<MemoryRegion> DescribeBacking(MemoryAccessContext? context = null)
Parameters
contextMemoryAccessContextShared mapping budget and cancellation, or a fresh default.
Returns
- IReadOnlyList<MemoryRegion>
Owned fragment list in logical order, retaining caller-owned source references.
Remarks
Provenance is demand-driven and does not read payload bytes. Source objects and unsigned coordinates identify fragments; diagnostic labels are not identities. Changing sources do not become atomic snapshots. Patch planning retains its static-mapping rules.
Exceptions
- MemoryAccessException
Mappings are absent, malformed or exceed work/depth limits.
- ArgumentOutOfRangeException
The region exceeds an int-sized provenance request.
Equals(MemoryRegion?)
public bool Equals(MemoryRegion? other)
Parameters
otherMemoryRegion
Returns
Equals(object?)
public override bool Equals(object? obj)
Parameters
objobject
Returns
GetHashCode()
public override int GetHashCode()
Returns
OpenRead(MemoryAccessContext?)
Opens a read-only, seekable stream over this region whose position zero is Address.
public Stream OpenRead(MemoryAccessContext? context = null)
Parameters
contextMemoryAccessContextShared operation budget and cancellation, or null to create a default budget.
Returns
- Stream
A non-owning finite stream positioned at zero.
Remarks
Use this to feed the core CStruct reader, for example to parse a runtime-sized layout that must stop at the region's end. The view cannot write, resize the source, or seek outside the region. Disposing it closes only the view; the source and any caller-owned file stream stay open. Core stream pointer rules still apply to pointers parsed through this view; use MemorySession for unsigned source-address resolution.
ReadExactly(Span<byte>, MemoryAccessContext)
Fills destination from the start of the region: a short read continues, and a read of
zero bytes inside the region is MissingBytes, never padding.
public void ReadExactly(Span<byte> destination, MemoryAccessContext context)
Parameters
destinationSpan<byte>The bytes to fill; it must not be longer than the region.
contextMemoryAccessContextShared budget charged by every underlying source read, and the cancellation token.
Remarks
A zero-length destination performs no transport requests but still observes cancellation. On failure a copied prefix may remain in the destination; unread bytes are untouched. The source remains caller-owned.
Exceptions
- ArgumentNullException
contextis null.- ArgumentOutOfRangeException
The destination exceeds this region's finite extent.
- MemoryAccessException
The source returned an invalid count or no bytes, or the operation budget was exhausted.
- OperationCanceledException
The context's token was cancelled between reads.
ReadPartial(Span<byte>, MemoryAccessContext)
Copies a confirmed prefix, reporting complete input or the exact source failure.
public MemoryReadResult ReadPartial(Span<byte> destination, MemoryAccessContext context)
Parameters
destinationSpan<byte>Caller-owned destination bounded by this region. Its unread suffix is unchanged.
contextMemoryAccessContextShared cancellation and work budget. Both terminate by throwing.
Returns
- MemoryReadResult
Copied prefix length and optional stop failure. Positive short reads continue.
Exceptions
- ArgumentOutOfRangeException
The destination exceeds the region.
- MemoryAccessException
The budget is exhausted.
- OperationCanceledException
Cancellation was requested, including for an empty destination.
Slice(long, long)
Creates a subregion that must lie entirely within this region.
public MemoryRegion Slice(long offset, long length)
Parameters
offsetlongByte offset from the start of this region.
lengthlongFinite byte extent of the subregion.
Returns
- MemoryRegion
A validated subregion in the same source.
Remarks
Offsets are relative to this region's start, which is how a schema's member offsets become
addresses: a field at offset 4 of a record region is record.Slice(4, size). An empty slice is allowed
at any offset up to and including Length.
ToString()
public override string ToString()
Returns
TryReadExactly(Span<byte>, MemoryAccessContext, out MemoryReadFailure?)
Fills a destination, returning expected missing-byte or source failures as data.
public bool TryReadExactly(Span<byte> destination, MemoryAccessContext context, out MemoryReadFailure? failure)
Parameters
destinationSpan<byte>Storage to fill from this region's start; its length cannot exceed the region.
contextMemoryAccessContextShared operation budget and cancellation; exhausted budgets and cancellation always propagate.
failureMemoryReadFailureFailure coordinates when false; null on success.
Returns
- bool
Whether every destination byte was supplied.
Remarks
Positive short reads continue. A copied prefix remains on failure and the unread suffix is untouched. Empty reads check cancellation without transport. Source implementations may still throw internally; zero-byte absence does not allocate an exception.
Exceptions
- ArgumentNullException
The context is null.
- ArgumentOutOfRangeException
The destination exceeds the finite region.
- MemoryAccessException
The operation budget is exhausted.
- OperationCanceledException
Cancellation was requested.
Operators
operator ==(MemoryRegion?, MemoryRegion?)
public static bool operator ==(MemoryRegion? left, MemoryRegion? right)
Parameters
leftMemoryRegionrightMemoryRegion
Returns
operator !=(MemoryRegion?, MemoryRegion?)
public static bool operator !=(MemoryRegion? left, MemoryRegion? right)
Parameters
leftMemoryRegionrightMemoryRegion