Table of Contents

Class MemorySession

Namespace
CStructSharp.Memory
Assembly
CStructSharp.dll

Caller-owned arrays and explicitly bounded transport operations.

public sealed class MemorySession
Inheritance
MemorySession
Inherited Members

Remarks

A session joins two independent descriptions. The schema says how a type's bytes are arranged; a region says where some bytes live. Neither knows about the other, so one session can read the same record type from a file, from a mapped process image, and from a test fixture. The session itself keeps no bytes and no per-region state, which is why it can be reused freely and why every operation takes its own MemoryAccessContext.

The main operations build on one another. Resolve(MemoryRegion, string, string, MemoryAccessContext?) turns a path such as "items[2].next.value.pid" into a MemorySelection: the region, type, and field the path names. Read(MemoryRegion, string, string, MemoryAccessContext?) resolves and then decodes the selected bytes. Inspect(MemoryRegion, string, string, MemoryAccessContext?) additionally flattens mapping layers to report where the bytes physically came from. PlanUpdate(MemoryRegion, string, string, object?, MemoryAccessContext?) resolves, reads the current bytes, encodes the new value over them, and returns a MemoryPatch that a caller commits separately. Serialize(string, object?, MemoryAccessContext?) stands apart: it needs no region because it creates new bytes.

Pointers are the one place where the session must read data to know where to go next. Reading a pointer field yields a StoredPointer and stops. Only the explicit .value path step calls the resolver supplied at construction, which may apply a relative base, strip a tag, or switch to another address space. The default resolver treats a nonzero stored value as an absolute address in the same source. Primitive decoding and encoding always go through the core compiled codecs; composite traversal applies the schema's explicit offsets.

Failures use the core CStructException hierarchy. A path that cannot be parsed or resolved against the schema throws CStructPathException; a value that does not have the declared shape throws CStructWriteException; memory that cannot be read throws MemoryAccessException, a CStructReadException. When one of these crosses a session operation, the session records the requested typeId.path as Path and, for a memory access failure, the root region as LogicalRegion. Null arguments and cancellation keep their .NET exception types.

Constructors

MemorySession(MemorySchema, Func<PointerRequest, MemoryAccessContext, MemoryRegion>?)

Creates a session over a compiled schema, optionally with a custom pointer resolver.

public MemorySession(MemorySchema schema, Func<PointerRequest, MemoryAccessContext, MemoryRegion>? resolver = null)

Parameters

schema MemorySchema

Validated type graph that describes the records this session reads.

resolver Func<PointerRequest, MemoryAccessContext, MemoryRegion>

Turns stored pointer bits into a target region using the active operation context; null selects absolute addressing in the pointer's own source. The callback must forward this context to translation reads and must not retain it.

Properties

Schema

Gets the immutable compiled schema this session applies.

public MemorySchema Schema { get; }

Property Value

MemorySchema

Methods

Inspect(MemoryRegion, string, string, MemoryAccessContext?)

Reads one selection and reports both its logical location and the physical backing ranges that supplied its bytes.

public MemoryInspection Inspect(MemoryRegion region, string typeId, string path = "", MemoryAccessContext? context = null)

Parameters

region MemoryRegion

Finite caller-owned region holding the root record.

typeId string

ID of the root record's type in the schema.

path string

Member/index path from the root; pointer targets need an explicit .value step.

context MemoryAccessContext

Shared operation budget and cancellation, or null to create a default budget.

Returns

MemoryInspection

The value, its selection metadata, and the ordered backing ranges.

Remarks

Use this for an inspector that must show where a value came from. Flattening mapping tables costs extra requests beyond the value read, so prefer Read(MemoryRegion, string, string, MemoryAccessContext?) when provenance is unnecessary. Backing ranges follow every MappedMemorySource layer; a custom source is reported as-is because the library cannot see inside it. The result describes this read; it does not lock the bytes against later change.

Exceptions

ArgumentNullException

region or path is null.

CStructPathException

typeId is unknown, or the path is malformed or names no member, element, or pointer that can be followed.

MemoryAccessException

The bytes needed to resolve or read the value are unavailable, a followed pointer is null, or the budget is exhausted.

OperationCanceledException

The context's token was cancelled.

PlanUpdate(MemoryRegion, string, string, object?, MemoryAccessContext?)

Stages a replacement of the selected storage, preserving every byte and bit the new value does not cover. Nothing is written.

public MemoryPatch PlanUpdate(MemoryRegion region, string typeId, string path, object? value, MemoryAccessContext? context = null)

Parameters

region MemoryRegion

Finite caller-owned region holding the root record.

typeId string

ID of the root record's type in the schema.

path string

Member/index path from the root; pointer targets need an explicit .value step.

value object

New value in the declared shape of the selected type.

context MemoryAccessContext

Shared operation budget and cancellation, or null to create a default budget.

Returns

MemoryPatch

An immutable preview of the physical writes; no backing bytes are changed.

Remarks

