Gorgon
Show / Hide Table of Contents

Class GorgonNativeBuffer<T>

Provides a buffer that uses native (unmanaged) memory to store its data.

Inheritance
object
GorgonNativeBuffer<T>
Implements
IDisposable
IReadOnlyList<T>
IReadOnlyCollection<T>
IEnumerable<T>
IEnumerable
Inherited Members
object.ToString()
object.Equals(object)
object.Equals(object, object)
object.ReferenceEquals(object, object)
object.GetHashCode()
object.GetType()
Namespace: Gorgon.Native
Assembly: Gorgon.Core.dll
Syntax
public sealed class GorgonNativeBuffer<T> : IDisposable, IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable where T : unmanaged
Type Parameters
Name Description
T

The type of data to store in the buffer. Must be an unmanaged value type.

Remarks

This buffer works similarly to an array or span type, only it is backed by unmanaged memory. This allows applications to use it for things like interop between native and managed code, or to have a buffer that allows the developer to control its lifetime. And, unlike a native pointer, it is safe for use because it will handle out of bounds errors correctly instead of just trashing memory arbitrarily.

Because this buffer is backed by native memory and the developer is repsonsible for its lifetime, it is important to ensure that the Dispose() method is called on this object when it is no longer needed. Failure to do so may result in a memory leak.

tip

The object will be finalized and the memory will ultimately be freed then, but this can still have a negative impact on the application.

Accessing data in the buffer is done through an indexer on the object like an array or other IList<T> types. This indexer performs a ref return so its contents can be updated using references for optimal performance. For example:

// Create a buffer of 10 DateTime objects
GorgonNativeBuffer<DateTime> dateInBuffer = new GorgonNativeBuffer<DateTime>(10);

// This will write today's date to the buffer at the second date/time index. dateInBuffer[1] = DateTime.Now;

ref DateTime currentDateTime = ref dateInBuffer[1]; // This will write back today's date plus 5 years to the buffer. currentDateTime = DateTime.Now.AddYears(5);

The buffer can also be used to pin an array or value type and act on those items as native memory. Please note that the standard disclaimers about pinning still apply.

Constructors

| Edit this page View Source

GorgonNativeBuffer(GorgonPtr<T>)

Initializes a new instance of the GorgonNativeBuffer<T> class.

Declaration
public GorgonNativeBuffer(GorgonPtr<T> pointer)
Parameters
Type Name Description
GorgonPtr<T> pointer

The pointer to wrap with the buffer interface.

Remarks

This construct is used to alias a GorgonPtr<T>. Because pointer is aliased, the lifetime for the pointer is not controlled by the buffer and therefore is the responsibility of the user. If the pointer memory is freed before the buffer is disposed, then undefined behavior will occur.

Exceptions
Type Condition
ArgumentNullException

Thrown when the pointer is null.

| Edit this page View Source

GorgonNativeBuffer(int, int)

Initializes a new instance of the GorgonNativeBuffer<T> class.

Declaration
public GorgonNativeBuffer(int count, int alignment = 16)
Parameters
Type Name Description
int count

The number of items of type T to allocate in the buffer.

int alignment

[Optional] The alignment of the buffer, in bytes.

Remarks

Use this constructor to create a new buffer backed by native memory of a given size and aligned to a boundary for the most efficient memory access. The contents of this memory are automatically cleared on allocation.

Exceptions
Type Condition
ArgumentOutOfRangeException

Thrown when the count is less than 0.

Properties

| Edit this page View Source

IsAlias

Property to return whether this buffer is an alias of a pointer.

Declaration
public bool IsAlias { get; }
Property Value
Type Description
bool
Remarks

This property will return true if the memory pointed at is not owned by this buffer. This is also the case when the IsAlias property is true.

| Edit this page View Source

IsPinned

Property to return whether this buffer is for a pinned type.

Declaration
public bool IsPinned { get; }
Property Value
Type Description
bool
| Edit this page View Source

this[int]

Property to return a reference to the item located at the specified index.

Declaration
public ref T this[int index] { get; }
Parameters
Type Name Description
int index
Property Value
Type Description
T
Exceptions
Type Condition
IndexOutOfRangeException

Thrown if the index is less than 0, or greater than/equal to Length.

| Edit this page View Source

Length

Property to return the number of items of type T stored in this buffer.

Declaration
public int Length { get; }
Property Value
Type Description
int
| Edit this page View Source

Pointer

Property to return the pointer to the block of memory allocated to the buffer.

