authorgravatar for dbandstra@protonmail.comdbandstra <dbandstra@protonmail.com> 2018-07-29 11:52:10-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-29 14:52:10-04:00
log608ff52dc3ea356b23fb6ae92fbca9fbb18c7892
treea2c630fac18864a811242898af76c715a515b705
parentf884381c608f47180d97534ba9b872d62ddb105b

add SliceOutStream, rename SliceStream to SliceInStream (#1301)


2 files changed, 72 insertions(+), 5 deletions(-)

std/io.zig+47-1
...@@ -419,7 +419,7 @@ pub fn PeekStream(comptime buffer_size: usize, comptime InStreamError: type) typ...@@ -419,7 +419,7 @@ pub fn PeekStream(comptime buffer_size: usize, comptime InStreamError: type) typ
419 };419 };
420}420}
421421
422pub const SliceStream = struct {422pub const SliceInStream = struct {
423 const Self = this;423 const Self = this;
424 pub const Error = error { };424 pub const Error = error { };
425 pub const Stream = InStream(Error);425 pub const Stream = InStream(Error);
...@@ -447,7 +447,53 @@ pub const SliceStream = struct {...@@ -447,7 +447,53 @@ pub const SliceStream = struct {
447447
448 return size;448 return size;
449 }449 }
450};
451
452/// This is a simple OutStream that writes to a slice, and returns an error
453/// when it runs out of space.
454pub const SliceOutStream = struct {
455 pub const Error = error{OutOfSpace};
456 pub const Stream = OutStream(Error);
457
458 pub stream: Stream,
459
460 pos: usize,
461 slice: []u8,
450462
463 pub fn init(slice: []u8) SliceOutStream {
464 return SliceOutStream{
465 .slice = slice,
466 .pos = 0,
467 .stream = Stream{ .writeFn = writeFn },
468 };
469 }
470
471 pub fn getWritten(self: *const SliceOutStream) []const u8 {
472 return self.slice[0..self.pos];
473 }
474
475 pub fn reset(self: *SliceOutStream) void {
476 self.pos = 0;
477 }
478
479 fn writeFn(out_stream: *Stream, bytes: []const u8) Error!void {
480 const self = @fieldParentPtr(SliceOutStream, "stream", out_stream);
481
482 assert(self.pos <= self.slice.len);
483
484 const n =
485 if (self.pos + bytes.len <= self.slice.len)
486 bytes.len
487 else
488 self.slice.len - self.pos;
489
490 std.mem.copy(u8, self.slice[self.pos..self.pos + n], bytes[0..n]);
491 self.pos += n;
492
493 if (n < bytes.len) {
494 return Error.OutOfSpace;
495 }
496 }
451};497};
452498
453pub fn BufferedOutStream(comptime Error: type) type {499pub fn BufferedOutStream(comptime Error: type) type {
std/io_test.zig+25-4
...@@ -2,6 +2,7 @@ const std = @import("index.zig");...@@ -2,6 +2,7 @@ const std = @import("index.zig");
2const io = std.io;2const io = std.io;
3const DefaultPrng = std.rand.DefaultPrng;3const DefaultPrng = std.rand.DefaultPrng;
4const assert = std.debug.assert;4const assert = std.debug.assert;
5const assertError = std.debug.assertError;
5const mem = std.mem;6const mem = std.mem;
6const os = std.os;7const os = std.os;
7const builtin = @import("builtin");8const builtin = @import("builtin");
...@@ -61,9 +62,9 @@ test "BufferOutStream" {...@@ -61,9 +62,9 @@ test "BufferOutStream" {
61 assert(mem.eql(u8, buffer.toSlice(), "x: 42\ny: 1234\n"));62 assert(mem.eql(u8, buffer.toSlice(), "x: 42\ny: 1234\n"));
62}63}
6364
64test "SliceStream" {65test "SliceInStream" {
65 const bytes = []const u8 { 1, 2, 3, 4, 5, 6, 7 };66 const bytes = []const u8 { 1, 2, 3, 4, 5, 6, 7 };
66 var ss = io.SliceStream.init(bytes);67 var ss = io.SliceInStream.init(bytes);
6768
68 var dest: [4]u8 = undefined;69 var dest: [4]u8 = undefined;
6970
...@@ -81,8 +82,8 @@ test "SliceStream" {...@@ -81,8 +82,8 @@ test "SliceStream" {
8182
82test "PeekStream" {83test "PeekStream" {
83 const bytes = []const u8 { 1, 2, 3, 4, 5, 6, 7, 8 };84 const bytes = []const u8 { 1, 2, 3, 4, 5, 6, 7, 8 };
84 var ss = io.SliceStream.init(bytes);85 var ss = io.SliceInStream.init(bytes);
85 var ps = io.PeekStream(2, io.SliceStream.Error).init(&ss.stream);86 var ps = io.PeekStream(2, io.SliceInStream.Error).init(&ss.stream);
8687
87 var dest: [4]u8 = undefined;88 var dest: [4]u8 = undefined;
8889
...@@ -111,3 +112,23 @@ test "PeekStream" {...@@ -111,3 +112,23 @@ test "PeekStream" {
111 assert(dest[0] == 12);112 assert(dest[0] == 12);
112 assert(dest[1] == 11);113 assert(dest[1] == 11);
113}114}
115
116test "SliceOutStream" {
117 var buffer: [10]u8 = undefined;
118 var ss = io.SliceOutStream.init(buffer[0..]);
119
120 try ss.stream.write("Hello");
121 assert(mem.eql(u8, ss.getWritten(), "Hello"));
122
123 try ss.stream.write("world");
124 assert(mem.eql(u8, ss.getWritten(), "Helloworld"));
125
126 assertError(ss.stream.write("!"), error.OutOfSpace);
127 assert(mem.eql(u8, ss.getWritten(), "Helloworld"));
128
129 ss.reset();
130 assert(ss.getWritten().len == 0);
131
132 assertError(ss.stream.write("Hello world!"), error.OutOfSpace);
133 assert(mem.eql(u8, ss.getWritten(), "Hello worl"));
134}