Skip to content

Commit 167754b

Browse files
ikskuhandrewrk
authored andcommitted
Makes std.io.StreamSource usable with freestanding
1 parent 5d94e75 commit 167754b

File tree

1 file changed

+47
-11
lines changed

1 file changed

+47
-11
lines changed

lib/std/io/stream_source.zig

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,23 @@ const io = std.io;
1111
/// For memory sources, if the supplied byte buffer is const, then `io.Writer` is not available.
1212
/// The error set of the stream functions is the error set of the corresponding file functions.
1313
pub const StreamSource = union(enum) {
14+
const has_file = (std.builtin.os.tag != .freestanding);
15+
16+
/// The stream access is redirected to this buffer.
1417
buffer: io.FixedBufferStream([]u8),
18+
19+
/// The stream access is redirected to this buffer.
20+
/// Writing to the source will always yield `error.AccessDenied`.
1521
const_buffer: io.FixedBufferStream([]const u8),
16-
file: std.fs.File,
1722

18-
pub const ReadError = std.fs.File.ReadError;
19-
pub const WriteError = std.fs.File.WriteError;
20-
pub const SeekError = std.fs.File.SeekError;
21-
pub const GetSeekPosError = std.fs.File.GetSeekPosError;
23+
/// The stream access is redirected to this file.
24+
/// On freestanding, this must never be initialized!
25+
file: if (has_file) std.fs.File else void,
26+
27+
pub const ReadError = io.FixedBufferStream([]u8).ReadError || (if (has_file) std.fs.File.ReadError else error{});
28+
pub const WriteError = error{AccessDenied} || io.FixedBufferStream([]u8).WriteError || (if (has_file) std.fs.File.WriteError else error{});
29+
pub const SeekError = io.FixedBufferStream([]u8).SeekError || (if (has_file) std.fs.File.SeekError else error{});
30+
pub const GetSeekPosError = io.FixedBufferStream([]u8).GetSeekPosError || (if (has_file) std.fs.File.GetSeekPosError else error{});
2231

2332
pub const Reader = io.Reader(*StreamSource, ReadError, read);
2433
pub const Writer = io.Writer(*StreamSource, WriteError, write);
@@ -36,47 +45,47 @@ pub const StreamSource = union(enum) {
3645
switch (self.*) {
3746
.buffer => |*x| return x.read(dest),
3847
.const_buffer => |*x| return x.read(dest),
39-
.file => |x| return x.read(dest),
48+
.file => |x| if (!has_file) unreachable else return x.read(dest),
4049
}
4150
}
4251

4352
pub fn write(self: *StreamSource, bytes: []const u8) WriteError!usize {
4453
switch (self.*) {
4554
.buffer => |*x| return x.write(bytes),
4655
.const_buffer => return error.AccessDenied,
47-
.file => |x| return x.write(bytes),
56+
.file => |x| if (!has_file) unreachable else return x.write(bytes),
4857
}
4958
}
5059

5160
pub fn seekTo(self: *StreamSource, pos: u64) SeekError!void {
5261
switch (self.*) {
5362
.buffer => |*x| return x.seekTo(pos),
5463
.const_buffer => |*x| return x.seekTo(pos),
55-
.file => |x| return x.seekTo(pos),
64+
.file => |x| if (!has_file) unreachable else return x.seekTo(pos),
5665
}
5766
}
5867

5968
pub fn seekBy(self: *StreamSource, amt: i64) SeekError!void {
6069
switch (self.*) {
6170
.buffer => |*x| return x.seekBy(amt),
6271
.const_buffer => |*x| return x.seekBy(amt),
63-
.file => |x| return x.seekBy(amt),
72+
.file => |x| if (!has_file) unreachable else return x.seekBy(amt),
6473
}
6574
}
6675

6776
pub fn getEndPos(self: *StreamSource) GetSeekPosError!u64 {
6877
switch (self.*) {
6978
.buffer => |*x| return x.getEndPos(),
7079
.const_buffer => |*x| return x.getEndPos(),
71-
.file => |x| return x.getEndPos(),
80+
.file => |x| if (!has_file) unreachable else return x.getEndPos(),
7281
}
7382
}
7483

7584
pub fn getPos(self: *StreamSource) GetSeekPosError!u64 {
7685
switch (self.*) {
7786
.buffer => |*x| return x.getPos(),
7887
.const_buffer => |*x| return x.getPos(),
79-
.file => |x| return x.getPos(),
88+
.file => |x| if (!has_file) unreachable else return x.getPos(),
8089
}
8190
}
8291

@@ -92,3 +101,30 @@ pub const StreamSource = union(enum) {
92101
return .{ .context = self };
93102
}
94103
};
104+
105+
test "StreamSource (refs)" {
106+
std.testing.refAllDecls(StreamSource);
107+
}
108+
109+
test "StreamSource (mutable buffer)" {
110+
var buffer: [64]u8 = undefined;
111+
var source = StreamSource{ .buffer = std.io.fixedBufferStream(&buffer) };
112+
113+
var writer = source.writer();
114+
115+
try writer.writeAll("Hello, World!");
116+
117+
try std.testing.expectEqualStrings("Hello, World!", source.buffer.getWritten());
118+
}
119+
120+
test "StreamSource (const buffer)" {
121+
const buffer: [64]u8 = "Hello, World!".* ++ ([1]u8{0xAA} ** 51);
122+
var source = StreamSource{ .const_buffer = std.io.fixedBufferStream(&buffer) };
123+
124+
var reader = source.reader();
125+
126+
var dst_buffer: [13]u8 = undefined;
127+
try reader.readNoEof(&dst_buffer);
128+
129+
try std.testing.expectEqualStrings("Hello, World!", &dst_buffer);
130+
}

0 commit comments

Comments
 (0)