ByteBlock.cs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Text;
  4. using TBL.CSharp.Base;
  5. namespace TBL.CSharp.Game.Server.Utilities;
  6. /// <summary>
  7. /// 字节块
  8. /// </summary>
  9. public readonly unsafe struct ByteBlock
  10. {
  11. /// <summary>
  12. /// 空字节块
  13. /// </summary>
  14. public static readonly ByteBlock Empty = new ByteBlock((void*) 0, 0);
  15. /// <summary>
  16. /// 地址
  17. /// </summary>
  18. public readonly void* Address;
  19. /// <summary>
  20. /// 字节尺寸
  21. /// </summary>
  22. public readonly int Size;
  23. public ByteBlock(void* ptr, int size)
  24. {
  25. Address = ptr;
  26. Size = size;
  27. }
  28. /// <summary>
  29. /// 是否在空指针
  30. /// </summary>
  31. public bool IsNullPtr => (void*) 0 == Address;
  32. /// <summary>
  33. /// 释放
  34. /// <para>不要重复进行释放操作</para>
  35. /// </summary>
  36. public void Free()
  37. {
  38. Marshal.FreeHGlobal(new IntPtr(Address));
  39. }
  40. /// <summary>
  41. /// 分配所需尺寸的字节块
  42. /// </summary>
  43. public static ByteBlock Alloc(int size) => new ByteBlock(Marshal.AllocHGlobal(size).ToPointer(), size);
  44. /// <summary>
  45. /// 分配所需尺寸的字节块并复制指定内容
  46. /// </summary>
  47. public static ByteBlock AllocWithCopy(void* source, int size)
  48. {
  49. var block = Alloc(size);
  50. Buffer.MemoryCopy(source, block.Address, size, size);
  51. return block;
  52. }
  53. /// <summary>
  54. /// 分配装载一个非托管值的字节块
  55. /// </summary>
  56. public static ByteBlock AllocWithValue<T>(T value) where T : unmanaged
  57. {
  58. var block = Alloc(sizeof(T));
  59. *(T*) block.Address = value;
  60. return block;
  61. }
  62. /// <summary>
  63. /// 分配装载一个字符串的字节块
  64. /// </summary>
  65. public static ByteBlock AllocWithString(string str)
  66. {
  67. fixed(void* ptr = str)
  68. {
  69. return AllocWithCopy(ptr, Encoding.Default.GetByteCount(str));
  70. }
  71. }
  72. /// <summary>
  73. /// 分配所需尺寸的字节块并初始化内容
  74. /// </summary>
  75. public static ByteBlock AllocWithInitialize(int size, Extension.OnBufferUse initializer)
  76. {
  77. var block = Alloc(size);
  78. initializer(block.Address);
  79. return block;
  80. }
  81. }