authorgravatar for srazin123@gmail.compoypoyan <srazin123@gmail.com> 2024-07-29 11:26:36+08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-07-28 20:26:36-07:00
log939fcce5ef415142631e246a91473317a8d3fa90
treee684565aed64b3792ddda454cbb3048efbea44fa
parent08e83fee57c488c08c7981ff448ac0c0c94dc043
signaturebadge-check Signed by PGP key B5690EEEBB952194

std.mem.readVarInt: fix for 8-bits and below (Reloaded) (#20513)


1 files changed, 30 insertions(+), 4 deletions(-)

lib/std/mem.zig+30-4
......@@ -1594,7 +1594,10 @@ test containsAtLeast {
15941594/// T specifies the return type, which must be large enough to store
15951595/// the result.
15961596pub fn readVarInt(comptime ReturnType: type, bytes: []const u8, endian: Endian) ReturnType {
1597 var result: ReturnType = 0;
1597 const bits = @typeInfo(ReturnType).Int.bits;
1598 const signedness = @typeInfo(ReturnType).Int.signedness;
1599 const WorkType = std.meta.Int(signedness, @max(16, bits));
1600 var result: WorkType = 0;
15981601 switch (endian) {
15991602 .big => {
16001603 for (bytes) |b| {
......@@ -1602,13 +1605,36 @@ pub fn readVarInt(comptime ReturnType: type, bytes: []const u8, endian: Endian)
16021605 }
16031606 },
16041607 .little => {
1605 const ShiftType = math.Log2Int(ReturnType);
1608 const ShiftType = math.Log2Int(WorkType);
16061609 for (bytes, 0..) |b, index| {
1607 result = result | (@as(ReturnType, b) << @as(ShiftType, @intCast(index * 8)));
1610 result = result | (@as(WorkType, b) << @as(ShiftType, @intCast(index * 8)));
16081611 }
16091612 },
16101613 }
1611 return result;
1614 return @as(ReturnType, @truncate(result));
1615}
1616
1617test readVarInt {
1618 try testing.expect(readVarInt(u0, &[_]u8{}, .big) == 0x0);
1619 try testing.expect(readVarInt(u0, &[_]u8{}, .little) == 0x0);
1620 try testing.expect(readVarInt(u8, &[_]u8{0x12}, .big) == 0x12);
1621 try testing.expect(readVarInt(u8, &[_]u8{0xde}, .little) == 0xde);
1622 try testing.expect(readVarInt(u16, &[_]u8{ 0x12, 0x34 }, .big) == 0x1234);
1623 try testing.expect(readVarInt(u16, &[_]u8{ 0x12, 0x34 }, .little) == 0x3412);
1624
1625 try testing.expect(readVarInt(i8, &[_]u8{0xff}, .big) == -1);
1626 try testing.expect(readVarInt(i8, &[_]u8{0xfe}, .little) == -2);
1627 try testing.expect(readVarInt(i16, &[_]u8{ 0xff, 0xfd }, .big) == -3);
1628 try testing.expect(readVarInt(i16, &[_]u8{ 0xfc, 0xff }, .little) == -4);
1629
1630 // Return type can be oversized (bytes.len * 8 < @typeInfo(ReturnType).Int.bits)
1631 try testing.expect(readVarInt(u9, &[_]u8{0x12}, .little) == 0x12);
1632 try testing.expect(readVarInt(u9, &[_]u8{0xde}, .big) == 0xde);
1633 try testing.expect(readVarInt(u80, &[_]u8{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x24 }, .big) == 0x123456789abcdef024);
1634 try testing.expect(readVarInt(u80, &[_]u8{ 0xec, 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe }, .little) == 0xfedcba9876543210ec);
1635
1636 try testing.expect(readVarInt(i9, &[_]u8{0xff}, .big) == 0xff);
1637 try testing.expect(readVarInt(i9, &[_]u8{0xfe}, .little) == 0xfe);
16121638}
16131639
16141640/// Loads an integer from packed memory with provided bit_count, bit_offset, and signedness.