MORE PROGRESS
This commit is contained in:
@@ -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
@@ -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.
|
||||
|
||||
+76
-5
@@ -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 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 = self.alloc.alloc(u8, self.file_size % self.block_size);
|
||||
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 {}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user