using System.Buffers.Binary; namespace Fleet.Core; /// LEB128 变长整数(无符号),以及 zigzag 有符号映射。 public static class VarInt { public const int MaxBytes = 10; public static ulong ZigZag(long value) => (ulong)((value << 1) ^ (value >> 63)); public static long UnZigZag(ulong value) => (long)(value >> 1) ^ -(long)(value & 1); public static int Write(Span destination, ulong value) { int i = 0; while (value >= 0x80) { destination[i++] = (byte)(value | 0x80); value >>= 7; } destination[i++] = (byte)value; return i; } public static void Write(Stream destination, ulong value) { Span buffer = stackalloc byte[MaxBytes]; int n = Write(buffer, value); destination.Write(buffer[..n]); } /// 读取失败(数据被截断或超过 10 字节)时返回 false。 public static bool TryRead(ReadOnlySpan source, out ulong value, out int consumed) { value = 0; consumed = 0; int shift = 0; while (consumed < source.Length && consumed < MaxBytes) { byte b = source[consumed++]; value |= (ulong)(b & 0x7F) << shift; if ((b & 0x80) == 0) { return true; } shift += 7; } return false; } }