Table of Contents

Class ArrayPoolMemoryStream

Namespace
CryptoHives.Foundation.Memory.Buffers
Assembly
CryptoHives.Foundation.Memory.dll

Class to create a MemoryStream which uses ArrayPool buffers.

public sealed class ArrayPoolMemoryStream : MemoryStream, IDisposable
Inheritance
ArrayPoolMemoryStream
Implements
Inherited Members

Constructors

ArrayPoolMemoryStream()

Initializes a new instance of the ArrayPoolMemoryStream class. Creates a writeable stream that creates buffers as necessary using buffer defaults.

public ArrayPoolMemoryStream()

ArrayPoolMemoryStream(bool)

Initializes a new instance of the ArrayPoolMemoryStream class. Creates a writeable stream using buffer defaults, choosing whether buffers are zeroed as they return to the ArrayPool<T>.

public ArrayPoolMemoryStream(bool clearArray)

Parameters

clearArray bool

Whether each buffer is zeroed as it goes back to the ArrayPool<T>, so the next renter cannot read what this stream wrote.

ArrayPoolMemoryStream(IEnumerable<ArraySegment<byte>>)

Initializes a new instance of the ArrayPoolMemoryStream class. Attaches the stream to read from a enumerable of buffers wrapped in ArraySegment<T>. Buffers are not returned to the ArrayPool when the stream is disposed.

public ArrayPoolMemoryStream(IEnumerable<ArraySegment<byte>> buffers)

Parameters

buffers IEnumerable<ArraySegment<byte>>

ArrayPoolMemoryStream(int, bool)

Initializes a new instance of the ArrayPoolMemoryStream class. Creates a writeable stream that creates buffers as necessary using buffer list size defaults.

public ArrayPoolMemoryStream(int bufferSize, bool clearArray = false)

Parameters

bufferSize int

The size of the buffers

clearArray bool

Whether each buffer is zeroed as it goes back to the ArrayPool<T>, so the next renter cannot read what this stream wrote.

ArrayPoolMemoryStream(int, int, bool)

Initializes a new instance of the ArrayPoolMemoryStream class. Creates a writeable stream that creates buffers as necessary.

public ArrayPoolMemoryStream(int bufferListSize, int bufferSize, bool clearArray = false)

Parameters

bufferListSize int

The initial size of the buffer list

bufferSize int

The size of the buffers

clearArray bool

Whether each buffer is zeroed as it goes back to the ArrayPool<T>, so the next renter cannot read what this stream wrote.

ArrayPoolMemoryStream(int, int, int, int, bool)

Initializes a new instance of the ArrayPoolMemoryStream class. Creates a writeable stream that rents ArrayPool buffers as necessary.

public ArrayPoolMemoryStream(int bufferListSize, int bufferSize, int start, int count, bool clearArray = false)

Parameters

bufferListSize int

The initial size of the buffer list

bufferSize int

The size of the buffers

start int

The start of the ArraySegment in a buffer

count int

The count of bytes in the ArraySegment that is used in the buffer

clearArray bool

Whether each buffer is zeroed as it goes back to the ArrayPool<T>, so the next renter cannot read what this stream wrote. Set it when the stream carries key material or other secrets; the cost is one Array.Clear per buffer at disposal.

Exceptions

ArgumentException

Fields

DefaultBufferListSize

The default list size for the array segments.

public static readonly int DefaultBufferListSize

Field Value

int

DefaultBufferSize

The default buffer size of the allocated array pool buffers.

public static readonly int DefaultBufferSize

Field Value

int

Properties

CanRead

Gets a value indicating whether the current stream supports reading.

public override bool CanRead { get; }

Property Value

bool

true if the stream is open.

CanSeek

Gets a value indicating whether the current stream supports seeking.

public override bool CanSeek { get; }

Property Value

bool

true if the stream is open.

CanWrite

Gets a value indicating whether the current stream supports writing.

public override bool CanWrite { get; }

Property Value

bool

true if the stream supports writing; otherwise, false.

Capacity

Gets the total capacity of the rented segments, in bytes.

public override int Capacity { get; set; }

Property Value

int

Remarks

