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
CancellationToken
Gets the cancellation token that every layer observes before each charged request.
public CancellationToken CancellationToken { get; init; }
Property Value
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
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
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
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
Exceptions
- ArgumentOutOfRangeException
The value set is zero or negative.
Requests
Gets the requests charged so far.
public int Requests { get; }
Property Value
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
sourceIdstringLabel 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.
addressulong?Address of the work being charged, reported if the budget is exceeded; null for work not tied to an address.
bytesintBytes 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
bytesis negative.