Skip to content

PgStringInfoStream

Namespace: Ankus

Assembly: Ankus.Runtime.dll

Appends binary data and UTF-8 text to a checked PostgreSQL StringInfo buffer.

public sealed class PgStringInfoStream : Stream, IDisposable, IAsyncDisposable

This write-only stream requires the active backend thread. Native buffers retain their PostgreSQL context ownership across ambient context switches. Disposal frees owned storage; borrowed storage remains with its native owner. No finalizer calls PostgreSQL.

Inheritance: object, MarshalByRefObject, Stream

Implements: IDisposable, IAsyncDisposable

Gets false because stream reads are unsupported; use checked byte copies instead.

public override bool CanRead { get; }

Value: bool

Gets false because writes always append to the native buffer.

public override bool CanSeek { get; }

Value: bool

Gets whether this undisposed wrapper was created for a writable native buffer.

public override bool CanWrite { get; }

Value: bool

This capability does not prove that its native lifetime remains live; each operation checks that lifetime.

Gets the payload capacity excluding NUL, or the payload length for a read-only external buffer.

public int Capacity { get; }

Value: int

Gets whether the checked native buffer currently contains no payload bytes.

public bool IsEmpty { get; }

Value: bool

Gets whether the native buffer is marked read-only.

public bool IsReadOnly { get; }

Value: bool

Gets the current payload byte length, excluding any trailing NUL.

public override long Length { get; }

Value: long

Gets the native owner for an owned buffer or the explicit lifetime anchor for a borrowed buffer.

public PgMemoryContext LifetimeContext { get; }

Value: PgMemoryContext

Rejects stream positioning because writes always append.

public override long Position { get; set; }

Value: long

Copies an exact payload range without exposing a span over resizable native storage.

public void CopyTo(Span<byte> destination, int offset = 0)

Parameters:

destination — Span<byte>

The managed destination; its length selects the byte count.

offset — int

The first native payload byte to copy.

Creates an empty PostgreSQL buffer with at least the requested payload capacity.

public static PgStringInfoStream Create(int capacity = 0, PgMemoryContext? context = null)

Parameters:

capacity — int

The minimum byte capacity, excluding the trailing NUL.

context — PgMemoryContext

The destination context, or null for the current context.

Returns: PgStringInfoStream

An individually owned native buffer.

Create(ReadOnlySpan<byte>, PgMemoryContext?)

Section titled “Create(ReadOnlySpan<byte>, PgMemoryContext?)”

Creates an owned buffer containing an independent copy of arbitrary bytes.

public static PgStringInfoStream Create(ReadOnlySpan<byte> value, PgMemoryContext? context = null)

Parameters:

value — ReadOnlySpan<byte>

The initial bytes, including any embedded NUL or invalid UTF-8.

context — PgMemoryContext

The destination context, or null for the current context.

Returns: PgStringInfoStream

The initialized native buffer.

Creates an owned buffer containing strict UTF-8, independently of the database encoding.

public static PgStringInfoStream Create(string value, PgMemoryContext? context = null)

Parameters:

value — string

The initial text; embedded NUL characters are preserved.

context — PgMemoryContext

The destination context, or null for the current context.

Returns: PgStringInfoStream

The initialized native buffer.

Exceptions:

Appends an explicitly accessible native byte range, including a slice of this buffer’s payload.

public void DangerousAppend(void* data, int length)

Parameters:

data — void*

The accessible source pointer, or null for an empty append.

length — int

The source byte count.

The caller guarantees the source range remains readable until copied. A slice of the current payload is resolved again after growth, so self-appending does not retain an obsolete pointer.

Borrows an external PostgreSQL StringInfo without acquiring release rights.

public static PgStringInfoStream? DangerousBorrow(void* address, PgMemoryContext lifetimeContext)

Parameters:

address — void*

The initialized native StringInfoData address, or null.

lifetimeContext — PgMemoryContext

The explicit reset-sensitive lifetime anchor.

Returns: PgStringInfoStream

A borrowed buffer, or null for a null address.

The caller guarantees accessible struct and payload storage until the shorter of its external lifetime and the anchor lifetime. Mutable buffers must support PostgreSQL’s repalloc contract. Read-only buffers may use non-palloc storage without a trailing NUL. The anchor does not establish allocator provenance or detect external free or resize.

Consumes this wrapper and returns the whole native StringInfo without freeing its storage.

public void* DangerousDetach()

Returns: void*

The native StringInfoData pointer with its original PostgreSQL lifetime.

Consumes the buffer only after proving its payload contains exactly one trailing NUL and no interior NUL.

public byte* DangerousDetachCString()

Returns: byte*

The original NUL-terminated data pointer, with the same ownership rules as DangerousDetachData.

For a read-only external buffer, the unsafe caller must prove Length plus one bytes are accessible. Rejection leaves this wrapper live and its bytes unchanged.

