| ... | ... | @@ -1,4 +1,12 @@ |
| 1 | 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 | 11 | pub fn Readable(T: type, this_kind: enum { _var, _const, _bare }) type { |
| 4 | 12 | return struct { |
| ... | ... | @@ -132,6 +140,9 @@ pub fn Writable(T: type, this_kind: enum { _var, _const, _bare }) type { |
| 132 | 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 | 146 | pub fn writeAll(self: Self, bytes: []const u8) Error!void { |
| 136 | 147 | var index: usize = 0; |
| 137 | 148 | while (index != bytes.len) { |
| ... | ... | @@ -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 | 185 | pub fn writeByteNTimes(self: Self, byte: u8, n: usize) Error!void { |
| 143 | 186 | var bytes: [1024]u8 = undefined; |
| 144 | 187 | @memset(bytes[0..], byte); |
| ... | ... | @@ -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 | 206 | pub fn writeInt(self: Self, comptime I: type, value: I, endian: std.builtin.Endian) Error!void { |
| 154 | 207 | var bytes: [@as(u16, @intCast((@as(u17, @typeInfo(I).Int.bits) + 7) / 8))]u8 = undefined; |
| 155 | 208 | std.mem.writeInt(std.math.ByteAlignedInt(I), &bytes, value, endian); |