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),
|
.ext_file => |f| alloc.free(f.block_sizes),
|
||||||
.symlink => |s| alloc.free(s.target),
|
.symlink => |s| alloc.free(s.target),
|
||||||
.ext_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 std = @import("std");
|
||||||
|
|
||||||
const Inode = @import("inode.zig");
|
const Inode = @import("inode.zig");
|
||||||
|
const File = @import("file.zig").File;
|
||||||
const Table = @import("table.zig").Table;
|
const Table = @import("table.zig").Table;
|
||||||
const PRead = @import("reader/p_read.zig").PRead;
|
const PRead = @import("reader/p_read.zig").PRead;
|
||||||
const FragEntry = @import("fragment.zig").FragEntry;
|
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.
|
/// 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.
|
/// 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,
|
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 {
|
pub fn init(alloc: std.mem.Allocator, rdr: T, offset: u64) !Self {
|
||||||
var out: Self = .{
|
var out: Self = .{
|
||||||
@@ -45,7 +46,31 @@ pub fn SfsReader(comptime T: type) type {
|
|||||||
self.id_table.deinit();
|
self.id_table.deinit();
|
||||||
self.frag_table.deinit();
|
self.frag_table.deinit();
|
||||||
self.export_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.
|
/// Returns the inode with the given Inode Number.
|
||||||
|
|||||||
+76
-5
@@ -1,6 +1,6 @@
|
|||||||
const std = @import("std");
|
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 FragEntry = @import("../fragment.zig").FragEntry;
|
||||||
const BlockSize = @import("../inode/file.zig").BlockSize;
|
const BlockSize = @import("../inode/file.zig").BlockSize;
|
||||||
const Compression = @import("../superblock.zig").Compression;
|
const Compression = @import("../superblock.zig").Compression;
|
||||||
@@ -10,16 +10,21 @@ pub fn DataReader(comptime T: type) type {
|
|||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
alloc: std.mem.Allocator,
|
alloc: std.mem.Allocator,
|
||||||
|
pool: ?*std.Thread.Pool = null,
|
||||||
|
|
||||||
rdr: PRead(T),
|
rdr: PRead(T),
|
||||||
comp: Compression,
|
comp: Compression,
|
||||||
offsets: []BlockSize,
|
offsets: []u64,
|
||||||
|
|
||||||
file_size: u64,
|
file_size: u64,
|
||||||
block_size: u32,
|
block_size: u32,
|
||||||
sizes: []BlockSize,
|
sizes: []BlockSize,
|
||||||
|
|
||||||
frag: []u8 = undefined,
|
frag: []u8 = &[0]u8{},
|
||||||
|
|
||||||
|
read_block: []u8,
|
||||||
|
read_offset: u64,
|
||||||
|
read_idx: u32 = 0,
|
||||||
|
|
||||||
pub fn init(
|
pub fn init(
|
||||||
alloc: std.mem.Allocator,
|
alloc: std.mem.Allocator,
|
||||||
@@ -46,10 +51,76 @@ pub fn DataReader(comptime T: type) type {
|
|||||||
.sizes = sizes,
|
.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 {
|
pub fn addFragment(self: *Self, entry: FragEntry, offset: u32) !void {
|
||||||
self.frag = self.alloc.alloc(u8, self.file_size % self.block_size);
|
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:
|
||||||
}
|
}
|
||||||
|
//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);
|
_ = try self.rdr.pread(std.mem.asBytes(hdr), self.offset);
|
||||||
self.offset += 2;
|
self.offset += 2;
|
||||||
self.block_size = try self.comp.decompress(
|
self.block_size = try self.comp.decompress(
|
||||||
8192,
|
|
||||||
self.alloc,
|
self.alloc,
|
||||||
std.io.limitedReader(self.rdr.readerAt(self.offset), hdr.size),
|
std.io.limitedReader(self.rdr.readerAt(self.offset), hdr.size),
|
||||||
self.block,
|
&self.block,
|
||||||
);
|
);
|
||||||
self.offset += hdr.size;
|
self.offset += hdr.size;
|
||||||
self.block_offset = 0;
|
self.block_offset = 0;
|
||||||
|
|||||||
+2
-2
@@ -51,7 +51,7 @@ pub const Compression = enum(u16) {
|
|||||||
lz4,
|
lz4,
|
||||||
zstd,
|
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) {
|
switch (self) {
|
||||||
.gzip => {
|
.gzip => {
|
||||||
const decomp = std.compress.zlib.decompressor(source);
|
const decomp = std.compress.zlib.decompressor(source);
|
||||||
@@ -70,7 +70,7 @@ pub const Compression = enum(u16) {
|
|||||||
},
|
},
|
||||||
.lz4 => return DecompressError.Lz4Unavailable,
|
.lz4 => return DecompressError.Lz4Unavailable,
|
||||||
.zstd => {
|
.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 });
|
const decomp = std.compress.zstd.decompressor(source, .{ .window_buffer = window });
|
||||||
return decomp.read(dest);
|
return decomp.read(dest);
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user