| author | |
| committer | |
| log | e392c1a0b33e69156c36234e6584be306caf16ef |
| tree | 752d92804098a096553dcaa1112634db93033a27 |
| parent | 4dfca01de4fda9a195048011b3339686dce4e936 |
This is a companion to #17344 to apply the same change to the
`std.io.Writer` interface.4 files changed, 123 insertions(+), 70 deletions(-)
CMakeLists.txt+1-1| ... | ... | @@ -265,7 +265,7 @@ set(ZIG_STAGE2_SOURCES |
| 265 | 265 | "${CMAKE_SOURCE_DIR}/lib/std/io/limited_reader.zig" |
| 266 | 266 | "${CMAKE_SOURCE_DIR}/lib/std/io/Reader.zig" |
| 267 | 267 | "${CMAKE_SOURCE_DIR}/lib/std/io/seekable_stream.zig" |
| 268 | "${CMAKE_SOURCE_DIR}/lib/std/io/writer.zig" | |
| 268 | "${CMAKE_SOURCE_DIR}/lib/std/io/Writer.zig" | |
| 269 | 269 | "${CMAKE_SOURCE_DIR}/lib/std/json.zig" |
| 270 | 270 | "${CMAKE_SOURCE_DIR}/lib/std/json/stringify.zig" |
| 271 | 271 | "${CMAKE_SOURCE_DIR}/lib/std/leb128.zig" |
lib/std/io.zig+62-2| ... | ... | @@ -333,13 +333,73 @@ pub fn GenericReader( |
| 333 | 333 | }; |
| 334 | 334 | } |
| 335 | 335 | |
| 336 | pub fn GenericWriter( | |
| 337 | comptime Context: type, | |
| 338 | comptime WriteError: type, | |
| 339 | comptime writeFn: fn (context: Context, bytes: []const u8) WriteError!usize, | |
| 340 | ) type { | |
| 341 | return struct { | |
| 342 | context: Context, | |
| 343 | ||
| 344 | const Self = @This(); | |
| 345 | pub const Error = WriteError; | |
| 346 | ||
| 347 | pub inline fn write(self: Self, bytes: []const u8) Error!usize { | |
| 348 | return writeFn(self.context, bytes); | |
| 349 | } | |
| 350 | ||
| 351 | pub inline fn writeAll(self: Self, bytes: []const u8) Error!void { | |
| 352 | return @errorCast(self.any().writeAll(bytes)); | |
| 353 | } | |
| 354 | ||
| 355 | pub inline fn print(self: Self, comptime format: []const u8, args: anytype) Error!void { | |
| 356 | return @errorCast(self.any().print(format, args)); | |
| 357 | } | |
| 358 | ||
| 359 | pub inline fn writeByte(self: Self, byte: u8) Error!void { | |
| 360 | return @errorCast(self.any().writeByte(byte)); | |
| 361 | } | |
| 362 | ||
| 363 | pub inline fn writeByteNTimes(self: Self, byte: u8, n: usize) Error!void { | |
| 364 | return @errorCast(self.any().writeByteNTimes(byte, n)); | |
| 365 | } | |
| 366 | ||
| 367 | pub inline fn writeBytesNTimes(self: Self, bytes: []const u8, n: usize) Error!void { | |
| 368 | return @errorCast(self.any().writeBytesNTimes(bytes, n)); | |
| 369 | } | |
| 370 | ||
| 371 | pub inline fn writeInt(self: Self, comptime T: type, value: T, endian: std.builtin.Endian) Error!void { | |
| 372 | return @errorCast(self.any().writeInt(T, value, endian)); | |
| 373 | } | |
| 374 | ||
| 375 | pub inline fn writeStruct(self: Self, value: anytype) Error!void { | |
| 376 | return @errorCast(self.any().writeStruct(value)); | |
| 377 | } | |
| 378 | ||
| 379 | pub inline fn any(self: *const Self) AnyWriter { | |
| 380 | return .{ | |
| 381 | .context = @ptrCast(&self.context), | |
| 382 | .writeFn = typeErasedWriteFn, | |
| 383 | }; | |
| 384 | } | |
| 385 | ||
| 386 | fn typeErasedWriteFn(context: *const anyopaque, bytes: []const u8) anyerror!usize { | |
| 387 | const ptr: *const Context = @alignCast(@ptrCast(context)); | |
| 388 | return writeFn(ptr.*, bytes); | |
| 389 | } | |
| 390 | }; | |
| 391 | } | |
| 392 | ||
| 336 | 393 | /// Deprecated; consider switching to `AnyReader` or use `GenericReader` |
| 337 | 394 | /// to use previous API. |
| 338 | 395 | pub const Reader = GenericReader; |
| 396 | /// Deprecated; consider switching to `AnyWriter` or use `GenericWriter` | |
| 397 | /// to use previous API. | |
| 398 | pub const Writer = GenericWriter; | |
| 339 | 399 | |
| 340 | 400 | pub const AnyReader = @import("io/Reader.zig"); |
| 401 | pub const AnyWriter = @import("io/Writer.zig"); | |
| 341 | 402 | |
| 342 | pub const Writer = @import("io/writer.zig").Writer; | |
| 343 | 403 | pub const SeekableStream = @import("io/seekable_stream.zig").SeekableStream; |
| 344 | 404 | |
| 345 | 405 | pub const BufferedWriter = @import("io/buffered_writer.zig").BufferedWriter; |
| ... | ... | @@ -652,6 +712,7 @@ pub fn PollFiles(comptime StreamEnum: type) type { |
| 652 | 712 | |
| 653 | 713 | test { |
| 654 | 714 | _ = AnyReader; |
| 715 | _ = AnyWriter; | |
| 655 | 716 | _ = @import("io/bit_reader.zig"); |
| 656 | 717 | _ = @import("io/bit_writer.zig"); |
| 657 | 718 | _ = @import("io/buffered_atomic_file.zig"); |
| ... | ... | @@ -661,7 +722,6 @@ test { |
| 661 | 722 | _ = @import("io/counting_writer.zig"); |
| 662 | 723 | _ = @import("io/counting_reader.zig"); |
| 663 | 724 | _ = @import("io/fixed_buffer_stream.zig"); |
| 664 | _ = @import("io/writer.zig"); | |
| 665 | 725 | _ = @import("io/peek_stream.zig"); |
| 666 | 726 | _ = @import("io/seekable_stream.zig"); |
| 667 | 727 | _ = @import("io/stream_source.zig"); |
lib/std/io/Writer.zig created+60| ... | ... | @@ -0,0 +1,60 @@ |
| 1 | const std = @import("../std.zig"); | |
| 2 | const assert = std.debug.assert; | |
| 3 | const mem = std.mem; | |
| 4 | ||
| 5 | context: *const anyopaque, | |
| 6 | writeFn: *const fn (context: *const anyopaque, bytes: []const u8) anyerror!usize, | |
| 7 | ||
| 8 | const Self = @This(); | |
| 9 | pub const Error = anyerror; | |
| 10 | ||
| 11 | pub fn write(self: Self, bytes: []const u8) anyerror!usize { | |
| 12 | return self.writeFn(self.context, bytes); | |
| 13 | } | |
| 14 | ||
| 15 | pub fn writeAll(self: Self, bytes: []const u8) anyerror!void { | |
| 16 | var index: usize = 0; | |
| 17 | while (index != bytes.len) { | |
| 18 | index += try self.write(bytes[index..]); | |
| 19 | } | |
| 20 | } | |
| 21 | ||
| 22 | pub fn print(self: Self, comptime format: []const u8, args: anytype) anyerror!void { | |
| 23 | return std.fmt.format(self, format, args); | |
| 24 | } | |
| 25 | ||
| 26 | pub fn writeByte(self: Self, byte: u8) anyerror!void { | |
| 27 | const array = [1]u8{byte}; | |
| 28 | return self.writeAll(&array); | |
| 29 | } | |
| 30 | ||
| 31 | pub fn writeByteNTimes(self: Self, byte: u8, n: usize) anyerror!void { | |
| 32 | var bytes: [256]u8 = undefined; | |
| 33 | @memset(bytes[0..], byte); | |
| 34 | ||
| 35 | var remaining: usize = n; | |
| 36 | while (remaining > 0) { | |
| 37 | const to_write = @min(remaining, bytes.len); | |
| 38 | try self.writeAll(bytes[0..to_write]); | |
| 39 | remaining -= to_write; | |
| 40 | } | |
| 41 | } | |
| 42 | ||
| 43 | pub fn writeBytesNTimes(self: Self, bytes: []const u8, n: usize) anyerror!void { | |
| 44 | var i: usize = 0; | |
| 45 | while (i < n) : (i += 1) { | |
| 46 | try self.writeAll(bytes); | |
| 47 | } | |
| 48 | } | |
| 49 | ||
| 50 | pub inline fn writeInt(self: Self, comptime T: type, value: T, endian: std.builtin.Endian) anyerror!void { | |
| 51 | var bytes: [@divExact(@typeInfo(T).Int.bits, 8)]u8 = undefined; | |
| 52 | mem.writeInt(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value, endian); | |
| 53 | return self.writeAll(&bytes); | |
| 54 | } | |
| 55 | ||
| 56 | pub fn writeStruct(self: Self, value: anytype) anyerror!void { | |
| 57 | // Only extern and packed structs have defined in-memory layout. | |
| 58 | comptime assert(@typeInfo(@TypeOf(value)).Struct.layout != .Auto); | |
| 59 | return self.writeAll(mem.asBytes(&value)); | |
| 60 | } |
lib/std/io/writer.zig deleted-67| ... | ... | @@ -1,67 +0,0 @@ |
| 1 | const std = @import("../std.zig"); | |
| 2 | const assert = std.debug.assert; | |
| 3 | const mem = std.mem; | |
| 4 | ||
| 5 | pub fn Writer( | |
| 6 | comptime Context: type, | |
| 7 | comptime WriteError: type, | |
| 8 | comptime writeFn: fn (context: Context, bytes: []const u8) WriteError!usize, | |
| 9 | ) type { | |
| 10 | return struct { | |
| 11 | context: Context, | |
| 12 | ||
| 13 | const Self = @This(); | |
| 14 | pub const Error = WriteError; | |
| 15 | ||
| 16 | pub fn write(self: Self, bytes: []const u8) Error!usize { | |
| 17 | return writeFn(self.context, bytes); | |
| 18 | } | |
| 19 | ||
| 20 | pub fn writeAll(self: Self, bytes: []const u8) Error!void { | |
| 21 | var index: usize = 0; | |
| 22 | while (index != bytes.len) { | |
| 23 | index += try self.write(bytes[index..]); | |
| 24 | } | |
| 25 | } | |
| 26 | ||
| 27 | pub fn print(self: Self, comptime format: []const u8, args: anytype) Error!void { | |
| 28 | return std.fmt.format(self, format, args); | |
| 29 | } | |
| 30 | ||
| 31 | pub fn writeByte(self: Self, byte: u8) Error!void { | |
| 32 | const array = [1]u8{byte}; | |
| 33 | return self.writeAll(&array); | |
| 34 | } | |
| 35 | ||
| 36 | pub fn writeByteNTimes(self: Self, byte: u8, n: usize) Error!void { | |
| 37 | var bytes: [256]u8 = undefined; | |
| 38 | @memset(bytes[0..], byte); | |
| 39 | ||
| 40 | var remaining: usize = n; | |
| 41 | while (remaining > 0) { | |
| 42 | const to_write = @min(remaining, bytes.len); | |
| 43 | try self.writeAll(bytes[0..to_write]); | |
| 44 | remaining -= to_write; | |
| 45 | } | |
| 46 | } | |
| 47 | ||
| 48 | pub fn writeBytesNTimes(self: Self, bytes: []const u8, n: usize) Error!void { | |
| 49 | var i: usize = 0; | |
| 50 | while (i < n) : (i += 1) { | |
| 51 | try self.writeAll(bytes); | |
| 52 | } | |
| 53 | } | |
| 54 | ||
| 55 | pub inline fn writeInt(self: Self, comptime T: type, value: T, endian: std.builtin.Endian) Error!void { | |
| 56 | var bytes: [@divExact(@typeInfo(T).Int.bits, 8)]u8 = undefined; | |
| 57 | mem.writeInt(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value, endian); | |
| 58 | return self.writeAll(&bytes); | |
| 59 | } | |
| 60 | ||
| 61 | pub fn writeStruct(self: Self, value: anytype) Error!void { | |
| 62 | // Only extern and packed structs have defined in-memory layout. | |
| 63 | comptime assert(@typeInfo(@TypeOf(value)).Struct.layout != .Auto); | |
| 64 | return self.writeAll(mem.asBytes(&value)); | |
| 65 | } | |
| 66 | }; | |
| 67 | } |