A BUNCH OF STUFF
Metadata reading Directory reading Decompile cache Actual SfsFile implementation Finished Inode implementation Actually build unsquashfs
This commit is contained in:
+88
-3
@@ -1,7 +1,92 @@
|
||||
const SfsFile = @This();
|
||||
|
||||
alloc: std.mem.Allocator,
|
||||
archive: *Archive,
|
||||
|
||||
inode: Inode,
|
||||
name: []const u8,
|
||||
|
||||
/// The given allocator must have been used to create the Inode and name.
|
||||
pub fn init(alloc: std.mem.Allocator, archive: *Archive, inode: Inode, name: []const u8) SfsFile {
|
||||
return .{
|
||||
.alloc = alloc,
|
||||
.archive = archive,
|
||||
|
||||
.inode = inode,
|
||||
.name = name,
|
||||
};
|
||||
}
|
||||
pub fn initDirEntry(alloc: std.mem.Allocator, io: Io, archive: *Archive, entry: Directory.Entry) !SfsFile {
|
||||
const new_name = try alloc.alloc(u8, entry.name.len);
|
||||
defer alloc.free(new_name);
|
||||
@memcpy(new_name, entry.name);
|
||||
|
||||
return .{
|
||||
.alloc = alloc,
|
||||
.archive = archive,
|
||||
|
||||
.inode = try .initDirEntry(
|
||||
alloc,
|
||||
io,
|
||||
archive.cache,
|
||||
archive.super.inode_start,
|
||||
archive.super.block_size,
|
||||
entry,
|
||||
),
|
||||
.name = new_name,
|
||||
};
|
||||
}
|
||||
/// Creates a new copy of the given SfsFile using the given allocator
|
||||
pub fn copy(self: SfsFile, alloc: std.mem.Allocator) !SfsFile {
|
||||
const new_name = try alloc(u8, self.name.len);
|
||||
errdefer alloc.free(new_name);
|
||||
|
||||
return .{
|
||||
.alloc = alloc,
|
||||
.archive = self.archive,
|
||||
|
||||
.inode = try self.inode.copy(alloc),
|
||||
.name = new_name,
|
||||
};
|
||||
}
|
||||
pub fn deinit(self: SfsFile) void {
|
||||
self.inode.deinit(self.alloc);
|
||||
self.alloc.free(self.name);
|
||||
}
|
||||
|
||||
/// Attempts to open the filepath if the SfsFile is a directory.
|
||||
/// If the given path refers to itself (such as "" or "."), a copied SfsFile is returned.
|
||||
pub fn open(self: SfsFile, alloc: std.mem.Allocator, io: Io, filepath: []const u8) !SfsFile {
|
||||
const path = std.mem.trim(u8, filepath, "/");
|
||||
|
||||
const first_element: []const u8 = std.mem.sliceTo(path, '/');
|
||||
|
||||
const dir: Directory = try self.inode.directory(alloc, io, self.archive.cache, self.archive.super.dir_start);
|
||||
defer dir.deinit(alloc);
|
||||
|
||||
var cur_slice = dir.entries;
|
||||
var idx: usize = undefined;
|
||||
while (cur_slice.len > 0) {
|
||||
idx = cur_slice.len / 2;
|
||||
switch (std.mem.order(u8, first_element, cur_slice[idx].name)) {
|
||||
.eq => break,
|
||||
.lt => cur_slice = cur_slice[0..idx],
|
||||
.gt => cur_slice = cur_slice[idx..],
|
||||
}
|
||||
} else {
|
||||
return error.NotFound;
|
||||
}
|
||||
if (first_element.len == path) return .initDirEntry(alloc, io, self.archive, cur_slice[idx]);
|
||||
if (cur_slice[idx].type != .dir) return error.NotFound;
|
||||
const tmp_file: SfsFile = try .initDirEntry(alloc, io, self.archive, cur_slice[idx]);
|
||||
defer tmp_file.deinit();
|
||||
|
||||
return tmp_file.open(alloc, io, path[first_element.len..]);
|
||||
}
|
||||
|
||||
const std = @import("std");
|
||||
const Io = std.Io;
|
||||
|
||||
const Archive = @import("archive.zig");
|
||||
const Directory = @import("directory.zig");
|
||||
const Inode = @import("inode.zig");
|
||||
|
||||
name: []const u8,
|
||||
inode: Inode,
|
||||
|
||||
Reference in New Issue
Block a user