This is the space available before another segment is rented, not the payload length; use Length for that. The inherited implementation would report the capacity of the unused base-class array, which is always zero.

Exceptions

NotSupportedException

On set. Capacity grows automatically as data is written.

Length

Gets the length of the stream in bytes.

public override long Length { get; }

Property Value

long

The length of the stream in bytes.

Exceptions

ObjectDisposedException

The stream is closed.

Position

Gets or sets the current position within the stream.

public override long Position { get; set; }

Property Value

long

The current position within the stream.

Exceptions

ArgumentOutOfRangeException

The position is set to a negative value or a value greater than MaxValue.

ObjectDisposedException

The stream is closed.

Methods

Dispose(bool)

Releases the unmanaged resources used by the MemoryStream class and optionally releases the managed resources.

protected override void Dispose(bool disposing)

Parameters

disposing bool

true to release both managed and unmanaged resources; false to release only unmanaged resources.

Flush()

Overrides the Flush() method so that no action is performed.

public override void Flush()

GetBuffer()

Not supported: the stream is backed by a list of pooled segments, so there is no single contiguous array to hand out.

public override byte[] GetBuffer()

Returns

byte[]

Remarks

Use GetReadOnlySequence() for a borrowed view of the payload, or LeaseSequence() to carry it past this scope. The base implementation is overridden because it would otherwise return the unused array of the MemoryStream this type derives from, silently reporting an empty payload.

Exceptions

NotSupportedException

Always.

GetReadOnlySequence()

Returns a ReadOnlySequence<T> of the buffers stored in the stream. ReadOnlySequence is only valid as long as the stream is not disposed and no more data is written.

public ReadOnlySequence<byte> GetReadOnlySequence()

Returns

ReadOnlySequence<byte>

Remarks

The sequence borrows the stream's buffers; it does not own them. Use LeaseSequence() when the payload has to leave the scope that built it.

LeaseSequence()

Pairs the stream's payload with the stream itself as a single disposable value, so the payload can leave the scope that produced it.

public SequenceLease<byte> LeaseSequence()

Returns

SequenceLease<byte>

A SequenceLease<T> over the payload. Disposing it disposes this stream, which returns its buffers to the array pool.

Remarks

The lease is a struct, so this costs only the segment chain that GetReadOnlySequence() builds — nothing beyond what reading the payload would cost anyway.

using SequenceLease<byte> payload = stream.LeaseSequence();
Send(payload.Sequence);

Do not write to the stream after leasing: that invalidates the leased sequence exactly as it would one from GetReadOnlySequence().

Read(byte[], int, int)

Reads a block of bytes from the current stream and writes the data to a buffer.

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

Parameters

buffer byte[]

When this method returns, contains the specified byte array with the values between offset and (offset + count - 1) replaced by the characters read from the current stream.

offset int

The zero-based byte offset in buffer at which to begin storing data from the current stream.

count int

The maximum number of bytes to read.

Returns

int

The total number of bytes written into the buffer. This can be less than the number of bytes requested if that number of bytes are not currently available, or zero if the end of the stream is reached before any bytes are read.

Exceptions

ArgumentNullException

buffer is null.

ArgumentOutOfRangeException

offset or count is negative.

ArgumentException

offset subtracted from the buffer length is less than count.

ObjectDisposedException

The current stream instance is closed.

Read(Span<byte>)

public int Read(Span<byte> destination)

Parameters

destination Span<byte>

Returns

int

ReadByte()

Reads a byte from the current stream.

public override int ReadByte()

Returns

int

The byte cast to a int, or -1 if the end of the stream has been reached.

Exceptions

ObjectDisposedException

The current stream instance is closed.

ReadExactly(byte[], int, int)

Reads count bytes from the current stream and advances the position within the stream.

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

Parameters

buffer byte[]

An array of bytes. When this method returns, the buffer contains the specified byte array with the values between offset and (offset + count - 1) replaced by the bytes read from the current source.

offset int

The byte offset in buffer at which to begin storing the data read from the current stream.

count int

The number of bytes to be read from the current stream.

Exceptions

EndOfStreamException

The end of the stream is reached before reading count bytes.

ReadExactly(Span<byte>)

Reads bytes from the current stream and advances the position within the stream until the buffer is filled.

