@@ 1,135 0,0 @@
-const std = @import("std");
-
-pub fn encodeVarUint(writer: anytype, value: u64) !void {
- var x = value;
-
- while (0x80 <= x) {
- const b: u8 = @truncate(x);
- try writer.writeByte(b | 0x80);
- x >>= 7;
- }
-
- try writer.writeByte(@truncate(x));
-}
-
-pub fn encodeVarInt(writer: anytype, value: i64) !void {
- const ux: u64 = @bitCast((2 * value) ^ (value >> 63));
- return encodeVarUint(writer, ux);
-}
-
-pub const DecodeError = error{Overflow};
-
-pub fn decodeVarInt(reader: anytype) !i64 {
- const ux = try decodeVarUint(reader);
- const x: i64 = @intCast(ux >> 1);
- const y: i64 = @intCast(ux & 1);
- return x ^ -y;
-}
-
-pub fn decodeVarUint(reader: anytype) !u64 {
- var x: u64 = 0;
- var s: u6 = 0;
-
- for (0..std.math.maxInt(u4)) |i| {
- const b = try reader.readByte();
- const orm: u64 = @intCast(b & 0x7f);
- x |= orm << s;
-
- if (b < 0x80) {
- if (9 < i or i == 9 and 1 < b)
- return DecodeError.Overflow;
-
- return x;
- }
-
- const ov = @addWithOverflow(s, 7);
-
- if (0 != ov[1])
- return DecodeError.Overflow;
-
- s = ov[0];
- }
-
- return 0;
-}
-
-const io = std.io;
-const testing = std.testing;
-
-test "read variable uint" {
- var fbs = io.fixedBufferStream("\x2a");
- var reader = fbs.reader();
- const x = try decodeVarUint(&reader);
- try testing.expectEqual(x, 42);
- fbs = io.fixedBufferStream("\x80\x02");
- const y = decodeVarUint(fbs.reader());
- try testing.expectEqual(y, 0x100);
-}
-
-test "read variable uint overflow 1" {
- const buf = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\x02";
- var fbs = io.fixedBufferStream(buf);
- var reader = fbs.reader();
- const x = decodeVarUint(reader);
- try testing.expectError(DecodeError.Overflow, x);
-}
-
-test "read variable uint overflow 2" {
- const buf = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00";
- var fbs = io.fixedBufferStream(buf);
- var reader = fbs.reader();
- const x = decodeVarUint(reader);
- try testing.expectError(DecodeError.Overflow, x);
-}
-
-test "write variable uint" {
- var buf: [4]u8 = undefined;
- var fbs = io.fixedBufferStream(&buf);
- var writer = fbs.writer();
- try encodeVarUint(writer, 42);
- try testing.expectEqual(fbs.getWritten()[0], 42);
- try encodeVarUint(writer, 0x100);
- try testing.expectEqual(fbs.getWritten()[1], 128);
- try testing.expectEqual(fbs.getWritten()[2], 2);
-}
-
-test "write variable int" {
- var buf: [4]u8 = undefined;
- var fbs = io.fixedBufferStream(&buf);
- var writer = fbs.writer();
- try encodeVarInt(writer, 42);
- try testing.expectEqual(fbs.getWritten()[0], 42 << 1);
-}
-
-test "round trip variable uint" {
- var buf: [4]u8 = undefined;
- var fbs = io.fixedBufferStream(&buf);
- var reader = fbs.reader();
- var writer = fbs.writer();
- try encodeVarUint(writer, 0x10000);
- fbs = io.fixedBufferStream(fbs.getWritten());
- const res = try decodeVarUint(reader);
- try testing.expectEqual(res, 0x10000);
-}
-
-test "round trip variable int 1" {
- var buf: [4]u8 = undefined;
- var fbs = io.fixedBufferStream(&buf);
- var reader = fbs.reader();
- var writer = fbs.writer();
- try encodeVarInt(writer, -0x10000);
- fbs = io.fixedBufferStream(fbs.getWritten());
- const res = try decodeVarInt(reader);
- try testing.expectEqual(res, -0x10000);
-}
-
-test "round trip variable int 2" {
- var buf: [4]u8 = undefined;
- var fbs = io.fixedBufferStream(&buf);
- var reader = fbs.reader();
- var writer = fbs.writer();
- try encodeVarInt(writer, 0x10000);
- fbs = io.fixedBufferStream(fbs.getWritten());
- const res = try decodeVarInt(reader);
- try testing.expectEqual(res, 0x10000);
-}