Fixed the final, lingering issues.
Updated README
This commit is contained in:
@@ -1,3 +1,7 @@
|
|||||||
# zig-squashfs
|
# zig-squashfs
|
||||||
|
|
||||||
Messing around with zig via making a squashfs library. May amount to something. Or not.
|
Messing around with zig via making a squashfs library. May amount to something. Or not.
|
||||||
|
|
||||||
|
## Current state
|
||||||
|
|
||||||
|
Everything seems to be working now, but performance is absolutely garbage.
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
.{
|
.{
|
||||||
.name = .zig_squashfs,
|
.name = .zig_squashfs,
|
||||||
.version = "0.0.0",
|
.version = "0.0.1",
|
||||||
.fingerprint = 0x527960c72c03ffe3, // Changing this has security and trust implications.
|
.fingerprint = 0x527960c72c03ffe3, // Changing this has security and trust implications.
|
||||||
|
|
||||||
.minimum_zig_version = "0.14.0",
|
.minimum_zig_version = "0.14.0",
|
||||||
|
|||||||
+3
-3
@@ -2,9 +2,9 @@ const std = @import("std");
|
|||||||
const io = std.io;
|
const io = std.io;
|
||||||
|
|
||||||
pub const BlockSize = packed struct {
|
pub const BlockSize = packed struct {
|
||||||
size: u23,
|
size: u24,
|
||||||
not_compressed: bool,
|
not_compressed: bool,
|
||||||
_: u8,
|
_: u7,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const FileInode = struct {
|
pub const FileInode = struct {
|
||||||
@@ -15,7 +15,7 @@ pub const FileInode = struct {
|
|||||||
blocks: []const BlockSize,
|
blocks: []const BlockSize,
|
||||||
|
|
||||||
pub fn init(alloc: std.mem.Allocator, rdr: io.AnyReader, block_size: u32) !FileInode {
|
pub fn init(alloc: std.mem.Allocator, rdr: io.AnyReader, block_size: u32) !FileInode {
|
||||||
var fixed_buf = [1]u8{0} ** 16;
|
var fixed_buf: [16]u8 = undefined;
|
||||||
_ = try rdr.readAll(&fixed_buf);
|
_ = try rdr.readAll(&fixed_buf);
|
||||||
const frag_idx = std.mem.bytesToValue(u32, fixed_buf[4..8]);
|
const frag_idx = std.mem.bytesToValue(u32, fixed_buf[4..8]);
|
||||||
const size = std.mem.bytesToValue(u32, fixed_buf[12..16]);
|
const size = std.mem.bytesToValue(u32, fixed_buf[12..16]);
|
||||||
|
|||||||
+16
-18
@@ -85,8 +85,9 @@ pub const Reader = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
test "root iter" {
|
|
||||||
const test_sfs_path = "testing/LinuxPATest.sfs";
|
const test_sfs_path = "testing/LinuxPATest.sfs";
|
||||||
|
|
||||||
|
test "root iter" {
|
||||||
var rdr: Reader = try .init(std.testing.allocator, test_sfs_path, 0);
|
var rdr: Reader = try .init(std.testing.allocator, test_sfs_path, 0);
|
||||||
defer rdr.deinit();
|
defer rdr.deinit();
|
||||||
var rootIter = try rdr.root.iterator(&rdr);
|
var rootIter = try rdr.root.iterator(&rdr);
|
||||||
@@ -96,23 +97,9 @@ test "root iter" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test "extract" {
|
|
||||||
const test_sfs_path = "testing/LinuxPATest.sfs";
|
|
||||||
const extract_path = "testing/testExtract";
|
|
||||||
std.fs.cwd().deleteTree(extract_path) catch |err| {
|
|
||||||
if (err != std.fs.Dir.DeleteFileError.FileNotFound) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var rdr: Reader = try .init(std.testing.allocator, test_sfs_path, 0);
|
|
||||||
defer rdr.deinit();
|
|
||||||
try rdr.root.extract(&rdr, try .init(), extract_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
test "extract single file" {
|
test "extract single file" {
|
||||||
const test_sfs_path = "testing/LinuxPATest.sfs";
|
const sfs_file_path = "PortableApps/Cool_Retro_Term-dac2b4f-x86_64.AppImage";
|
||||||
const sfs_file_path = "Start.exe";
|
const extract_path = "testing/Cool_Retro_Term-dac2b4f-x86_64.AppImage";
|
||||||
const extract_path = "testing/Start.exe";
|
|
||||||
std.fs.cwd().deleteFile(extract_path) catch |err| {
|
std.fs.cwd().deleteFile(extract_path) catch |err| {
|
||||||
if (err != std.fs.Dir.DeleteFileError.FileNotFound) {
|
if (err != std.fs.Dir.DeleteFileError.FileNotFound) {
|
||||||
return err;
|
return err;
|
||||||
@@ -126,7 +113,6 @@ test "extract single file" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "extract single directory" {
|
test "extract single directory" {
|
||||||
const test_sfs_path = "testing/LinuxPATest.sfs";
|
|
||||||
const sfs_file_path = "Documents";
|
const sfs_file_path = "Documents";
|
||||||
const extract_path = "testing/Documents";
|
const extract_path = "testing/Documents";
|
||||||
try std.fs.cwd().deleteTree(extract_path);
|
try std.fs.cwd().deleteTree(extract_path);
|
||||||
@@ -138,3 +124,15 @@ test "extract single directory" {
|
|||||||
config.verbose = true;
|
config.verbose = true;
|
||||||
try fil.extract(&rdr, config, extract_path);
|
try fil.extract(&rdr, config, extract_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "full extract" {
|
||||||
|
const extract_path = "testing/testExtract";
|
||||||
|
std.fs.cwd().deleteTree(extract_path) catch |err| {
|
||||||
|
if (err != std.fs.Dir.DeleteFileError.FileNotFound) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var rdr: Reader = try .init(std.testing.allocator, test_sfs_path, 0);
|
||||||
|
defer rdr.deinit();
|
||||||
|
try rdr.root.extract(&rdr, try .init(), extract_path);
|
||||||
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ pub const DataExtractor = struct {
|
|||||||
if (self.frag_data != null) self.alloc.free(self.frag_data.?);
|
if (self.frag_data != null) self.alloc.free(self.frag_data.?);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn processBlockToFile(self: *DataExtractor, wg: *std.Thread.WaitGroup, errs: *std.ArrayList(anyerror), block_ind: usize, fil: *fs.File) void {
|
fn processBlockToFile(self: *DataExtractor, wg: *std.Thread.WaitGroup, errs: *MutexList, block_ind: usize, fil: *fs.File) void {
|
||||||
defer wg.finish();
|
defer wg.finish();
|
||||||
if (self.sizes[block_ind].not_compressed) {
|
if (self.sizes[block_ind].not_compressed) {
|
||||||
@branchHint(.unlikely);
|
@branchHint(.unlikely);
|
||||||
@@ -95,18 +95,15 @@ pub const DataExtractor = struct {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const dat = self.alloc.alloc(u8, self.sizes[block_ind].size) catch |err| {
|
const dat = self.alloc.alloc(u8, self.sizes[block_ind].size) catch |err| {
|
||||||
std.debug.print("yo3\n", .{});
|
|
||||||
errs.append(err) catch {};
|
errs.append(err) catch {};
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
defer self.alloc.free(dat);
|
defer self.alloc.free(dat);
|
||||||
_ = fil.preadAll(dat, self.block_offset[block_ind]) catch |err| {
|
_ = self.holder.file.preadAll(dat, self.block_offset[block_ind]) catch |err| {
|
||||||
std.debug.print("yo4\n", .{});
|
|
||||||
errs.append(err) catch {};
|
errs.append(err) catch {};
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
fil.pwriteAll(dat, block_ind * self.block_size) catch |err| {
|
fil.pwriteAll(dat, block_ind * self.block_size) catch |err| {
|
||||||
std.debug.print("yo5\n", .{});
|
|
||||||
errs.append(err) catch {};
|
errs.append(err) catch {};
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
@@ -119,16 +116,14 @@ pub const DataExtractor = struct {
|
|||||||
limit.reader().any(),
|
limit.reader().any(),
|
||||||
fil_wrtr.any(),
|
fil_wrtr.any(),
|
||||||
) catch |err| {
|
) catch |err| {
|
||||||
std.debug.print("yo6\n", .{});
|
|
||||||
errs.append(err) catch {};
|
errs.append(err) catch {};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fragmentToFile(self: *DataExtractor, wg: *std.Thread.WaitGroup, errs: *std.ArrayList(anyerror), fil: *fs.File) void {
|
fn fragmentToFile(self: *DataExtractor, wg: *std.Thread.WaitGroup, errs: *MutexList, fil: *fs.File) void {
|
||||||
defer wg.finish();
|
defer wg.finish();
|
||||||
fil.pwriteAll(self.frag_data.?, self.block_size * self.sizes.len) catch |err| {
|
fil.pwriteAll(self.frag_data.?, self.block_size * self.sizes.len) catch |err| {
|
||||||
std.debug.print("yo7\n", .{});
|
|
||||||
errs.append(err) catch {};
|
errs.append(err) catch {};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -140,7 +135,7 @@ pub const DataExtractor = struct {
|
|||||||
/// Optimized for lower memory usage by using File.pwrite.
|
/// Optimized for lower memory usage by using File.pwrite.
|
||||||
pub fn writeToFile(self: *DataExtractor, pool: *std.Thread.Pool, fil: *fs.File) !void {
|
pub fn writeToFile(self: *DataExtractor, pool: *std.Thread.Pool, fil: *fs.File) !void {
|
||||||
var wg: std.Thread.WaitGroup = .{};
|
var wg: std.Thread.WaitGroup = .{};
|
||||||
var errs: std.ArrayList(anyerror) = .init(self.alloc);
|
var errs: MutexList = .init(self.alloc);
|
||||||
defer errs.deinit();
|
defer errs.deinit();
|
||||||
for (0..self.sizes.len) |i| {
|
for (0..self.sizes.len) |i| {
|
||||||
wg.start();
|
wg.start();
|
||||||
@@ -151,9 +146,9 @@ pub const DataExtractor = struct {
|
|||||||
try pool.spawn(fragmentToFile, .{ self, &wg, &errs, fil });
|
try pool.spawn(fragmentToFile, .{ self, &wg, &errs, fil });
|
||||||
}
|
}
|
||||||
wg.wait();
|
wg.wait();
|
||||||
if (errs.items.len > 0) {
|
if (errs.list.items.len > 0) {
|
||||||
//TODO: better handle all the errors
|
//TODO: better handle all the errors
|
||||||
return errs.items[0];
|
return errs.list.items[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,3 +180,23 @@ pub const DataExtractor = struct {
|
|||||||
// wg.wait();
|
// wg.wait();
|
||||||
// }
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const MutexList = struct {
|
||||||
|
list: std.ArrayList(anyerror),
|
||||||
|
mut: std.Thread.Mutex = .{},
|
||||||
|
|
||||||
|
fn init(alloc: std.mem.Allocator) MutexList {
|
||||||
|
return .{
|
||||||
|
.list = .init(alloc),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
fn deinit(self: *MutexList) void {
|
||||||
|
self.list.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn append(self: *MutexList, err: anyerror) !void {
|
||||||
|
self.mut.lock();
|
||||||
|
defer self.mut.unlock();
|
||||||
|
try self.list.append(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ pub fn main() !void {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
defer args.deinit();
|
defer args.deinit();
|
||||||
|
_ = args.next();
|
||||||
while (args.next()) |arg| {
|
while (args.next()) |arg| {
|
||||||
if (std.mem.eql(u8, arg, "--help") or std.mem.eql(u8, arg, "-h")) {
|
if (std.mem.eql(u8, arg, "--help") or std.mem.eql(u8, arg, "-h")) {
|
||||||
try help();
|
try help();
|
||||||
|
|||||||
Reference in New Issue
Block a user