| author | |
| committer | |
| log | 7ce5ee2e92bf1bf1f39ccc08df19f9a1044e9f2c |
| tree | 6d1d5f066c72636fc1da74fddce4e44e211b431f |
| parent | 21d0264c61ac29724b98187aa87d192f97b52425 |
6 files changed, 47 insertions(+), 43 deletions(-)
lib/std/Build/Cache.zig+6-6| ... | @@ -1384,8 +1384,8 @@ test "check that changing a file makes cache fail" { | ... | @@ -1384,8 +1384,8 @@ test "check that changing a file makes cache fail" { |
| 1384 | try tmp.dir.writeFile(io, .{ .sub_path = temp_file, .data = original_temp_file_contents }); | 1384 | try tmp.dir.writeFile(io, .{ .sub_path = temp_file, .data = original_temp_file_contents }); |
| 1385 | 1385 | ||
| 1386 | // Wait for file timestamps to tick | 1386 | // Wait for file timestamps to tick |
| 1387 | const initial_time = try testGetCurrentFileTimestamp(tmp.dir); | 1387 | const initial_time = try testGetCurrentFileTimestamp(io, tmp.dir); |
| 1388 | while ((try testGetCurrentFileTimestamp(tmp.dir)).nanoseconds == initial_time.nanoseconds) { | 1388 | while ((try testGetCurrentFileTimestamp(io, tmp.dir)).nanoseconds == initial_time.nanoseconds) { |
| 1389 | try std.Io.Clock.Duration.sleep(.{ .clock = .boot, .raw = .fromNanoseconds(1) }, io); | 1389 | try std.Io.Clock.Duration.sleep(.{ .clock = .boot, .raw = .fromNanoseconds(1) }, io); |
| 1390 | } | 1390 | } |
| 1391 | 1391 | ||
| ... | @@ -1502,8 +1502,8 @@ test "Manifest with files added after initial hash work" { | ... | @@ -1502,8 +1502,8 @@ test "Manifest with files added after initial hash work" { |
| 1502 | try tmp.dir.writeFile(io, .{ .sub_path = temp_file2, .data = "Hello world the second!\n" }); | 1502 | try tmp.dir.writeFile(io, .{ .sub_path = temp_file2, .data = "Hello world the second!\n" }); |
| 1503 | 1503 | ||
| 1504 | // Wait for file timestamps to tick | 1504 | // Wait for file timestamps to tick |
| 1505 | const initial_time = try testGetCurrentFileTimestamp(tmp.dir); | 1505 | const initial_time = try testGetCurrentFileTimestamp(io, tmp.dir); |
| 1506 | while ((try testGetCurrentFileTimestamp(tmp.dir)).nanoseconds == initial_time.nanoseconds) { | 1506 | while ((try testGetCurrentFileTimestamp(io, tmp.dir)).nanoseconds == initial_time.nanoseconds) { |
| 1507 | try std.Io.Clock.Duration.sleep(.{ .clock = .boot, .raw = .fromNanoseconds(1) }, io); | 1507 | try std.Io.Clock.Duration.sleep(.{ .clock = .boot, .raw = .fromNanoseconds(1) }, io); |
| 1508 | } | 1508 | } |
| 1509 | 1509 | ||
| ... | @@ -1553,8 +1553,8 @@ test "Manifest with files added after initial hash work" { | ... | @@ -1553,8 +1553,8 @@ test "Manifest with files added after initial hash work" { |
| 1553 | try tmp.dir.writeFile(io, .{ .sub_path = temp_file2, .data = "Hello world the second, updated\n" }); | 1553 | try tmp.dir.writeFile(io, .{ .sub_path = temp_file2, .data = "Hello world the second, updated\n" }); |
| 1554 | 1554 | ||
| 1555 | // Wait for file timestamps to tick | 1555 | // Wait for file timestamps to tick |
| 1556 | const initial_time2 = try testGetCurrentFileTimestamp(tmp.dir); | 1556 | const initial_time2 = try testGetCurrentFileTimestamp(io, tmp.dir); |
| 1557 | while ((try testGetCurrentFileTimestamp(tmp.dir)).nanoseconds == initial_time2.nanoseconds) { | 1557 | while ((try testGetCurrentFileTimestamp(io, tmp.dir)).nanoseconds == initial_time2.nanoseconds) { |
| 1558 | try std.Io.Clock.Duration.sleep(.{ .clock = .boot, .raw = .fromNanoseconds(1) }, io); | 1558 | try std.Io.Clock.Duration.sleep(.{ .clock = .boot, .raw = .fromNanoseconds(1) }, io); |
| 1559 | } | 1559 | } |
| 1560 | 1560 |
lib/std/Io/File/Reader.zig+2-2| ... | @@ -18,8 +18,8 @@ io: Io, | ... | @@ -18,8 +18,8 @@ io: Io, |
| 18 | file: File, | 18 | file: File, |
| 19 | err: ?Error = null, | 19 | err: ?Error = null, |
| 20 | mode: Mode = .positional, | 20 | mode: Mode = .positional, |
| 21 | /// Tracks the true seek position in the file. To obtain the logical | 21 | /// Tracks the true seek position in the file. To obtain the logical position, |
| 22 | /// position, use `logicalPos`. | 22 | /// use `logicalPos`. |
| 23 | pos: u64 = 0, | 23 | pos: u64 = 0, |
| 24 | size: ?u64 = null, | 24 | size: ?u64 = null, |
| 25 | size_err: ?SizeError = null, | 25 | size_err: ?SizeError = null, |
lib/std/Io/File/Writer.zig+6-2| ... | @@ -11,8 +11,8 @@ io: Io, | ... | @@ -11,8 +11,8 @@ io: Io, |
| 11 | file: File, | 11 | file: File, |
| 12 | err: ?Error = null, | 12 | err: ?Error = null, |
| 13 | mode: Mode = .positional, | 13 | mode: Mode = .positional, |
| 14 | /// Tracks the true seek position in the file. To obtain the logical | 14 | /// Tracks the true seek position in the file. To obtain the logical position, |
| 15 | /// position, add the buffer size to this value. | 15 | /// use `logicalPos`. |
| 16 | pos: u64 = 0, | 16 | pos: u64 = 0, |
| 17 | write_file_err: ?WriteFileError = null, | 17 | write_file_err: ?WriteFileError = null, |
| 18 | seek_err: ?SeekError = null, | 18 | seek_err: ?SeekError = null, |
| ... | @@ -221,6 +221,10 @@ pub fn seekTo(w: *Writer, offset: u64) (SeekError || Io.Writer.Error)!void { | ... | @@ -221,6 +221,10 @@ pub fn seekTo(w: *Writer, offset: u64) (SeekError || Io.Writer.Error)!void { |
| 221 | try seekToUnbuffered(w, offset); | 221 | try seekToUnbuffered(w, offset); |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | pub fn logicalPos(w: *const Writer) u64 { | ||
| 225 | return w.pos + w.interface.end; | ||
| 226 | } | ||
| 227 | |||
| 224 | /// Asserts that no data is currently buffered. | 228 | /// Asserts that no data is currently buffered. |
| 225 | pub fn seekToUnbuffered(w: *Writer, offset: u64) SeekError!void { | 229 | pub fn seekToUnbuffered(w: *Writer, offset: u64) SeekError!void { |
| 226 | assert(w.interface.buffered().len == 0); | 230 | assert(w.interface.buffered().len == 0); |
lib/std/Io/test.zig+18-21| ... | @@ -64,33 +64,28 @@ test "write a file, read it, then delete it" { | ... | @@ -64,33 +64,28 @@ test "write a file, read it, then delete it" { |
| 64 | try tmp.dir.deleteFile(io, tmp_file_name); | 64 | try tmp.dir.deleteFile(io, tmp_file_name); |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | test "File seek ops" { | 67 | test "File.Writer.seekTo" { |
| 68 | var tmp = tmpDir(.{}); | 68 | var tmp = tmpDir(.{}); |
| 69 | defer tmp.cleanup(); | 69 | defer tmp.cleanup(); |
| 70 | 70 | ||
| 71 | const io = testing.io; | 71 | const io = testing.io; |
| 72 | 72 | ||
| 73 | var data: [8192]u8 = undefined; | ||
| 74 | @memset(&data, 0x55); | ||
| 75 | |||
| 73 | const tmp_file_name = "temp_test_file.txt"; | 76 | const tmp_file_name = "temp_test_file.txt"; |
| 74 | var file = try tmp.dir.createFile(io, tmp_file_name, .{}); | 77 | var file = try tmp.dir.createFile(io, tmp_file_name, .{}); |
| 75 | defer file.close(io); | 78 | defer file.close(io); |
| 76 | 79 | ||
| 77 | try file.writeAll(&([_]u8{0x55} ** 8192)); | 80 | var fw = file.writerStreaming(io, &.{}); |
| 78 | 81 | ||
| 79 | // Seek to the end | 82 | try fw.interface.writeAll(&data); |
| 80 | try file.seekFromEnd(0); | 83 | try expect(fw.logicalPos() == try file.length(io)); |
| 81 | try expect((try file.getPos()) == try file.length(io)); | 84 | try fw.seekTo(1234); |
| 82 | // Negative delta | 85 | try expect(fw.logicalPos() == 1234); |
| 83 | try file.seekBy(-4096); | ||
| 84 | try expect((try file.getPos()) == 4096); | ||
| 85 | // Positive delta | ||
| 86 | try file.seekBy(10); | ||
| 87 | try expect((try file.getPos()) == 4106); | ||
| 88 | // Absolute position | ||
| 89 | try file.seekTo(1234); | ||
| 90 | try expect((try file.getPos()) == 1234); | ||
| 91 | } | 86 | } |
| 92 | 87 | ||
| 93 | test "setLength" { | 88 | test "File.setLength" { |
| 94 | const io = testing.io; | 89 | const io = testing.io; |
| 95 | 90 | ||
| 96 | var tmp = tmpDir(.{}); | 91 | var tmp = tmpDir(.{}); |
| ... | @@ -100,19 +95,21 @@ test "setLength" { | ... | @@ -100,19 +95,21 @@ test "setLength" { |
| 100 | var file = try tmp.dir.createFile(io, tmp_file_name, .{}); | 95 | var file = try tmp.dir.createFile(io, tmp_file_name, .{}); |
| 101 | defer file.close(io); | 96 | defer file.close(io); |
| 102 | 97 | ||
| 98 | var fw = file.writerStreaming(io, &.{}); | ||
| 99 | |||
| 103 | // Verify that the file size changes and the file offset is not moved | 100 | // Verify that the file size changes and the file offset is not moved |
| 104 | try expect((try file.length(io)) == 0); | 101 | try expect((try file.length(io)) == 0); |
| 105 | try expect((try file.getPos()) == 0); | 102 | try expect(fw.logicalPos() == 0); |
| 106 | try file.setLength(io, 8192); | 103 | try file.setLength(io, 8192); |
| 107 | try expect((try file.length(io)) == 8192); | 104 | try expect((try file.length(io)) == 8192); |
| 108 | try expect((try file.getPos()) == 0); | 105 | try expect(fw.logicalPos() == 0); |
| 109 | try file.seekTo(100); | 106 | try fw.seekTo(100); |
| 110 | try file.setLength(io, 4096); | 107 | try file.setLength(io, 4096); |
| 111 | try expect((try file.length(io)) == 4096); | 108 | try expect((try file.length(io)) == 4096); |
| 112 | try expect((try file.getPos()) == 100); | 109 | try expect(fw.logicalPos() == 100); |
| 113 | try file.setLength(io, 0); | 110 | try file.setLength(io, 0); |
| 114 | try expect((try file.length(io)) == 0); | 111 | try expect((try file.length(io)) == 0); |
| 115 | try expect((try file.getPos()) == 100); | 112 | try expect(fw.logicalPos() == 100); |
| 116 | } | 113 | } |
| 117 | 114 | ||
| 118 | test "legacy setLength" { | 115 | test "legacy setLength" { |
lib/std/Thread.zig+10-8| ... | @@ -211,7 +211,7 @@ pub fn setName(self: Thread, io: Io, name: []const u8) SetNameError!void { | ... | @@ -211,7 +211,7 @@ pub fn setName(self: Thread, io: Io, name: []const u8) SetNameError!void { |
| 211 | const file = try Io.Dir.cwd().openFile(io, path, .{ .mode = .write_only }); | 211 | const file = try Io.Dir.cwd().openFile(io, path, .{ .mode = .write_only }); |
| 212 | defer file.close(io); | 212 | defer file.close(io); |
| 213 | 213 | ||
| 214 | try file.writeAll(name); | 214 | try file.writeStreamingAll(io, name); |
| 215 | return; | 215 | return; |
| 216 | }, | 216 | }, |
| 217 | .windows => { | 217 | .windows => { |
| ... | @@ -1676,14 +1676,14 @@ const LinuxThreadImpl = struct { | ... | @@ -1676,14 +1676,14 @@ const LinuxThreadImpl = struct { |
| 1676 | } | 1676 | } |
| 1677 | }; | 1677 | }; |
| 1678 | 1678 | ||
| 1679 | fn testThreadName(thread: *Thread) !void { | 1679 | fn testThreadName(io: Io, thread: *Thread) !void { |
| 1680 | const testCases = &[_][]const u8{ | 1680 | const testCases = &[_][]const u8{ |
| 1681 | "mythread", | 1681 | "mythread", |
| 1682 | "b" ** max_name_len, | 1682 | "b" ** max_name_len, |
| 1683 | }; | 1683 | }; |
| 1684 | 1684 | ||
| 1685 | inline for (testCases) |tc| { | 1685 | inline for (testCases) |tc| { |
| 1686 | try thread.setName(tc); | 1686 | try thread.setName(io, tc); |
| 1687 | 1687 | ||
| 1688 | var name_buffer: [max_name_len:0]u8 = undefined; | 1688 | var name_buffer: [max_name_len:0]u8 = undefined; |
| 1689 | 1689 | ||
| ... | @@ -1698,6 +1698,8 @@ fn testThreadName(thread: *Thread) !void { | ... | @@ -1698,6 +1698,8 @@ fn testThreadName(thread: *Thread) !void { |
| 1698 | test "setName, getName" { | 1698 | test "setName, getName" { |
| 1699 | if (builtin.single_threaded) return error.SkipZigTest; | 1699 | if (builtin.single_threaded) return error.SkipZigTest; |
| 1700 | 1700 | ||
| 1701 | const io = testing.io; | ||
| 1702 | |||
| 1701 | const Context = struct { | 1703 | const Context = struct { |
| 1702 | start_wait_event: ResetEvent = .unset, | 1704 | start_wait_event: ResetEvent = .unset, |
| 1703 | test_done_event: ResetEvent = .unset, | 1705 | test_done_event: ResetEvent = .unset, |
| ... | @@ -1711,11 +1713,11 @@ test "setName, getName" { | ... | @@ -1711,11 +1713,11 @@ test "setName, getName" { |
| 1711 | ctx.start_wait_event.wait(); | 1713 | ctx.start_wait_event.wait(); |
| 1712 | 1714 | ||
| 1713 | switch (native_os) { | 1715 | switch (native_os) { |
| 1714 | .windows => testThreadName(&ctx.thread) catch |err| switch (err) { | 1716 | .windows => testThreadName(io, &ctx.thread) catch |err| switch (err) { |
| 1715 | error.Unsupported => return error.SkipZigTest, | 1717 | error.Unsupported => return error.SkipZigTest, |
| 1716 | else => return err, | 1718 | else => return err, |
| 1717 | }, | 1719 | }, |
| 1718 | else => try testThreadName(&ctx.thread), | 1720 | else => try testThreadName(io, &ctx.thread), |
| 1719 | } | 1721 | } |
| 1720 | 1722 | ||
| 1721 | // Signal our test is done | 1723 | // Signal our test is done |
| ... | @@ -1735,14 +1737,14 @@ test "setName, getName" { | ... | @@ -1735,14 +1737,14 @@ test "setName, getName" { |
| 1735 | 1737 | ||
| 1736 | switch (native_os) { | 1738 | switch (native_os) { |
| 1737 | .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => { | 1739 | .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos => { |
| 1738 | const res = thread.setName("foobar"); | 1740 | const res = thread.setName(io, "foobar"); |
| 1739 | try std.testing.expectError(error.Unsupported, res); | 1741 | try std.testing.expectError(error.Unsupported, res); |
| 1740 | }, | 1742 | }, |
| 1741 | .windows => testThreadName(&thread) catch |err| switch (err) { | 1743 | .windows => testThreadName(io, &thread) catch |err| switch (err) { |
| 1742 | error.Unsupported => return error.SkipZigTest, | 1744 | error.Unsupported => return error.SkipZigTest, |
| 1743 | else => return err, | 1745 | else => return err, |
| 1744 | }, | 1746 | }, |
| 1745 | else => try testThreadName(&thread), | 1747 | else => try testThreadName(io, &thread), |
| 1746 | } | 1748 | } |
| 1747 | 1749 | ||
| 1748 | context.thread_done_event.set(); | 1750 | context.thread_done_event.set(); |
lib/std/debug.zig+5-4| ... | @@ -384,12 +384,13 @@ pub fn dumpHexFallible(t: Io.Terminal, bytes: []const u8) !void { | ... | @@ -384,12 +384,13 @@ pub fn dumpHexFallible(t: Io.Terminal, bytes: []const u8) !void { |
| 384 | } | 384 | } |
| 385 | 385 | ||
| 386 | test dumpHexFallible { | 386 | test dumpHexFallible { |
| 387 | const gpa = testing.allocator; | ||
| 387 | const bytes: []const u8 = &.{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01, 0x12, 0x13 }; | 388 | const bytes: []const u8 = &.{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x01, 0x12, 0x13 }; |
| 388 | var aw: Writer.Allocating = .init(testing.allocator); | 389 | var aw: Writer.Allocating = .init(gpa); |
| 389 | defer aw.deinit(); | 390 | defer aw.deinit(); |
| 390 | 391 | ||
| 391 | try dumpHexFallible(&aw.writer, .no_color, bytes); | 392 | try dumpHexFallible(.{ .writer = &aw.writer, .mode = .no_color }, bytes); |
| 392 | const expected = try std.fmt.allocPrint(testing.allocator, | 393 | const expected = try std.fmt.allocPrint(gpa, |
| 393 | \\{x:0>[2]} 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF .."3DUfw........ | 394 | \\{x:0>[2]} 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF .."3DUfw........ |
| 394 | \\{x:0>[2]} 01 12 13 ... | 395 | \\{x:0>[2]} 01 12 13 ... |
| 395 | \\ | 396 | \\ |
| ... | @@ -398,7 +399,7 @@ test dumpHexFallible { | ... | @@ -398,7 +399,7 @@ test dumpHexFallible { |
| 398 | @intFromPtr(bytes.ptr) + 16, | 399 | @intFromPtr(bytes.ptr) + 16, |
| 399 | @sizeOf(usize) * 2, | 400 | @sizeOf(usize) * 2, |
| 400 | }); | 401 | }); |
| 401 | defer testing.allocator.free(expected); | 402 | defer gpa.free(expected); |
| 402 | try testing.expectEqualStrings(expected, aw.written()); | 403 | try testing.expectEqualStrings(expected, aw.written()); |
| 403 | } | 404 | } |
| 404 | 405 |