Declaration
public ref readonly GorgonPtr<T> Pointer { get; }
Property Value
Type Description
GorgonPtr<T>
| Edit this page View Source

SizeInBytes

Property to return the number of bytes allocated for this buffer.

Declaration
public int SizeInBytes { get; }
Property Value
Type Description
int
| Edit this page View Source

TypeSize

Property to return the size, in bytes, for the type parameter T.

Declaration
public int TypeSize { get; }
Property Value
Type Description
int

Methods

| Edit this page View Source

AsRef<TCastType>(int)

Function to interpret a reference to the value at the index as the specified type.

Declaration
public ref TCastType AsRef<TCastType>(int offset = 0) where TCastType : unmanaged
Parameters
Type Name Description
int offset

[Optional] The offset, in bytes, within the memory pointed at this pointer to start at.

Returns
Type Description
TCastType

The value in the buffer, casted to the required type.

Type Parameters
Name Description
TCastType

The type to cast to. Must be an unmanaged value type.

Remarks

This method returns a reference to the value in the buffer, so applications can immediately write back to the value and have it reflected in the buffer:

GorgonNativeBuffer<int> buffer = ...;
byte newValue = 123;

// This will write the byte value 123 at the 2nd byte in the first integer (since the buffer expects a int values). buffer.AsRef<byte>(1) = newValue;

Exceptions
Type Condition
ArgumentOutOfRangeException

Thrown when the offset parameter is less than 0, or greater than/equal to SizeInBytes.

| Edit this page View Source

CopyTo(GorgonNativeBuffer<T>, int, int?, int)

Function to copy the contents of this buffer into other.

Declaration
public void CopyTo(GorgonNativeBuffer<T> destination, int sourceIndex = 0, int? count = null, int destIndex = 0)
Parameters
Type Name Description
GorgonNativeBuffer<T> destination

The destination buffer that will receive the data.

int sourceIndex

[Optional] The first index to start copying from.

int? count

[Optional] The number of items to copy.

int destIndex

[Optional] The destination index in the destination buffer to start copying into.

Remarks

If the count parameter is ommitted, then the full length of the source buffer, minus the sourceIndex is used. Ensure that there is enough space in the destination buffer to accomodate the amount of data required.

Exceptions
Type Condition
ArgumentNullException

Thrown when the destination parameter is null.

ArgumentOutOfRangeException

Thrown when the sourceIndex, or the destIndex parameter is less than 0.

ArgumentException

Thrown when the sourceIndex + count is too big for this buffer.

-or-

Thrown when the destIndex + count is too big for the destination buffer.

| Edit this page View Source

CopyTo(Stream, int, int?)

Function to copy the contents of this buffer into a stream.

Declaration
public void CopyTo(Stream stream, int startIndex = 0, int? count = null)
Parameters
Type Name Description
Stream stream

The stream to write into.

int startIndex

[Optional] The index in the buffer to start copying from.

int? count

[Optional] The maximum number of items to read from the stream.

Remarks

If the count parameter is ommitted, then the full length of the source buffer, minus the startIndex is used. Ensure that there is enough space in the stream to accomodate the amount of data required.

Exceptions
Type Condition
ArgumentNullException

Thrown when the stream parameter is null.

IOException

Thrown when the stream is read only.

ArgumentOutOfRangeException

Thrown when the startIndex is less than 0.

ArgumentException

Thrown when the startIndex + count are equal to or greater than the Length.

See Also
ToStream(int, int?)
| Edit this page View Source

CopyTo(Memory<T>, int)

Function to copy the contents of this buffer into a span.

Declaration
public void CopyTo(Memory<T> memory, int index = 0)
Parameters
Type Name Description
Memory<T> memory

The span to write into.

int index

[Optional] The offset within the buffer to start reading from.

Exceptions
Type Condition
ArgumentOutOfRangeException

Thrown when the index is less than 0.

| Edit this page View Source

CopyTo(Span<T>, int)

Function to copy the contents of this buffer into a span.

Declaration
public void CopyTo(Span<T> span, int index = 0)
Parameters
Type Name Description
Span<T> span

The span to write into.

int index

[Optional] The offset within the buffer to start reading from.

Exceptions
Type Condition
ArgumentOutOfRangeException

Thrown when the index is less than 0.

| Edit this page View Source

CopyTo(T[], int, int?, int)

Function to copy the contents of this buffer into an array of type T.

