| ... | @@ -1,4 +1,12 @@ | ... | @@ -1,4 +1,12 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| | 2 | const builtin = @import("builtin"); |
| | 3 | const extras = @import("extras"); |
| | 4 | const sys_linux = @import("sys-linux"); |
| | 5 | |
| | 6 | const sys = switch (builtin.target.os.tag) { |
| | 7 | .linux => sys_linux, |
| | 8 | else => unreachable, |
| | 9 | }; |
| 2 | | 10 | |
| 3 | pub fn Readable(T: type, this_kind: enum { _var, _const, _bare }) type { | 11 | pub fn Readable(T: type, this_kind: enum { _var, _const, _bare }) type { |
| 4 | return struct { | 12 | return struct { |
| ... | @@ -132,6 +140,9 @@ pub fn Writable(T: type, this_kind: enum { _var, _const, _bare }) type { | ... | @@ -132,6 +140,9 @@ pub fn Writable(T: type, this_kind: enum { _var, _const, _bare }) type { |
| 132 | // pub fn write(self: Self, bytes: []const u8) Error!usize { | 140 | // pub fn write(self: Self, bytes: []const u8) Error!usize { |
| 133 | // } | 141 | // } |
| 134 | | 142 | |
| | 143 | // pub fn writev(self: Self, iovec: []const sys.struct_iovec) Error!usize { |
| | 144 | // } |
| | 145 | |
| 135 | pub fn writeAll(self: Self, bytes: []const u8) Error!void { | 146 | pub fn writeAll(self: Self, bytes: []const u8) Error!void { |
| 136 | var index: usize = 0; | 147 | var index: usize = 0; |
| 137 | while (index != bytes.len) { | 148 | while (index != bytes.len) { |
| ... | @@ -139,6 +150,38 @@ pub fn Writable(T: type, this_kind: enum { _var, _const, _bare }) type { | ... | @@ -139,6 +150,38 @@ pub fn Writable(T: type, this_kind: enum { _var, _const, _bare }) type { |
| 139 | } | 150 | } |
| 140 | } | 151 | } |
| 141 | | 152 | |
| | 153 | pub fn writevAll(self: Self, bytes: []const []const u8) Error!void { |
| | 154 | var iovec: [1024]sys.struct_iovec = undefined; |
| | 155 | for (bytes, 0..) |slice, i| iovec[i] = .{ .base = @constCast(slice.ptr), .len = slice.len }; |
| | 156 | var left: usize = 0; |
| | 157 | for (bytes) |item| left += item.len; |
| | 158 | |
| | 159 | while (left > 0) { |
| | 160 | var written: usize = try self.writev(&iovec); |
| | 161 | left -= written; |
| | 162 | for (iovec[0..bytes.len], 0..) |vec, i| { |
| | 163 | switch (std.math.order(written, vec.len)) { |
| | 164 | .gt => { |
| | 165 | written -= iovec[i].len; |
| | 166 | iovec[i].len = 0; |
| | 167 | continue; |
| | 168 | }, |
| | 169 | .eq => { |
| | 170 | written -= iovec[i].len; |
| | 171 | iovec[i].len = 0; |
| | 172 | break; |
| | 173 | }, |
| | 174 | .lt => { |
| | 175 | iovec[i].base += written; |
| | 176 | iovec[i].len -= written; |
| | 177 | written -= written; |
| | 178 | }, |
| | 179 | } |
| | 180 | } |
| | 181 | std.debug.assert(written == 0); |
| | 182 | } |
| | 183 | } |
| | 184 | |
| 142 | pub fn writeByteNTimes(self: Self, byte: u8, n: usize) Error!void { | 185 | pub fn writeByteNTimes(self: Self, byte: u8, n: usize) Error!void { |
| 143 | var bytes: [1024]u8 = undefined; | 186 | var bytes: [1024]u8 = undefined; |
| 144 | @memset(bytes[0..], byte); | 187 | @memset(bytes[0..], byte); |
| ... | @@ -150,6 +193,16 @@ pub fn Writable(T: type, this_kind: enum { _var, _const, _bare }) type { | ... | @@ -150,6 +193,16 @@ pub fn Writable(T: type, this_kind: enum { _var, _const, _bare }) type { |
| 150 | } | 193 | } |
| 151 | } | 194 | } |
| 152 | | 195 | |
| | 196 | pub fn writeNTimes(self: Self, input: []const u8, n: usize) Error!void { |
| | 197 | var bytes: [1024][]const u8 = @splat(input); |
| | 198 | var remaining: usize = n; |
| | 199 | while (remaining > 0) { |
| | 200 | const to_write = @min(remaining, bytes.len); |
| | 201 | try writevAll(self, bytes[0..n]); |
| | 202 | remaining -= to_write; |
| | 203 | } |
| | 204 | } |
| | 205 | |
| 153 | pub fn writeInt(self: Self, comptime I: type, value: I, endian: std.builtin.Endian) Error!void { | 206 | pub fn writeInt(self: Self, comptime I: type, value: I, endian: std.builtin.Endian) Error!void { |
| 154 | var bytes: [@as(u16, @intCast((@as(u17, @typeInfo(I).Int.bits) + 7) / 8))]u8 = undefined; | 207 | var bytes: [@as(u16, @intCast((@as(u17, @typeInfo(I).Int.bits) + 7) / 8))]u8 = undefined; |
| 155 | std.mem.writeInt(std.math.ByteAlignedInt(I), &bytes, value, endian); | 208 | std.mem.writeInt(std.math.ByteAlignedInt(I), &bytes, value, endian); |