wip varint
This commit is contained in:
parent
b58063ef63
commit
d555994960
@ -5,4 +5,5 @@ test "turbonss test suite" {
|
||||
_ = @import("user.zig");
|
||||
_ = @import("group.zig");
|
||||
_ = @import("padding.zig");
|
||||
_ = @import("varint.zig");
|
||||
}
|
||||
|
90
src/varint.zig
Normal file
90
src/varint.zig
Normal file
@ -0,0 +1,90 @@
|
||||
//
|
||||
// varint64 []const u8 variants
|
||||
//
|
||||
// Thanks to https://github.com/gsquire/zig-snappy/blob/master/snappy.zig and golang's
|
||||
// varint implementation.
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
// Represents a variable length integer that we read from a byte stream along
|
||||
// with how many bytes were read to decode it.
|
||||
pub const Varint = struct {
|
||||
value: u64,
|
||||
bytesRead: usize,
|
||||
};
|
||||
|
||||
const MaxVarintLen64 = 10;
|
||||
|
||||
// https://golang.org/pkg/encoding/binary/#Uvarint
|
||||
pub fn uvarint(buf: []const u8) error{Overflow}!Varint {
|
||||
var x: u64 = 0;
|
||||
var s: u6 = 0;
|
||||
|
||||
for (buf) |b, i| {
|
||||
if (i == MaxVarintLen64) {
|
||||
// Catch byte reads past MaxVarintLen64.
|
||||
// See issue https://golang.org/issues/41185
|
||||
return error.Overflow;
|
||||
}
|
||||
|
||||
if (b < 0x80) {
|
||||
if (i == MaxVarintLen64 - 1 and b > 1) {
|
||||
return error.Overflow;
|
||||
}
|
||||
return Varint{ .value = x | (@as(u64, b) << s), .bytesRead = i + 1 };
|
||||
}
|
||||
x |= (@as(u64, b & 0x7f) << s);
|
||||
s += 7;
|
||||
}
|
||||
|
||||
return Varint{
|
||||
.value = 0,
|
||||
.bytesRead = 0,
|
||||
};
|
||||
}
|
||||
|
||||
// https://golang.org/pkg/encoding/binary/#PutUvarint
|
||||
pub fn putUvarint(buf: []u8, x: u64) usize {
|
||||
var i: usize = 0;
|
||||
var mutX = x;
|
||||
|
||||
while (mutX >= 0x80) {
|
||||
buf[i] = @truncate(u8, mutX) | 0x80;
|
||||
mutX >>= 7;
|
||||
i += 1;
|
||||
}
|
||||
buf[i] = @truncate(u8, mutX);
|
||||
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
const testing = std.testing;
|
||||
|
||||
const tests = [_]u64{
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
10,
|
||||
20,
|
||||
63,
|
||||
64,
|
||||
65,
|
||||
127,
|
||||
128,
|
||||
129,
|
||||
255,
|
||||
256,
|
||||
257,
|
||||
1 << 63 - 1,
|
||||
};
|
||||
|
||||
test "uvarint" {
|
||||
for (tests) |x| {
|
||||
var buf: [MaxVarintLen64]u8 = undefined;
|
||||
const n = putUvarint(buf[0..], x);
|
||||
const got = try uvarint(buf[0..n]);
|
||||
|
||||
try testing.expectEqual(x, got.value);
|
||||
try testing.expectEqual(n, got.bytesRead);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user