Declaration
public void CopyTo(T[] destination, int sourceIndex = 0, int? count = null, int destIndex = 0)
Parameters
Type Name Description
T[] destination

The destination array that will receive the data.

int sourceIndex

[Optional] The first index to start copying from.

int? count

[Optional] The number of items to copy.

int destIndex

[Optional] The destination index in the destination array to start copying into.

Remarks

If the count parameter is ommitted, then the full length of the source buffer, minus the sourceIndex is used. Ensure that there is enough space in the destination buffer to accomodate the amount of data required.

Exceptions
Type Condition
ArgumentNullException

Thrown when the destination parameter is null.

ArgumentOutOfRangeException

Thrown when the sourceIndex, or the destIndex parameter is less than 0.

ArgumentException

Thrown when the sourceIndex + count is too big for this buffer.

-or-

Thrown when the destIndex + count is too big for the destination buffer.

| Edit this page View Source

Dispose()

Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

Declaration
public void Dispose()
Remarks

This method is not thread safe.

| Edit this page View Source

Fill(byte)

Function to fill the buffer with a specific value.

Declaration
public void Fill(byte clearValue)
Parameters
Type Name Description
byte clearValue

The value used to fill the buffer.

| Edit this page View Source

~GorgonNativeBuffer()

Finalizes an instance of the GorgonNativeBuffer<T> class.

Declaration
protected ~GorgonNativeBuffer()
| Edit this page View Source

GetEnumerator()

Returns an enumerator that iterates through the collection.

Declaration
public IEnumerator<T> GetEnumerator()
Returns
Type Description
IEnumerator<T>

An enumerator that can be used to iterate through the collection.

| Edit this page View Source

Pin(T[], int, int?)

Function to pin an array and access its contents natively.

Declaration
public static GorgonNativeBuffer<T> Pin(T[] array, int index = 0, int? count = null)
Parameters
Type Name Description
T[] array

The array to pin.

int index

[Optional] The starting index in the array to pin.

int? count

[Optional] The number of items in the array to pin.

Returns
Type Description
GorgonNativeBuffer<T>

A new GorgonNativeBuffer<T> containing the pinned contents of the array.

Remarks

This method pins the supplied array and returns a new GorgonNativeBuffer<T> containing the pinned data.

If the index is not supplied, then the beginning of the array is used as the start of the buffer, and if the count parameter is not supplied, then the length of the array (minus the index) is used.

warning

This method pins the array, which can cause performance issues with the garbage collector. Applications should only pin their objects for a very short time for best performance.

Exceptions
Type Condition
ArgumentNullException

Thrown when the array parameter is null.

ArgumentOutOfRangeException

Thrown when the index is less than 0.

ArgumentException

Thrown when the index + count are equal to or greater than the length of array.

| Edit this page View Source

PinAsByteBuffer(ref T)

Function to pin a value type of type T, and access its contents as a byte buffer.

Declaration
public static GorgonNativeBuffer<byte> PinAsByteBuffer(ref T valueType)
Parameters
Type Name Description
T valueType

The value to pin

Returns
Type Description
GorgonNativeBuffer<byte>

A new GorgonNativeBuffer<T> containing the contents of the value as a series of byte values.

Remarks

This allows access to the value passed to valueType as a series bytes for native manipulation.

warning

This method pins the valueType, which can cause performance issues with the garbage collector. Applications should only pin their objects for a very short time for best performance.

| Edit this page View Source

ToGorgonPtr(GorgonNativeBuffer<T>)

Function to return the underlying GorgonPtr<T> for this buffer.

Declaration
public static GorgonPtr<T> ToGorgonPtr(GorgonNativeBuffer<T> buffer)
Parameters
Type Name Description
GorgonNativeBuffer<T> buffer

The buffer to containing the pointer.

Returns
Type Description
GorgonPtr<T>

The underlying GorgonPtr<T> for the buffer.

Exceptions
Type Condition
ArgumentNullException

Thrown when the buffer parameter is null.

| Edit this page View Source

ToNint(GorgonNativeBuffer<T>)

Function to return the pointer to the underlying data in the buffer.

Declaration
public static nint ToNint(GorgonNativeBuffer<T> buffer)
Parameters
Type Name Description
GorgonNativeBuffer<T> buffer

The buffer to retrieve the native pointer from.

Returns
Type Description
nint

The void pointer to the underlying data in the buffer.

Remarks

warning

This method returns the pointer to the memory address of this buffer. Developers should only use this for interop scenarios where a native call needs a pointer. Manipulation of this pointer is not advisable and may cause harm.

