Skip to content

Commit

Permalink
add SliceOutStream, rename SliceStream to SliceInStream (#1301)
Browse files Browse the repository at this point in the history
  • Loading branch information
dbandstra authored and andrewrk committed Jul 29, 2018
1 parent f884381 commit 608ff52
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 5 deletions.
48 changes: 47 additions & 1 deletion std/io.zig
Expand Up @@ -419,7 +419,7 @@ pub fn PeekStream(comptime buffer_size: usize, comptime InStreamError: type) typ
};
}

pub const SliceStream = struct {
pub const SliceInStream = struct {
const Self = this;
pub const Error = error { };
pub const Stream = InStream(Error);
Expand Down Expand Up @@ -447,7 +447,53 @@ pub const SliceStream = struct {

return size;
}
};

/// This is a simple OutStream that writes to a slice, and returns an error
/// when it runs out of space.
pub const SliceOutStream = struct {
pub const Error = error{OutOfSpace};
pub const Stream = OutStream(Error);

pub stream: Stream,

pos: usize,
slice: []u8,

pub fn init(slice: []u8) SliceOutStream {
return SliceOutStream{
.slice = slice,
.pos = 0,
.stream = Stream{ .writeFn = writeFn },
};
}

pub fn getWritten(self: *const SliceOutStream) []const u8 {
return self.slice[0..self.pos];
}

pub fn reset(self: *SliceOutStream) void {
self.pos = 0;
}

fn writeFn(out_stream: *Stream, bytes: []const u8) Error!void {
const self = @fieldParentPtr(SliceOutStream, "stream", out_stream);

assert(self.pos <= self.slice.len);

const n =
if (self.pos + bytes.len <= self.slice.len)
bytes.len
else
self.slice.len - self.pos;

std.mem.copy(u8, self.slice[self.pos..self.pos + n], bytes[0..n]);
self.pos += n;

if (n < bytes.len) {
return Error.OutOfSpace;
}
}
};

pub fn BufferedOutStream(comptime Error: type) type {
Expand Down
29 changes: 25 additions & 4 deletions std/io_test.zig
Expand Up @@ -2,6 +2,7 @@ const std = @import("index.zig");
const io = std.io;
const DefaultPrng = std.rand.DefaultPrng;
const assert = std.debug.assert;
const assertError = std.debug.assertError;
const mem = std.mem;
const os = std.os;
const builtin = @import("builtin");
Expand Down Expand Up @@ -61,9 +62,9 @@ test "BufferOutStream" {
assert(mem.eql(u8, buffer.toSlice(), "x: 42\ny: 1234\n"));
}

test "SliceStream" {
test "SliceInStream" {
const bytes = []const u8 { 1, 2, 3, 4, 5, 6, 7 };
var ss = io.SliceStream.init(bytes);
var ss = io.SliceInStream.init(bytes);

var dest: [4]u8 = undefined;

Expand All @@ -81,8 +82,8 @@ test "SliceStream" {

test "PeekStream" {
const bytes = []const u8 { 1, 2, 3, 4, 5, 6, 7, 8 };
var ss = io.SliceStream.init(bytes);
var ps = io.PeekStream(2, io.SliceStream.Error).init(&ss.stream);
var ss = io.SliceInStream.init(bytes);
var ps = io.PeekStream(2, io.SliceInStream.Error).init(&ss.stream);

var dest: [4]u8 = undefined;

Expand Down Expand Up @@ -111,3 +112,23 @@ test "PeekStream" {
assert(dest[0] == 12);
assert(dest[1] == 11);
}

test "SliceOutStream" {
var buffer: [10]u8 = undefined;
var ss = io.SliceOutStream.init(buffer[0..]);

try ss.stream.write("Hello");
assert(mem.eql(u8, ss.getWritten(), "Hello"));

try ss.stream.write("world");
assert(mem.eql(u8, ss.getWritten(), "Helloworld"));

assertError(ss.stream.write("!"), error.OutOfSpace);
assert(mem.eql(u8, ss.getWritten(), "Helloworld"));

ss.reset();
assert(ss.getWritten().len == 0);

assertError(ss.stream.write("Hello world!"), error.OutOfSpace);
assert(mem.eql(u8, ss.getWritten(), "Hello worl"));
}

0 comments on commit 608ff52

Please sign in to comment.