using System.Buffers; using System.IO.Pipelines; namespace PCC.App.BinaryFormatter; public static class BinaryRwExtensionMethod { public static void WriteBlock(this BinaryWriter writer, ReadOnlySpan data) { writer.Write7BitEncodedInt(data.Length); writer.Write(data); } public static void WriteBlock(this PipeWriter writer, byte[] data) { writer.Write7BitEncodedInt(data.Length); writer.Write(data); } public static void WriteBlock(this PipeWriter writer, ReadOnlyMemory data) { writer.Write7BitEncodedInt(data.Length); writer.Write(data.Span); } public static void Write(this BinaryWriter writer, DateTimeOffset dateTimeOffset) { writer.Write(dateTimeOffset.ToUnixTimeMilliseconds()); } public static DateTimeOffset ReadDateTimeOffset(this BinaryReader reader) { return DateTimeOffset.FromUnixTimeMilliseconds(reader.ReadInt64()); } /// /// 向 PipeWriter 中写入 7 位编码的整数。 /// /// PipeWriter,用于写入数据 /// 需要编码的整数 private static void Write7BitEncodedInt(this PipeWriter writer, int value) { Span buffer = stackalloc byte[5]; // 最多需要 5 个字节来编码 int int index = 0; // 循环,直到处理完所有 7 位段 while (value >= 0x80) { // 写入低 7 位,并将最高位置 1 表示后续还有数据 buffer[index++] = (byte)(value & 0x7F | 0x80); value >>= 7; // 继续处理剩余部分 } // 最后一个字节,最高位为 0 buffer[index++] = (byte)(value & 0x7F); // 将编码后的字节写入 PipeWriter writer.Write(buffer.Slice(0, index)); } public static byte[] ReadBlock(this BinaryReader reader) => reader.ReadBytes(reader.Read7BitEncodedInt()); /// /// 从 SequenceReader 中读取 7 位编码的整数。 /// /// 字节序列读取器 /// 解码后的整数值 /// 解码是否成功。返回 true 表示成功,false 表示数据格式无效(溢出),null 表示数据不足。 public static bool? TryRead7BitEncodedInt(this ref SequenceReader reader, out int value) { value = 0; var bitsRead = 0; while (true) { if (!reader.TryRead(out byte currentByte)) { // 数据不足 return null; } // 将当前字节的低 7 位加到结果中 value |= (currentByte & 0x7F) << bitsRead; bitsRead += 7; // 如果最高位是 0,则结束读取 if ((currentByte & 0x80) == 0) { return true; } // 防止过大的整数导致溢出 if (bitsRead >= 35) { // 数据格式无效,表示溢出 value = 0; return false; } } } }