| ... | ... | @@ -104,11 +104,11 @@ pub const Node = struct { |
| 104 | 104 | } |
| 105 | 105 | }; |
| 106 | 106 | |
| 107 | | const Parent = enum(u16) { |
| 107 | const Parent = enum(u8) { |
| 108 | 108 | /// Unallocated storage. |
| 109 | | unused = std.math.maxInt(u16) - 1, |
| 109 | unused = std.math.maxInt(u8) - 1, |
| 110 | 110 | /// Indicates root node. |
| 111 | | none = std.math.maxInt(u16), |
| 111 | none = std.math.maxInt(u8), |
| 112 | 112 | /// Index into `node_storage`. |
| 113 | 113 | _, |
| 114 | 114 | |
| ... | ... | @@ -120,8 +120,8 @@ pub const Node = struct { |
| 120 | 120 | } |
| 121 | 121 | }; |
| 122 | 122 | |
| 123 | | const OptionalIndex = enum(u16) { |
| 124 | | none = std.math.maxInt(u16), |
| 123 | const OptionalIndex = enum(u8) { |
| 124 | none = std.math.maxInt(u8), |
| 125 | 125 | /// Index into `node_storage`. |
| 126 | 126 | _, |
| 127 | 127 | |
| ... | ... | @@ -137,7 +137,7 @@ pub const Node = struct { |
| 137 | 137 | }; |
| 138 | 138 | |
| 139 | 139 | /// Index into `node_storage`. |
| 140 | | const Index = enum(u16) { |
| 140 | const Index = enum(u8) { |
| 141 | 141 | _, |
| 142 | 142 | |
| 143 | 143 | fn toParent(i: @This()) Parent { |
| ... | ... | @@ -589,8 +589,6 @@ fn serialize(serialized_buffer: *Serialized.Buffer) Serialized { |
| 589 | 589 | }; |
| 590 | 590 | } |
| 591 | 591 | |
| 592 | | var ipc_metadata_len: u16 = 0; |
| 593 | | |
| 594 | 592 | const SavedMetadata = struct { |
| 595 | 593 | ipc_fd: u16, |
| 596 | 594 | main_index: u8, |
| ... | ... | @@ -612,6 +610,9 @@ const SavedMetadata = struct { |
| 612 | 610 | } |
| 613 | 611 | }; |
| 614 | 612 | |
| 613 | var ipc_metadata_len: u8 = 0; |
| 614 | var remaining_read_trash_bytes: usize = 0; |
| 615 | |
| 615 | 616 | fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buffer) usize { |
| 616 | 617 | const ipc_metadata_copy = &serialized_buffer.ipc_metadata_copy; |
| 617 | 618 | const ipc_metadata = &serialized_buffer.ipc_metadata; |
| ... | ... | @@ -641,36 +642,43 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff |
| 641 | 642 | }, |
| 642 | 643 | }; |
| 643 | 644 | if (n == 0) break; |
| 645 | if (remaining_read_trash_bytes > 0) { |
| 646 | assert(bytes_read == 0); |
| 647 | if (remaining_read_trash_bytes >= n) { |
| 648 | remaining_read_trash_bytes -= n; |
| 649 | continue; |
| 650 | } |
| 651 | const src = pipe_buf[remaining_read_trash_bytes..n]; |
| 652 | std.mem.copyForwards(u8, &pipe_buf, src); |
| 653 | remaining_read_trash_bytes = 0; |
| 654 | bytes_read = src.len; |
| 655 | continue; |
| 656 | } |
| 644 | 657 | bytes_read += n; |
| 645 | 658 | } |
| 646 | 659 | // Ignore all but the last message on the pipe. |
| 647 | | var input: []align(2) u8 = pipe_buf[0..bytes_read]; |
| 660 | var input: []u8 = pipe_buf[0..bytes_read]; |
| 648 | 661 | if (input.len == 0) { |
| 649 | 662 | serialized_len = useSavedIpcData(serialized_len, serialized_buffer, main_storage, main_index, old_ipc_metadata); |
| 650 | 663 | continue; |
| 651 | 664 | } |
| 652 | 665 | |
| 653 | 666 | const storage, const parents = while (true) { |
| 654 | | if (input.len < 4) { |
| 655 | | std.log.warn("short read: {d} out of 4 header bytes", .{input.len}); |
| 656 | | // TODO keep track of the short read to trash odd bytes with the next read |
| 657 | | serialized_len = useSavedIpcData(serialized_len, serialized_buffer, main_storage, main_index, old_ipc_metadata); |
| 658 | | continue :main_loop; |
| 659 | | } |
| 660 | | const subtree_len = std.mem.readInt(u32, input[0..4], .little); |
| 661 | | const expected_bytes = 4 + subtree_len * (@sizeOf(Node.Storage) + @sizeOf(Node.Parent)); |
| 667 | const subtree_len: usize = input[0]; |
| 668 | const expected_bytes = 1 + subtree_len * (@sizeOf(Node.Storage) + @sizeOf(Node.Parent)); |
| 662 | 669 | if (input.len < expected_bytes) { |
| 663 | | std.log.warn("short read: {d} out of {d} ({d} nodes)", .{ input.len, expected_bytes, subtree_len }); |
| 664 | | // TODO keep track of the short read to trash odd bytes with the next read |
| 670 | // Ignore short reads. We'll handle the next full message when it comes instead. |
| 671 | assert(remaining_read_trash_bytes == 0); |
| 672 | remaining_read_trash_bytes = expected_bytes - input.len; |
| 665 | 673 | serialized_len = useSavedIpcData(serialized_len, serialized_buffer, main_storage, main_index, old_ipc_metadata); |
| 666 | 674 | continue :main_loop; |
| 667 | 675 | } |
| 668 | 676 | if (input.len > expected_bytes) { |
| 669 | | input = @alignCast(input[expected_bytes..]); |
| 677 | input = input[expected_bytes..]; |
| 670 | 678 | continue; |
| 671 | 679 | } |
| 672 | | const storage_bytes = input[4..][0 .. subtree_len * @sizeOf(Node.Storage)]; |
| 673 | | const parents_bytes = input[4 + storage_bytes.len ..][0 .. subtree_len * @sizeOf(Node.Parent)]; |
| 680 | const storage_bytes = input[1..][0 .. subtree_len * @sizeOf(Node.Storage)]; |
| 681 | const parents_bytes = input[1 + storage_bytes.len ..][0 .. subtree_len * @sizeOf(Node.Parent)]; |
| 674 | 682 | break .{ |
| 675 | 683 | std.mem.bytesAsSlice(Node.Storage, storage_bytes), |
| 676 | 684 | std.mem.bytesAsSlice(Node.Parent, parents_bytes), |
| ... | ... | @@ -722,7 +730,7 @@ fn serializeIpc(start_serialized_len: usize, serialized_buffer: *Serialized.Buff |
| 722 | 730 | return serialized_len; |
| 723 | 731 | } |
| 724 | 732 | |
| 725 | | fn copyRoot(dest: *Node.Storage, src: *align(2) Node.Storage) void { |
| 733 | fn copyRoot(dest: *Node.Storage, src: *align(1) Node.Storage) void { |
| 726 | 734 | dest.* = .{ |
| 727 | 735 | .completed_count = src.completed_count, |
| 728 | 736 | .estimated_total_count = src.estimated_total_count, |
| ... | ... | @@ -937,7 +945,7 @@ fn write(buf: []const u8) void { |
| 937 | 945 | |
| 938 | 946 | fn writeIpc(fd: posix.fd_t, serialized: Serialized) error{BrokenPipe}!void { |
| 939 | 947 | assert(serialized.parents.len == serialized.storage.len); |
| 940 | | const serialized_len: u32 = @intCast(serialized.parents.len); |
| 948 | const serialized_len: u8 = @intCast(serialized.parents.len); |
| 941 | 949 | const header = std.mem.asBytes(&serialized_len); |
| 942 | 950 | const storage = std.mem.sliceAsBytes(serialized.storage); |
| 943 | 951 | const parents = std.mem.sliceAsBytes(serialized.parents); |
| ... | ... | @@ -977,7 +985,9 @@ fn maybeUpdateSize(resize_flag: bool) void { |
| 977 | 985 | var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined; |
| 978 | 986 | |
| 979 | 987 | if (windows.kernel32.GetConsoleScreenBufferInfo(fd, &info) == windows.FALSE) { |
| 980 | | @panic("TODO: handle this failure"); |
| 988 | std.log.debug("failed to determine terminal size; using conservative guess 80x25", .{}); |
| 989 | global_progress.rows = 25; |
| 990 | global_progress.cols = 80; |
| 981 | 991 | } |
| 982 | 992 | |
| 983 | 993 | global_progress.rows = @intCast(info.dwSize.Y); |
| ... | ... | @@ -995,7 +1005,9 @@ fn maybeUpdateSize(resize_flag: bool) void { |
| 995 | 1005 | global_progress.rows = winsize.ws_row; |
| 996 | 1006 | global_progress.cols = winsize.ws_col; |
| 997 | 1007 | } else { |
| 998 | | @panic("TODO: handle this failure"); |
| 1008 | std.log.debug("failed to determine terminal size; using conservative guess 80x25", .{}); |
| 1009 | global_progress.rows = 25; |
| 1010 | global_progress.cols = 80; |
| 999 | 1011 | } |
| 1000 | 1012 | } |
| 1001 | 1013 | } |