authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-12-13 06:38:14-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-12-13 06:38:14-05:00
loge98ba5fc4044cd84ab88b10cb8c88d765884462f
tree822dabd0323a9e061e351908bb314ce8dae1c1f9
parent6395cf8d6b2cf585214a284039c16d6dc5ef5de3
signature Commit is signed but in an unrecognized format.

add mem.readVarInt, fix InStream.readVarInt, fix stack traces

fixes a regression from b883bc8

3 files changed, 28 insertions(+), 6 deletions(-)

std/debug/index.zig+1-1
...@@ -1200,7 +1200,7 @@ const Constant = struct {...@@ -1200,7 +1200,7 @@ const Constant = struct {
1200 fn asUnsignedLe(self: *const Constant) !u64 {1200 fn asUnsignedLe(self: *const Constant) !u64 {
1201 if (self.payload.len > @sizeOf(u64)) return error.InvalidDebugInfo;1201 if (self.payload.len > @sizeOf(u64)) return error.InvalidDebugInfo;
1202 if (self.signed) return error.InvalidDebugInfo;1202 if (self.signed) return error.InvalidDebugInfo;
1203 return mem.readIntSliceLittle(u64, self.payload);1203 return mem.readVarInt(u64, self.payload, builtin.Endian.Little);
1204 }1204 }
1205};1205};
12061206
std/io.zig+6-5
...@@ -183,11 +183,12 @@ pub fn InStream(comptime ReadError: type) type {...@@ -183,11 +183,12 @@ pub fn InStream(comptime ReadError: type) type {
183 return mem.readIntSlice(T, bytes, endian);183 return mem.readIntSlice(T, bytes, endian);
184 }184 }
185185
186 pub fn readVarInt(self: *Self, comptime T: type, endian: builtin.Endian, size: usize) !T {186 pub fn readVarInt(self: *Self, comptime ReturnType: type, endian: builtin.Endian, size: usize) !ReturnType {
187 assert(size <= @sizeOf(T));187 assert(size <= @sizeOf(ReturnType));
188 var bytes: [@sizeOf(T)]u8 = undefined;188 var bytes_buf: [@sizeOf(ReturnType)]u8 = undefined;
189 try self.readNoEof(bytes[0..size]);189 const bytes = bytes_buf[0..size];
190 return mem.readIntSlice(T, bytes, endian);190 try self.readNoEof(bytes);
191 return mem.readVarInt(ReturnType, bytes, endian);
191 }192 }
192193
193 pub fn skipBytes(self: *Self, num_bytes: usize) !void {194 pub fn skipBytes(self: *Self, num_bytes: usize) !void {
std/mem.zig+21
...@@ -407,6 +407,27 @@ test "mem.indexOf" {...@@ -407,6 +407,27 @@ test "mem.indexOf" {
407 assert(lastIndexOfScalar(u8, "boo", 'o').? == 2);407 assert(lastIndexOfScalar(u8, "boo", 'o').? == 2);
408}408}
409409
410/// Reads an integer from memory with size equal to bytes.len.
411/// T specifies the return type, which must be large enough to store
412/// the result.
413pub fn readVarInt(comptime ReturnType: type, bytes: []const u8, endian: builtin.Endian) ReturnType {
414 var result: ReturnType = 0;
415 switch (endian) {
416 builtin.Endian.Big => {
417 for (bytes) |b| {
418 result = (result << 8) | b;
419 }
420 },
421 builtin.Endian.Little => {
422 const ShiftType = math.Log2Int(ReturnType);
423 for (bytes) |b, index| {
424 result = result | (ReturnType(b) << @intCast(ShiftType, index * 8));
425 }
426 },
427 }
428 return result;
429}
430
410/// Reads an integer from memory with bit count specified by T.431/// Reads an integer from memory with bit count specified by T.
411/// The bit count of T must be evenly divisible by 8.432/// The bit count of T must be evenly divisible by 8.
412/// This function cannot fail and cannot cause undefined behavior.433/// This function cannot fail and cannot cause undefined behavior.