Added basic test
Fixed various bugs
This commit is contained in:
@@ -119,7 +119,7 @@ pub fn main() !void {
|
||||
return;
|
||||
}
|
||||
const fil = try std.fs.cwd().openFile(filename, .{});
|
||||
var rdr = squashfs.FileReader.init(
|
||||
var rdr = squashfs.SfsFile.init(
|
||||
alloc.allocator(),
|
||||
fil,
|
||||
offset,
|
||||
|
||||
+5
-5
@@ -17,7 +17,7 @@ const RawEntry = struct {
|
||||
name: []const u8,
|
||||
|
||||
pub fn init(alloc: std.mem.Allocator, rdr: anytype) !RawEntry {
|
||||
const fixed: [8]u8 = undefined;
|
||||
var fixed: [8]u8 = undefined;
|
||||
_ = try rdr.read(&fixed);
|
||||
const size = std.mem.readInt(u16, fixed[6..8], .little);
|
||||
const name = try alloc.alloc(u8, size + 1);
|
||||
@@ -25,7 +25,7 @@ const RawEntry = struct {
|
||||
return .{
|
||||
.offset = std.mem.readInt(u16, fixed[0..2], .little),
|
||||
.num_offset = std.mem.readInt(i16, fixed[2..4], .little),
|
||||
.type = std.mem.readInt(u16, fixed[4..6], .little),
|
||||
.type = @enumFromInt(std.mem.readInt(u16, fixed[4..6], .little)),
|
||||
.size = size,
|
||||
.name = name,
|
||||
};
|
||||
@@ -44,8 +44,8 @@ pub const Entry = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub fn readDirectory(alloc: std.mem.Allocator, rdr: anytype, size: u32) []Entry {
|
||||
const entries: std.ArrayList(Entry) = .init(alloc);
|
||||
pub fn readDirectory(alloc: std.mem.Allocator, rdr: anytype, size: u32) ![]Entry {
|
||||
var entries: std.ArrayList(Entry) = .init(alloc);
|
||||
errdefer entries.deinit();
|
||||
var cur_red: u32 = 3; // dir size includes "." & "..", so its actual size is off by 3.
|
||||
var hdr: Header = undefined;
|
||||
@@ -60,7 +60,7 @@ pub fn readDirectory(alloc: std.mem.Allocator, rdr: anytype, size: u32) []Entry
|
||||
entries.appendAssumeCapacity(.{
|
||||
.block = hdr.block,
|
||||
.offset = raw_ent.offset,
|
||||
.num = hdr.num + raw_ent.num_offset,
|
||||
.num = @truncate(@abs(@as(i64, hdr.num) + raw_ent.num_offset)),
|
||||
.type = raw_ent.type,
|
||||
.name = raw_ent.name,
|
||||
});
|
||||
|
||||
+44
-12
@@ -7,6 +7,7 @@ const Inode = @import("inode.zig");
|
||||
const SfsReader = @import("reader.zig").SfsReader;
|
||||
const ToReader = @import("reader/to_read.zig").ToRead;
|
||||
const ExtractionOptions = @import("extract_options.zig");
|
||||
const DataReader = @import("reader/data.zig").DataReader;
|
||||
const Compression = @import("superblock.zig").Compression;
|
||||
const MetadataReader = @import("reader/metadata.zig").MetadataReader;
|
||||
|
||||
@@ -27,7 +28,7 @@ pub fn File(comptime T: type) type {
|
||||
/// Directory entries. Only populated on directories.
|
||||
entries: ?[]DirEntry = null,
|
||||
/// File reader. Only populated on regular files.
|
||||
// data_reader: ?DataReader
|
||||
data_reader: ?DataReader(T) = null,
|
||||
|
||||
pub fn init(rdr: *SfsReader(T), inode: Inode, name: []const u8) !Self {
|
||||
var out = Self{
|
||||
@@ -37,33 +38,60 @@ pub fn File(comptime T: type) type {
|
||||
};
|
||||
switch (inode.data) {
|
||||
.dir => |d| {
|
||||
const meta = MetadataReader(T).init(
|
||||
var meta = MetadataReader(T).init(
|
||||
rdr.alloc,
|
||||
rdr.super.comp,
|
||||
rdr.rdr,
|
||||
d.block + rdr.super.dir_start,
|
||||
);
|
||||
try meta.skip(d.offset);
|
||||
out.entries = try dir.readDirectory(rdr.alloc, meta, d.size);
|
||||
out.entries = try dir.readDirectory(rdr.alloc, &meta, d.size);
|
||||
},
|
||||
.ext_dir => |d| {
|
||||
const meta = MetadataReader(T).init(
|
||||
var meta = MetadataReader(T).init(
|
||||
rdr.alloc,
|
||||
rdr.super.comp,
|
||||
rdr.rdr,
|
||||
d.block + rdr.super.dir_start,
|
||||
);
|
||||
try meta.skip(d.offset);
|
||||
out.entries = try dir.readDirectory(rdr.alloc, meta, d.size);
|
||||
out.entries = try dir.readDirectory(rdr.alloc, &meta, d.size);
|
||||
},
|
||||
.file => |f| {
|
||||
_ = f;
|
||||
//TODO
|
||||
out.data_reader = try .init(
|
||||
rdr.alloc,
|
||||
rdr.rdr,
|
||||
rdr.super.comp,
|
||||
f.block,
|
||||
f.size,
|
||||
f.block_sizes,
|
||||
rdr.super.block_size,
|
||||
);
|
||||
if (f.hasFragment()) {
|
||||
try out.data_reader.?.addFragment(
|
||||
try rdr.frag_table.get(f.frag_idx),
|
||||
f.frag_offset,
|
||||
);
|
||||
}
|
||||
},
|
||||
.ext_file => |f| {
|
||||
_ = f;
|
||||
//TODO
|
||||
out.data_reader = try .init(
|
||||
rdr.alloc,
|
||||
rdr.rdr,
|
||||
rdr.super.comp,
|
||||
f.block,
|
||||
f.size,
|
||||
f.block_sizes,
|
||||
rdr.super.block_size,
|
||||
);
|
||||
if (f.hasFragment()) {
|
||||
try out.data_reader.?.addFragment(
|
||||
try rdr.frag_table.get(f.frag_idx),
|
||||
f.frag_offset,
|
||||
);
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -76,9 +104,13 @@ pub fn File(comptime T: type) type {
|
||||
}
|
||||
self.rdr.alloc.free(self.entries.?);
|
||||
}
|
||||
// if(self.data_reader != null){
|
||||
// self.data_reader.?.deinit();
|
||||
// }
|
||||
if (self.data_reader != null) {
|
||||
self.data_reader.?.deinit();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter(self: Self) !void {
|
||||
_ = self;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
+15
-21
@@ -4,12 +4,6 @@ const dir = @import("inode/dir.zig");
|
||||
const file = @import("inode/file.zig");
|
||||
const misc = @import("inode/misc.zig");
|
||||
|
||||
const Reader = @import("reader.zig");
|
||||
const DirEntry = @import("directory.zig").Entry;
|
||||
const ToRead = @import("reader/to_read.zig").ToRead;
|
||||
const Compression = @import("superblock.zig").Compression;
|
||||
const MetadataReader = @import("reader/metadata.zig").MetadataReader;
|
||||
|
||||
pub const Ref = packed struct {
|
||||
offset: u16,
|
||||
block: u32,
|
||||
@@ -67,21 +61,21 @@ data: Data,
|
||||
pub fn init(rdr: anytype, alloc: std.mem.Allocator, block_size: u32) !Self {
|
||||
var hdr: Header = undefined;
|
||||
_ = try rdr.read(std.mem.asBytes(&hdr));
|
||||
const data = switch (hdr.type) {
|
||||
.dir => .{ .dir = .init(rdr) },
|
||||
.file => .{ .file = .init(rdr, alloc, block_size) },
|
||||
.symlink => .{ .symlink = .init(rdr, alloc) },
|
||||
.block_dev => .{ .block_dev = .init(rdr) },
|
||||
.char_dev => .{ .char_dev = .init(rdr) },
|
||||
.fifo => .{ .fifo = .init(rdr) },
|
||||
.socket => .{ .socket = .init(rdr) },
|
||||
.ext_dir => .{ .ext_dir = .init(rdr) },
|
||||
.ext_file => .{ .ext_file = .init(rdr, alloc, block_size) },
|
||||
.ext_symlink => .{ .ext_symlink = .init(rdr, alloc) },
|
||||
.ext_block_dev => .{ .ext_block_dev = .init(rdr) },
|
||||
.ext_char_dev => .{ .ext_char_dev = .init(rdr) },
|
||||
.ext_fifo => .{ .ext_fifo = .init(rdr) },
|
||||
.ext_socket => .{ .ext_socket = .init(rdr) },
|
||||
const data: Data = switch (hdr.type) {
|
||||
.dir => .{ .dir = try .init(rdr) },
|
||||
.file => .{ .file = try .init(rdr, alloc, block_size) },
|
||||
.symlink => .{ .symlink = try .init(rdr, alloc) },
|
||||
.block_dev => .{ .block_dev = try .init(rdr) },
|
||||
.char_dev => .{ .char_dev = try .init(rdr) },
|
||||
.fifo => .{ .fifo = try .init(rdr) },
|
||||
.socket => .{ .socket = try .init(rdr) },
|
||||
.ext_dir => .{ .ext_dir = try .init(rdr) },
|
||||
.ext_file => .{ .ext_file = try .init(rdr, alloc, block_size) },
|
||||
.ext_symlink => .{ .ext_symlink = try .init(rdr, alloc) },
|
||||
.ext_block_dev => .{ .ext_block_dev = try .init(rdr) },
|
||||
.ext_char_dev => .{ .ext_char_dev = try .init(rdr) },
|
||||
.ext_fifo => .{ .ext_fifo = try .init(rdr) },
|
||||
.ext_socket => .{ .ext_socket = try .init(rdr) },
|
||||
};
|
||||
return .{
|
||||
.hdr = hdr,
|
||||
|
||||
+4
-4
@@ -8,8 +8,8 @@ pub const Dir = packed struct {
|
||||
parent_num: u32,
|
||||
|
||||
pub fn init(rdr: anytype) !Dir {
|
||||
const out: Dir = undefined;
|
||||
_ = rdr.read(std.mem.asBytes(&out));
|
||||
var out: Dir = undefined;
|
||||
_ = try rdr.read(std.mem.asBytes(&out));
|
||||
return out;
|
||||
}
|
||||
};
|
||||
@@ -24,8 +24,8 @@ pub const ExtDir = packed struct {
|
||||
xattr_idx: u32,
|
||||
|
||||
pub fn init(rdr: anytype) !ExtDir {
|
||||
const out: ExtDir = undefined;
|
||||
_ = rdr.read(std.mem.asBytes(&out));
|
||||
var out: ExtDir = undefined;
|
||||
_ = try rdr.read(std.mem.asBytes(&out));
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
+14
-8
@@ -9,7 +9,7 @@ pub const BlockSize = packed struct {
|
||||
pub const File = struct {
|
||||
block: u32,
|
||||
frag_idx: u32,
|
||||
offset: u32,
|
||||
frag_offset: u32,
|
||||
size: u32,
|
||||
block_sizes: []BlockSize,
|
||||
|
||||
@@ -22,17 +22,20 @@ pub const File = struct {
|
||||
if (size % block_size > 0 and frag_idx != 0xffffffff) {
|
||||
blocks += 1;
|
||||
}
|
||||
const block_sizes = alloc.alloc(BlockSize, blocks);
|
||||
const block_sizes = try alloc.alloc(BlockSize, blocks);
|
||||
errdefer alloc.free(block_sizes);
|
||||
_ = try rdr.read(std.mem.sliceAsBytes(block_sizes));
|
||||
return .{
|
||||
.block = std.mem.readInt(u32, fixed[0..4], .little),
|
||||
.frag_idx = frag_idx,
|
||||
.offset = std.mem.readInt(u32, fixed[8..12], .little),
|
||||
.frag_offset = std.mem.readInt(u32, fixed[8..12], .little),
|
||||
.size = size,
|
||||
.block_sizes = block_sizes,
|
||||
};
|
||||
}
|
||||
pub fn hasFragment(self: File) bool {
|
||||
return self.frag_idx != 0xffffffff;
|
||||
}
|
||||
};
|
||||
|
||||
pub const ExtFile = struct {
|
||||
@@ -41,7 +44,7 @@ pub const ExtFile = struct {
|
||||
sparse: u64,
|
||||
hard_link: u32,
|
||||
frag_idx: u32,
|
||||
offset: u32,
|
||||
frag_offset: u32,
|
||||
xattr_idx: u32,
|
||||
block_sizes: []BlockSize,
|
||||
|
||||
@@ -50,11 +53,11 @@ pub const ExtFile = struct {
|
||||
_ = try rdr.read(&fixed);
|
||||
const size = std.mem.readInt(u64, fixed[8..16], .little);
|
||||
const frag_idx = std.mem.readInt(u32, fixed[28..32], .little);
|
||||
var blocks: u32 = size / block_size;
|
||||
var blocks: u32 = @truncate(size / block_size);
|
||||
if (size % block_size > 0 and frag_idx != 0xffffffff) {
|
||||
blocks += 1;
|
||||
}
|
||||
const block_sizes = alloc.alloc(BlockSize, blocks);
|
||||
const block_sizes = try alloc.alloc(BlockSize, blocks);
|
||||
errdefer alloc.free(block_sizes);
|
||||
_ = try rdr.read(std.mem.sliceAsBytes(block_sizes));
|
||||
return .{
|
||||
@@ -63,9 +66,12 @@ pub const ExtFile = struct {
|
||||
.sparse = std.mem.readInt(u64, fixed[16..24], .little),
|
||||
.hard_link = std.mem.readInt(u32, fixed[24..28], .little),
|
||||
.frag_idx = frag_idx,
|
||||
.offset = std.mem.readInt(u32, fixed[32..36], .little),
|
||||
.frag_offset = std.mem.readInt(u32, fixed[32..36], .little),
|
||||
.xattr_idx = std.mem.readInt(u32, fixed[36..40], .little),
|
||||
.block_sizes = blocks,
|
||||
.block_sizes = block_sizes,
|
||||
};
|
||||
}
|
||||
pub fn hasFragment(self: ExtFile) bool {
|
||||
return self.frag_idx != 0xffffffff;
|
||||
}
|
||||
};
|
||||
|
||||
+6
-6
@@ -9,7 +9,7 @@ pub const Symlink = struct {
|
||||
var fixed: [8]u8 = undefined;
|
||||
_ = try rdr.read(&fixed);
|
||||
const size = std.mem.readInt(u32, fixed[4..8], .little);
|
||||
const target = alloc.alloc(u8, size);
|
||||
const target = try alloc.alloc(u8, size);
|
||||
errdefer alloc.free(target);
|
||||
_ = try rdr.read(target);
|
||||
return .{
|
||||
@@ -29,7 +29,7 @@ pub const ExtSymlink = struct {
|
||||
var fixed: [8]u8 = undefined;
|
||||
_ = try rdr.read(&fixed);
|
||||
const size = std.mem.readInt(u32, fixed[4..8], .little);
|
||||
const target = alloc.alloc(u8, size);
|
||||
const target = try alloc.alloc(u8, size);
|
||||
errdefer alloc.free(target);
|
||||
_ = try rdr.read(target);
|
||||
var xattr_idx: u32 = 0;
|
||||
@@ -47,7 +47,7 @@ pub const Dev = packed struct {
|
||||
device: u32,
|
||||
|
||||
pub fn init(rdr: anytype) !Dev {
|
||||
const out: Dev = undefined;
|
||||
var out: Dev = undefined;
|
||||
_ = try rdr.read(std.mem.asBytes(&out));
|
||||
return out;
|
||||
}
|
||||
@@ -59,7 +59,7 @@ pub const ExtDev = packed struct {
|
||||
xattr_idx: u32,
|
||||
|
||||
pub fn init(rdr: anytype) !ExtDev {
|
||||
const out: ExtDev = undefined;
|
||||
var out: ExtDev = undefined;
|
||||
_ = try rdr.read(std.mem.asBytes(&out));
|
||||
return out;
|
||||
}
|
||||
@@ -69,7 +69,7 @@ pub const IPC = packed struct {
|
||||
hard_link: u32,
|
||||
|
||||
pub fn init(rdr: anytype) !IPC {
|
||||
const out: IPC = undefined;
|
||||
var out: IPC = undefined;
|
||||
_ = try rdr.read(std.mem.asBytes(&out));
|
||||
return out;
|
||||
}
|
||||
@@ -80,7 +80,7 @@ pub const ExtIPC = packed struct {
|
||||
xattr_idx: u32,
|
||||
|
||||
pub fn init(rdr: anytype) !ExtIPC {
|
||||
const out: ExtIPC = undefined;
|
||||
var out: ExtIPC = undefined;
|
||||
_ = try rdr.read(std.mem.asBytes(&out));
|
||||
return out;
|
||||
}
|
||||
|
||||
+7
-15
@@ -29,7 +29,6 @@ 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: ?File(T) = null,
|
||||
|
||||
pub fn init(alloc: std.mem.Allocator, rdr: T, offset: u64) !Self {
|
||||
var out: Self = .{
|
||||
@@ -46,28 +45,21 @@ 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();
|
||||
}
|
||||
|
||||
fn populateRoot(self: *Self) !void {
|
||||
if (self.root != null) return;
|
||||
const meta = MetadataReader(T).init(
|
||||
pub fn archiveRoot(self: *Self) !File(T) {
|
||||
var 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, "");
|
||||
const root_inode: Inode = try .init(&meta, self.alloc, self.super.block_size);
|
||||
return 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();
|
||||
pub fn open(self: *Self, path: []const u8) !File(T) {
|
||||
_ = self;
|
||||
_ = path;
|
||||
// return self.root.?.open(path);
|
||||
return error{TODO}.TODO;
|
||||
@@ -78,7 +70,7 @@ pub fn SfsReader(comptime T: type) type {
|
||||
pub fn inodeAt(self: Self, num: u32) !Inode {
|
||||
if (!self.super.flags.has_export) return SfsError.NotExportable;
|
||||
const ref = try self.export_table.get(num - 1);
|
||||
const meta = MetadataReader(T).init(
|
||||
var meta = MetadataReader(T).init(
|
||||
self.alloc,
|
||||
self.super.comp,
|
||||
self.rdr,
|
||||
|
||||
+5
-11
@@ -27,8 +27,8 @@ pub fn DataReader(comptime T: type) type {
|
||||
|
||||
frag: []u8 = &[0]u8{},
|
||||
|
||||
read_block: []u8,
|
||||
read_offset: u64,
|
||||
read_block: []u8 = &[0]u8{},
|
||||
read_offset: u64 = 0,
|
||||
read_idx: u32 = 0,
|
||||
|
||||
pub fn init(
|
||||
@@ -41,7 +41,7 @@ pub fn DataReader(comptime T: type) type {
|
||||
block_size: u32,
|
||||
) !Self {
|
||||
var cur_offset = init_offset;
|
||||
const offsets = alloc.alloc(u64, sizes.len);
|
||||
const offsets = try alloc.alloc(u64, sizes.len);
|
||||
for (0..sizes.len) |i| {
|
||||
offsets[i] = cur_offset;
|
||||
cur_offset += sizes[i].size;
|
||||
@@ -74,10 +74,7 @@ pub fn DataReader(comptime T: type) type {
|
||||
defer self.alloc.free(block);
|
||||
_ = try self.comp.decompress(
|
||||
self.alloc,
|
||||
std.io.limitedReader(
|
||||
self.rdr.readerAt(entry.block),
|
||||
entry.size.size,
|
||||
),
|
||||
self.rdr.readerAt(entry.block).reader(),
|
||||
block,
|
||||
);
|
||||
@memcpy(self.frag, block[offset..]);
|
||||
@@ -106,10 +103,7 @@ pub fn DataReader(comptime T: type) type {
|
||||
}
|
||||
_ = try self.comp.decompress(
|
||||
self.alloc,
|
||||
std.io.limitedReader(
|
||||
self.rdr.readerAt(self.offsets[idx]),
|
||||
self.sizes[idx].size,
|
||||
),
|
||||
self.rdr.readerAt(self.offsets[idx]).reader(),
|
||||
block,
|
||||
);
|
||||
return block;
|
||||
|
||||
@@ -32,12 +32,12 @@ pub fn MetadataReader(comptime T: type) type {
|
||||
}
|
||||
|
||||
fn readNextBlock(self: *Self) !void {
|
||||
const hdr: MetaHeader = undefined;
|
||||
_ = try self.rdr.pread(std.mem.asBytes(hdr), self.offset);
|
||||
var hdr: MetaHeader = undefined;
|
||||
_ = try self.rdr.pread(std.mem.asBytes(&hdr), self.offset);
|
||||
self.offset += 2;
|
||||
self.block_size = try self.comp.decompress(
|
||||
self.alloc,
|
||||
std.io.limitedReader(self.rdr.readerAt(self.offset), hdr.size),
|
||||
self.rdr.readerAt(self.offset).reader(),
|
||||
&self.block,
|
||||
);
|
||||
self.offset += hdr.size;
|
||||
@@ -45,14 +45,14 @@ pub fn MetadataReader(comptime T: type) type {
|
||||
}
|
||||
|
||||
pub fn skip(self: *Self, offset: u32) !void {
|
||||
var skipped = 0;
|
||||
const hdr: MetaHeader = undefined;
|
||||
var skipped: u32 = 0;
|
||||
var hdr: MetaHeader = undefined;
|
||||
while (offset - skipped >= 8192) {
|
||||
_ = try self.rdr.pread(std.mem.asBytes(hdr), self.offset);
|
||||
_ = try self.rdr.pread(std.mem.asBytes(&hdr), self.offset);
|
||||
self.offset += 2 + hdr.size;
|
||||
skipped += 8192;
|
||||
}
|
||||
var to_skip = 0;
|
||||
var to_skip: u32 = 0;
|
||||
while (skipped < offset) {
|
||||
if (self.block_offset >= self.block_size) try self.readNextBlock();
|
||||
to_skip = @min(self.block_size - self.block_offset, offset - skipped);
|
||||
@@ -69,7 +69,7 @@ pub fn MetadataReader(comptime T: type) type {
|
||||
to_read = @min(buf.len - cur_red, self.block_size - self.block_offset);
|
||||
@memcpy(buf[cur_red .. cur_red + to_read], self.block[self.block_offset .. self.block_offset + to_read]);
|
||||
cur_red += to_read;
|
||||
self.block_offset += to_read;
|
||||
self.block_offset += @truncate(to_read);
|
||||
}
|
||||
return cur_red;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ pub fn ToRead(comptime T: type) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
|
||||
pub const Error = anyerror;
|
||||
|
||||
rdr: T,
|
||||
offset: u64,
|
||||
|
||||
@@ -20,5 +22,21 @@ pub fn ToRead(comptime T: type) type {
|
||||
self.offset += red;
|
||||
return red;
|
||||
}
|
||||
pub fn readAll(self: *Self, buf: []u8) !usize {
|
||||
var cur_red = try self.read(buf);
|
||||
if (cur_red == 0) return cur_red;
|
||||
var res: usize = 0;
|
||||
while (cur_red < buf.len) {
|
||||
res = try self.read(buf[cur_red..]);
|
||||
if (res == 0) break;
|
||||
cur_red += res;
|
||||
}
|
||||
return cur_red;
|
||||
}
|
||||
pub fn reader(self: anytype) std.io.Reader(*Self, anyerror, read) {
|
||||
return .{
|
||||
.context = @constCast(self),
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
+13
-1
@@ -3,4 +3,16 @@ const std = @import("std");
|
||||
pub const SfsReader = @import("reader.zig").SfsReader;
|
||||
pub const ExtractionOptions = @import("extract_options.zig");
|
||||
|
||||
pub const FileReader = SfsReader(std.fs.File);
|
||||
pub const SfsFile = SfsReader(std.fs.File);
|
||||
|
||||
const test_file = "testing/LinuxPATest.sfs";
|
||||
|
||||
test "OpenTest" {
|
||||
const fil = try std.fs.cwd().openFile(test_file, .{});
|
||||
defer fil.close();
|
||||
var rdr: SfsFile = try .init(std.testing.allocator, fil, 0);
|
||||
defer rdr.deinit();
|
||||
std.debug.print("{}\n", .{rdr.super});
|
||||
const root = try rdr.archiveRoot();
|
||||
defer root.deinit();
|
||||
}
|
||||
|
||||
+5
-5
@@ -54,24 +54,24 @@ pub const Compression = enum(u16) {
|
||||
pub fn decompress(self: Compression, alloc: std.mem.Allocator, source: anytype, dest: []u8) !usize {
|
||||
switch (self) {
|
||||
.gzip => {
|
||||
const decomp = std.compress.zlib.decompressor(source);
|
||||
var decomp = std.compress.zlib.decompressor(source);
|
||||
return decomp.read(dest);
|
||||
},
|
||||
.lzma => {
|
||||
const decomp = try std.compress.lzma.decompress(alloc, source);
|
||||
var decomp = try std.compress.lzma.decompress(alloc, source);
|
||||
defer decomp.deinit();
|
||||
return decomp.read(dest);
|
||||
},
|
||||
.lzo => return DecompressError.LzoUnavailable,
|
||||
.xz => {
|
||||
const decomp = try std.compress.xz.decompress(alloc, source);
|
||||
var decomp = try std.compress.xz.decompress(alloc, source);
|
||||
defer decomp.deinit();
|
||||
return decomp.read(dest);
|
||||
},
|
||||
.lz4 => return DecompressError.Lz4Unavailable,
|
||||
.zstd => {
|
||||
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 });
|
||||
var window: [std.compress.zstd.DecompressorOptions.default_window_buffer_len]u8 = undefined;
|
||||
var decomp = std.compress.zstd.decompressor(source, .{ .window_buffer = &window });
|
||||
return decomp.read(dest);
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user