MORE PROGRESS

This commit is contained in:
Caleb Gardner
2025-07-14 01:40:04 -05:00
parent 69d90242ba
commit b0dced90bc
5 changed files with 109 additions and 13 deletions
+1
View File
@@ -94,5 +94,6 @@ pub fn deinit(self: Self, alloc: std.mem.Allocator) void {
.ext_file => |f| alloc.free(f.block_sizes),
.symlink => |s| alloc.free(s.target),
.ext_symlink => |s| alloc.free(s.target),
else => {},
}
}
+27 -2
View File
@@ -1,6 +1,7 @@
const std = @import("std");
const Inode = @import("inode.zig");
const File = @import("file.zig").File;
const Table = @import("table.zig").Table;
const PRead = @import("reader/p_read.zig").PRead;
const FragEntry = @import("fragment.zig").FragEntry;
@@ -28,7 +29,7 @@ pub fn SfsReader(comptime T: type) type {
/// Export table. Each element is an inode referce.
/// If accessing directly, keep in mind, the table starts at inode 1, as such it's recommended to use the InodeAt function instead.
export_table: Table(Inode.Ref, T) = undefined,
root: ?Inode = null,
root: ?File(T) = null,
pub fn init(alloc: std.mem.Allocator, rdr: T, offset: u64) !Self {
var out: Self = .{
@@ -45,7 +46,31 @@ pub fn SfsReader(comptime T: type) type {
self.id_table.deinit();
self.frag_table.deinit();
self.export_table.deinit();
// if (self.root != null) self.root.?.deinit();
if (self.root != null) self.root.?.deinit();
}
fn populateRoot(self: *Self) !void {
if (self.root != null) return;
const meta = MetadataReader(T).init(
self.alloc,
self.super.comp,
self.rdr,
self.super.inode_start + self.super.root_ref.block,
);
try meta.skip(self.super.root_ref.offset);
const root_inode: Inode = try .init(meta, self.alloc, self.super.block_size);
self.root = try .init(self, root_inode, "");
}
pub fn archiveRoot(self: *Self) !File {
if (self.root == null) try self.populateRoot();
return self.root.?;
}
pub fn open(self: *Self, path: []const u8) !File {
if (self.root == null) try self.populateRoot();
_ = path;
// return self.root.?.open(path);
return error{TODO}.TODO;
}
/// Returns the inode with the given Inode Number.
+78 -7
View File
@@ -1,6 +1,6 @@
const std = @import("std");
const PRead = @import("p_read.zig").Pread;
const PRead = @import("p_read.zig").PRead;
const FragEntry = @import("../fragment.zig").FragEntry;
const BlockSize = @import("../inode/file.zig").BlockSize;
const Compression = @import("../superblock.zig").Compression;
@@ -10,16 +10,21 @@ pub fn DataReader(comptime T: type) type {
const Self = @This();
alloc: std.mem.Allocator,
pool: ?*std.Thread.Pool = null,
rdr: PRead(T),
comp: Compression,
offsets: []BlockSize,
offsets: []u64,
file_size: u64,
block_size: u32,
sizes: []BlockSize,
frag: []u8 = undefined,
frag: []u8 = &[0]u8{},
read_block: []u8,
read_offset: u64,
read_idx: u32 = 0,
pub fn init(
alloc: std.mem.Allocator,
@@ -46,10 +51,76 @@ pub fn DataReader(comptime T: type) type {
.sizes = sizes,
};
}
pub fn addFragment(self: *Self, entry: FragEntry, offset: u32) void {
self.frag = self.alloc.alloc(u8, self.file_size % self.block_size);
//TODO:
pub fn deinit(self: Self) void {
self.alloc.free(self.offsets);
self.alloc.free(self.frag);
}
pub fn addFragment(self: *Self, entry: FragEntry, offset: u32) !void {
self.frag = try self.alloc.alloc(u8, self.file_size % self.block_size);
if (entry.size.size == 0) {
@memset(self.frag, 0);
return;
} else if (entry.size.uncompressed) {
_ = try self.rdr.pread(self.frag, entry.block + offset);
return;
}
const block = try self.alloc.alloc(u8, offset + self.frag.len);
defer self.alloc.free(block);
_ = try self.comp.decompress(
self.alloc,
std.io.limitedReader(
self.rdr.readerAt(entry.block),
entry.size.size,
),
block,
);
@memcpy(self.frag, block[offset..]);
}
pub fn setPool(self: *Self, pool: *std.Thread.Pool) void {
self.pool = pool;
}
fn blockAt(self: Self, idx: u32) ![]u8 {
const size = if (idx == self.sizes.len - 1 and self.frag.len == 0) {
self.file_size % self.block_size;
} else {
self.block_size;
};
const block = try self.alloc.alloc(u8, size);
errdefer self.alloc.free(block);
if (self.sizes[idx].size == 0) {
@memset(block, 0);
return block;
} else if (self.sizes[idx].uncompressed) {
_ = try self.rdr.pread(block, self.offsets[idx]);
return block;
}
_ = try self.comp.decompress(
self.alloc,
std.io.limitedReader(
self.rdr.readerAt(self.offsets[idx]),
self.sizes[idx].size,
),
block,
);
return block;
}
pub fn read(self: *Self, buf: []u8) !usize {
var cur_red: usize = 0;
while (cur_red < buf.len) {
if (self.read_offset >= self.read_block.len) {
//TODO:
}
//TODO:
}
return cur_red;
}
/// Write the entire file's contents to the writer.
/// If availble, pwrite will be used.
/// If a thread pool is not set via setPool, one is created based on cpu thread count.
pub fn writeTo(self: Self, writer: anytype) !usize {}
};
}
+1 -2
View File
@@ -36,10 +36,9 @@ pub fn MetadataReader(comptime T: type) type {
_ = try self.rdr.pread(std.mem.asBytes(hdr), self.offset);
self.offset += 2;
self.block_size = try self.comp.decompress(
8192,
self.alloc,
std.io.limitedReader(self.rdr.readerAt(self.offset), hdr.size),
self.block,
&self.block,
);
self.offset += hdr.size;
self.block_offset = 0;
+2 -2
View File
@@ -51,7 +51,7 @@ pub const Compression = enum(u16) {
lz4,
zstd,
pub fn decompress(self: Compression, comptime max_size: u16, alloc: std.mem.Allocator, source: anytype, dest: *[max_size]u8) !usize {
pub fn decompress(self: Compression, alloc: std.mem.Allocator, source: anytype, dest: []u8) !usize {
switch (self) {
.gzip => {
const decomp = std.compress.zlib.decompressor(source);
@@ -70,7 +70,7 @@ pub const Compression = enum(u16) {
},
.lz4 => return DecompressError.Lz4Unavailable,
.zstd => {
const window: [@min(std.compress.zstd.DecompressorOptions.default_window_buffer_len, max_size)]u8 = undefined;
const window: [@min(std.compress.zstd.DecompressorOptions.default_window_buffer_len, dest.len)]u8 = undefined;
const decomp = std.compress.zstd.decompressor(source, .{ .window_buffer = window });
return decomp.read(dest);
},