So close yet so far away
This commit is contained in:
+14
-2
@@ -1,3 +1,5 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
const BlockSize = @import("inode/file.zig").BlockSize;
|
const BlockSize = @import("inode/file.zig").BlockSize;
|
||||||
const Reader = @import("reader.zig").Reader;
|
const Reader = @import("reader.zig").Reader;
|
||||||
|
|
||||||
@@ -6,9 +8,19 @@ pub const FragEntry = packed struct {
|
|||||||
size: BlockSize,
|
size: BlockSize,
|
||||||
_: u32,
|
_: u32,
|
||||||
|
|
||||||
pub fn getData(self: FragEntry, rdr: *Reader, offset: u32) ![]u8 {
|
pub fn getData(self: FragEntry, rdr: *Reader, offset: u32, frag_size: u32) ![]u8 {
|
||||||
|
var offset_rdr = rdr.holder.readerAt(self.start);
|
||||||
if (self.size.not_compressed) {
|
if (self.size.not_compressed) {
|
||||||
//TODO
|
const buf = try rdr.alloc.alloc(u8, frag_size);
|
||||||
|
_ = try offset_rdr.read(buf);
|
||||||
|
return buf;
|
||||||
}
|
}
|
||||||
|
var limit_rdr = std.io.limitedReader(offset_rdr, self.size.size);
|
||||||
|
var decomp = try rdr.super.decomp.decompress(rdr.alloc, limit_rdr.reader().any());
|
||||||
|
var frag_all = try decomp.toOwnedSlice();
|
||||||
|
defer rdr.alloc.free(frag_all);
|
||||||
|
const out = try rdr.alloc.alloc(u8, frag_size);
|
||||||
|
@memcpy(out, frag_all[offset .. offset + frag_size]);
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+12
-12
@@ -96,18 +96,18 @@ test "root iter" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// test "extract" {
|
test "extract" {
|
||||||
// const test_sfs_path = "testing/LinuxPATest.sfs";
|
const test_sfs_path = "testing/LinuxPATest.sfs";
|
||||||
// const extract_path = "testing/testExtract";
|
const extract_path = "testing/testExtract";
|
||||||
// std.fs.cwd().deleteTree(extract_path) catch |err| {
|
std.fs.cwd().deleteTree(extract_path) catch |err| {
|
||||||
// if (err != std.fs.Dir.DeleteFileError.FileNotFound) {
|
if (err != std.fs.Dir.DeleteFileError.FileNotFound) {
|
||||||
// return err;
|
return err;
|
||||||
// }
|
}
|
||||||
// };
|
};
|
||||||
// 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();
|
||||||
// try rdr.root.extract(&rdr, try .init(), extract_path);
|
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 test_sfs_path = "testing/LinuxPATest.sfs";
|
||||||
|
|||||||
@@ -64,13 +64,8 @@ pub const DataExtractor = struct {
|
|||||||
offset += out.sizes[i].size;
|
offset += out.sizes[i].size;
|
||||||
}
|
}
|
||||||
if (frag_idx != 0xFFFFFFFF) {
|
if (frag_idx != 0xFFFFFFFF) {
|
||||||
const frag_entry = try reader.frag_table.getValue(reader, frag_idx);
|
const frag_ent = try reader.frag_table.getValue(reader, frag_idx);
|
||||||
var frag_rdr: DataReader = try .fromFragEntry(reader, frag_entry);
|
out.frag_data = try frag_ent.getData(reader, frag_offset, @truncate(file_size % reader.super.block_size));
|
||||||
std.debug.print("{} {}\n", .{ frag_offset, frag_entry });
|
|
||||||
defer frag_rdr.deinit();
|
|
||||||
try frag_rdr.skip(frag_offset);
|
|
||||||
out.frag_data = try reader.alloc.alloc(u8, file_size % out.block_size);
|
|
||||||
_ = try frag_rdr.any().readAll(out.frag_data.?);
|
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@@ -83,35 +78,40 @@ pub const DataExtractor = struct {
|
|||||||
|
|
||||||
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: *std.ArrayList(anyerror), block_ind: usize, fil: *fs.File) void {
|
||||||
defer wg.finish();
|
defer wg.finish();
|
||||||
var offset_rdr = self.holder.readerAt(self.block_offset[block_ind]);
|
|
||||||
if (self.sizes[block_ind].not_compressed) {
|
if (self.sizes[block_ind].not_compressed) {
|
||||||
@branchHint(.unlikely);
|
@branchHint(.unlikely);
|
||||||
if (self.sizes[block_ind].size == 0) {
|
if (self.sizes[block_ind].size == 0) {
|
||||||
if (block_ind == self.sizes.len - 1) {
|
if (block_ind == self.sizes.len - 1) {
|
||||||
fil.pwriteAll(&[1]u8{0}, self.file_size - 1) catch |err| {
|
fil.pwriteAll(&[1]u8{0}, self.file_size - 1) catch |err| {
|
||||||
|
std.debug.print("yo1\n", .{});
|
||||||
errs.append(err) catch {};
|
errs.append(err) catch {};
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
fil.pwriteAll(&[1]u8{0}, ((block_ind + 1) * self.block_size) - 1) catch |err| {
|
fil.pwriteAll(&[1]u8{0}, ((block_ind + 1) * self.block_size) - 1) catch |err| {
|
||||||
|
std.debug.print("yo2\n", .{});
|
||||||
errs.append(err) catch {};
|
errs.append(err) catch {};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
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);
|
||||||
_ = offset_rdr.any().readAll(dat) catch |err| {
|
_ = fil.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 {
|
||||||
@branchHint(.likely);
|
@branchHint(.likely);
|
||||||
|
const offset_rdr = self.holder.readerAt(self.block_offset[block_ind]);
|
||||||
var fil_wrtr: FileOffsetWriter = .init(fil, block_ind * self.block_size);
|
var fil_wrtr: FileOffsetWriter = .init(fil, block_ind * self.block_size);
|
||||||
var limit = std.io.limitedReader(offset_rdr, self.sizes[block_ind].size);
|
var limit = std.io.limitedReader(offset_rdr, self.sizes[block_ind].size);
|
||||||
self.decomp.decompressTo(
|
self.decomp.decompressTo(
|
||||||
@@ -119,6 +119,7 @@ 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 {};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -127,6 +128,7 @@ pub const DataExtractor = struct {
|
|||||||
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: *std.ArrayList(anyerror), 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 {};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-11
@@ -18,6 +18,7 @@ pub const DataReader = struct {
|
|||||||
decomp: DecompressionType,
|
decomp: DecompressionType,
|
||||||
rdr: FileOffsetReader,
|
rdr: FileOffsetReader,
|
||||||
block_size: u32,
|
block_size: u32,
|
||||||
|
file_size: u64,
|
||||||
sizes: []BlockSize,
|
sizes: []BlockSize,
|
||||||
frag_data: ?[]u8 = null,
|
frag_data: ?[]u8 = null,
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@ pub const DataReader = struct {
|
|||||||
pub fn init(fil: *File, reader: *Reader) !DataReader {
|
pub fn init(fil: *File, reader: *Reader) !DataReader {
|
||||||
var data_start: u64 = 0;
|
var data_start: u64 = 0;
|
||||||
var sizes: []BlockSize = undefined;
|
var sizes: []BlockSize = undefined;
|
||||||
var size: u64 = 0;
|
var file_size: u64 = 0;
|
||||||
var frag_idx: u32 = 0;
|
var frag_idx: u32 = 0;
|
||||||
var frag_offset: u32 = 0;
|
var frag_offset: u32 = 0;
|
||||||
switch (fil.inode.data) {
|
switch (fil.inode.data) {
|
||||||
@@ -36,7 +37,7 @@ pub const DataReader = struct {
|
|||||||
sizes = try reader.alloc.alloc(BlockSize, f.blocks.len);
|
sizes = try reader.alloc.alloc(BlockSize, f.blocks.len);
|
||||||
@memcpy(sizes, f.blocks);
|
@memcpy(sizes, f.blocks);
|
||||||
data_start = f.data_start;
|
data_start = f.data_start;
|
||||||
size = f.size;
|
file_size = f.size;
|
||||||
frag_idx = f.frag_idx;
|
frag_idx = f.frag_idx;
|
||||||
frag_offset = f.frag_offset;
|
frag_offset = f.frag_offset;
|
||||||
},
|
},
|
||||||
@@ -44,7 +45,7 @@ pub const DataReader = struct {
|
|||||||
sizes = try reader.alloc.alloc(BlockSize, f.blocks.len);
|
sizes = try reader.alloc.alloc(BlockSize, f.blocks.len);
|
||||||
@memcpy(sizes, f.blocks);
|
@memcpy(sizes, f.blocks);
|
||||||
data_start = f.data_start;
|
data_start = f.data_start;
|
||||||
size = f.size;
|
file_size = f.size;
|
||||||
frag_idx = f.frag_idx;
|
frag_idx = f.frag_idx;
|
||||||
frag_offset = f.frag_offset;
|
frag_offset = f.frag_offset;
|
||||||
},
|
},
|
||||||
@@ -55,16 +56,13 @@ pub const DataReader = struct {
|
|||||||
.decomp = reader.super.decomp,
|
.decomp = reader.super.decomp,
|
||||||
.rdr = reader.holder.readerAt(data_start),
|
.rdr = reader.holder.readerAt(data_start),
|
||||||
.block_size = reader.super.block_size,
|
.block_size = reader.super.block_size,
|
||||||
|
.file_size = file_size,
|
||||||
.sizes = sizes,
|
.sizes = sizes,
|
||||||
};
|
};
|
||||||
errdefer out.deinit();
|
errdefer out.deinit();
|
||||||
if (frag_idx != 0xFFFFFFFF) {
|
if (frag_idx != 0xFFFFFFFF) {
|
||||||
const frag_entry = try reader.frag_table.getValue(frag_idx);
|
const frag_ent = try reader.frag_table.getValue(reader, frag_idx);
|
||||||
var frag_rdr = try .fromFragEntry(reader, frag_entry);
|
out.frag_data = try frag_ent.getData(reader, frag_offset, @truncate(file_size % reader.super.block_size));
|
||||||
defer frag_rdr.deinit();
|
|
||||||
try frag_rdr.skip(frag_offset);
|
|
||||||
out.frag_data = try reader.alloc.alloc(u8, size % out.block_size);
|
|
||||||
_ = try frag_rdr.any().readAll(out.frag_data);
|
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@@ -104,13 +102,17 @@ pub const DataReader = struct {
|
|||||||
}
|
}
|
||||||
const siz = self.sizes[self.next_block_num];
|
const siz = self.sizes[self.next_block_num];
|
||||||
self.next_block_num += 1;
|
self.next_block_num += 1;
|
||||||
if (self.next_block_num == self.sizes.len - 1 and self.frag_data != null) {
|
if (self.next_block_num == self.sizes.len and self.frag_data != null) {
|
||||||
try self.sizeBlock(self.frag_data.?.len);
|
try self.sizeBlock(self.frag_data.?.len);
|
||||||
@memcpy(self.cur_bloc, self.frag_data.?);
|
@memcpy(self.cur_bloc, self.frag_data.?);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (siz.size == 0) {
|
if (siz.size == 0) {
|
||||||
try self.sizeBlock(self.block_size);
|
if (self.next_block_num == self.sizes.len) {
|
||||||
|
try self.sizeBlock(@truncate(self.file_size % self.block_size));
|
||||||
|
} else {
|
||||||
|
try self.sizeBlock(self.block_size);
|
||||||
|
}
|
||||||
@memset(self.cur_bloc, 0);
|
@memset(self.cur_bloc, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user