Merge pull request #5164 from daurnimator/in_stream-helpers

A couple of helpers for streams that I've found helpful
This commit is contained in:
Veikka Tuominen 2020-05-17 22:02:10 +03:00 committed by GitHub
commit 2a5c0ef7f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -184,35 +184,38 @@ pub fn InStream(
return @bitCast(i8, try self.readByte());
}
/// Reads exactly `num_bytes` bytes and returns as an array.
/// `num_bytes` must be comptime-known
pub fn readBytesNoEof(self: Self, comptime num_bytes: usize) ![num_bytes]u8 {
var bytes: [num_bytes]u8 = undefined;
try self.readNoEof(&bytes);
return bytes;
}
/// Reads a native-endian integer
pub fn readIntNative(self: Self, comptime T: type) !T {
var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
try self.readNoEof(bytes[0..]);
const bytes = try self.readBytesNoEof((T.bit_count + 7) / 8);
return mem.readIntNative(T, &bytes);
}
/// Reads a foreign-endian integer
pub fn readIntForeign(self: Self, comptime T: type) !T {
var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
try self.readNoEof(bytes[0..]);
const bytes = try self.readBytesNoEof((T.bit_count + 7) / 8);
return mem.readIntForeign(T, &bytes);
}
pub fn readIntLittle(self: Self, comptime T: type) !T {
var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
try self.readNoEof(bytes[0..]);
const bytes = try self.readBytesNoEof((T.bit_count + 7) / 8);
return mem.readIntLittle(T, &bytes);
}
pub fn readIntBig(self: Self, comptime T: type) !T {
var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
try self.readNoEof(bytes[0..]);
const bytes = try self.readBytesNoEof((T.bit_count + 7) / 8);
return mem.readIntBig(T, &bytes);
}
pub fn readInt(self: Self, comptime T: type, endian: builtin.Endian) !T {
var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
try self.readNoEof(bytes[0..]);
const bytes = try self.readBytesNoEof((T.bit_count + 7) / 8);
return mem.readInt(T, &bytes, endian);
}
@ -231,6 +234,18 @@ pub fn InStream(
}
}
/// Reads `slice.len` bytes from the stream and returns if they are the same as the passed slice
pub fn isBytes(self: Self, slice: []const u8) !bool {
var i: usize = 0;
var matches = true;
while (i < slice.len) : (i += 1) {
if (slice[i] != try self.readByte()) {
matches = false;
}
}
return matches;
}
pub fn readStruct(self: Self, comptime T: type) !T {
// Only extern and packed structs have defined in-memory layout.
comptime assert(@typeInfo(T).Struct.layout != builtin.TypeInfo.ContainerLayout.Auto);
@ -273,3 +288,9 @@ test "InStream" {
}, undefined)) == .c);
testing.expectError(error.EndOfStream, in_stream.readByte());
}
test "InStream.isBytes" {
const in_stream = std.io.fixedBufferStream("foobar").inStream();
testing.expectEqual(true, try in_stream.isBytes("foo"));
testing.expectEqual(false, try in_stream.isBytes("qux"));
}