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, IAsyncDisposableThis 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
Properties
Section titled “Properties”CanRead
Section titled “CanRead”Gets false because stream reads are unsupported; use checked byte copies instead.
public override bool CanRead { get; }Value: bool
CanSeek
Section titled “CanSeek”Gets false because writes always append to the native buffer.
public override bool CanSeek { get; }Value: bool
CanWrite
Section titled “CanWrite”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.
Capacity
Section titled “Capacity”Gets the payload capacity excluding NUL, or the payload length for a read-only external buffer.
public int Capacity { get; }Value: int
IsEmpty
Section titled “IsEmpty”Gets whether the checked native buffer currently contains no payload bytes.
public bool IsEmpty { get; }Value: bool
IsReadOnly
Section titled “IsReadOnly”Gets whether the native buffer is marked read-only.
public bool IsReadOnly { get; }Value: bool
Length
Section titled “Length”Gets the current payload byte length, excluding any trailing NUL.
public override long Length { get; }Value: long
LifetimeContext
Section titled “LifetimeContext”Gets the native owner for an owned buffer or the explicit lifetime anchor for a borrowed buffer.
public PgMemoryContext LifetimeContext { get; }Value: PgMemoryContext
Position
Section titled “Position”Rejects stream positioning because writes always append.
public override long Position { get; set; }Value: long
Methods
Section titled “Methods”CopyTo(Span<byte>, int)
Section titled “CopyTo(Span<byte>, int)”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.
Create(int, PgMemoryContext?)
Section titled “Create(int, PgMemoryContext?)”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.
Create(string, PgMemoryContext?)
Section titled “Create(string, PgMemoryContext?)”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:
- EncoderFallbackException: The text contains an unpaired UTF-16 surrogate.
DangerousAppend(void*, int)
Section titled “DangerousAppend(void*, int)”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.
DangerousBorrow(void*, PgMemoryContext)
Section titled “DangerousBorrow(void*, PgMemoryContext)”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.
DangerousDetach()
Section titled “DangerousDetach()”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.
DangerousDetachCString()
Section titled “DangerousDetachCString()”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.
DangerousDetachData()
Section titled “DangerousDetachData()”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.
Dispose(bool)
Section titled “Dispose(bool)”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.
DisposeAsync()
Section titled “DisposeAsync()”Releases owned storage synchronously on the invoking backend thread.
public override ValueTask DisposeAsync()Returns: ValueTask
A completed operation.
Enlarge(int)
Section titled “Enlarge(int)”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.
EnsureCapacity(int)
Section titled “EnsureCapacity(int)”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.
Flush()
Section titled “Flush()”Validates the buffer; appended bytes already reside in PostgreSQL storage.
public override void Flush()FlushAsync(CancellationToken)
Section titled “FlushAsync(CancellationToken)”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.
Read(byte[], int, int)
Section titled “Read(byte[], int, int)”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.
Reset()
Section titled “Reset()”Clears the payload and native cursor while retaining the allocated capacity.
public void Reset()Seek(long, SeekOrigin)
Section titled “Seek(long, SeekOrigin)”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.
SetLength(long)
Section titled “SetLength(long)”Rejects arbitrary length changes; use Reset to clear the payload.
public override void SetLength(long value)Parameters:
value — long
The unused length.
ToArray()
Section titled “ToArray()”Copies the complete payload into independent managed storage.
public byte[] ToArray()Returns: byte[]
The exact payload bytes without the native terminator.
ToString()
Section titled “ToString()”Decodes the complete payload as strict UTF-8, preserving embedded NUL characters.
public override string ToString()Returns: string
The decoded text.
Exceptions:
- DecoderFallbackException: The payload is not valid UTF-8.
ToStringLossy()
Section titled “ToStringLossy()”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.
Write(byte[], int, int)
Section titled “Write(byte[], int, int)”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.
Write(char)
Section titled “Write(char)”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.
Write(ReadOnlySpan<byte>)
Section titled “Write(ReadOnlySpan<byte>)”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.
Write(string)
Section titled “Write(string)”Appends strict UTF-8 text without database-encoding conversion.
public void Write(string value)Parameters:
value — string
The text, including any embedded NUL.
Exceptions:
- EncoderFallbackException: The text contains an unpaired UTF-16 surrogate.
Write(Rune)
Section titled “Write(Rune)”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.
WriteAt(int, ReadOnlySpan<byte>)
Section titled “WriteAt(int, ReadOnlySpan<byte>)”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.
WriteByte(byte)
Section titled “WriteByte(byte)”Appends one byte, including zero.
public override void WriteByte(byte value)Parameters:
value — byte
The byte to append.