public void ReadExactly(Span<byte> buffer)

Parameters

buffer Span<byte>

A region of memory. When this method returns, the contents of this region are replaced by the bytes read from the current stream.

Exceptions

EndOfStreamException

The end of the stream is reached before filling the buffer.

Seek(long, SeekOrigin)

Sets the position within the current stream to the specified value.

public override long Seek(long offset, SeekOrigin loc)

Parameters

offset long

The new position within the stream. This is relative to the loc parameter, and can be positive or negative.

loc SeekOrigin

A value of type SeekOrigin, which acts as the seek reference point.

Returns

long

The new position within the stream, calculated by combining the initial reference point and the offset.

Exceptions

IOException

Seeking is attempted before the beginning of the stream.

ArgumentOutOfRangeException

offset is greater than MaxValue.

ArgumentException

There is an invalid SeekOrigin. -or-offset caused an arithmetic overflow.

ObjectDisposedException

The current stream instance is closed.

SetLength(long)

Sets the length of the stream, renting or returning pooled segments as needed.

public override void SetLength(long value)

Parameters

value long

The desired length in bytes.

Remarks

Truncating returns the segments that fall away to the pool and keeps the rest, which is what makes SetLength(0) a cheap way to reuse the stream for another payload. Growing appends zeroed bytes, since a rented array carries whatever the previous tenant left in it. As with MemoryStream, a position past the new end is pulled back to it.

Exceptions

ArgumentOutOfRangeException

value is negative or exceeds MaxValue.

NotSupportedException

The stream wraps externally owned buffers and is read-only.

ToArray()

Writes the stream contents to a byte array, regardless of the Position property.

public override byte[] ToArray()

Returns

byte[]

A new byte array.

TryCopyTo(Span<byte>, out int)

Attempts to copy the stream content into the provided destination span. Returns true on success, false if the destination is too small.

public bool TryCopyTo(Span<byte> destination, out int bytesWritten)

Parameters

destination Span<byte>

The destination span that receives the stream content.

bytesWritten int

When this method returns, contains the number of bytes written to destination.

Returns

bool

true if the content was copied; otherwise false.

TryGetBuffer(out ArraySegment<byte>)

Always fails: the payload may span several pooled segments, and a segment handed out here would be returned to the pool when the stream is disposed.

public override bool TryGetBuffer(out ArraySegment<byte> buffer)

Parameters

buffer ArraySegment<byte>

Always set to the default value.

Returns

bool

Always false.

Remarks

Overridden for the same reason as GetBuffer(): the inherited implementation reports success with an empty segment. Use GetReadOnlySequence() or LeaseSequence() instead.

Write(byte[], int, int)

Writes a block of bytes to the current stream using data read from a buffer.

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

Parameters

buffer byte[]

The buffer to write data from.

offset int

The zero-based byte offset in buffer at which to begin copying bytes to the current stream.

count int

The maximum number of bytes to write.

Exceptions

ArgumentNullException

buffer is null.

NotSupportedException

The stream does not support writing. For additional information see CanWrite.-or- The current position is closer than count bytes to the end of the stream, and the capacity cannot be modified.

ArgumentException

offset subtracted from the buffer length is less than count.

ArgumentOutOfRangeException

offset or count are negative.

IOException

An I/O error occurs.

ObjectDisposedException

The current stream instance is closed.

Write(ReadOnlySpan<byte>)

public void Write(ReadOnlySpan<byte> destination)

Parameters

destination ReadOnlySpan<byte>

WriteByte(byte)

Writes a byte to the current stream at the current position.

public override void WriteByte(byte value)

Parameters

value byte

The byte to write.

Exceptions

NotSupportedException

The stream does not support writing. For additional information see CanWrite.-or- The current position is at the end of the stream, and the capacity cannot be modified.

ObjectDisposedException

The current stream is closed.

WriteTo(Stream)

Writes the entire payload to stream, one pooled segment at a time.

public override void WriteTo(Stream stream)

Parameters

stream Stream

The destination stream.

Remarks

Overridden because the inherited implementation writes the unused base-class array, i.e. nothing at all. The read cursor is not affected.

Exceptions

ArgumentNullException

stream is null.