| ... | @@ -19,6 +19,10 @@ buffer: std.ArrayListUnmanaged(u8), | ... | @@ -19,6 +19,10 @@ buffer: std.ArrayListUnmanaged(u8), |
| 19 | /// equals number of bytes provided. This property is exploited by | 19 | /// equals number of bytes provided. This property is exploited by |
| 20 | /// `std.io.AllocatingWriter` for example. | 20 | /// `std.io.AllocatingWriter` for example. |
| 21 | unbuffered_writer: Writer, | 21 | unbuffered_writer: Writer, |
| | 22 | /// Tracks total number of bytes written to this `BufferedWriter`. This value |
| | 23 | /// only increases. In the case of fixed mode, this value always equals |
| | 24 | /// `buffer.items.len`. |
| | 25 | bytes_written: usize = 0, |
| 22 | | 26 | |
| 23 | /// Number of slices to store on the stack, when trying to send as many byte | 27 | /// Number of slices to store on the stack, when trying to send as many byte |
| 24 | /// vectors through the underlying write calls as possible. | 28 | /// vectors through the underlying write calls as possible. |
| ... | @@ -106,6 +110,7 @@ pub fn advance(bw: *BufferedWriter, n: usize) void { | ... | @@ -106,6 +110,7 @@ pub fn advance(bw: *BufferedWriter, n: usize) void { |
| 106 | const list = &bw.buffer; | 110 | const list = &bw.buffer; |
| 107 | list.items.len += n; | 111 | list.items.len += n; |
| 108 | assert(list.items.len <= list.capacity); | 112 | assert(list.items.len <= list.capacity); |
| | 113 | bw.bytes_written += n; |
| 109 | } | 114 | } |
| 110 | | 115 | |
| 111 | /// The `data` parameter is mutable because this function needs to mutate the | 116 | /// The `data` parameter is mutable because this function needs to mutate the |
| ... | @@ -114,8 +119,9 @@ pub fn writevAll(bw: *BufferedWriter, data: [][]const u8) anyerror!void { | ... | @@ -114,8 +119,9 @@ pub fn writevAll(bw: *BufferedWriter, data: [][]const u8) anyerror!void { |
| 114 | var i: usize = 0; | 119 | var i: usize = 0; |
| 115 | while (true) { | 120 | while (true) { |
| 116 | var n = try passthru_writeSplat(bw, data[i..], 1); | 121 | var n = try passthru_writeSplat(bw, data[i..], 1); |
| 117 | while (n >= data[i].len) { | 122 | const len = data[i].len; |
| 118 | n -= data[i].len; | 123 | while (n >= len) { |
| | 124 | n -= len; |
| 119 | i += 1; | 125 | i += 1; |
| 120 | if (i >= data.len) return; | 126 | if (i >= data.len) return; |
| 121 | } | 127 | } |
| ... | @@ -147,7 +153,7 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us | ... | @@ -147,7 +153,7 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us |
| 147 | end = new_end; | 153 | end = new_end; |
| 148 | continue; | 154 | continue; |
| 149 | } | 155 | } |
| 150 | if (end == 0) return bw.unbuffered_writer.writeSplat(data, splat); | 156 | if (end == 0) return track(&bw.bytes_written, try bw.unbuffered_writer.writeSplat(data, splat)); |
| 151 | buffers[0] = buffer[0..end]; | 157 | buffers[0] = buffer[0..end]; |
| 152 | const remaining_data = data[i..]; | 158 | const remaining_data = data[i..]; |
| 153 | const remaining_buffers = buffers[1..]; | 159 | const remaining_buffers = buffers[1..]; |
| ... | @@ -163,10 +169,10 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us | ... | @@ -163,10 +169,10 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us |
| 163 | const remainder = buffer[n..end]; | 169 | const remainder = buffer[n..end]; |
| 164 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); | 170 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); |
| 165 | list.items.len = remainder.len; | 171 | list.items.len = remainder.len; |
| 166 | return end - start_end; | 172 | return track(&bw.bytes_written, end - start_end); |
| 167 | } | 173 | } |
| 168 | list.items.len = 0; | 174 | list.items.len = 0; |
| 169 | return n - start_end; | 175 | return track(&bw.bytes_written, n - start_end); |
| 170 | } | 176 | } |
| 171 | const n = try bw.unbuffered_writer.writeSplat(send_buffers, 1); | 177 | const n = try bw.unbuffered_writer.writeSplat(send_buffers, 1); |
| 172 | if (n < end) { | 178 | if (n < end) { |
| ... | @@ -174,10 +180,10 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us | ... | @@ -174,10 +180,10 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us |
| 174 | const remainder = buffer[n..end]; | 180 | const remainder = buffer[n..end]; |
| 175 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); | 181 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); |
| 176 | list.items.len = remainder.len; | 182 | list.items.len = remainder.len; |
| 177 | return end - start_end; | 183 | return track(&bw.bytes_written, end - start_end); |
| 178 | } | 184 | } |
| 179 | list.items.len = 0; | 185 | list.items.len = 0; |
| 180 | return n - start_end; | 186 | return track(&bw.bytes_written, n - start_end); |
| 181 | } | 187 | } |
| 182 | | 188 | |
| 183 | const pattern = data[data.len - 1]; | 189 | const pattern = data[data.len - 1]; |
| ... | @@ -187,7 +193,7 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us | ... | @@ -187,7 +193,7 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us |
| 187 | // It was added in the loop above; undo it here. | 193 | // It was added in the loop above; undo it here. |
| 188 | end -= pattern.len; | 194 | end -= pattern.len; |
| 189 | list.items.len = end; | 195 | list.items.len = end; |
| 190 | return end - start_end; | 196 | return track(&bw.bytes_written, end - start_end); |
| 191 | } | 197 | } |
| 192 | | 198 | |
| 193 | const remaining_splat = splat - 1; | 199 | const remaining_splat = splat - 1; |
| ... | @@ -195,7 +201,7 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us | ... | @@ -195,7 +201,7 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us |
| 195 | switch (pattern.len) { | 201 | switch (pattern.len) { |
| 196 | 0 => { | 202 | 0 => { |
| 197 | list.items.len = end; | 203 | list.items.len = end; |
| 198 | return end - start_end; | 204 | return track(&bw.bytes_written, end - start_end); |
| 199 | }, | 205 | }, |
| 200 | 1 => { | 206 | 1 => { |
| 201 | const new_end = end + remaining_splat; | 207 | const new_end = end + remaining_splat; |
| ... | @@ -203,7 +209,7 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us | ... | @@ -203,7 +209,7 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us |
| 203 | @branchHint(.likely); | 209 | @branchHint(.likely); |
| 204 | @memset(buffer[end..new_end], pattern[0]); | 210 | @memset(buffer[end..new_end], pattern[0]); |
| 205 | list.items.len = new_end; | 211 | list.items.len = new_end; |
| 206 | return new_end - start_end; | 212 | return track(&bw.bytes_written, new_end - start_end); |
| 207 | } | 213 | } |
| 208 | buffers[0] = buffer[0..end]; | 214 | buffers[0] = buffer[0..end]; |
| 209 | buffers[1] = pattern; | 215 | buffers[1] = pattern; |
| ... | @@ -213,10 +219,10 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us | ... | @@ -213,10 +219,10 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us |
| 213 | const remainder = buffer[n..end]; | 219 | const remainder = buffer[n..end]; |
| 214 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); | 220 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); |
| 215 | list.items.len = remainder.len; | 221 | list.items.len = remainder.len; |
| 216 | return end - start_end; | 222 | return track(&bw.bytes_written, end - start_end); |
| 217 | } | 223 | } |
| 218 | list.items.len = 0; | 224 | list.items.len = 0; |
| 219 | return n - start_end; | 225 | return track(&bw.bytes_written, n - start_end); |
| 220 | }, | 226 | }, |
| 221 | else => { | 227 | else => { |
| 222 | const new_end = end + pattern.len * remaining_splat; | 228 | const new_end = end + pattern.len * remaining_splat; |
| ... | @@ -226,7 +232,7 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us | ... | @@ -226,7 +232,7 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us |
| 226 | @memcpy(buffer[end..][0..pattern.len], pattern); | 232 | @memcpy(buffer[end..][0..pattern.len], pattern); |
| 227 | } | 233 | } |
| 228 | list.items.len = new_end; | 234 | list.items.len = new_end; |
| 229 | return new_end - start_end; | 235 | return track(&bw.bytes_written, new_end - start_end); |
| 230 | } | 236 | } |
| 231 | buffers[0] = buffer[0..end]; | 237 | buffers[0] = buffer[0..end]; |
| 232 | buffers[1] = pattern; | 238 | buffers[1] = pattern; |
| ... | @@ -236,14 +242,19 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us | ... | @@ -236,14 +242,19 @@ fn passthru_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: us |
| 236 | const remainder = buffer[n..end]; | 242 | const remainder = buffer[n..end]; |
| 237 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); | 243 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); |
| 238 | list.items.len = remainder.len; | 244 | list.items.len = remainder.len; |
| 239 | return end - start_end; | 245 | return track(&bw.bytes_written, end - start_end); |
| 240 | } | 246 | } |
| 241 | list.items.len = 0; | 247 | list.items.len = 0; |
| 242 | return n - start_end; | 248 | return track(&bw.bytes_written, n - start_end); |
| 243 | }, | 249 | }, |
| 244 | } | 250 | } |
| 245 | } | 251 | } |
| 246 | | 252 | |
| | 253 | fn track(bytes_written: *usize, n: usize) usize { |
| | 254 | bytes_written.* += n; |
| | 255 | return n; |
| | 256 | } |
| | 257 | |
| 247 | /// When this function is called it means the buffer got full, so it's time | 258 | /// When this function is called it means the buffer got full, so it's time |
| 248 | /// to return an error. However, we still need to make sure all of the | 259 | /// to return an error. However, we still need to make sure all of the |
| 249 | /// available buffer has been filled. | 260 | /// available buffer has been filled. |
| ... | @@ -256,6 +267,7 @@ fn fixed_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize | ... | @@ -256,6 +267,7 @@ fn fixed_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize |
| 256 | const len = @min(bytes.len, dest.len); | 267 | const len = @min(bytes.len, dest.len); |
| 257 | @memcpy(dest[0..len], bytes[0..len]); | 268 | @memcpy(dest[0..len], bytes[0..len]); |
| 258 | list.items.len += len; | 269 | list.items.len += len; |
| | 270 | bw.bytes_written = list.items.len; |
| 259 | } | 271 | } |
| 260 | const pattern = data[data.len - 1]; | 272 | const pattern = data[data.len - 1]; |
| 261 | const dest = list.unusedCapacitySlice(); | 273 | const dest = list.unusedCapacitySlice(); |
| ... | @@ -265,6 +277,7 @@ fn fixed_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize | ... | @@ -265,6 +277,7 @@ fn fixed_writeSplat(context: ?*anyopaque, data: []const []const u8, splat: usize |
| 265 | else => for (0..splat - 1) |i| @memcpy(dest[i * pattern.len ..][0..pattern.len], pattern), | 277 | else => for (0..splat - 1) |i| @memcpy(dest[i * pattern.len ..][0..pattern.len], pattern), |
| 266 | } | 278 | } |
| 267 | list.items.len = list.capacity; | 279 | list.items.len = list.capacity; |
| | 280 | bw.bytes_written = list.items.len; |
| 268 | return error.NoSpaceLeft; | 281 | return error.NoSpaceLeft; |
| 269 | } | 282 | } |
| 270 | | 283 | |
| ... | @@ -284,17 +297,11 @@ pub fn write(bw: *BufferedWriter, bytes: []const u8) anyerror!usize { | ... | @@ -284,17 +297,11 @@ pub fn write(bw: *BufferedWriter, bytes: []const u8) anyerror!usize { |
| 284 | return 0; | 297 | return 0; |
| 285 | } | 298 | } |
| 286 | list.items.len = 0; | 299 | list.items.len = 0; |
| 287 | return n - end; | 300 | return track(&bw.bytes_written, n - end); |
| 288 | } | 301 | } |
| 289 | @memcpy(buffer[end..new_end], bytes); | 302 | @memcpy(buffer[end..new_end], bytes); |
| 290 | list.items.len = new_end; | 303 | list.items.len = new_end; |
| 291 | return bytes.len; | 304 | return track(&bw.bytes_written, bytes.len); |
| 292 | } | | |
| 293 | | | |
| 294 | /// Convenience function that calls `writeAll` and then returns `bytes.len`. | | |
| 295 | pub fn writeAllCount(bw: *BufferedWriter, bytes: []const u8) anyerror!usize { | | |
| 296 | try writeAll(bw, bytes); | | |
| 297 | return bytes.len; | | |
| 298 | } | 305 | } |
| 299 | | 306 | |
| 300 | /// Calls `write` as many times as necessary such that all of `bytes` are | 307 | /// Calls `write` as many times as necessary such that all of `bytes` are |
| ... | @@ -305,17 +312,7 @@ pub fn writeAll(bw: *BufferedWriter, bytes: []const u8) anyerror!void { | ... | @@ -305,17 +312,7 @@ pub fn writeAll(bw: *BufferedWriter, bytes: []const u8) anyerror!void { |
| 305 | } | 312 | } |
| 306 | | 313 | |
| 307 | pub fn print(bw: *BufferedWriter, comptime format: []const u8, args: anytype) anyerror!void { | 314 | pub fn print(bw: *BufferedWriter, comptime format: []const u8, args: anytype) anyerror!void { |
| 308 | _ = try std.fmt.format(bw, format, args); | 315 | try std.fmt.format(bw, format, args); |
| 309 | } | | |
| 310 | | | |
| 311 | pub fn printCount(bw: *BufferedWriter, comptime format: []const u8, args: anytype) anyerror!usize { | | |
| 312 | return std.fmt.format(bw, format, args); | | |
| 313 | } | | |
| 314 | | | |
| 315 | /// Returns 0 or 1 indicating how many bytes were written. | | |
| 316 | pub fn writeByteCount(bw: *BufferedWriter, byte: u8) anyerror!usize { | | |
| 317 | try writeByte(bw, byte); | | |
| 318 | return 1; | | |
| 319 | } | 316 | } |
| 320 | | 317 | |
| 321 | pub fn writeByte(bw: *BufferedWriter, byte: u8) anyerror!void { | 318 | pub fn writeByte(bw: *BufferedWriter, byte: u8) anyerror!void { |
| ... | @@ -325,6 +322,7 @@ pub fn writeByte(bw: *BufferedWriter, byte: u8) anyerror!void { | ... | @@ -325,6 +322,7 @@ pub fn writeByte(bw: *BufferedWriter, byte: u8) anyerror!void { |
| 325 | @branchHint(.likely); | 322 | @branchHint(.likely); |
| 326 | buffer.ptr[buffer.len] = byte; | 323 | buffer.ptr[buffer.len] = byte; |
| 327 | list.items.len = buffer.len + 1; | 324 | list.items.len = buffer.len + 1; |
| | 325 | bw.bytes_written += 1; |
| 328 | return; | 326 | return; |
| 329 | } | 327 | } |
| 330 | var buffers: [2][]const u8 = .{ buffer, &.{byte} }; | 328 | var buffers: [2][]const u8 = .{ buffer, &.{byte} }; |
| ... | @@ -333,7 +331,9 @@ pub fn writeByte(bw: *BufferedWriter, byte: u8) anyerror!void { | ... | @@ -333,7 +331,9 @@ pub fn writeByte(bw: *BufferedWriter, byte: u8) anyerror!void { |
| 333 | if (n == 0) { | 331 | if (n == 0) { |
| 334 | @branchHint(.unlikely); | 332 | @branchHint(.unlikely); |
| 335 | continue; | 333 | continue; |
| 336 | } else if (n >= buffer.len) { | 334 | } |
| | 335 | bw.bytes_written += 1; |
| | 336 | if (n >= buffer.len) { |
| 337 | @branchHint(.likely); | 337 | @branchHint(.likely); |
| 338 | if (n > buffer.len) { | 338 | if (n > buffer.len) { |
| 339 | @branchHint(.likely); | 339 | @branchHint(.likely); |
| ... | @@ -353,12 +353,6 @@ pub fn writeByte(bw: *BufferedWriter, byte: u8) anyerror!void { | ... | @@ -353,12 +353,6 @@ pub fn writeByte(bw: *BufferedWriter, byte: u8) anyerror!void { |
| 353 | } | 353 | } |
| 354 | } | 354 | } |
| 355 | | 355 | |
| 356 | /// Convenience function that calls `splatByteAll` and then returns `n`. | | |
| 357 | pub fn splatByteAllCount(bw: *BufferedWriter, byte: u8, n: usize) anyerror!usize { | | |
| 358 | try splatByteAll(bw, byte, n); | | |
| 359 | return n; | | |
| 360 | } | | |
| 361 | | | |
| 362 | /// Writes the same byte many times, performing the underlying write call as | 356 | /// Writes the same byte many times, performing the underlying write call as |
| 363 | /// many times as necessary. | 357 | /// many times as necessary. |
| 364 | pub fn splatByteAll(bw: *BufferedWriter, byte: u8, n: usize) anyerror!void { | 358 | pub fn splatByteAll(bw: *BufferedWriter, byte: u8, n: usize) anyerror!void { |
| ... | @@ -438,7 +432,10 @@ fn passthru_writeFile( | ... | @@ -438,7 +432,10 @@ fn passthru_writeFile( |
| 438 | const bw: *BufferedWriter = @alignCast(@ptrCast(context)); | 432 | const bw: *BufferedWriter = @alignCast(@ptrCast(context)); |
| 439 | const list = &bw.buffer; | 433 | const list = &bw.buffer; |
| 440 | const buffer = list.allocatedSlice(); | 434 | const buffer = list.allocatedSlice(); |
| 441 | if (buffer.len == 0) return bw.unbuffered_writer.writeFile(file, offset, len, headers_and_trailers, headers_len); | 435 | if (buffer.len == 0) return track( |
| | 436 | &bw.bytes_written, |
| | 437 | try bw.unbuffered_writer.writeFile(file, offset, len, headers_and_trailers, headers_len), |
| | 438 | ); |
| 442 | const start_end = list.items.len; | 439 | const start_end = list.items.len; |
| 443 | const headers = headers_and_trailers[0..headers_len]; | 440 | const headers = headers_and_trailers[0..headers_len]; |
| 444 | const trailers = headers_and_trailers[headers_len..]; | 441 | const trailers = headers_and_trailers[headers_len..]; |
| ... | @@ -470,10 +467,10 @@ fn passthru_writeFile( | ... | @@ -470,10 +467,10 @@ fn passthru_writeFile( |
| 470 | const remainder = buffer[n..end]; | 467 | const remainder = buffer[n..end]; |
| 471 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); | 468 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); |
| 472 | list.items.len = remainder.len; | 469 | list.items.len = remainder.len; |
| 473 | return end - start_end; | 470 | return track(&bw.bytes_written, end - start_end); |
| 474 | } | 471 | } |
| 475 | list.items.len = 0; | 472 | list.items.len = 0; |
| 476 | return n - start_end; | 473 | return track(&bw.bytes_written, n - start_end); |
| 477 | } | 474 | } |
| 478 | // Have not made it past the headers yet; must call `writev`. | 475 | // Have not made it past the headers yet; must call `writev`. |
| 479 | const n = try bw.unbuffered_writer.writev(buffers[0 .. buffers_len + 1]); | 476 | const n = try bw.unbuffered_writer.writev(buffers[0 .. buffers_len + 1]); |
| ... | @@ -482,10 +479,10 @@ fn passthru_writeFile( | ... | @@ -482,10 +479,10 @@ fn passthru_writeFile( |
| 482 | const remainder = buffer[n..end]; | 479 | const remainder = buffer[n..end]; |
| 483 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); | 480 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); |
| 484 | list.items.len = remainder.len; | 481 | list.items.len = remainder.len; |
| 485 | return end - start_end; | 482 | return track(&bw.bytes_written, end - start_end); |
| 486 | } | 483 | } |
| 487 | list.items.len = 0; | 484 | list.items.len = 0; |
| 488 | return n - start_end; | 485 | return track(&bw.bytes_written, n - start_end); |
| 489 | } | 486 | } |
| 490 | // All headers written to buffer. | 487 | // All headers written to buffer. |
| 491 | buffers[0] = buffer[0..end]; | 488 | buffers[0] = buffer[0..end]; |
| ... | @@ -500,10 +497,10 @@ fn passthru_writeFile( | ... | @@ -500,10 +497,10 @@ fn passthru_writeFile( |
| 500 | const remainder = buffer[n..end]; | 497 | const remainder = buffer[n..end]; |
| 501 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); | 498 | std.mem.copyForwards(u8, buffer[0..remainder.len], remainder); |
| 502 | list.items.len = remainder.len; | 499 | list.items.len = remainder.len; |
| 503 | return end - start_end; | 500 | return track(&bw.bytes_written, end - start_end); |
| 504 | } | 501 | } |
| 505 | list.items.len = 0; | 502 | list.items.len = 0; |
| 506 | return n - start_end; | 503 | return track(&bw.bytes_written, n - start_end); |
| 507 | } | 504 | } |
| 508 | | 505 | |
| 509 | pub const WriteFileOptions = struct { | 506 | pub const WriteFileOptions = struct { |
| ... | @@ -583,54 +580,51 @@ pub fn alignBuffer( | ... | @@ -583,54 +580,51 @@ pub fn alignBuffer( |
| 583 | width: usize, | 580 | width: usize, |
| 584 | alignment: std.fmt.Alignment, | 581 | alignment: std.fmt.Alignment, |
| 585 | fill: u8, | 582 | fill: u8, |
| 586 | ) anyerror!usize { | 583 | ) anyerror!void { |
| 587 | const padding = if (buffer.len < width) width - buffer.len else 0; | 584 | const padding = if (buffer.len < width) width - buffer.len else 0; |
| 588 | if (padding == 0) { | 585 | if (padding == 0) { |
| 589 | @branchHint(.likely); | 586 | @branchHint(.likely); |
| 590 | return bw.writeAllCount(buffer); | 587 | return bw.writeAll(buffer); |
| 591 | } | 588 | } |
| 592 | var n: usize = 0; | | |
| 593 | switch (alignment) { | 589 | switch (alignment) { |
| 594 | .left => { | 590 | .left => { |
| 595 | n += try bw.writeAllCount(buffer); | 591 | try bw.writeAll(buffer); |
| 596 | n += try bw.splatByteAllCount(fill, padding); | 592 | try bw.splatByteAll(fill, padding); |
| 597 | }, | 593 | }, |
| 598 | .center => { | 594 | .center => { |
| 599 | const left_padding = padding / 2; | 595 | const left_padding = padding / 2; |
| 600 | const right_padding = (padding + 1) / 2; | 596 | const right_padding = (padding + 1) / 2; |
| 601 | n += try bw.splatByteAllCount(fill, left_padding); | 597 | try bw.splatByteAll(fill, left_padding); |
| 602 | n += try bw.writeAllCount(buffer); | 598 | try bw.writeAll(buffer); |
| 603 | n += try bw.splatByteAllCount(fill, right_padding); | 599 | try bw.splatByteAll(fill, right_padding); |
| 604 | }, | 600 | }, |
| 605 | .right => { | 601 | .right => { |
| 606 | n += try bw.splatByteAllCount(fill, padding); | 602 | try bw.splatByteAll(fill, padding); |
| 607 | n += try bw.writeAllCount(buffer); | 603 | try bw.writeAll(buffer); |
| 608 | }, | 604 | }, |
| 609 | } | 605 | } |
| 610 | return n; | | |
| 611 | } | 606 | } |
| 612 | | 607 | |
| 613 | pub fn alignBufferOptions(bw: *BufferedWriter, buffer: []const u8, options: std.fmt.Options) anyerror!usize { | 608 | pub fn alignBufferOptions(bw: *BufferedWriter, buffer: []const u8, options: std.fmt.Options) anyerror!void { |
| 614 | return alignBuffer(bw, buffer, options.width orelse buffer.len, options.alignment, options.fill); | 609 | return alignBuffer(bw, buffer, options.width orelse buffer.len, options.alignment, options.fill); |
| 615 | } | 610 | } |
| 616 | | 611 | |
| 617 | pub fn printAddress(bw: *BufferedWriter, value: anytype) anyerror!usize { | 612 | pub fn printAddress(bw: *BufferedWriter, value: anytype) anyerror!void { |
| 618 | const T = @TypeOf(value); | 613 | const T = @TypeOf(value); |
| 619 | var n: usize = 0; | | |
| 620 | switch (@typeInfo(T)) { | 614 | switch (@typeInfo(T)) { |
| 621 | .pointer => |info| { | 615 | .pointer => |info| { |
| 622 | n += try bw.writeAllCount(@typeName(info.child) ++ "@"); | 616 | try bw.writeAll(@typeName(info.child) ++ "@"); |
| 623 | if (info.size == .slice) | 617 | if (info.size == .slice) |
| 624 | n += try printIntOptions(bw, @intFromPtr(value.ptr), 16, .lower, .{}) | 618 | try printIntOptions(bw, @intFromPtr(value.ptr), 16, .lower, .{}) |
| 625 | else | 619 | else |
| 626 | n += try printIntOptions(bw, @intFromPtr(value), 16, .lower, .{}); | 620 | try printIntOptions(bw, @intFromPtr(value), 16, .lower, .{}); |
| 627 | return n; | 621 | return; |
| 628 | }, | 622 | }, |
| 629 | .optional => |info| { | 623 | .optional => |info| { |
| 630 | if (@typeInfo(info.child) == .pointer) { | 624 | if (@typeInfo(info.child) == .pointer) { |
| 631 | n += try bw.writeAll(@typeName(info.child) ++ "@"); | 625 | try bw.writeAll(@typeName(info.child) ++ "@"); |
| 632 | n += try printIntOptions(bw, @intFromPtr(value), 16, .lower, .{}); | 626 | try printIntOptions(bw, @intFromPtr(value), 16, .lower, .{}); |
| 633 | return n; | 627 | return; |
| 634 | } | 628 | } |
| 635 | }, | 629 | }, |
| 636 | else => {}, | 630 | else => {}, |
| ... | @@ -645,7 +639,7 @@ pub fn printValue( | ... | @@ -645,7 +639,7 @@ pub fn printValue( |
| 645 | options: std.fmt.Options, | 639 | options: std.fmt.Options, |
| 646 | value: anytype, | 640 | value: anytype, |
| 647 | max_depth: usize, | 641 | max_depth: usize, |
| 648 | ) anyerror!usize { | 642 | ) anyerror!void { |
| 649 | const T = @TypeOf(value); | 643 | const T = @TypeOf(value); |
| 650 | const actual_fmt = comptime if (std.mem.eql(u8, fmt, ANY)) | 644 | const actual_fmt = comptime if (std.mem.eql(u8, fmt, ANY)) |
| 651 | defaultFormatString(T) | 645 | defaultFormatString(T) |
| ... | @@ -700,104 +694,96 @@ pub fn printValue( | ... | @@ -700,104 +694,96 @@ pub fn printValue( |
| 700 | }, | 694 | }, |
| 701 | .error_set => { | 695 | .error_set => { |
| 702 | if (actual_fmt.len > 0 and actual_fmt[0] == 's') { | 696 | if (actual_fmt.len > 0 and actual_fmt[0] == 's') { |
| 703 | return bw.writeAllCount(@errorName(value)); | 697 | return bw.writeAll(@errorName(value)); |
| 704 | } else if (actual_fmt.len != 0) { | 698 | } else if (actual_fmt.len != 0) { |
| 705 | invalidFmtError(fmt, value); | 699 | invalidFmtError(fmt, value); |
| 706 | } else { | 700 | } else { |
| 707 | var n: usize = 0; | 701 | try bw.writeAll("error."); |
| 708 | n += try bw.writeAllCount("error."); | 702 | try bw.writeAll(@errorName(value)); |
| 709 | n += try bw.writeAllCount(@errorName(value)); | | |
| 710 | return n; | | |
| 711 | } | 703 | } |
| 712 | }, | 704 | }, |
| 713 | .@"enum" => |enum_info| { | 705 | .@"enum" => |enum_info| { |
| 714 | var n: usize = 0; | 706 | try bw.writeAll(@typeName(T)); |
| 715 | n += try bw.writeAllCount(@typeName(T)); | | |
| 716 | if (enum_info.is_exhaustive) { | 707 | if (enum_info.is_exhaustive) { |
| 717 | if (actual_fmt.len != 0) invalidFmtError(fmt, value); | 708 | if (actual_fmt.len != 0) invalidFmtError(fmt, value); |
| 718 | n += try bw.writeAllCount("."); | 709 | try bw.writeAll("."); |
| 719 | n += try bw.writeAllCount(@tagName(value)); | 710 | try bw.writeAll(@tagName(value)); |
| 720 | return n; | 711 | return; |
| 721 | } | 712 | } |
| 722 | | 713 | |
| 723 | // Use @tagName only if value is one of known fields | 714 | // Use @tagName only if value is one of known fields |
| 724 | @setEvalBranchQuota(3 * enum_info.fields.len); | 715 | @setEvalBranchQuota(3 * enum_info.fields.len); |
| 725 | inline for (enum_info.fields) |enumField| { | 716 | inline for (enum_info.fields) |enumField| { |
| 726 | if (@intFromEnum(value) == enumField.value) { | 717 | if (@intFromEnum(value) == enumField.value) { |
| 727 | n += try bw.writeAllCount("."); | 718 | try bw.writeAll("."); |
| 728 | n += try bw.writeAllCount(@tagName(value)); | 719 | try bw.writeAll(@tagName(value)); |
| 729 | return; | 720 | return; |
| 730 | } | 721 | } |
| 731 | } | 722 | } |
| 732 | | 723 | |
| 733 | n += try bw.writeByteCount('('); | 724 | try bw.writeByteCount('('); |
| 734 | n += try printValue(bw, actual_fmt, options, @intFromEnum(value), max_depth); | 725 | try printValue(bw, actual_fmt, options, @intFromEnum(value), max_depth); |
| 735 | n += try bw.writeByteCount(')'); | 726 | try bw.writeByteCount(')'); |
| 736 | return n; | | |
| 737 | }, | 727 | }, |
| 738 | .@"union" => |info| { | 728 | .@"union" => |info| { |
| 739 | if (actual_fmt.len != 0) invalidFmtError(fmt, value); | 729 | if (actual_fmt.len != 0) invalidFmtError(fmt, value); |
| 740 | var n: usize = 0; | 730 | try bw.writeAll(@typeName(T)); |
| 741 | n += try bw.writeAllCount(@typeName(T)); | | |
| 742 | if (max_depth == 0) { | 731 | if (max_depth == 0) { |
| 743 | n += bw.writeAllCount("{ ... }"); | 732 | bw.writeAll("{ ... }"); |
| 744 | return n; | 733 | return; |
| 745 | } | 734 | } |
| 746 | if (info.tag_type) |UnionTagType| { | 735 | if (info.tag_type) |UnionTagType| { |
| 747 | n += try bw.writeAllCount("{ ."); | 736 | try bw.writeAll("{ ."); |
| 748 | n += try bw.writeAllCount(@tagName(@as(UnionTagType, value))); | 737 | try bw.writeAll(@tagName(@as(UnionTagType, value))); |
| 749 | n += try bw.writeAllCount(" = "); | 738 | try bw.writeAll(" = "); |
| 750 | inline for (info.fields) |u_field| { | 739 | inline for (info.fields) |u_field| { |
| 751 | if (value == @field(UnionTagType, u_field.name)) { | 740 | if (value == @field(UnionTagType, u_field.name)) { |
| 752 | n += try printValue(bw, ANY, options, @field(value, u_field.name), max_depth - 1); | 741 | try printValue(bw, ANY, options, @field(value, u_field.name), max_depth - 1); |
| 753 | } | 742 | } |
| 754 | } | 743 | } |
| 755 | n += try bw.writeAllCount(" }"); | 744 | try bw.writeAll(" }"); |
| 756 | } else { | 745 | } else { |
| 757 | n += try bw.writeByte('@'); | 746 | try bw.writeByte('@'); |
| 758 | n += try bw.printIntOptions(@intFromPtr(&value), 16, .lower); | 747 | try bw.printIntOptions(@intFromPtr(&value), 16, .lower); |
| 759 | } | 748 | } |
| 760 | return n; | | |
| 761 | }, | 749 | }, |
| 762 | .@"struct" => |info| { | 750 | .@"struct" => |info| { |
| 763 | if (actual_fmt.len != 0) invalidFmtError(fmt, value); | 751 | if (actual_fmt.len != 0) invalidFmtError(fmt, value); |
| 764 | var n: usize = 0; | | |
| 765 | if (info.is_tuple) { | 752 | if (info.is_tuple) { |
| 766 | // Skip the type and field names when formatting tuples. | 753 | // Skip the type and field names when formatting tuples. |
| 767 | if (max_depth == 0) { | 754 | if (max_depth == 0) { |
| 768 | n += try bw.writeAllCount("{ ... }"); | 755 | try bw.writeAll("{ ... }"); |
| 769 | return n; | 756 | return; |
| 770 | } | 757 | } |
| 771 | n += try bw.writeAllCount("{"); | 758 | try bw.writeAll("{"); |
| 772 | inline for (info.fields, 0..) |f, i| { | 759 | inline for (info.fields, 0..) |f, i| { |
| 773 | if (i == 0) { | 760 | if (i == 0) { |
| 774 | n += try bw.writeAllCount(" "); | 761 | try bw.writeAll(" "); |
| 775 | } else { | 762 | } else { |
| 776 | n += try bw.writeAllCount(", "); | 763 | try bw.writeAll(", "); |
| 777 | } | 764 | } |
| 778 | n += try printValue(bw, ANY, options, @field(value, f.name), max_depth - 1); | 765 | try printValue(bw, ANY, options, @field(value, f.name), max_depth - 1); |
| 779 | } | 766 | } |
| 780 | n += try bw.writeAllCount(" }"); | 767 | try bw.writeAll(" }"); |
| 781 | return n; | 768 | return; |
| 782 | } | 769 | } |
| 783 | n += try bw.writeAllCount(@typeName(T)); | 770 | try bw.writeAll(@typeName(T)); |
| 784 | if (max_depth == 0) { | 771 | if (max_depth == 0) { |
| 785 | n += try bw.writeAllCount("{ ... }"); | 772 | try bw.writeAll("{ ... }"); |
| 786 | return n; | 773 | return; |
| 787 | } | 774 | } |
| 788 | n += try bw.writeAllCount("{"); | 775 | try bw.writeAll("{"); |
| 789 | inline for (info.fields, 0..) |f, i| { | 776 | inline for (info.fields, 0..) |f, i| { |
| 790 | if (i == 0) { | 777 | if (i == 0) { |
| 791 | n += try bw.writeAllCount(" ."); | 778 | try bw.writeAll(" ."); |
| 792 | } else { | 779 | } else { |
| 793 | n += try bw.writeAllCount(", ."); | 780 | try bw.writeAll(", ."); |
| 794 | } | 781 | } |
| 795 | n += try bw.writeAllCount(f.name); | 782 | try bw.writeAll(f.name); |
| 796 | n += try bw.writeAllCount(" = "); | 783 | try bw.writeAll(" = "); |
| 797 | n += try printValue(bw, ANY, options, @field(value, f.name), max_depth - 1); | 784 | try printValue(bw, ANY, options, @field(value, f.name), max_depth - 1); |
| 798 | } | 785 | } |
| 799 | n += try bw.writeAllCount(" }"); | 786 | try bw.writeAll(" }"); |
| 800 | return n; | | |
| 801 | }, | 787 | }, |
| 802 | .pointer => |ptr_info| switch (ptr_info.size) { | 788 | .pointer => |ptr_info| switch (ptr_info.size) { |
| 803 | .one => switch (@typeInfo(ptr_info.child)) { | 789 | .one => switch (@typeInfo(ptr_info.child)) { |
| ... | @@ -806,10 +792,9 @@ pub fn printValue( | ... | @@ -806,10 +792,9 @@ pub fn printValue( |
| 806 | }, | 792 | }, |
| 807 | else => { | 793 | else => { |
| 808 | var buffers: [2][]const u8 = .{ @typeName(ptr_info.child), "@" }; | 794 | var buffers: [2][]const u8 = .{ @typeName(ptr_info.child), "@" }; |
| 809 | var n: usize = 0; | 795 | try writevAll(bw, &buffers); |
| 810 | n += try writevAll(bw, &buffers); | 796 | try printIntOptions(bw, @intFromPtr(value), 16, .lower, options); |
| 811 | n += try printIntOptions(bw, @intFromPtr(value), 16, .lower, options); | 797 | return; |
| 812 | return n; | | |
| 813 | }, | 798 | }, |
| 814 | }, | 799 | }, |
| 815 | .many, .c => { | 800 | .many, .c => { |
| ... | @@ -827,7 +812,7 @@ pub fn printValue( | ... | @@ -827,7 +812,7 @@ pub fn printValue( |
| 827 | if (actual_fmt.len == 0) | 812 | if (actual_fmt.len == 0) |
| 828 | @compileError("cannot format slice without a specifier (i.e. {s}, {x}, {b64}, or {any})"); | 813 | @compileError("cannot format slice without a specifier (i.e. {s}, {x}, {b64}, or {any})"); |
| 829 | if (max_depth == 0) { | 814 | if (max_depth == 0) { |
| 830 | return bw.writeAllCount("{ ... }"); | 815 | return bw.writeAll("{ ... }"); |
| 831 | } | 816 | } |
| 832 | if (ptr_info.child == u8) switch (actual_fmt.len) { | 817 | if (ptr_info.child == u8) switch (actual_fmt.len) { |
| 833 | 1 => switch (actual_fmt[0]) { | 818 | 1 => switch (actual_fmt[0]) { |
| ... | @@ -841,23 +826,21 @@ pub fn printValue( | ... | @@ -841,23 +826,21 @@ pub fn printValue( |
| 841 | }, | 826 | }, |
| 842 | else => {}, | 827 | else => {}, |
| 843 | }; | 828 | }; |
| 844 | var n: usize = 0; | 829 | try bw.writeAll("{ "); |
| 845 | n += try bw.writeAllCount("{ "); | | |
| 846 | for (value, 0..) |elem, i| { | 830 | for (value, 0..) |elem, i| { |
| 847 | n += try printValue(bw, actual_fmt, options, elem, max_depth - 1); | 831 | try printValue(bw, actual_fmt, options, elem, max_depth - 1); |
| 848 | if (i != value.len - 1) { | 832 | if (i != value.len - 1) { |
| 849 | n += try bw.writeAllCount(", "); | 833 | try bw.writeAll(", "); |
| 850 | } | 834 | } |
| 851 | } | 835 | } |
| 852 | n += try bw.writeAllCount(" }"); | 836 | try bw.writeAll(" }"); |
| 853 | return n; | | |
| 854 | }, | 837 | }, |
| 855 | }, | 838 | }, |
| 856 | .array => |info| { | 839 | .array => |info| { |
| 857 | if (actual_fmt.len == 0) | 840 | if (actual_fmt.len == 0) |
| 858 | @compileError("cannot format array without a specifier (i.e. {s} or {any})"); | 841 | @compileError("cannot format array without a specifier (i.e. {s} or {any})"); |
| 859 | if (max_depth == 0) { | 842 | if (max_depth == 0) { |
| 860 | return bw.writeAllCount("{ ... }"); | 843 | return bw.writeAll("{ ... }"); |
| 861 | } | 844 | } |
| 862 | if (info.child == u8) { | 845 | if (info.child == u8) { |
| 863 | if (actual_fmt[0] == 's') { | 846 | if (actual_fmt[0] == 's') { |
| ... | @@ -868,32 +851,28 @@ pub fn printValue( | ... | @@ -868,32 +851,28 @@ pub fn printValue( |
| 868 | return printHex(bw, &value, .upper); | 851 | return printHex(bw, &value, .upper); |
| 869 | } | 852 | } |
| 870 | } | 853 | } |
| 871 | var n: usize = 0; | 854 | try bw.writeAll("{ "); |
| 872 | n += try bw.writeAllCount("{ "); | | |
| 873 | for (value, 0..) |elem, i| { | 855 | for (value, 0..) |elem, i| { |
| 874 | n += try printValue(bw, actual_fmt, options, elem, max_depth - 1); | 856 | try printValue(bw, actual_fmt, options, elem, max_depth - 1); |
| 875 | if (i < value.len - 1) { | 857 | if (i < value.len - 1) { |
| 876 | n += try bw.writeAllCount(", "); | 858 | try bw.writeAll(", "); |
| 877 | } | 859 | } |
| 878 | } | 860 | } |
| 879 | n += try bw.writeAllCount(" }"); | 861 | try bw.writeAll(" }"); |
| 880 | return n; | | |
| 881 | }, | 862 | }, |
| 882 | .vector => |info| { | 863 | .vector => |info| { |
| 883 | if (max_depth == 0) { | 864 | if (max_depth == 0) { |
| 884 | return bw.writeAllCount("{ ... }"); | 865 | return bw.writeAll("{ ... }"); |
| 885 | } | 866 | } |
| 886 | var n: usize = 0; | 867 | try bw.writeAll("{ "); |
| 887 | n += try bw.writeAllCount("{ "); | | |
| 888 | var i: usize = 0; | 868 | var i: usize = 0; |
| 889 | while (i < info.len) : (i += 1) { | 869 | while (i < info.len) : (i += 1) { |
| 890 | n += try printValue(bw, actual_fmt, options, value[i], max_depth - 1); | 870 | try printValue(bw, actual_fmt, options, value[i], max_depth - 1); |
| 891 | if (i < info.len - 1) { | 871 | if (i < info.len - 1) { |
| 892 | n += try bw.writeAllCount(", "); | 872 | try bw.writeAll(", "); |
| 893 | } | 873 | } |
| 894 | } | 874 | } |
| 895 | n += try bw.writeAllCount(" }"); | 875 | try bw.writeAll(" }"); |
| 896 | return n; | | |
| 897 | }, | 876 | }, |
| 898 | .@"fn" => @compileError("unable to format function body type, use '*const " ++ @typeName(T) ++ "' for a function pointer type"), | 877 | .@"fn" => @compileError("unable to format function body type, use '*const " ++ @typeName(T) ++ "' for a function pointer type"), |
| 899 | .type => { | 878 | .type => { |
| ... | @@ -918,7 +897,7 @@ pub fn printInt( | ... | @@ -918,7 +897,7 @@ pub fn printInt( |
| 918 | comptime fmt: []const u8, | 897 | comptime fmt: []const u8, |
| 919 | options: std.fmt.Options, | 898 | options: std.fmt.Options, |
| 920 | value: anytype, | 899 | value: anytype, |
| 921 | ) anyerror!usize { | 900 | ) anyerror!void { |
| 922 | const int_value = if (@TypeOf(value) == comptime_int) blk: { | 901 | const int_value = if (@TypeOf(value) == comptime_int) blk: { |
| 923 | const Int = std.math.IntFittingRange(value, value); | 902 | const Int = std.math.IntFittingRange(value, value); |
| 924 | break :blk @as(Int, value); | 903 | break :blk @as(Int, value); |
| ... | @@ -962,15 +941,15 @@ pub fn printInt( | ... | @@ -962,15 +941,15 @@ pub fn printInt( |
| 962 | comptime unreachable; | 941 | comptime unreachable; |
| 963 | } | 942 | } |
| 964 | | 943 | |
| 965 | pub fn printAsciiChar(bw: *BufferedWriter, c: u8, options: std.fmt.Options) anyerror!usize { | 944 | pub fn printAsciiChar(bw: *BufferedWriter, c: u8, options: std.fmt.Options) anyerror!void { |
| 966 | return alignBufferOptions(bw, @as(*const [1]u8, &c), options); | 945 | return alignBufferOptions(bw, @as(*const [1]u8, &c), options); |
| 967 | } | 946 | } |
| 968 | | 947 | |
| 969 | pub fn printAscii(bw: *BufferedWriter, bytes: []const u8, options: std.fmt.Options) anyerror!usize { | 948 | pub fn printAscii(bw: *BufferedWriter, bytes: []const u8, options: std.fmt.Options) anyerror!void { |
| 970 | return alignBufferOptions(bw, bytes, options); | 949 | return alignBufferOptions(bw, bytes, options); |
| 971 | } | 950 | } |
| 972 | | 951 | |
| 973 | pub fn printUnicodeCodepoint(bw: *BufferedWriter, c: u21, options: std.fmt.Options) anyerror!usize { | 952 | pub fn printUnicodeCodepoint(bw: *BufferedWriter, c: u21, options: std.fmt.Options) anyerror!void { |
| 974 | var buf: [4]u8 = undefined; | 953 | var buf: [4]u8 = undefined; |
| 975 | const len = try std.unicode.utf8Encode(c, &buf); | 954 | const len = try std.unicode.utf8Encode(c, &buf); |
| 976 | return alignBufferOptions(bw, buf[0..len], options); | 955 | return alignBufferOptions(bw, buf[0..len], options); |
| ... | @@ -982,7 +961,7 @@ pub fn printIntOptions( | ... | @@ -982,7 +961,7 @@ pub fn printIntOptions( |
| 982 | base: u8, | 961 | base: u8, |
| 983 | case: std.fmt.Case, | 962 | case: std.fmt.Case, |
| 984 | options: std.fmt.Options, | 963 | options: std.fmt.Options, |
| 985 | ) anyerror!usize { | 964 | ) anyerror!void { |
| 986 | assert(base >= 2); | 965 | assert(base >= 2); |
| 987 | | 966 | |
| 988 | const int_value = if (@TypeOf(value) == comptime_int) blk: { | 967 | const int_value = if (@TypeOf(value) == comptime_int) blk: { |
| ... | @@ -1049,7 +1028,7 @@ pub fn printFloat( | ... | @@ -1049,7 +1028,7 @@ pub fn printFloat( |
| 1049 | comptime fmt: []const u8, | 1028 | comptime fmt: []const u8, |
| 1050 | options: std.fmt.Options, | 1029 | options: std.fmt.Options, |
| 1051 | value: anytype, | 1030 | value: anytype, |
| 1052 | ) anyerror!usize { | 1031 | ) anyerror!void { |
| 1053 | var buf: [std.fmt.float.bufferSize(.decimal, f64)]u8 = undefined; | 1032 | var buf: [std.fmt.float.bufferSize(.decimal, f64)]u8 = undefined; |
| 1054 | | 1033 | |
| 1055 | if (fmt.len > 1) invalidFmtError(fmt, value); | 1034 | if (fmt.len > 1) invalidFmtError(fmt, value); |
| ... | @@ -1337,7 +1316,7 @@ pub fn printDuration(bw: *BufferedWriter, nanoseconds: anytype, options: std.fmt | ... | @@ -1337,7 +1316,7 @@ pub fn printDuration(bw: *BufferedWriter, nanoseconds: anytype, options: std.fmt |
| 1337 | return alignBufferOptions(bw, sub_bw.getWritten(), options); | 1316 | return alignBufferOptions(bw, sub_bw.getWritten(), options); |
| 1338 | } | 1317 | } |
| 1339 | | 1318 | |
| 1340 | pub fn printHex(bw: *BufferedWriter, bytes: []const u8, case: std.fmt.Case) anyerror!usize { | 1319 | pub fn printHex(bw: *BufferedWriter, bytes: []const u8, case: std.fmt.Case) anyerror!void { |
| 1341 | const charset = switch (case) { | 1320 | const charset = switch (case) { |
| 1342 | .upper => "0123456789ABCDEF", | 1321 | .upper => "0123456789ABCDEF", |
| 1343 | .lower => "0123456789abcdef", | 1322 | .lower => "0123456789abcdef", |
| ... | @@ -1346,21 +1325,18 @@ pub fn printHex(bw: *BufferedWriter, bytes: []const u8, case: std.fmt.Case) anye | ... | @@ -1346,21 +1325,18 @@ pub fn printHex(bw: *BufferedWriter, bytes: []const u8, case: std.fmt.Case) anye |
| 1346 | try writeByte(bw, charset[c >> 4]); | 1325 | try writeByte(bw, charset[c >> 4]); |
| 1347 | try writeByte(bw, charset[c & 15]); | 1326 | try writeByte(bw, charset[c & 15]); |
| 1348 | } | 1327 | } |
| 1349 | return bytes.len * 2; | | |
| 1350 | } | 1328 | } |
| 1351 | | 1329 | |
| 1352 | pub fn printBase64(bw: *BufferedWriter, bytes: []const u8) anyerror!usize { | 1330 | pub fn printBase64(bw: *BufferedWriter, bytes: []const u8) anyerror!void { |
| 1353 | var chunker = std.mem.window(u8, bytes, 3, 3); | 1331 | var chunker = std.mem.window(u8, bytes, 3, 3); |
| 1354 | var temp: [5]u8 = undefined; | 1332 | var temp: [5]u8 = undefined; |
| 1355 | var n: usize = 0; | | |
| 1356 | while (chunker.next()) |chunk| { | 1333 | while (chunker.next()) |chunk| { |
| 1357 | n += try bw.writeAllCount(std.base64.standard.Encoder.encode(&temp, chunk)); | 1334 | try bw.writeAll(std.base64.standard.Encoder.encode(&temp, chunk)); |
| 1358 | } | 1335 | } |
| 1359 | return n; | | |
| 1360 | } | 1336 | } |
| 1361 | | 1337 | |
| 1362 | /// Write a single unsigned integer as unsigned LEB128 to the given writer. | 1338 | /// Write a single unsigned integer as unsigned LEB128 to the given writer. |
| 1363 | pub fn writeUleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!usize { | 1339 | pub fn writeUleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!void { |
| 1364 | const Arg = @TypeOf(arg); | 1340 | const Arg = @TypeOf(arg); |
| 1365 | const Int = switch (Arg) { | 1341 | const Int = switch (Arg) { |
| 1366 | comptime_int => std.math.IntFittingRange(arg, arg), | 1342 | comptime_int => std.math.IntFittingRange(arg, arg), |
| ... | @@ -1368,23 +1344,21 @@ pub fn writeUleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!usize { | ... | @@ -1368,23 +1344,21 @@ pub fn writeUleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!usize { |
| 1368 | }; | 1344 | }; |
| 1369 | const Value = if (@typeInfo(Int).int.bits < 8) u8 else Int; | 1345 | const Value = if (@typeInfo(Int).int.bits < 8) u8 else Int; |
| 1370 | var value: Value = arg; | 1346 | var value: Value = arg; |
| 1371 | var n: usize = 0; | | |
| 1372 | | 1347 | |
| 1373 | while (true) { | 1348 | while (true) { |
| 1374 | const byte: u8 = @truncate(value & 0x7f); | 1349 | const byte: u8 = @truncate(value & 0x7f); |
| 1375 | value >>= 7; | 1350 | value >>= 7; |
| 1376 | if (value == 0) { | 1351 | if (value == 0) { |
| 1377 | try bw.writeByte(byte); | 1352 | try bw.writeByte(byte); |
| 1378 | return n + 1; | 1353 | return; |
| 1379 | } else { | 1354 | } else { |
| 1380 | try bw.writeByte(byte | 0x80); | 1355 | try bw.writeByte(byte | 0x80); |
| 1381 | n += 1; | | |
| 1382 | } | 1356 | } |
| 1383 | } | 1357 | } |
| 1384 | } | 1358 | } |
| 1385 | | 1359 | |
| 1386 | /// Write a single signed integer as signed LEB128 to the given writer. | 1360 | /// Write a single signed integer as signed LEB128 to the given writer. |
| 1387 | pub fn writeIleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!usize { | 1361 | pub fn writeIleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!void { |
| 1388 | const Arg = @TypeOf(arg); | 1362 | const Arg = @TypeOf(arg); |
| 1389 | const Int = switch (Arg) { | 1363 | const Int = switch (Arg) { |
| 1390 | comptime_int => std.math.IntFittingRange(-@abs(arg), @abs(arg)), | 1364 | comptime_int => std.math.IntFittingRange(-@abs(arg), @abs(arg)), |
| ... | @@ -1393,7 +1367,6 @@ pub fn writeIleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!usize { | ... | @@ -1393,7 +1367,6 @@ pub fn writeIleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!usize { |
| 1393 | const Signed = if (@typeInfo(Int).int.bits < 8) i8 else Int; | 1367 | const Signed = if (@typeInfo(Int).int.bits < 8) i8 else Int; |
| 1394 | const Unsigned = std.meta.Int(.unsigned, @typeInfo(Signed).int.bits); | 1368 | const Unsigned = std.meta.Int(.unsigned, @typeInfo(Signed).int.bits); |
| 1395 | var value: Signed = arg; | 1369 | var value: Signed = arg; |
| 1396 | var n: usize = 0; | | |
| 1397 | | 1370 | |
| 1398 | while (true) { | 1371 | while (true) { |
| 1399 | const unsigned: Unsigned = @bitCast(value); | 1372 | const unsigned: Unsigned = @bitCast(value); |
| ... | @@ -1401,11 +1374,10 @@ pub fn writeIleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!usize { | ... | @@ -1401,11 +1374,10 @@ pub fn writeIleb128(bw: *std.io.BufferedWriter, arg: anytype) anyerror!usize { |
| 1401 | value >>= 6; | 1374 | value >>= 6; |
| 1402 | if (value == -1 or value == 0) { | 1375 | if (value == -1 or value == 0) { |
| 1403 | try bw.writeByte(byte & 0x7F); | 1376 | try bw.writeByte(byte & 0x7F); |
| 1404 | return n + 1; | 1377 | return; |
| 1405 | } else { | 1378 | } else { |
| 1406 | value >>= 1; | 1379 | value >>= 1; |
| 1407 | try bw.writeByte(byte | 0x80); | 1380 | try bw.writeByte(byte | 0x80); |
| 1408 | n += 1; | | |
| 1409 | } | 1381 | } |
| 1410 | } | 1382 | } |
| 1411 | } | 1383 | } |