using System;
using System.Runtime.InteropServices;
using System.Text;
using TBL.CSharp.Base;
namespace TBL.CSharp.Game.Server.Utilities;
///
/// 字节块
///
public readonly unsafe struct ByteBlock
{
///
/// 空字节块
///
public static readonly ByteBlock Empty = new ByteBlock((void*) 0, 0);
///
/// 地址
///
public readonly void* Address;
///
/// 字节尺寸
///
public readonly int Size;
public ByteBlock(void* ptr, int size)
{
Address = ptr;
Size = size;
}
///
/// 是否在空指针
///
public bool IsNullPtr => (void*) 0 == Address;
///
/// 释放
/// 不要重复进行释放操作
///
public void Free()
{
Marshal.FreeHGlobal(new IntPtr(Address));
}
///
/// 分配所需尺寸的字节块
///
public static ByteBlock Alloc(int size) => new ByteBlock(Marshal.AllocHGlobal(size).ToPointer(), size);
///
/// 分配所需尺寸的字节块并复制指定内容
///
public static ByteBlock AllocWithCopy(void* source, int size)
{
var block = Alloc(size);
Buffer.MemoryCopy(source, block.Address, size, size);
return block;
}
///
/// 分配装载一个非托管值的字节块
///
public static ByteBlock AllocWithValue(T value) where T : unmanaged
{
var block = Alloc(sizeof(T));
*(T*) block.Address = value;
return block;
}
///
/// 分配装载一个字符串的字节块
///
public static ByteBlock AllocWithString(string str)
{
fixed(void* ptr = str)
{
return AllocWithCopy(ptr, Encoding.Default.GetByteCount(str));
}
}
///
/// 分配所需尺寸的字节块并初始化内容
///
public static ByteBlock AllocWithInitialize(int size, Extension.OnBufferUse initializer)
{
var block = Alloc(size);
initializer(block.Address);
return block;
}
}