@@ -1096,33 +1096,41 @@ pub inline fn takeInt(r: *Reader, comptime T: type, endian: std.builtin.Endian)
10961096 return std .mem .readInt (T , try r .takeArray (n ), endian );
10971097}
10981098
1099+ /// Asserts the buffer was initialized with a capacity at least `@bitSizeOf(T) / 8`.
1100+ pub inline fn peekInt (r : * Reader , comptime T : type , endian : std.builtin.Endian ) Error ! T {
1101+ const n = @divExact (@typeInfo (T ).int .bits , 8 );
1102+ return std .mem .readInt (T , try r .peekArray (n ), endian );
1103+ }
1104+
10991105/// Asserts the buffer was initialized with a capacity at least `n`.
11001106pub fn takeVarInt (r : * Reader , comptime Int : type , endian : std.builtin.Endian , n : usize ) Error ! Int {
11011107 assert (n <= @sizeOf (Int ));
11021108 return std .mem .readVarInt (Int , try r .take (n ), endian );
11031109}
11041110
1105- /// Asserts the buffer was initialized with a capacity at least `@sizeOf(T)`.
1111+ /// Obtains an unaligned pointer to the beginning of the stream, reinterpreted
1112+ /// as a pointer to the provided type, advancing the seek position.
11061113///
1107- /// Advances the seek position .
1114+ /// Asserts the buffer was initialized with a capacity at least `@sizeOf(T)` .
11081115///
11091116/// See also:
1110- /// * `peekStruct `
1111- /// * `takeStructEndian `
1112- pub fn takeStruct (r : * Reader , comptime T : type ) Error ! * align (1 ) T {
1117+ /// * `peekStructReference `
1118+ /// * `takeStruct `
1119+ pub fn takeStructReference (r : * Reader , comptime T : type ) Error ! * align (1 ) T {
11131120 // Only extern and packed structs have defined in-memory layout.
11141121 comptime assert (@typeInfo (T ).@"struct" .layout != .auto );
11151122 return @ptrCast (try r .takeArray (@sizeOf (T )));
11161123}
11171124
1118- /// Asserts the buffer was initialized with a capacity at least `@sizeOf(T)`.
1125+ /// Obtains an unaligned pointer to the beginning of the stream, reinterpreted
1126+ /// as a pointer to the provided type, without advancing the seek position.
11191127///
1120- /// Does not advance the seek position .
1128+ /// Asserts the buffer was initialized with a capacity at least `@sizeOf(T)` .
11211129///
11221130/// See also:
1123- /// * `takeStruct `
1124- /// * `peekStructEndian `
1125- pub fn peekStruct (r : * Reader , comptime T : type ) Error ! * align (1 ) T {
1131+ /// * `takeStructReference `
1132+ /// * `peekStruct `
1133+ pub fn peekStructReference (r : * Reader , comptime T : type ) Error ! * align (1 ) T {
11261134 // Only extern and packed structs have defined in-memory layout.
11271135 comptime assert (@typeInfo (T ).@"struct" .layout != .auto );
11281136 return @ptrCast (try r .peekArray (@sizeOf (T )));
@@ -1134,12 +1142,23 @@ pub fn peekStruct(r: *Reader, comptime T: type) Error!*align(1) T {
11341142/// when `endian` is comptime-known and matches the host endianness.
11351143///
11361144/// See also:
1137- /// * `takeStruct`
1138- /// * `peekStructEndian`
1139- pub inline fn takeStructEndian (r : * Reader , comptime T : type , endian : std.builtin.Endian ) Error ! T {
1140- var res = (try r .takeStruct (T )).* ;
1141- if (native_endian != endian ) std .mem .byteSwapAllFields (T , & res );
1142- return res ;
1145+ /// * `takeStructReference`
1146+ /// * `peekStruct`
1147+ pub inline fn takeStruct (r : * Reader , comptime T : type , endian : std.builtin.Endian ) Error ! T {
1148+ switch (@typeInfo (T )) {
1149+ .@"struct" = > | info | switch (info .layout ) {
1150+ .auto = > @compileError ("ill-defined memory layout" ),
1151+ .@"extern" = > {
1152+ var res = (try r .takeStructReference (T )).* ;
1153+ if (native_endian != endian ) std .mem .byteSwapAllFields (T , & res );
1154+ return res ;
1155+ },
1156+ .@"packed" = > {
1157+ return takeInt (r , info .backing_integer .? , endian );
1158+ },
1159+ },
1160+ else = > @compileError ("not a struct" ),
1161+ }
11431162}
11441163
11451164/// Asserts the buffer was initialized with a capacity at least `@sizeOf(T)`.
@@ -1148,12 +1167,23 @@ pub inline fn takeStructEndian(r: *Reader, comptime T: type, endian: std.builtin
11481167/// when `endian` is comptime-known and matches the host endianness.
11491168///
11501169/// See also:
1151- /// * `takeStructEndian`
1152- /// * `peekStruct`
1153- pub inline fn peekStructEndian (r : * Reader , comptime T : type , endian : std.builtin.Endian ) Error ! T {
1154- var res = (try r .peekStruct (T )).* ;
1155- if (native_endian != endian ) std .mem .byteSwapAllFields (T , & res );
1156- return res ;
1170+ /// * `takeStruct`
1171+ /// * `peekStructReference`
1172+ pub inline fn peekStruct (r : * Reader , comptime T : type , endian : std.builtin.Endian ) Error ! T {
1173+ switch (@typeInfo (T )) {
1174+ .@"struct" = > | info | switch (info .layout ) {
1175+ .auto = > @compileError ("ill-defined memory layout" ),
1176+ .@"extern" = > {
1177+ var res = (try r .peekStructReference (T )).* ;
1178+ if (native_endian != endian ) std .mem .byteSwapAllFields (T , & res );
1179+ return res ;
1180+ },
1181+ .@"packed" = > {
1182+ return peekInt (r , info .backing_integer .? , endian );
1183+ },
1184+ },
1185+ else = > @compileError ("not a struct" ),
1186+ }
11571187}
11581188
11591189pub const TakeEnumError = Error || error {InvalidEnumTag };
@@ -1519,43 +1549,43 @@ test takeVarInt {
15191549 try testing .expectError (error .EndOfStream , r .takeVarInt (u16 , .little , 1 ));
15201550}
15211551
1522- test takeStruct {
1552+ test takeStructReference {
15231553 var r : Reader = .fixed (&.{ 0x12 , 0x00 , 0x34 , 0x56 });
15241554 const S = extern struct { a : u8 , b : u16 };
15251555 switch (native_endian ) {
1526- .little = > try testing .expectEqual (@as (S , .{ .a = 0x12 , .b = 0x5634 }), (try r .takeStruct (S )).* ),
1527- .big = > try testing .expectEqual (@as (S , .{ .a = 0x12 , .b = 0x3456 }), (try r .takeStruct (S )).* ),
1556+ .little = > try testing .expectEqual (@as (S , .{ .a = 0x12 , .b = 0x5634 }), (try r .takeStructReference (S )).* ),
1557+ .big = > try testing .expectEqual (@as (S , .{ .a = 0x12 , .b = 0x3456 }), (try r .takeStructReference (S )).* ),
15281558 }
1529- try testing .expectError (error .EndOfStream , r .takeStruct (S ));
1559+ try testing .expectError (error .EndOfStream , r .takeStructReference (S ));
15301560}
15311561
1532- test peekStruct {
1562+ test peekStructReference {
15331563 var r : Reader = .fixed (&.{ 0x12 , 0x00 , 0x34 , 0x56 });
15341564 const S = extern struct { a : u8 , b : u16 };
15351565 switch (native_endian ) {
15361566 .little = > {
1537- try testing .expectEqual (@as (S , .{ .a = 0x12 , .b = 0x5634 }), (try r .peekStruct (S )).* );
1538- try testing .expectEqual (@as (S , .{ .a = 0x12 , .b = 0x5634 }), (try r .peekStruct (S )).* );
1567+ try testing .expectEqual (@as (S , .{ .a = 0x12 , .b = 0x5634 }), (try r .peekStructReference (S )).* );
1568+ try testing .expectEqual (@as (S , .{ .a = 0x12 , .b = 0x5634 }), (try r .peekStructReference (S )).* );
15391569 },
15401570 .big = > {
1541- try testing .expectEqual (@as (S , .{ .a = 0x12 , .b = 0x3456 }), (try r .peekStruct (S )).* );
1542- try testing .expectEqual (@as (S , .{ .a = 0x12 , .b = 0x3456 }), (try r .peekStruct (S )).* );
1571+ try testing .expectEqual (@as (S , .{ .a = 0x12 , .b = 0x3456 }), (try r .peekStructReference (S )).* );
1572+ try testing .expectEqual (@as (S , .{ .a = 0x12 , .b = 0x3456 }), (try r .peekStructReference (S )).* );
15431573 },
15441574 }
15451575}
15461576
1547- test takeStructEndian {
1577+ test takeStruct {
15481578 var r : Reader = .fixed (&.{ 0x12 , 0x00 , 0x34 , 0x56 });
15491579 const S = extern struct { a : u8 , b : u16 };
1550- try testing .expectEqual (@as (S , .{ .a = 0x12 , .b = 0x3456 }), try r .takeStructEndian (S , .big ));
1551- try testing .expectError (error .EndOfStream , r .takeStructEndian (S , .little ));
1580+ try testing .expectEqual (@as (S , .{ .a = 0x12 , .b = 0x3456 }), try r .takeStruct (S , .big ));
1581+ try testing .expectError (error .EndOfStream , r .takeStruct (S , .little ));
15521582}
15531583
1554- test peekStructEndian {
1584+ test peekStruct {
15551585 var r : Reader = .fixed (&.{ 0x12 , 0x00 , 0x34 , 0x56 });
15561586 const S = extern struct { a : u8 , b : u16 };
1557- try testing .expectEqual (@as (S , .{ .a = 0x12 , .b = 0x3456 }), try r .peekStructEndian (S , .big ));
1558- try testing .expectEqual (@as (S , .{ .a = 0x12 , .b = 0x5634 }), try r .peekStructEndian (S , .little ));
1587+ try testing .expectEqual (@as (S , .{ .a = 0x12 , .b = 0x3456 }), try r .peekStruct (S , .big ));
1588+ try testing .expectEqual (@as (S , .{ .a = 0x12 , .b = 0x5634 }), try r .peekStruct (S , .little ));
15591589}
15601590
15611591test takeEnum {
0 commit comments