The selected bytes are read first and the new value is encoded over a copy of them, so padding and neighboring bit slices survive. Replacing a whole union with a UnionValue that selects a member is the exception: the union is cleared before the chosen member is encoded. The returned patch has already flattened mapping layers and captured expected bytes, which means planning reads the storage more than once and needs a budget larger than the replacement length. Call Commit(MemoryAccessContext?) to perform the writes.

Exceptions

ArgumentNullException

region or path is null.

CStructPathException

typeId is unknown, or the path is malformed or names nothing writable.

CStructWriteException

value does not have the declared shape, or a bit-slice value is out of range.

MemoryAccessException

The current bytes are unavailable, the selection exceeds the byte budget, or planning found a stale source.

OperationCanceledException

The context's token was cancelled.

Read(MemoryRegion, string, string, MemoryAccessContext?)

Resolves a path and decodes the selected value. Pointers stay StoredPointer unless the path consumes .value.

public object? Read(MemoryRegion region, string typeId, string path = "", MemoryAccessContext? context = null)

Parameters

region MemoryRegion

Finite caller-owned region holding the root record.

typeId string

ID of the root record's type in the schema.

path string

Member/index path from the root; pointer targets need an explicit .value step.

context MemoryAccessContext

Shared operation budget and cancellation, or null to create a default budget.

Returns

object

The decoded scalar, stored pointer, structure, or fixed array.

Remarks

An empty path reads the root. Values have the shapes the core reader returns: a struct is a StructValue, a union a UnionValue with its raw storage and every member's interpretation of it, an array of a numeric or bool scalar a PrimitiveArray<T> and any other array a List<T> of object, a scalar its codec's managed type, and a signed bit slice a long. A selected path decodes only the storage it needs, so an unavailable unrelated member does not prevent reading a known field. Reading a whole union does not decide which member the application's tag selects.

Exceptions

ArgumentNullException

region or path is null.

CStructPathException

typeId is unknown, or the path is malformed or names no member, element, or pointer that can be followed.

MemoryAccessException

The bytes needed to resolve or read the value are unavailable, a followed pointer is null, or the budget is exhausted.

OperationCanceledException

The context's token was cancelled.

ReadArray<T>(MemoryRegion, string, Span<T>, MemoryAccessContext?, MemoryArrayReadMode, int)

Decodes a caller-counted numeric or stored-pointer array within an explicit permitted storage extent.

public void ReadArray<T>(MemoryRegion storage, string elementTypeId, Span<T> destination, MemoryAccessContext? context = null, MemoryArrayReadMode mode = MemoryArrayReadMode.Elementwise, int chunkBytes = 4096) where T : unmanaged

Parameters

storage MemoryRegion

Explicitly permitted array extent, independent of a fixed-size root header. No read may exceed it.

elementTypeId string

Schema identity of one scalar or pointer element.

destination Span<T>

Caller-owned destination; its element count determines the read count.

context MemoryAccessContext

Shared budget and cancellation.

mode MemoryArrayReadMode

Elementwise by default; Bulk explicitly changes requests and failure boundaries.

chunkBytes int

Maximum bulk request bytes, 1 to 65536 and at least one complete element.

Type Parameters

T

Exact numeric codec type; use ulong for pointers of any supported width, preserving all stored bits.

Remarks

On an unavailable-memory outcome every complete element of the confirmed copied prefix is committed, even within the final partial chunk. Unread elements remain untouched; an incomplete element's staged bytes are discarded. Custom codecs and enums use the ordinary API. Counts and total extent are validated before transport or staging allocation.

ReadBytes(MemoryRegion, string, string, MemoryAccessContext?)

Reads a declared one-byte integer array into its final owned raw-byte result without an intermediate numeric array.

public byte[] ReadBytes(MemoryRegion region, string typeId, string path = "", MemoryAccessContext? context = null)

Parameters

region MemoryRegion

Finite root record.

typeId string

Root schema identity.

path string

Relative byte-array path.

context MemoryAccessContext

Shared operation context; the full byte count is checked before allocation.

Returns

byte[]

A complete owned array; missing bytes never become zero padding.

Exceptions

ArgumentException

The path does not select a one-byte integer array.

MemoryAccessException

The source is unavailable or the operation budget is exhausted.

ReadBytes(MemoryRegion, string, string, Span<byte>, MemoryAccessContext?)

Copies a declared byte or signed-byte array directly to caller-owned raw storage.

public void ReadBytes(MemoryRegion region, string typeId, string path, Span<byte> destination, MemoryAccessContext? context = null)

Parameters

region MemoryRegion

Finite root record.

typeId string

Root type identity.

path string

Path to a fixed one-byte integer array.

destination Span<byte>

Destination with exactly the declared element count.

context MemoryAccessContext

Shared context, or null to create one.

Remarks

The destination must hold exactly the declared count. Each byte is read individually. Use ReadArray with Bulk for explicit chunked transport. A failure can leave a written prefix; no unread byte is manufactured.

Exceptions

ArgumentException

The path does not select a byte array or its count differs from the destination.

Resolve(MemoryRegion, string, string, MemoryAccessContext?)

Walks a path step by step to the region, type, and field it names, without decoding the final value.