Consumes this wrapper and returns its payload without freeing the payload storage.

public byte* DangerousDetachData()

Returns: byte*

The original payload pointer with its existing native lifetime.

For owned buffers, the now-unneeded native struct is freed. Borrowed structs and payloads remain untouched. This operation does not promise C-string termination or transfer a borrowed allocator’s rights.

Frees both native allocations when owned; borrowed disposal only closes this wrapper.

protected override void Dispose(bool disposing)

Parameters:

disposing — bool

Whether explicit managed disposal is occurring.

Releases owned storage synchronously on the invoking backend thread.

public override ValueTask DisposeAsync()

Returns: ValueTask

A completed operation.

Ensures capacity for at least the requested number of additional payload bytes.

public void Enlarge(int additionalByteCount)

Parameters:

additionalByteCount — int

Additional bytes beyond the current length.

Ensures an absolute minimum payload capacity while preserving all existing bytes.

public int EnsureCapacity(int capacity)

Parameters:

capacity — int

The minimum payload capacity excluding NUL.

Returns: int

The resulting payload capacity.

Validates the buffer; appended bytes already reside in PostgreSQL storage.

public override void Flush()

Validates the buffer synchronously on the invoking backend thread.

public override Task FlushAsync(CancellationToken cancellationToken)

Parameters:

cancellationToken — CancellationToken

Cancellation checked before validation.

Returns: Task

A completed task.

Rejects stream reads; use ToArray or CopyTo with a destination span.

public override int Read(byte[] buffer, int offset, int count)

Parameters:

buffer — byte[]

The unused destination.

offset — int

The unused destination offset.

count — int

The unused requested length.

Returns: int

No value; this method throws NotSupportedException.

Clears the payload and native cursor while retaining the allocated capacity.

public void Reset()

Rejects seeking because stream writes always append.

public override long Seek(long offset, SeekOrigin origin)

Parameters:

offset — long

The unused offset.

origin — SeekOrigin

The unused origin.

Returns: long

No value; this method throws NotSupportedException.

Rejects arbitrary length changes; use Reset to clear the payload.

public override void SetLength(long value)

Parameters:

value — long

The unused length.

Copies the complete payload into independent managed storage.

public byte[] ToArray()

Returns: byte[]

The exact payload bytes without the native terminator.

Decodes the complete payload as strict UTF-8, preserving embedded NUL characters.

public override string ToString()

Returns: string

The decoded text.

Exceptions:

Formats arbitrary bytes for display by explicitly replacing malformed UTF-8 sequences.

public string ToStringLossy()

Returns: string

Display text containing replacement characters for invalid sequences.

This matches pgrx’s lossy Display formatting. Use ToArray or strict ToString when preserving values.

Appends the selected managed byte range.

public override void Write(byte[] buffer, int offset, int count)

Parameters:

buffer — byte[]

The source array.

offset — int

The first source byte.

count — int

The number of bytes to append.

Appends one non-surrogate UTF-16 character as UTF-8.

public void Write(char value)

Parameters:

value — char

The character to append; use a string or Rune for a surrogate pair.

Appends arbitrary bytes, retaining embedded NUL and invalid UTF-8.

public override void Write(ReadOnlySpan<byte> buffer)

Parameters:

buffer — ReadOnlySpan<byte>

The payload to append.

Appends strict UTF-8 text without database-encoding conversion.

public void Write(string value)

Parameters:

value — string

The text, including any embedded NUL.

Exceptions:

Appends one complete Unicode scalar as UTF-8.

public void Write(Rune value)

Parameters:

value — Rune

The scalar to append.

WriteAsync(byte[], int, int, CancellationToken)

Section titled “WriteAsync(byte[], int, int, CancellationToken)”

Writes synchronously on the current backend thread and returns a completed task.

public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)

Parameters:

buffer — byte[]

The source array.

offset — int

The first source byte.

count — int

The number of bytes to append.

cancellationToken — CancellationToken

Cancellation checked before accessing native storage.

Returns: Task

A completed task; no work is queued to another thread.

WriteAsync(ReadOnlyMemory<byte>, CancellationToken)

Section titled “WriteAsync(ReadOnlyMemory<byte>, CancellationToken)”

Writes synchronously on the current backend thread and returns a completed operation.

public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default)

Parameters:

buffer — ReadOnlyMemory<byte>

The source bytes.

cancellationToken — CancellationToken

Cancellation checked before accessing native storage.

Returns: ValueTask

A completed operation; no native capability flows to another thread.

Replaces an existing payload range without appending or changing its length.

public void WriteAt(int offset, ReadOnlySpan<byte> source)

Parameters:

offset — int

The first native payload byte to replace.

source — ReadOnlySpan<byte>

The replacement bytes.

Appends one byte, including zero.

public override void WriteByte(byte value)

Parameters:

value — byte

The byte to append.