-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathVarInt.cs
More file actions
90 lines (74 loc) · 2.29 KB
/
Copy pathVarInt.cs
File metadata and controls
90 lines (74 loc) · 2.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
namespace dnproto.repo;
/// <summary>
/// In CAR files, several values are stored as variable-length integers (varints).
/// A varint is a sequence of bytes where the lower 7 bits of each byte are data
/// and the high bit is a flag indicating whether there are more bytes in the sequence.
/// Use this class to read varints from a stream.
///
/// https://protobuf.dev/programming-guides/encoding/#varints
///
/// </summary>
public class VarInt
{
public long Value { get; set; }
public override string ToString()
{
return $"{Value} (hex:0x{Value:X})";
}
public static VarInt FromLong(long value)
{
VarInt vi = new VarInt();
vi.Value = value;
return vi;
}
/// <summary>
/// Read a varint from a stream.
/// </summary>
public static VarInt ReadVarInt(Stream fs)
{
VarInt ret = new VarInt();
ret.Value = 0;
int shift = 0;
byte b;
do
{
b = (byte) fs.ReadByte();
ret.Value |= (long)(b & 0x7F) << shift;
shift += 7;
}
// check if the high bit is set.
// If it is, there are more bytes in the sequence
while ((b & 0x80) != 0);
return ret;
}
/// <summary>
/// Write a varint to a stream.
/// </summary>
public static void WriteVarInt(Stream fs, VarInt varInt)
{
long value = varInt.Value;
while (value >= 0x80)
{
// Write the lower 7 bits with the high bit set (continuation flag)
fs.WriteByte((byte)((value & 0x7F) | 0x80));
value >>= 7;
}
// Write the final byte without the high bit set
fs.WriteByte((byte)value);
}
/// <summary>
/// Write a varint to a stream.
/// </summary>
public static async Task WriteVarIntAsync(Stream fs, VarInt varInt)
{
long value = varInt.Value;
while (value >= 0x80)
{
// Write the lower 7 bits with the high bit set (continuation flag)
await fs.WriteAsync(new byte[] { (byte)((value & 0x7F) | 0x80) }, 0, 1);
value >>= 7;
}
// Write the final byte without the high bit set
await fs.WriteAsync(new byte[] { (byte)value }, 0, 1);
}
}