mirror of
https://github.com/ziglang/zig.git
synced 2026-01-21 06:45:24 +00:00
std.mem.readVarInt: fix for 8-bits and below (Reloaded) (#20513)
This commit is contained in:
parent
08e83fee57
commit
939fcce5ef
@ -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.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user