From 4f47409af6a34bf31c50eccef353076c9353bfd1 Mon Sep 17 00:00:00 2001 From: DrDeano Date: Mon, 9 Nov 2020 19:06:31 +0000 Subject: [PATCH] mkFAT32 use a anytype stream This allows mkFAT32 to work on a File or a fixedBufferStream or any streram that allows for reader(), writer() or seekableStream() interfaces. --- build.zig | 8 ++++- mkfat32.zig | 90 +++++++++++++++++++++++++---------------------------- 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/build.zig b/build.zig index 3827878..069dbc0 100644 --- a/build.zig +++ b/build.zig @@ -211,7 +211,13 @@ const Fat32BuilderStep = struct { /// fn make(step: *Step) (error{EndOfStream} || File.OpenError || File.ReadError || File.WriteError || File.SeekError || Fat32.Error)!void { const self = @fieldParentPtr(Fat32BuilderStep, "step", step); - try Fat32.make(self.options, self.out_file_path); + // Open the out file + const image = try std.fs.cwd().createFile(self.out_file_path, .{ .read = true }); + + // If there was an error, delete the image as this will be invalid + errdefer (std.fs.cwd().deleteFile(self.out_file_path) catch unreachable); + defer image.close(); + try Fat32.make(self.options, image); } /// diff --git a/mkfat32.zig b/mkfat32.zig index d36fc9c..468d22b 100644 --- a/mkfat32.zig +++ b/mkfat32.zig @@ -1,5 +1,4 @@ const std = @import("std"); -const File = std.fs.File; // This is the assembly for the FAT bootleader. // [bits 16] @@ -350,23 +349,23 @@ pub const Fat32 = struct { } /// - /// Write the FSInfo and backup FSInfo sector to a image file. This uses a valid FAT32 boot - /// sector header for creating the FSInfo sector. + /// Write the FSInfo and backup FSInfo sector to a stream. This uses a valid FAT32 boot sector + /// header for creating the FSInfo sector. /// /// Argument: - /// IN/OUT image: File - The image file to write the FSInfo to. + /// IN/OUT stream: anytype - The stream to write the FSInfo to. /// IN fat32_header: Header - A valid FAT32 boot header for creating the FSInfo sector. /// IN free_cluster_num: u32 - The number of free data clusters on the image. /// IN next_free_cluster: u32 - The next free data cluster to start looking for when writing /// files. /// - /// Error File.WriteError || File.SeekError - /// File.WriteError - If there is an error when writing to the image. See File.WriteError - /// File.SeekError - If there is an error when seeking the image. See File.SeekError + /// Error @TypeOf(stream).WriteError || @TypeOf(stream).SeekError + /// @TypeOf(stream).WriteError - If there is an error when writing. See the relevant error for the stream. + /// @TypeOf(stream).SeekError - If there is an error when seeking. See the relevant error for the stream. /// - fn writeFSInfo(image: File, fat32_header: Header, free_cluster_num: u32, next_free_cluster: u32) (File.WriteError || File.SeekError)!void { - const seekable_stream = image.seekableStream(); - const writer = image.writer(); + fn writeFSInfo(stream: anytype, fat32_header: Header, free_cluster_num: u32, next_free_cluster: u32) (@TypeOf(stream).WriteError || @TypeOf(stream).SeekError)!void { + const seekable_stream = stream.seekableStream(); + const writer = stream.writer(); // Seek to the correct location try seekable_stream.seekTo(fat32_header.fsinfo_sector * fat32_header.bytes_per_sector); @@ -404,20 +403,20 @@ pub const Fat32 = struct { } /// - /// Write the FAT to the image. This sets up a blank FAT with end marker of 0x0FFFFFFF and root + /// Write the FAT to the stream. This sets up a blank FAT with end marker of 0x0FFFFFFF and root /// directory cluster of 0x0FFFFFFF (one cluster chain). /// /// Argument: - /// IN/OUT image: File - The image file to write the FSInfo to. + /// IN/OUT stream: anytype - The stream to write the FSInfo to. /// IN fat32_header: Header - A valid FAT32 boot header for creating the FAT. /// - /// Error File.WriteError || File.SeekError - /// File.WriteError - If there is an error when writing to the image. See File.WriteError - /// File.SeekError - If there is an error when seeking the image. See File.SeekError + /// Error @TypeOf(stream).WriteError || @TypeOf(stream).SeekError + /// @TypeOf(stream).WriteError - If there is an error when writing. See the relevant error for the stream. + /// @TypeOf(stream).SeekError - If there is an error when seeking. See the relevant error for the stream. /// - fn writeFAT(image: File, fat32_header: Header) (File.WriteError || File.SeekError)!void { - const seekable_stream = image.seekableStream(); - const writer = image.writer(); + fn writeFAT(stream: anytype, fat32_header: Header) (@TypeOf(stream).WriteError || @TypeOf(stream).SeekError)!void { + const seekable_stream = stream.seekableStream(); + const writer = stream.writer(); // This FAT is below the reserved sectors try seekable_stream.seekTo(fat32_header.reserved_sectors * fat32_header.bytes_per_sector); @@ -439,19 +438,19 @@ pub const Fat32 = struct { } /// - /// Write the FAT boot sector with the boot code and FAT32 header to the image. + /// Write the FAT boot sector with the boot code and FAT32 header to the stream. /// /// Argument: - /// IN/OUT image: File - The image file to write the FSInfo to. + /// IN/OUT stream: anytype - The stream to write the FSInfo to. /// IN fat32_header: Header - A valid FAT32 boot header for creating the FAT. /// - /// Error: File.WriteError || File.SeekError - /// File.WriteError - If there is an error when writing to the image. See File.WriteError. - /// File.SeekError - If there is an error when seeking the image. See File.SeekError. + /// Error: @TypeOf(stream).WriteError || @TypeOf(stream).SeekError + /// @TypeOf(stream).WriteError - If there is an error when writing. See the relevant error for the stream. + /// @TypeOf(stream).SeekError - If there is an error when seeking. See the relevant error for the stream. /// - fn writeBootSector(image: File, fat32_header: Header) (File.WriteError || File.SeekError)!void { - const seekable_stream = image.seekableStream(); - const writer = image.writer(); + fn writeBootSector(stream: anytype, fat32_header: Header) (@TypeOf(stream).WriteError || @TypeOf(stream).SeekError)!void { + const seekable_stream = stream.seekableStream(); + const writer = stream.writer(); var boot_sector: [512]u8 = undefined; std.mem.copy(u8, &boot_sector, &bootsector_boot_code); @@ -538,43 +537,38 @@ pub const Fat32 = struct { /// user. The file will be saved to the path specified. /// /// Argument: - /// IN options: Options - The FAT32 options that the user can provide to change - /// the parameters of a FAT32 image. - /// IN out_file_path: []const u8 - The location for which the FAT32 image will be created. + /// IN options: Options - The FAT32 options that the user can provide to change the + /// parameters of a FAT32 image. + /// IN stream: anytype - The stream to create a new FAT32 image. This stream must support + /// reader(), writer() and seekableStream() interfaces. /// - /// Error: File.OpenError || File.WriteError || File.SeekError || Error - /// File.OpenError || File.WriteError || File.SeekError - Error relating to file operations. See std.fs.File. - /// Error.InvalidOptionValue - In the user has provided invalid options. - /// Error.TooLarge - The image size is too small. < 17.5KB. - /// Error.TooSmall - The image size is to large. > 2TB. + /// Error: @TypeOf(stream).WriteError || @TypeOf(stream).SeekError || Error + /// @TypeOf(stream).WriteError - If there is an error when writing. See the relevant error for the stream. + /// @TypeOf(stream).SeekError - If there is an error when seeking. See the relevant error for the stream. + /// Error.InvalidOptionValue - In the user has provided invalid options. + /// Error.TooLarge - The stream size is too small. < 17.5KB. + /// Error.TooSmall - The stream size is to large. > 2TB. /// - pub fn make(options: Options, out_file_path: []const u8) (File.OpenError || File.WriteError || File.SeekError || Error)!void { + pub fn make(options: Options, stream: anytype) (@TypeOf(stream).WriteError || @TypeOf(stream).SeekError || Error)!void { // First set up the header const fat32_header = try Fat32.createFATHeader(options); - // Get the total image size again. As the above has a check for the image size, we don't need one here again + // Get the total image size again. As the above has a check for the size, we don't need one here again const image_size = std.mem.alignBackward(options.image_size, fat32_header.bytes_per_sector); - // Open the out file - const image = try std.fs.cwd().createFile(out_file_path, .{ .read = true }); - - // If there was an error, delete the image as this will be invalid - errdefer (std.fs.cwd().deleteFile(out_file_path) catch unreachable); - defer image.close(); - - // Initialise the image with all zeros - try image.writer().writeByteNTimes(0x00, image_size); + // Initialise the stream with all zeros + try stream.writer().writeByteNTimes(0x00, image_size); // Write the boot sector with the bootstrap code and header and the backup boot sector. - try Fat32.writeBootSector(image, fat32_header); + try Fat32.writeBootSector(stream, fat32_header); // Write the FAT and second FAT - try Fat32.writeFAT(image, fat32_header); + try Fat32.writeFAT(stream, fat32_header); // Calculate the usable clusters. const usable_sectors = fat32_header.total_sectors - fat32_header.reserved_sectors - (fat32_header.fat_count * fat32_header.sectors_per_fat); const usable_clusters = @divFloor(usable_sectors, fat32_header.sectors_per_cluster) - 1; // Write the FSInfo and backup FSInfo sectors - try Fat32.writeFSInfo(image, fat32_header, usable_clusters, 2); + try Fat32.writeFSInfo(stream, fat32_header, usable_clusters, 2); } };