2019-10-30 02:59:30 +00:00
|
|
|
const std = @import("../std.zig");
|
|
|
|
const builtin = @import("builtin");
|
|
|
|
const root = @import("root");
|
|
|
|
const mem = std.mem;
|
|
|
|
|
|
|
|
pub const default_stack_size = 1 * 1024 * 1024;
|
|
|
|
pub const stack_size: usize = if (@hasDecl(root, "stack_size_std_io_OutStream"))
|
|
|
|
root.stack_size_std_io_OutStream
|
|
|
|
else
|
|
|
|
default_stack_size;
|
|
|
|
|
|
|
|
pub fn OutStream(comptime WriteError: type) type {
|
|
|
|
return struct {
|
|
|
|
const Self = @This();
|
|
|
|
pub const Error = WriteError;
|
2020-02-06 22:56:40 +00:00
|
|
|
pub const WriteFn = if (std.io.is_async)
|
2019-10-30 02:59:30 +00:00
|
|
|
async fn (self: *Self, bytes: []const u8) Error!void
|
|
|
|
else
|
|
|
|
fn (self: *Self, bytes: []const u8) Error!void;
|
|
|
|
|
|
|
|
writeFn: WriteFn,
|
|
|
|
|
|
|
|
pub fn write(self: *Self, bytes: []const u8) Error!void {
|
2020-02-06 22:56:40 +00:00
|
|
|
if (std.io.is_async) {
|
2019-10-30 02:59:30 +00:00
|
|
|
// Let's not be writing 0xaa in safe modes for upwards of 4 MiB for every stream write.
|
|
|
|
@setRuntimeSafety(false);
|
|
|
|
var stack_frame: [stack_size]u8 align(std.Target.stack_align) = undefined;
|
|
|
|
return await @asyncCall(&stack_frame, {}, self.writeFn, self, bytes);
|
|
|
|
} else {
|
|
|
|
return self.writeFn(self, bytes);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-09 03:53:51 +00:00
|
|
|
pub fn print(self: *Self, comptime format: []const u8, args: var) Error!void {
|
2020-02-05 21:52:18 +00:00
|
|
|
return std.fmt.format(self, Error, write, format, args);
|
2019-10-30 02:59:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn writeByte(self: *Self, byte: u8) Error!void {
|
2020-02-06 22:56:40 +00:00
|
|
|
const array = [1]u8{byte};
|
|
|
|
return self.write(&array);
|
2019-10-30 02:59:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn writeByteNTimes(self: *Self, byte: u8, n: usize) Error!void {
|
2020-01-21 19:58:02 +00:00
|
|
|
var bytes: [256]u8 = undefined;
|
|
|
|
mem.set(u8, bytes[0..], byte);
|
|
|
|
|
|
|
|
var remaining: usize = n;
|
|
|
|
while (remaining > 0) {
|
|
|
|
const to_write = std.math.min(remaining, bytes.len);
|
2020-02-06 22:56:40 +00:00
|
|
|
try self.write(bytes[0..to_write]);
|
2020-01-21 19:58:02 +00:00
|
|
|
remaining -= to_write;
|
2019-10-30 02:59:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a native-endian integer.
|
|
|
|
pub fn writeIntNative(self: *Self, comptime T: type, value: T) Error!void {
|
|
|
|
var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
|
|
|
|
mem.writeIntNative(T, &bytes, value);
|
2020-02-06 22:56:40 +00:00
|
|
|
return self.write(&bytes);
|
2019-10-30 02:59:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Write a foreign-endian integer.
|
|
|
|
pub fn writeIntForeign(self: *Self, comptime T: type, value: T) Error!void {
|
|
|
|
var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
|
|
|
|
mem.writeIntForeign(T, &bytes, value);
|
2020-02-06 22:56:40 +00:00
|
|
|
return self.write(&bytes);
|
2019-10-30 02:59:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn writeIntLittle(self: *Self, comptime T: type, value: T) Error!void {
|
|
|
|
var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
|
|
|
|
mem.writeIntLittle(T, &bytes, value);
|
2020-02-06 22:56:40 +00:00
|
|
|
return self.write(&bytes);
|
2019-10-30 02:59:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn writeIntBig(self: *Self, comptime T: type, value: T) Error!void {
|
|
|
|
var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
|
|
|
|
mem.writeIntBig(T, &bytes, value);
|
2020-02-06 22:56:40 +00:00
|
|
|
return self.write(&bytes);
|
2019-10-30 02:59:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn writeInt(self: *Self, comptime T: type, value: T, endian: builtin.Endian) Error!void {
|
|
|
|
var bytes: [(T.bit_count + 7) / 8]u8 = undefined;
|
|
|
|
mem.writeInt(T, &bytes, value, endian);
|
2020-02-06 22:56:40 +00:00
|
|
|
return self.write(&bytes);
|
2019-10-30 02:59:30 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|