123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- using System.Buffers;
- using System.IO.Pipelines;
- namespace PCC.App.BinaryFormatter;
- public static class BinaryRwExtensionMethod
- {
- public static void WriteBlock(this BinaryWriter writer, ReadOnlySpan<byte> 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<byte> 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());
- }
- /// <summary>
- /// 向 PipeWriter 中写入 7 位编码的整数。
- /// </summary>
- /// <param name="writer">PipeWriter,用于写入数据</param>
- /// <param name="value">需要编码的整数</param>
- private static void Write7BitEncodedInt(this PipeWriter writer, int value)
- {
- Span<byte> 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());
- /// <summary>
- /// 从 SequenceReader 中读取 7 位编码的整数。
- /// </summary>
- /// <param name="reader">字节序列读取器</param>
- /// <param name="value">解码后的整数值</param>
- /// <returns>解码是否成功。返回 true 表示成功,false 表示数据格式无效(溢出),null 表示数据不足。</returns>
- public static bool? TryRead7BitEncodedInt(this ref SequenceReader<byte> 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;
- }
- }
- }
- }
|