public MemorySelection Resolve(MemoryRegion region, string typeId, string path = "", MemoryAccessContext? context = null)

Parameters

region MemoryRegion

Finite caller-owned region holding the root record.

typeId string

ID of the root record's type in the schema.

path string

Member/index path from the root; pointer targets need an explicit .value step.

context MemoryAccessContext

Shared operation budget and cancellation, or null to create a default budget.

Returns

MemorySelection

The selected storage location and its metadata; the value is not decoded.

Remarks

The walk starts with the root type over the root region and applies one token at a time. A member name slices the current region by the field's offset; an index slices an array by element size; both are pure arithmetic on schema data. A .value step on a pointer is different: the session must read the pointer bytes, refuse null and incomplete targets, and ask the resolver for the target region, which may lie outside the root region or in another source. A .address step keeps the pointer's stored-bit semantics and must end the path, so an update through it can never encode a resolved target by mistake.

Member and index steps count against the context's MaxNestingDepth, which restarts at each pointer target; every .value step counts against MaxPointerDepth. Together they bound pathological paths and pointer chains.

Exceptions

ArgumentNullException

region or path is null.

CStructPathException

typeId is unknown, or the path is malformed or names no member, element, or pointer that can be followed.

MemoryAccessException

The bytes needed to resolve or read the value are unavailable, a followed pointer is null, or the budget is exhausted.

OperationCanceledException

The context's token was cancelled.

Serialize(string, object?, MemoryAccessContext?)

Creates the bytes of one new record from zero-filled storage. Gaps and unselected union bytes stay zero.

public byte[] Serialize(string typeId, object? value, MemoryAccessContext? context = null)

Parameters

typeId string

ID of the type to encode.

value object

Value in the declared shape for that type.

context MemoryAccessContext

Shared operation budget and cancellation, or null to create a default budget.

Returns

byte[]

A new owned byte array of the type's size containing the encoded value.

Remarks

Struct input is a dictionary of member values, an array is an IList of the declared count, a pointer is a StoredPointer of the declared width, and a union is a UnionValue, as for the core writer: FromRaw(string, ReadOnlySpan<byte>) for its exact bytes or FromMember(string, string, object?) for one member. The method creates storage for this one value only; it does not allocate pointer targets or choose addresses. Write the result into a source yourself or pass it to Create(MemoryRegion, ReadOnlySpan<byte>, MemoryAccessContext?, byte[]?). Unlike PlanUpdate(MemoryRegion, string, string, object?, MemoryAccessContext?), this starts from zeroes, so padding recorded by the metadata is initialized to zero rather than preserved.

Exceptions

CStructPathException

typeId is unknown or names an incomplete type.

CStructWriteException

value does not have the declared shape, or a scalar codec rejects it.

MemoryAccessException

The output or the nesting exceeds the budget; the failure has no source coordinates.

OperationCanceledException

The context's token was cancelled.

TryReadArray<T>(MemoryRegion, string, Span<T>, out int, out MemoryReadFailure?, MemoryAccessContext?, MemoryArrayReadMode, int)

Decodes a bounded caller-counted array, reporting completed elements and expected memory failure as data.

public bool TryReadArray<T>(MemoryRegion storage, string elementTypeId, Span<T> destination, out int elementsWritten, out MemoryReadFailure? failure, MemoryAccessContext? context = null, MemoryArrayReadMode mode = MemoryArrayReadMode.Elementwise, int chunkBytes = 4096) where T : unmanaged

Parameters

storage MemoryRegion

Finite permitted byte extent; a flexible-array count never extends this region.

elementTypeId string

Scalar or pointer element identity.

destination Span<T>

Caller-owned values; unread elements are untouched.

elementsWritten int

Complete elements committed, including the confirmed prefix of a failed chunk.

failure MemoryReadFailure

Memory failure on false, null on success.

context MemoryAccessContext

Operation budget; exhaustion and cancellation propagate.

mode MemoryArrayReadMode

Explicit transport shape.

chunkBytes int

Bulk staging/request bound in bytes, at most 65536.

Returns

bool

Whether every element was decoded.

Type Parameters

T

Exact primitive result type, or ulong for stored pointers.

Exceptions

ArgumentException

Element type, destination extent or mode is invalid.

MemoryAccessException

The remaining operation budget is insufficient.

OperationCanceledException

Cancellation was requested.

TryResolve(MemoryRegion, string, string, out MemorySelection?, out MemoryReadFailure?, MemoryAccessContext?)

Resolves a path while returning expected schema and memory failures as structured data.

public bool TryResolve(MemoryRegion region, string typeId, string path, out MemorySelection? selection, out MemoryReadFailure? failure, MemoryAccessContext? context = null)

Parameters

region MemoryRegion

Finite root storage.

typeId string

Root schema identity.

path string

Relative member/index/pointer path.

selection MemorySelection

Selected storage when true.

failure MemoryReadFailure

Structured outcome when false.

context MemoryAccessContext

Shared operation context; budget exhaustion and cancellation propagate.

Returns

bool

Whether the complete path resolved.