Merge pull request #263 from ZystemOS/feature/mkfat32-any-stream

mkFAT32 use a anytype stream
This commit is contained in:
Edward Dean 2020-11-11 16:58:59 +00:00 committed by GitHub
commit ea6a0b7a9f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 49 deletions

View file

@ -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);
}
///

View file

@ -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);
}
};