From 82011a092cfdc55b68d18f33186bd8be126f8303 Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Sat, 24 May 2025 05:24:05 -0500 Subject: [PATCH] Small tweaks and fixes --- src/decompress.zig | 39 ++++++++++++++++++++++++++++++++++ src/inode/file.zig | 10 ++++----- src/reader.zig | 2 +- src/readers/data_extractor.zig | 35 ++++++++++++++++++++++++++++-- 4 files changed, 78 insertions(+), 8 deletions(-) diff --git a/src/decompress.zig b/src/decompress.zig index 9029792..ed43d87 100644 --- a/src/decompress.zig +++ b/src/decompress.zig @@ -43,4 +43,43 @@ pub const DecompressType = enum(u16) { } return out; } + + pub fn decompressTo(self: DecompressType, alloc: std.mem.Allocator, rdr: io.AnyReader, writer: io.AnyWriter) !void { + const buf_size: usize = 1024; + switch (self) { + .zlib => try compress.zlib.decompress(rdr, writer), + .lzma => { + var decomp = try compress.lzma.decompress(alloc, rdr); + defer decomp.deinit(); + const buf: [buf_size]u8 = {}; + var red = try decomp.read(&buf); + while (red > 0) : (red = try decomp.read()) { + _ = try writer.writeAll(&buf); + } + }, + .lzo => return DecompressError.LzoUnsupported, + .xz => { + var decomp = try compress.xz.decompress(alloc, rdr); + defer decomp.deinit(); + const buf: [buf_size]u8 = {}; + var red = try decomp.read(&buf); + while (red > 0) : (red = try decomp.read()) { + _ = try writer.writeAll(&buf); + } + }, + .lz4 => return DecompressError.Lz4Unsupported, + .zstd => { + const window_buf = try alloc.alloc(u8, compress.zstd.DecompressorOptions.default_window_buffer_len); + defer alloc.free(window_buf); + var decomp = compress.zstd.decompressor(rdr, .{ + .window_buffer = window_buf, + }); + const buf: [buf_size]u8 = {}; + var red = try decomp.read(&buf); + while (red > 0) : (red = try decomp.read()) { + _ = try writer.writeAll(&buf); + } + }, + } + } }; diff --git a/src/inode/file.zig b/src/inode/file.zig index 41a1d12..4f70b19 100644 --- a/src/inode/file.zig +++ b/src/inode/file.zig @@ -15,12 +15,12 @@ pub const FileInode = struct { blocks: []const BlockSize, pub fn init(alloc: std.mem.Allocator, rdr: io.AnyReader, block_size: u32) !FileInode { - var fixed_buf = [_]u8{0} ** 16; - _ = try rdr.readAll(@ptrCast(&fixed_buf)); + const fixed_buf = [16]u8{}; + _ = try rdr.readAll(&fixed_buf); const frag_idx = std.mem.bytesToValue(u32, fixed_buf[4..8]); const size = std.mem.bytesToValue(u32, fixed_buf[12..16]); var block_num = size / block_size; - if (frag_idx != 0xFFFFFFFF) { + if (frag_idx == 0xFFFFFFFF and size % block_size > 0) { block_num += 1; } const blocks = try alloc.alloc(BlockSize, block_num); @@ -49,12 +49,12 @@ pub const ExtFileInode = struct { blocks: []const BlockSize, pub fn init(alloc: std.mem.Allocator, rdr: io.AnyReader, block_size: u32) !ExtFileInode { - var fixed_buf = [_]u8{0} ** 40; + var fixed_buf = [40]u8{}; _ = try rdr.readAll(&fixed_buf); const size = std.mem.bytesToValue(u64, fixed_buf[8..16]); const frag_idx = std.mem.bytesToValue(u32, fixed_buf[28..32]); var block_num = size / block_size; - if (frag_idx != 0xFFFFFFFF) { + if (frag_idx == 0xFFFFFFFF and size % block_size > 0) { block_num += 1; } const blocks = try alloc.alloc(BlockSize, block_num); diff --git a/src/reader.zig b/src/reader.zig index a62aab1..d241d43 100644 --- a/src/reader.zig +++ b/src/reader.zig @@ -8,7 +8,7 @@ const Superblock = @import("superblock.zig").Superblock; const File = @import("file.zig").File; const MetadataReader = @import("readers/metadata.zig").MetadataReader; const DirEntry = @import("directory.zig").DirEntry; -const FragEntry = @import("readers/data.zig").FragEntry; +const FragEntry = @import("readers/data_reader.zig").FragEntry; /// A squashfs archive reader. Make sure to call deinit(). /// For most actions, you'll want to use the Reader.root File. diff --git a/src/readers/data_extractor.zig b/src/readers/data_extractor.zig index 7296368..437e729 100644 --- a/src/readers/data_extractor.zig +++ b/src/readers/data_extractor.zig @@ -1,5 +1,6 @@ const std = @import("std"); const fs = std.fs; +const io = std.io; const File = @import("../file.zig").File; const Reader = @import("../reader.zig").Reader; @@ -19,6 +20,20 @@ pub const DataExtractor = struct { block_offset: []u64, frag_data: ?[]u8 = null, + pub const Config = struct { + /// The amount of worker threads to spawn. Defaults to your cpu core count. + thread_count: u16, + /// The maximum amount of additional memory this extraction will use. + /// Default is 1GB. + max_mem: u64, + pub fn init() !Config { + return .{ + .thread_count = try std.Thread.getCpuCount(), + .max_mem = comptime 1024 * 1024 * 1024, + }; + } + }; + pub fn init(fil: *File, reader: *Reader) !DataExtractor { var data_start: u64 = 0; var sizes: []BlockSize = undefined; @@ -78,10 +93,15 @@ pub const DataExtractor = struct { } fn processBlock(self: DataExtractor, block_ind: u32) ![]u8 { + _ = self; + _ = block_ind; //TODO } fn processBlockToFile(self: DataExtractor, block_ind: u32, fil: *fs.File) !void { + _ = self; + _ = block_ind; + _ = fil; //TODO } @@ -90,7 +110,10 @@ pub const DataExtractor = struct { /// Returns the amount of bytes written. /// /// Optimized for lower memory usage by using File.pwrite. - pub fn writeToFile(self: DataExtractor, fil: *fs.File) !void { + pub fn writeToFile(self: DataExtractor, conf: Config, fil: *fs.File) !void { + _ = self; + _ = fil; + _ = conf; //TODO } @@ -98,7 +121,15 @@ pub const DataExtractor = struct { /// Returns the amount of bytes written. /// /// To write data in order, some data may end up cached temporarily. - pub fn writeToWriter(self: DataExtractor, writer: io.AnyWriter) !void { + pub fn writeToWriter(self: DataExtractor, conf: Config, writer: io.AnyWriter) !void { + var pol: std.Thread.Pool = .{}; + pol.init(std.Thread.Pool.Options{ + .allocator = std.heap.page_allocator, + .n_jobs = 5, + }); + _ = self; + _ = writer; + _ = conf; //TODO } };