Table of Contents

Class MemoryAccessContext

Namespace
CStructSharp.Memory
Assembly
CStructSharp.dll

The budget for one logical operation: byte, request, nesting, and pointer limits plus a cancellation token. Not safe for concurrent use.

public sealed class MemoryAccessContext
Inheritance
MemoryAccessContext
Inherited Members

Remarks

Code that reads untrusted bytes must assume the worst: a corrupt list that loops forever, a pointer chain that never ends, a mapping table that sends every request through ten layers. A budget turns those into a bounded failure instead of a hang. The library passes one context through every layer that participates in an operation (session, mapping adapters, walkers, callbacks), so splitting work across objects never resets the limits. Create a fresh instance for each independent operation.

Set limits with an object initializer, for example new MemoryAccessContext { MaxTotalBytes = 4096 }; unset limits keep their defaults (64 MiB, 100 000 requests, nesting depth 256, pointer depth 64, the same nesting and pointer defaults as ReadOptions). Every limit must be positive: the init accessor throws ArgumentOutOfRangeException for zero or a negative value.

The counters measure library work, not unique addresses or hardware I/O. Re-reading a byte charges it again; validation and staging in a patch charge the same bytes several times. Requests counts zero-byte work too (a mapping lookup, a path step, a traversal step), which prevents a loop of individually cheap operations from running unbounded. MaxNestingDepth separately limits nested values and stacked source layers, and MaxPointerDepth limits the pointer steps one path follows. Cancellation is cooperative: it is checked before each request and cannot interrupt a source that blocks inside a transport call.

Constructors

MemoryAccessContext()

Creates a budget with the default limits and no cancellation; set properties in an object initializer to change them.

public MemoryAccessContext()

Properties

BytesRequested

Gets the bytes charged so far, including work attempted before a failure.

public long BytesRequested { get; }

Property Value

long

CancellationToken

Gets the cancellation token that every layer observes before each charged request.

public CancellationToken CancellationToken { get; init; }

Property Value

CancellationToken

MaxNestingDepth

Gets the greatest nesting depth (default 256, as MaxNestingDepth) of composite values being read, serialized, or flattened, and of source layers stacked on one another.

public int MaxNestingDepth { get; init; }

Property Value

int

Exceptions

ArgumentOutOfRangeException

The value set is zero or negative.

MaxPointerDepth

Gets the greatest number of pointer .value steps (default 64, as MaxPointerDepth) that one operation's path may follow.

public int MaxPointerDepth { get; init; }

Property Value

int

Exceptions

ArgumentOutOfRangeException

The value set is zero or negative.

MaxRequests

Gets the request limit (default 100 000): every charged unit of work counts, including zero-byte work such as mapping lookups, path steps, and traversal steps.

public int MaxRequests { get; init; }

Property Value

int

Exceptions

ArgumentOutOfRangeException

The value set is zero or negative.

MaxTotalBytes

Gets the byte limit (default 64 MiB): bytes requested from leaf sources plus bytes staged for output, counting repeated reads of the same address.

public long MaxTotalBytes { get; init; }

Property Value

long

Exceptions

ArgumentOutOfRangeException

The value set is zero or negative.

Requests

Gets the requests charged so far.

public int Requests { get; }

Property Value

int

Methods

Charge(string?, ulong?, int)

Charges one request and bytes bytes, throwing instead when the charge would exceed a limit.

public void Charge(string? sourceId, ulong? address, int bytes)

Parameters

sourceId string

Label of the source charging the work, reported if the budget is exceeded; null for work not tied to a source, such as staging serialized output.

address ulong?

Address of the work being charged, reported if the budget is exceeded; null for work not tied to an address.

bytes int

Bytes about to be read from a leaf source or staged as output; zero for translation-only work.

Remarks

Call this before doing the work, so exceeding a limit prevents the next request rather than being noticed afterwards. A successful charge stays counted even if the subsequent source operation fails. Leaf sources pass the requested byte count; translation-only adapters pass zero so bytes are not counted once per layer. Cancellation is checked first and has its own exception type.

Exceptions

OperationCanceledException

The caller has requested cancellation.

MemoryAccessException

The charge would exceed MaxTotalBytes or MaxRequests; the failure is BudgetExceeded.

ArgumentOutOfRangeException

bytes is negative.