Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ set(ZIG_STAGE2_SOURCES
"${CMAKE_SOURCE_DIR}/lib/std/io/limited_reader.zig"
"${CMAKE_SOURCE_DIR}/lib/std/io/Reader.zig"
"${CMAKE_SOURCE_DIR}/lib/std/io/seekable_stream.zig"
"${CMAKE_SOURCE_DIR}/lib/std/io/writer.zig"
"${CMAKE_SOURCE_DIR}/lib/std/io/Writer.zig"
"${CMAKE_SOURCE_DIR}/lib/std/json.zig"
"${CMAKE_SOURCE_DIR}/lib/std/json/stringify.zig"
"${CMAKE_SOURCE_DIR}/lib/std/leb128.zig"
Expand Down
7 changes: 5 additions & 2 deletions lib/std/fmt.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1986,7 +1986,10 @@ pub const BufPrintError = error{
/// Returns a slice of the bytes printed to.
pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: anytype) BufPrintError![]u8 {
var fbs = std.io.fixedBufferStream(buf);
try format(fbs.writer(), fmt, args);
format(fbs.writer().any(), fmt, args) catch |err| switch (err) {
error.NoSpaceLeft => return error.NoSpaceLeft,
else => unreachable,
};
return fbs.getWritten();
}

Expand All @@ -1998,7 +2001,7 @@ pub fn bufPrintZ(buf: []u8, comptime fmt: []const u8, args: anytype) BufPrintErr
/// Count the characters needed for format. Useful for preallocating memory
pub fn count(comptime fmt: []const u8, args: anytype) u64 {
var counting_writer = std.io.countingWriter(std.io.null_writer);
format(counting_writer.writer(), fmt, args) catch |err| switch (err) {};
format(counting_writer.writer().any(), fmt, args) catch unreachable;
return counting_writer.bytes_written;
}

Expand Down
64 changes: 62 additions & 2 deletions lib/std/io.zig
Original file line number Diff line number Diff line change
Expand Up @@ -333,13 +333,73 @@ pub fn GenericReader(
};
}

pub fn GenericWriter(
comptime Context: type,
comptime WriteError: type,
comptime writeFn: fn (context: Context, bytes: []const u8) WriteError!usize,
) type {
return struct {
context: Context,

const Self = @This();
pub const Error = WriteError;

pub inline fn write(self: Self, bytes: []const u8) Error!usize {
return writeFn(self.context, bytes);
}

pub inline fn writeAll(self: Self, bytes: []const u8) Error!void {
return @errorCast(self.any().writeAll(bytes));
}

pub inline fn print(self: Self, comptime format: []const u8, args: anytype) Error!void {
return @errorCast(self.any().print(format, args));
}

pub inline fn writeByte(self: Self, byte: u8) Error!void {
return @errorCast(self.any().writeByte(byte));
}

pub inline fn writeByteNTimes(self: Self, byte: u8, n: usize) Error!void {
return @errorCast(self.any().writeByteNTimes(byte, n));
}

pub inline fn writeBytesNTimes(self: Self, bytes: []const u8, n: usize) Error!void {
return @errorCast(self.any().writeBytesNTimes(bytes, n));
}

pub inline fn writeInt(self: Self, comptime T: type, value: T, endian: std.builtin.Endian) Error!void {
return @errorCast(self.any().writeInt(T, value, endian));
}

pub inline fn writeStruct(self: Self, value: anytype) Error!void {
return @errorCast(self.any().writeStruct(value));
}

pub inline fn any(self: *const Self) AnyWriter {
return .{
.context = @ptrCast(&self.context),
.writeFn = typeErasedWriteFn,
};
}

fn typeErasedWriteFn(context: *const anyopaque, bytes: []const u8) anyerror!usize {
const ptr: *const Context = @alignCast(@ptrCast(context));
return writeFn(ptr.*, bytes);
}
};
}

/// Deprecated; consider switching to `AnyReader` or use `GenericReader`
/// to use previous API.
pub const Reader = GenericReader;
/// Deprecated; consider switching to `AnyWriter` or use `GenericWriter`
/// to use previous API.
pub const Writer = GenericWriter;

pub const AnyReader = @import("io/Reader.zig");
pub const AnyWriter = @import("io/Writer.zig");

pub const Writer = @import("io/writer.zig").Writer;
pub const SeekableStream = @import("io/seekable_stream.zig").SeekableStream;

pub const BufferedWriter = @import("io/buffered_writer.zig").BufferedWriter;
Expand Down Expand Up @@ -652,6 +712,7 @@ pub fn PollFiles(comptime StreamEnum: type) type {

test {
_ = AnyReader;
_ = AnyWriter;
_ = @import("io/bit_reader.zig");
_ = @import("io/bit_writer.zig");
_ = @import("io/buffered_atomic_file.zig");
Expand All @@ -661,7 +722,6 @@ test {
_ = @import("io/counting_writer.zig");
_ = @import("io/counting_reader.zig");
_ = @import("io/fixed_buffer_stream.zig");
_ = @import("io/writer.zig");
_ = @import("io/peek_stream.zig");
_ = @import("io/seekable_stream.zig");
_ = @import("io/stream_source.zig");
Expand Down
60 changes: 60 additions & 0 deletions lib/std/io/Writer.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const std = @import("../std.zig");
const assert = std.debug.assert;
const mem = std.mem;

context: *const anyopaque,
writeFn: *const fn (context: *const anyopaque, bytes: []const u8) anyerror!usize,

const Self = @This();
pub const Error = anyerror;

pub fn write(self: Self, bytes: []const u8) anyerror!usize {
return self.writeFn(self.context, bytes);
}

pub fn writeAll(self: Self, bytes: []const u8) anyerror!void {
var index: usize = 0;
while (index != bytes.len) {
index += try self.write(bytes[index..]);
}
}

pub fn print(self: Self, comptime format: []const u8, args: anytype) anyerror!void {
return std.fmt.format(self, format, args);
}

pub fn writeByte(self: Self, byte: u8) anyerror!void {
const array = [1]u8{byte};
return self.writeAll(&array);
}

pub fn writeByteNTimes(self: Self, byte: u8, n: usize) anyerror!void {
var bytes: [256]u8 = undefined;
@memset(bytes[0..], byte);

var remaining: usize = n;
while (remaining > 0) {
const to_write = @min(remaining, bytes.len);
try self.writeAll(bytes[0..to_write]);
remaining -= to_write;
}
}

pub fn writeBytesNTimes(self: Self, bytes: []const u8, n: usize) anyerror!void {
var i: usize = 0;
while (i < n) : (i += 1) {
try self.writeAll(bytes);
}
}

pub inline fn writeInt(self: Self, comptime T: type, value: T, endian: std.builtin.Endian) anyerror!void {
var bytes: [@divExact(@typeInfo(T).Int.bits, 8)]u8 = undefined;
mem.writeInt(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value, endian);
return self.writeAll(&bytes);
}

pub fn writeStruct(self: Self, value: anytype) anyerror!void {
// Only extern and packed structs have defined in-memory layout.
comptime assert(@typeInfo(@TypeOf(value)).Struct.layout != .Auto);
return self.writeAll(mem.asBytes(&value));
}
67 changes: 0 additions & 67 deletions lib/std/io/writer.zig

This file was deleted.

Loading