No safety checks are done on this pointer, and as such, memory corruption is possible if the pointer is used without due care.

Use this at your own risk.

| Edit this page View Source

ToPointer(GorgonNativeBuffer<T>)

Function to return the pointer to the underlying data in the buffer.

Declaration
public static void* ToPointer(GorgonNativeBuffer<T> buffer)
Parameters
Type Name Description
GorgonNativeBuffer<T> buffer

The buffer to retrieve the native pointer from.

Returns
Type Description
void*

The void pointer to the underlying data in the buffer.

Remarks

warning

This method returns the pointer to the memory address of this buffer. Developers should only use this for interop scenarios where a native call needs a pointer. Manipulation of this pointer is not advisable and may cause harm.

No safety checks are done on this pointer, and as such, memory corruption is possible if the pointer is used without due care.

Use this at your own risk.

| Edit this page View Source

ToReadOnlySpan(GorgonNativeBuffer<T>)

Function to access a native buffer as a read only span.

Declaration
public static ReadOnlySpan<T> ToReadOnlySpan(GorgonNativeBuffer<T> buffer)
Parameters
Type Name Description
GorgonNativeBuffer<T> buffer

The buffer to access.

Returns
Type Description
ReadOnlySpan<T>

A span for the buffer.

| Edit this page View Source

ToReadOnlySpan(int, int?)

Function to access a native buffer as a read only span slice.

Declaration
public ReadOnlySpan<T> ToReadOnlySpan(int index, int? count = null)
Parameters
Type Name Description
int index

The index of the item to start slicing at.

int? count

[Optional] The number of items to slice.

Returns
Type Description
ReadOnlySpan<T>

A span for the buffer.

Exceptions
Type Condition
ArgumentOutOfRangeException

Thrown when the index, or the count parameter is less than 0.

| Edit this page View Source

ToSpan(GorgonNativeBuffer<T>)

Function to access a native buffer as a span.

Declaration
public static Span<T> ToSpan(GorgonNativeBuffer<T> buffer)
Parameters
Type Name Description
GorgonNativeBuffer<T> buffer

The buffer to access.

Returns
Type Description
Span<T>

A span for the buffer.

| Edit this page View Source

ToSpan(int, int?)

Function to access a native buffer as a span slice.

Declaration
public Span<T> ToSpan(int index = 0, int? count = null)
Parameters
Type Name Description
int index

[Optional] The index of the item to start slicing at.

int? count

[Optional] The number of items to slice.

Returns
Type Description
Span<T>

A span for the buffer.

Exceptions
Type Condition
ArgumentOutOfRangeException

Thrown when the index, or the count parameter is less than 0.

| Edit this page View Source

ToStream(int, int?)

Function to return a stream wrapping this buffer.

Declaration
public Stream ToStream(int index = 0, int? count = null)
Parameters
Type Name Description
int index

[Optional] The index in the buffer to map to the beginning of the stream.

int? count

[Optional] The number of items to wrap in the stream.

Returns
Type Description
Stream

A new Stream which will wrap the contents of the buffer.

Remarks

This method takes the unmanaged memory used by the buffer and wraps it in a Stream. The stream returned is not a copy of the memory used by the buffer, so it is important to ensure that the stream lifetime is managed in conjunction with the lifetime of the buffer. Disposing of the buffer and using the returned stream will result in undefined behavior and potential memory access violations.

A portion of the buffer can be wrapped by the stream by supplying a value for index and/or count. If the count is omitted, all data from index up to the end of the buffer is wrapped by the stream. Likewise, if index is omitted, all data from the beginning of the buffer up to the count is wrapped. If no parameters are supplied, then the entire buffer is wrapped.

Exceptions
Type Condition
ArgumentOutOfRangeException

Thrown when the index, or the count parameter is less than 0.

ArgumentException

Thrown when the index plus the count exceeds the size of the buffer.

| Edit this page View Source

To<TCastType>()

Function to cast the type in this buffer to another type.

Declaration
public GorgonNativeBuffer<TCastType> To<TCastType>() where TCastType : unmanaged
Returns
Type Description
GorgonNativeBuffer<TCastType>

A new GorgonNativeBuffer<T> pointing at the same memory.

Type Parameters
Name Description
TCastType

The type to cast to. Must be an unmanaged value type.

Remarks

This method will cast the contents of the buffer from their original type to another type specified by TCastType.

