StreamPeerBuffer
An in-memory byte stream with an explicit read/write cursor.
Reads and writes advance one shared cursor. Seek moves it; DataArray replaces the whole array and resets it. Seek(0) before reading a buffer you just wrote.
Resize does not clamp the cursor, Clear retains BigEndian, and Duplicate copies bytes but starts at position 0 with BigEndian=false. The C# DataArray getter returns a copy; editing that byte[] does not mutate the object.
The example defines its own message format: a big-endian header containing magic 0x52464C31, format version 1, flags 0 and UTF-8 payload length. Header size is 12 bytes; payload is at most 4096 bytes. The decoder expects exactly one complete message and rejects truncation, trailing bytes, invalid fields and malformed UTF-8. It does not assemble a TCP stream for you.
using System;
using System.Text;
using Reckfell;
public static class BinaryMessageExample
{
private const uint Magic = 0x52464C31;
private const int HeaderSize = 12;
private const int MaxPayload = 4096;
public static bool TryEncode(string message, out byte[] packet)
{
packet = Array.Empty<byte>();
if (message.Length > MaxPayload)
return false;
byte[] payload;
try { payload = new UTF8Encoding(false, true).GetBytes(message); }
catch (EncoderFallbackException) { return false; }
if (payload.Length > MaxPayload)
return false;
using var writer = new StreamPeerBuffer { BigEndian = true };
writer.PutU32(Magic);
writer.PutU16(1);
writer.PutU16(0);
writer.PutU32((uint)payload.Length);
if (writer.PutData(payload) != Error.Ok)
return false;
packet = writer.DataArray;
return true;
}
public static bool TryDecode(byte[] packet, out string message)
{
message = "";
if (packet.Length < HeaderSize || packet.Length > HeaderSize + MaxPayload)
return false;
using var reader = new StreamPeerBuffer { BigEndian = true, DataArray = packet };
if (reader.GetU32() != Magic || reader.GetU16() != 1 || reader.GetU16() != 0)
return false;
uint length = reader.GetU32();
if (length > MaxPayload || length != (uint)reader.GetAvailableBytes())
return false;
if (length == 0)
return true;
using var result = reader.GetData((int)length);
using Variant status = result[0];
using Variant data = result[1];
if (status.AsInt32() != (int)Error.Ok)
return false;
try { message = new UTF8Encoding(false, true).GetString(data.AsByteArray()); }
catch (DecoderFallbackException) { return false; }
return true;
}
}Numeric shortcuts run only after a complete-header check. For a transport, separately accumulate input and check raw-operation Error results.
Declarations checked against C# SDK 1.0.0. Expand a name to see declarations and documentation.
Constructors1
StreamPeerBufferConstructor
public StreamPeerBuffer();Creates an empty buffer at position 0 with BigEndian=false. A memory stream, not a network connection.
Properties1
DataArrayProperty
public byte[] DataArray { get; set; }Bytes of the entire buffer, not just its unread tail. The C# getter returns a byte[] copy; mutating it does not edit the buffer. Setting replaces data and resets the cursor to 0 while retaining BigEndian.
Methods9
Clearvoid
public void Clear();Removes bytes and resets the cursor to 0. Retains BigEndian; not a complete reset to new-object settings.
DuplicateStreamPeerBuffer
public StreamPeerBuffer Duplicate();Creates a separate StreamPeerBuffer with the same data. The new cursor is 0 and BigEndian=false; source settings are not copied. Writing the duplicate does not mutate the source.
StreamPeerBufferNew independently writable buffer with new-object settings.
GetDataArraybyte[]
public byte[] GetDataArray();Returns the entire buffer as a managed byte[] snapshot, as in DataArray. Does not move the cursor. Explicitly assign an edited array back to update data.
byte[]Copy of the complete byte[] contents, not a live editable engine-data view.
GetPositionint
public int GetPosition();Returns the byte cursor position. Normally 0..GetSize(), but shrinking Resize does not automatically clamp the old position.
intCurrent byte position from the start of the buffer; reads and writes share this cursor.
GetSizeint
public int GetSize();Returns total buffer length in bytes. Not automatically GetAvailableBytes; account for the cursor.
intTotal buffer length in bytes, including the already-read portion.
Resizevoid
public void Resize(int size);Changes buffer length without adjusting the cursor. Explicitly Seek to a valid position after shrinking; otherwise GetAvailableBytes can be negative. Do not treat newly added bytes as initialized message contents.
| Name | Type | Default |
|---|---|---|
size | int | — |
sizeNew nonnegative byte length. Reconcile cursor position after shrinking and do not read beyond the end.
Seekvoid
public void Seek(int position);Sets byte position without reading data. Valid range is 0..GetSize() inclusive. Unlike XmlParser.Seek, does not automatically read; the end position allows appending.
| Name | Type | Default |
|---|---|---|
position | int | — |
positionNew byte position from 0 through GetSize() inclusive. Invalid positions produce native diagnostics, not a guaranteed C# exception.
SetDataArray2 overloads
public void SetDataArray(byte[] data);Replaces contents from an array/span and resets the cursor to 0. Managed input is copied across the engine boundary. Does not change BigEndian.
| Name | Type | Default |
|---|---|---|
data | byte[] | — |
dataBytes of complete new contents; replacement, not insertion at the current cursor.
public void SetDataArray(ReadOnlySpan<byte> data);Replaces contents from an array/span and resets the cursor to 0. Managed input is copied across the engine boundary. Does not change BigEndian.
| Name | Type | Default |
|---|---|---|
data | ReadOnlySpan<byte> | — |
dataBytes of complete new contents; replacement, not insertion at the current cursor.