using System;
namespace CSNetwork
{
public class Octets : IDisposable
{
private byte[] _buffer;
private int _size;
private int _capacity;
public int Size => _size;
public int Capacity => _capacity;
public int Length => _size;
public Octets(int capacity = 0)
{
_capacity = capacity;
_buffer = new byte[capacity];
_size = 0;
}
public Octets(byte[] data)
{
if (data == null)
{
throw new ArgumentNullException(nameof(data), "Input byte array cannot be null.");
}
_capacity = data.Length;
_buffer = new byte[_capacity];
Buffer.BlockCopy(data, 0, _buffer, 0, data.Length);
_size = data.Length;
}
public Octets(byte[] data, int capacity)
{
_capacity = capacity;
_buffer = new byte[_capacity];
Buffer.BlockCopy(data, 0, _buffer, 0, capacity);
_size = capacity;
}
///
/// Creates an Octets instance by copying a slice from a source buffer.
///
/// The buffer to copy from.
/// The starting position in the source buffer.
/// The number of bytes to copy.
public Octets(byte[] sourceBuffer, int offset, int length)
{
if (sourceBuffer == null)
throw new ArgumentNullException(nameof(sourceBuffer));
if (offset < 0 || length < 0 || offset + length > sourceBuffer.Length)
throw new ArgumentOutOfRangeException("Invalid offset or length for source buffer.");
_capacity = length;
_buffer = new byte[_capacity];
Buffer.BlockCopy(sourceBuffer, offset, _buffer, 0, length);
_size = length;
}
public void Reserve(int newCapacity)
{
if (newCapacity <= _capacity)
return;
Array.Resize(ref _buffer, newCapacity);
_capacity = newCapacity;
}
///
/// Sets the logical size of the data within the buffer.
/// Throws ArgumentOutOfRangeException if newSize is negative or exceeds capacity.
///
/// The new logical size.
public void SetSize(int newSize)
{
if (newSize < 0 || newSize > _capacity)
{
throw new ArgumentOutOfRangeException(nameof(newSize), $"newSize must be between 0 and capacity ({_capacity}).");
}
_size = newSize;
}
public void Replace(byte[] data)
{
Reserve(data.Length);
Buffer.BlockCopy(data, 0, _buffer, 0, data.Length);
_size = data.Length;
}
public void Insert(int pos, byte[] data)
{
if (data.Length == 0)
return;
int newSize = _size + data.Length;
Reserve(newSize);
// Shift existing data
Array.Copy(_buffer, pos, _buffer, pos + data.Length, _size - pos);
// Insert new data
Buffer.BlockCopy(data, 0, _buffer, pos, data.Length);
_size = newSize;
}
public void Erase(int pos, int length)
{
if (length == 0)
return;
// Shift remaining data
Array.Copy(_buffer, pos + length, _buffer, pos, _size - (pos + length));
_size -= length;
}
public byte[] ToArray() => _buffer[.._size];
public byte[] ByteArray => ToArray();
public byte[] RawBuffer => _buffer;
public void Dispose() => _buffer = null;
public override string ToString()
{
return BitConverter.ToString(_buffer, 0, _size).Replace("-", " ");
}
internal void Resize(int newSize)
{
Reserve(newSize);
SetSize(newSize);
}
}
}