StreamPeerBuffer
Байтовый поток в памяти с явным курсором чтения и записи.
Чтение и запись сдвигают один курсор. Seek меняет позицию; DataArray заменяет весь массив и сбрасывает её. Для чтения только что записанного буфера сначала выполните Seek(0).
Resize не ограничивает курсор, Clear сохраняет BigEndian, а Duplicate копирует данные, но начинает с позиции 0 и BigEndian=false. Getter DataArray в C# даёт копию — редактирование этого byte[] само по себе не меняет объект.
Пример задаёт собственный формат сообщения: big-endian заголовок из magic 0x52464C31, версии формата 1, флагов 0 и длины UTF-8 данных. Заголовок 12 байт, полезные данные до 4096 байт. Декодер получает ровно одно полное сообщение и отклоняет усечённый ввод, лишние байты, неверные поля и некорректный UTF-8. Он не собирает TCP-поток за вас.
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;
}
}Числовые сокращения вызываются только после проверки полного заголовка. При работе с транспортом отдельно накопите входные данные и проверяйте Error raw-операций.
Объявления сверены с C# SDK 1.0.0. Раскройте имя, чтобы увидеть сигнатуры и описание.
Конструкторы1
StreamPeerBufferКонструктор
public StreamPeerBuffer();Создаёт пустой буфер с позицией 0 и BigEndian=false. Это поток в памяти, а не сетевое соединение.
Свойства1
DataArrayСвойство
public byte[] DataArray { get; set; }Байты всего буфера, не только непрочитанного хвоста. Getter в C# возвращает копию byte[]; изменение массива не правит буфер. Setter заменяет данные и сбрасывает курсор 0, сохраняя BigEndian.
Методы9
Clearvoid
public void Clear();Удаляет байты и устанавливает курсор 0. BigEndian сохраняется; это не полный сброс настроек нового объекта.
DuplicateStreamPeerBuffer
public StreamPeerBuffer Duplicate();Создаёт отдельный StreamPeerBuffer с теми же данными. Курсор нового объекта 0, BigEndian=false: настройки исходного не копируются. Запись в копию не меняет исходный буфер.
StreamPeerBufferНовый буфер с независимой записью и исходными настройками нового объекта.
GetDataArraybyte[]
public byte[] GetDataArray();Возвращает весь буфер как управляемый byte[]-снимок, как DataArray. Не перемещает курсор. Для записи изменённого массива присвойте его обратно явно.
byte[]Копия полного byte[] содержимого, не живой редактируемый вид данных движка.
GetPositionint
public int GetPosition();Возвращает байтовую позицию курсора. Обычно 0..GetSize(), но уменьшение Resize не ограничивает прежнюю позицию автоматически.
intТекущая позиция в байтах от начала буфера; чтение и запись используют один курсор.
GetSizeint
public int GetSize();Возвращает полную длину буфера в байтах. Не равно автоматически GetAvailableBytes: учитывайте курсор.
intПолная длина буфера в байтах, включая уже прочитанную часть.
Resizevoid
public void Resize(int size);Изменяет длину буфера и не корректирует курсор. После уменьшения явно задайте допустимый Seek; иначе GetAvailableBytes может быть отрицательным. Не считайте новые байты готовым нулевым содержимым сообщения.
| Имя | Тип | По умолчанию |
|---|---|---|
size | int | — |
sizeНовая неотрицательная длина в байтах. После уменьшения согласуйте позицию курсора и не читайте за концом.
Seekvoid
public void Seek(int position);Ставит байтовую позицию без чтения данных. Допустимо 0..GetSize() включительно. В отличие от XmlParser.Seek не выполняет чтение автоматически; позиция на конце позволяет дописать данные.
| Имя | Тип | По умолчанию |
|---|---|---|
position | int | — |
positionНовая позиция в байтах: от 0 до GetSize() включительно. Неверная позиция вызывает нативную диагностику, не гарантированное исключение C#.
SetDataArray2 перегрузки
public void SetDataArray(byte[] data);Заменяет содержимое массивом/span и ставит курсор 0. Исходный управляемый массив копируется при переходе в движок. Не меняет BigEndian.
| Имя | Тип | По умолчанию |
|---|---|---|
data | byte[] | — |
dataБайты полного нового содержимого; это замена, не вставка в текущую позицию.
public void SetDataArray(ReadOnlySpan<byte> data);Заменяет содержимое массивом/span и ставит курсор 0. Исходный управляемый массив копируется при переходе в движок. Не меняет BigEndian.
| Имя | Тип | По умолчанию |
|---|---|---|
data | ReadOnlySpan<byte> | — |
dataБайты полного нового содержимого; это замена, не вставка в текущую позицию.