@@ -1594,21 +1594,47 @@ test containsAtLeast {
1594
1594
/// T specifies the return type, which must be large enough to store
1595
1595
/// the result.
1596
1596
pub 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 ;
1598
1601
switch (endian ) {
1599
1602
.big = > {
1600
1603
for (bytes ) | b | {
1601
1604
result = (result << 8 ) | b ;
1602
1605
}
1603
1606
},
1604
1607
.little = > {
1605
- const ShiftType = math .Log2Int (ReturnType );
1608
+ const ShiftType = math .Log2Int (WorkType );
1606
1609
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 )));
1608
1611
}
1609
1612
},
1610
1613
}
1611
- return result ;
1614
+ return @as (ReturnType , @truncate (result ));
1615
+ }
1616
+
1617
+ test 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 );
1612
1638
}
1613
1639
1614
1640
/// Loads an integer from packed memory with provided bit_count, bit_offset, and signedness.
0 commit comments