The returned buffer will be a new buffer object, but it will point at the same memory location. It will have the same SizeInBytes as the original buffer, but its Length will be updated to reflect the number of items at the specified TCastType.

warning

If the size (in bytes) of the TCastType is not evenly divisble by the SizeInBytes, then the buffer returned will not cover the entire size of the original buffer.

Operators

| Edit this page View Source

explicit operator nint(GorgonNativeBuffer<T>)

Implicit operator to return the pointer to the underlying data in the buffer.

Declaration
public static explicit operator nint(GorgonNativeBuffer<T> buffer)
Parameters
Type Name Description
GorgonNativeBuffer<T> buffer

The buffer to retrieve the native pointer from.

Returns
Type Description
nint

The void pointer to the underlying data in the buffer.

Remarks

warning

This operator returns the pointer to the memory address of this buffer. Developers should only use this for interop scenarios where a native call needs a pointer. Manipulation of this pointer is not advisable and may cause harm.

No safety checks are done on this pointer, and as such, memory corruption is possible if the pointer is used without due care.

Use this at your own risk.

| Edit this page View Source

explicit operator ReadOnlySpan<T>(GorgonNativeBuffer<T>)

Operator to implicitly convert this buffer to a span.

Declaration
public static explicit operator ReadOnlySpan<T>(GorgonNativeBuffer<T> buffer)
Parameters
Type Name Description
GorgonNativeBuffer<T> buffer

The buffer to convert.

Returns
Type Description
ReadOnlySpan<T>
| Edit this page View Source

explicit operator Span<T>(GorgonNativeBuffer<T>)

Operator to implicitly convert this buffer to a span.

Declaration
public static explicit operator Span<T>(GorgonNativeBuffer<T> buffer)
Parameters
Type Name Description
GorgonNativeBuffer<T> buffer

The buffer to convert.

Returns
Type Description
Span<T>
| Edit this page View Source

explicit operator void*(GorgonNativeBuffer<T>)

Implicit operator to return the pointer to the underlying data in the buffer.

Declaration
public static explicit operator void*(GorgonNativeBuffer<T> buffer)
Parameters
Type Name Description
GorgonNativeBuffer<T> buffer

The buffer to retrieve the native pointer from.

Returns
Type Description
void*

The void pointer to the underlying data in the buffer.

Remarks

warning

This operator returns the pointer to the memory address of this buffer. Developers should only use this for interop scenarios where a native call needs a pointer. Manipulation of this pointer is not advisable and may cause harm.

No safety checks are done on this pointer, and as such, memory corruption is possible if the pointer is used without due care.

Use this at your own risk.

| Edit this page View Source

implicit operator GorgonPtr<T>(GorgonNativeBuffer<T>)

Operator to convert this buffer to a GorgonPtr<T>.

Declaration
public static implicit operator GorgonPtr<T>(GorgonNativeBuffer<T> buffer)
Parameters
Type Name Description
GorgonNativeBuffer<T> buffer

The buffer to convert.

Returns
Type Description
GorgonPtr<T>

The GorgonPtr<T> wrapping the buffer data.

Implements

IDisposable
IReadOnlyList<T>
IReadOnlyCollection<T>
IEnumerable<T>
IEnumerable

Extension Methods

GorgonDebugExtensions.ValidateObject<T>(T, string)
GorgonTreeLinqExtensions.TraverseDepthFirst<T>(IEnumerable<T>, Func<T, IEnumerable<T>>)
GorgonTreeLinqExtensions.Traverse<T>(IEnumerable<T>, Func<T, IEnumerable<T>>)
GorgonIReadOnlyListExtensions.Contains<T>(IReadOnlyList<T>, T)
GorgonIReadOnlyListExtensions.CopyTo<T>(IReadOnlyList<T>, T[])
GorgonIReadOnlyListExtensions.FirstIndexOf<T>(IReadOnlyList<T>, Predicate<T>)
GorgonIReadOnlyListExtensions.IndexOf<T>(IReadOnlyList<T>, T)
GorgonIReadOnlyListExtensions.LastIndexOf<T>(IReadOnlyList<T>, Predicate<T>)
GorgonNullExtensions.AsNullable<T>(object)
GorgonNullExtensions.IfNull<T>(object, T)
GorgonNullExtensions.IsNull(object)
  • Edit this page
  • View Source
In this article
Back to top Copyright 2023 - Licensed under the MIT license by Michael Winsor (Tape_Worm).
Send comments on this topic to the author