Tweaking to get stuff workign
This commit is contained in:
+13
-9
@@ -15,8 +15,8 @@ const RawDirEntry = struct {
|
|||||||
name_size: u16,
|
name_size: u16,
|
||||||
name: []u8,
|
name: []u8,
|
||||||
|
|
||||||
fn init(rdr: std.io.AnyReader, alloc: std.mem.Allocator) !DirEntry {
|
fn init(rdr: std.io.AnyReader, alloc: std.mem.Allocator) !RawDirEntry {
|
||||||
var out: DirEntry = .{
|
var out: RawDirEntry = .{
|
||||||
.inode_offset = try rdr.readInt(u16, std.builtin.Endian.little),
|
.inode_offset = try rdr.readInt(u16, std.builtin.Endian.little),
|
||||||
.inode_num_difference = try rdr.readInt(i16, std.builtin.Endian.little),
|
.inode_num_difference = try rdr.readInt(i16, std.builtin.Endian.little),
|
||||||
.inode_type = try rdr.readInt(u16, std.builtin.Endian.little),
|
.inode_type = try rdr.readInt(u16, std.builtin.Endian.little),
|
||||||
@@ -39,7 +39,7 @@ pub const DirEntry = struct {
|
|||||||
return .{
|
return .{
|
||||||
.inode_offset = raw.inode_offset,
|
.inode_offset = raw.inode_offset,
|
||||||
.inode_block_start = hdr.inode_block_start,
|
.inode_block_start = hdr.inode_block_start,
|
||||||
.inode_num = hdr.inode_num - raw.inode_num_difference,
|
.inode_num = hdr.inode_num + @as(u32, @intCast(raw.inode_num_difference)),
|
||||||
.name = raw.name,
|
.name = raw.name,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -52,25 +52,29 @@ pub fn readDirEntries(alloc: std.mem.Allocator, comp: CompressionType, rdr: std.
|
|||||||
var meta_hdr: MetadataHeader = undefined;
|
var meta_hdr: MetadataHeader = undefined;
|
||||||
var dir_hdr: DirHeader = undefined;
|
var dir_hdr: DirHeader = undefined;
|
||||||
var buf: []u8 = undefined;
|
var buf: []u8 = undefined;
|
||||||
var buf_rdr: std.io.FixedBufferStream(u8) = undefined;
|
|
||||||
var i = 0;
|
|
||||||
var entries: std.ArrayList(DirEntry) = .init(alloc);
|
|
||||||
defer alloc.free(buf);
|
defer alloc.free(buf);
|
||||||
|
var buf_rdr: std.io.FixedBufferStream([]u8) = undefined;
|
||||||
|
var i: u32 = 0;
|
||||||
|
var entries: std.ArrayList(DirEntry) = .init(alloc);
|
||||||
|
var raw: RawDirEntry = undefined;
|
||||||
while (total_size < size) {
|
while (total_size < size) {
|
||||||
meta_hdr = try rdr.readStruct(MetadataHeader);
|
meta_hdr = try rdr.readStruct(MetadataHeader);
|
||||||
if (meta_hdr.not_compressed) {
|
if (meta_hdr.not_compressed) {
|
||||||
buf = try alloc.realloc(buf, meta_hdr.size);
|
buf = try alloc.realloc(buf, meta_hdr.size);
|
||||||
_ = try rdr.readAll(rdr);
|
_ = try rdr.readAll(buf);
|
||||||
} else {
|
} else {
|
||||||
alloc.free(buf);
|
alloc.free(buf);
|
||||||
buf = try comp.Decompress(alloc, std.io.limitedReader(rdr, meta_hdr.size));
|
var limit = std.io.limitedReader(rdr, meta_hdr.size);
|
||||||
|
buf = try comp.decompress(alloc, limit.reader().any());
|
||||||
}
|
}
|
||||||
buf_rdr = std.io.fixedBufferStream(buf);
|
buf_rdr = std.io.fixedBufferStream(buf);
|
||||||
dir_hdr = try buf_rdr.reader().readStruct(DirHeader);
|
dir_hdr = try buf_rdr.reader().readStruct(DirHeader);
|
||||||
total_size += 12;
|
total_size += 12;
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < dir_hdr.count) : (i += 1) {
|
while (i < dir_hdr.count) : (i += 1) {
|
||||||
entries.append(try .init(try .init(buf_rdr, alloc), dir_hdr));
|
raw = try .init(buf_rdr.reader().any(), alloc);
|
||||||
|
total_size += @sizeOf(RawDirEntry);
|
||||||
|
try entries.append(.init(raw, dir_hdr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return try entries.toOwnedSlice();
|
return try entries.toOwnedSlice();
|
||||||
|
|||||||
+48
-16
@@ -4,7 +4,7 @@ const inode = @import("inode.zig");
|
|||||||
const Reader = @import("squashfs.zig").Reader;
|
const Reader = @import("squashfs.zig").Reader;
|
||||||
const MetadataReader = @import("metadata_reader.zig").MetadataReader;
|
const MetadataReader = @import("metadata_reader.zig").MetadataReader;
|
||||||
const FileOffsetReader = @import("file_offset_reader.zig").FileOffsetReader;
|
const FileOffsetReader = @import("file_offset_reader.zig").FileOffsetReader;
|
||||||
const DirEntry = @import("directory.zig").DirEntry;
|
const dir = @import("directory.zig");
|
||||||
|
|
||||||
const FileOpenError = error{
|
const FileOpenError = error{
|
||||||
NotFound,
|
NotFound,
|
||||||
@@ -15,10 +15,10 @@ pub const File = struct {
|
|||||||
rdr: *Reader,
|
rdr: *Reader,
|
||||||
inode: inode.Inode,
|
inode: inode.Inode,
|
||||||
name: []const u8,
|
name: []const u8,
|
||||||
dir_entries: []DirEntry = undefined,
|
dir_entries: []dir.DirEntry = &[0]dir.DirEntry{},
|
||||||
|
|
||||||
pub fn fromRef(rdr: *Reader, ref: inode.InodeRef, name: []const u8) !File {
|
pub fn fromRef(rdr: *Reader, ref: inode.InodeRef, name: []const u8) !File {
|
||||||
var offset_rdr: FileOffsetReader = .init(rdr.file, rdr.super.inode_table + ref.block_start);
|
var offset_rdr: FileOffsetReader = .init(rdr.rdr, rdr.super.inode_table + ref.block_start);
|
||||||
var meta_rdr: MetadataReader = .init(rdr.super.comp, offset_rdr.any(), rdr.alloc.allocator());
|
var meta_rdr: MetadataReader = .init(rdr.super.comp, offset_rdr.any(), rdr.alloc.allocator());
|
||||||
try meta_rdr.skip(ref.offset);
|
try meta_rdr.skip(ref.offset);
|
||||||
const in = try inode.readInode(meta_rdr, rdr.super.block_size, rdr.alloc.allocator());
|
const in = try inode.readInode(meta_rdr, rdr.super.block_size, rdr.alloc.allocator());
|
||||||
@@ -29,15 +29,15 @@ pub const File = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fromDirEntry(rdr: *Reader, ent: DirEntry) !File {
|
pub fn fromDirEntry(rdr: *Reader, ent: dir.DirEntry) !File {
|
||||||
var offset_rdr: FileOffsetReader = .init(rdr.file, rdr.super.inode_table + ent.inode_block_start);
|
var offset_rdr: FileOffsetReader = .init(&rdr.rdr, rdr.super.inode_table + ent.inode_block_start);
|
||||||
var meta_rdr: MetadataReader = .init(
|
var meta_rdr: MetadataReader = try .init(
|
||||||
rdr.super.comp,
|
rdr.super.comp,
|
||||||
offset_rdr.any(),
|
offset_rdr.any(),
|
||||||
rdr.alloc,
|
rdr.alloc.allocator(),
|
||||||
);
|
);
|
||||||
try meta_rdr.skip(ent.inode_offset);
|
try meta_rdr.skip(ent.inode_offset);
|
||||||
const in = try inode.readInode(meta_rdr, rdr.super.block_size, rdr.alloc.allocator());
|
const in = try inode.readInode(meta_rdr.any(), rdr.super.block_size, rdr.alloc.allocator());
|
||||||
return .{
|
return .{
|
||||||
.rdr = rdr,
|
.rdr = rdr,
|
||||||
.inode = in,
|
.inode = in,
|
||||||
@@ -45,18 +45,50 @@ pub const File = struct {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open(self: File, path: []const u8) (anyerror || FileOpenError)!File {
|
pub fn open(self: *File, path: []const u8) (anyerror || FileOpenError)!File {
|
||||||
|
if (path.len == 0) return self.*;
|
||||||
|
const clean_path: []const u8 = std.mem.trimLeft(u8, path, "/");
|
||||||
|
if (clean_path.len == 0 or std.mem.eql(u8, clean_path, ".")) {
|
||||||
|
return self.*;
|
||||||
|
}
|
||||||
switch (self.inode.header.inode_type) {
|
switch (self.inode.header.inode_type) {
|
||||||
.dir, .ext_dir => {},
|
.dir, .ext_dir => {},
|
||||||
else => return FileOpenError.NotDirectory,
|
else => return FileOpenError.NotDirectory,
|
||||||
}
|
}
|
||||||
const clean_path: []const u8 = if (std.mem.startsWith(u8, path, "/")) {
|
try self.readDirEntries();
|
||||||
return path[1..];
|
const file_name = std.mem.sliceTo(clean_path, '/');
|
||||||
} else {
|
for (self.dir_entries) |ent| {
|
||||||
return path;
|
std.debug.print("yo {}\n", .{ent});
|
||||||
};
|
if (std.mem.eql(u8, file_name, ent.name)) {
|
||||||
const path_split = std.mem.splitAny(u8, clean_path, "/");
|
return try File.fromDirEntry(self.rdr, ent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FileOpenError.NotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn readDirEntries(self: *File) (anyerror || FileOpenError)!File {}
|
fn readDirEntries(self: *File) (anyerror || FileOpenError)!void {
|
||||||
|
if (self.dir_entries.len != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var dir_block_offset: u32 = undefined;
|
||||||
|
var dir_block_start: u32 = undefined;
|
||||||
|
var size: u32 = undefined;
|
||||||
|
switch (self.inode.data) {
|
||||||
|
.dir => |d| {
|
||||||
|
dir_block_start = d.dir_block_start;
|
||||||
|
dir_block_offset = d.dir_block_offset;
|
||||||
|
size = d.dir_table_size;
|
||||||
|
},
|
||||||
|
.ext_dir => |d| {
|
||||||
|
dir_block_start = d.dir_block_start;
|
||||||
|
dir_block_offset = d.dir_block_offset;
|
||||||
|
size = d.dir_table_size;
|
||||||
|
},
|
||||||
|
else => return FileOpenError.NotDirectory,
|
||||||
|
}
|
||||||
|
std.debug.print("{}\n", .{self.rdr});
|
||||||
|
var offset_rdr: FileOffsetReader = .init(&self.rdr.rdr, self.rdr.super.dir_table + dir_block_start);
|
||||||
|
var meta_rdr: MetadataReader = try .init(self.rdr.super.comp, offset_rdr.any(), self.rdr.alloc.allocator());
|
||||||
|
self.dir_entries = try dir.readDirEntries(self.rdr.alloc.allocator(), self.rdr.super.comp, meta_rdr.any(), size);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
pub const FileOffsetReader = struct {
|
pub const FileOffsetReader = struct {
|
||||||
file: std.fs.File,
|
file: *std.fs.File,
|
||||||
offset: u64,
|
offset: u64,
|
||||||
|
|
||||||
pub fn init(file: std.fs.File, initial_offset: u64) FileOffsetReader {
|
pub fn init(file: *std.fs.File, initial_offset: u64) FileOffsetReader {
|
||||||
return .{
|
return .{
|
||||||
.file = file,
|
.file = file,
|
||||||
.offset = initial_offset,
|
.offset = initial_offset,
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ pub const MetadataReader = struct {
|
|||||||
decomp: CompressionType,
|
decomp: CompressionType,
|
||||||
curBlock: []u8,
|
curBlock: []u8,
|
||||||
curOffset: u16,
|
curOffset: u16,
|
||||||
free: bool = false,
|
|
||||||
|
|
||||||
pub fn init(decomp: CompressionType, rdr: io.AnyReader, alloc: std.mem.Allocator) !MetadataReader {
|
pub fn init(decomp: CompressionType, rdr: io.AnyReader, alloc: std.mem.Allocator) !MetadataReader {
|
||||||
var out: MetadataReader = .{
|
var out: MetadataReader = .{
|
||||||
@@ -58,7 +57,7 @@ pub const MetadataReader = struct {
|
|||||||
_ = try self.rdr.readAll(self.curBlock);
|
_ = try self.rdr.readAll(self.curBlock);
|
||||||
} else {
|
} else {
|
||||||
var limit_rdr = std.io.limitedReader(self.rdr, hdr.size);
|
var limit_rdr = std.io.limitedReader(self.rdr, hdr.size);
|
||||||
self.curBlock = try self.decomp.Decompress(self.alloc, limit_rdr.reader().any());
|
self.curBlock = try self.decomp.decompress(self.alloc, limit_rdr.reader().any());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+22
-17
@@ -11,22 +11,16 @@ pub const Reader = struct {
|
|||||||
super: Superblock,
|
super: Superblock,
|
||||||
rdr: fs.File,
|
rdr: fs.File,
|
||||||
root: File,
|
root: File,
|
||||||
alloc: std.heap.GeneralPurposeAllocator(.{}),
|
alloc: std.heap.ArenaAllocator,
|
||||||
|
|
||||||
pub fn deinit(self: *Reader) void {
|
pub fn init(filename: []const u8) !Reader {
|
||||||
self.rdr.close();
|
var file = try std.fs.cwd().openFile(filename, .{});
|
||||||
// _ = self.alloc.deinit();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn newReader(filename: []const u8) !Reader {
|
|
||||||
const file = try std.fs.cwd().openFile(filename, .{});
|
|
||||||
errdefer file.close();
|
errdefer file.close();
|
||||||
var alloc: std.heap.GeneralPurposeAllocator(.{}) = .init;
|
var alloc: std.heap.ArenaAllocator = .init(std.heap.smp_allocator);
|
||||||
errdefer _ = alloc.deinit();
|
errdefer _ = alloc.deinit();
|
||||||
const super = try file.reader().readStruct(Superblock);
|
const super = try file.reader().readStruct(Superblock);
|
||||||
try super.valid();
|
try super.valid();
|
||||||
var offset_rdr: FileOffsetReader = .init(file, super.inode_table + super.root_inode.block_start);
|
var offset_rdr: FileOffsetReader = .init(&file, super.inode_table + super.root_inode.block_start);
|
||||||
var root_reader: MetadataReader = try .init(
|
var root_reader: MetadataReader = try .init(
|
||||||
super.comp,
|
super.comp,
|
||||||
offset_rdr.any(),
|
offset_rdr.any(),
|
||||||
@@ -34,16 +28,27 @@ pub fn newReader(filename: []const u8) !Reader {
|
|||||||
);
|
);
|
||||||
defer root_reader.deinit();
|
defer root_reader.deinit();
|
||||||
try root_reader.skip(super.root_inode.offset);
|
try root_reader.skip(super.root_inode.offset);
|
||||||
var out: Reader = undefined;
|
var out: Reader = .{
|
||||||
out = Reader{
|
|
||||||
.super = super,
|
.super = super,
|
||||||
.rdr = file,
|
.rdr = file,
|
||||||
.root = .{
|
.root = undefined,
|
||||||
|
.alloc = alloc,
|
||||||
|
};
|
||||||
|
out.root = .{
|
||||||
.inode = try inode.readInode(root_reader.any(), super.block_size, alloc.allocator()),
|
.inode = try inode.readInode(root_reader.any(), super.block_size, alloc.allocator()),
|
||||||
.name = "",
|
.name = "",
|
||||||
.rdr = &out,
|
.rdr = &out,
|
||||||
},
|
|
||||||
.alloc = alloc,
|
|
||||||
};
|
};
|
||||||
|
std.debug.print("init {}\n", .{out});
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *Reader) void {
|
||||||
|
self.rdr.close();
|
||||||
|
self.alloc.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn open(self: *Reader, path: []const u8) !File {
|
||||||
|
return self.root.open(path);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
@@ -8,4 +8,6 @@ const testFileName = "testing/LinuxPATest.sfs";
|
|||||||
test "open test file" {
|
test "open test file" {
|
||||||
var reader = try squashfs.newReader(testFileName);
|
var reader = try squashfs.newReader(testFileName);
|
||||||
defer reader.deinit();
|
defer reader.deinit();
|
||||||
|
const fil = try reader.open("PortableApps/Desktop.ini");
|
||||||
|
std.debug.print("{s}\n", .{fil.name});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user