Commit 939fcce5ef
Changed files (1)
lib
std
lib/std/mem.zig
@@ -1594,7 +1594,10 @@ test containsAtLeast {
/// T specifies the return type, which must be large enough to store
/// the result.
pub fn readVarInt(comptime ReturnType: type, bytes: []const u8, endian: Endian) ReturnType {
- var result: ReturnType = 0;
+ const bits = @typeInfo(ReturnType).Int.bits;
+ const signedness = @typeInfo(ReturnType).Int.signedness;
+ const WorkType = std.meta.Int(signedness, @max(16, bits));
+ var result: WorkType = 0;
switch (endian) {
.big => {
for (bytes) |b| {
@@ -1602,13 +1605,36 @@ pub fn readVarInt(comptime ReturnType: type, bytes: []const u8, endian: Endian)
}
},
.little => {
- const ShiftType = math.Log2Int(ReturnType);
+ const ShiftType = math.Log2Int(WorkType);
for (bytes, 0..) |b, index| {
- result = result | (@as(ReturnType, b) << @as(ShiftType, @intCast(index * 8)));
+ result = result | (@as(WorkType, b) << @as(ShiftType, @intCast(index * 8)));
}
},
}
- return result;
+ return @as(ReturnType, @truncate(result));
+}
+
+test readVarInt {
+ try testing.expect(readVarInt(u0, &[_]u8{}, .big) == 0x0);
+ try testing.expect(readVarInt(u0, &[_]u8{}, .little) == 0x0);
+ try testing.expect(readVarInt(u8, &[_]u8{0x12}, .big) == 0x12);
+ try testing.expect(readVarInt(u8, &[_]u8{0xde}, .little) == 0xde);
+ try testing.expect(readVarInt(u16, &[_]u8{ 0x12, 0x34 }, .big) == 0x1234);
+ try testing.expect(readVarInt(u16, &[_]u8{ 0x12, 0x34 }, .little) == 0x3412);
+
+ try testing.expect(readVarInt(i8, &[_]u8{0xff}, .big) == -1);
+ try testing.expect(readVarInt(i8, &[_]u8{0xfe}, .little) == -2);
+ try testing.expect(readVarInt(i16, &[_]u8{ 0xff, 0xfd }, .big) == -3);
+ try testing.expect(readVarInt(i16, &[_]u8{ 0xfc, 0xff }, .little) == -4);
+
+ // Return type can be oversized (bytes.len * 8 < @typeInfo(ReturnType).Int.bits)
+ try testing.expect(readVarInt(u9, &[_]u8{0x12}, .little) == 0x12);
+ try testing.expect(readVarInt(u9, &[_]u8{0xde}, .big) == 0xde);
+ try testing.expect(readVarInt(u80, &[_]u8{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x24 }, .big) == 0x123456789abcdef024);
+ try testing.expect(readVarInt(u80, &[_]u8{ 0xec, 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe }, .little) == 0xfedcba9876543210ec);
+
+ try testing.expect(readVarInt(i9, &[_]u8{0xff}, .big) == 0xff);
+ try testing.expect(readVarInt(i9, &[_]u8{0xfe}, .little) == 0xfe);
}
/// Loads an integer from packed memory with provided bit_count, bit_offset, and signedness.