Directory table parsing
This commit is contained in:
+1
-1
@@ -14,7 +14,7 @@ pub const CompressionType = enum(u16) {
|
|||||||
lz4,
|
lz4,
|
||||||
zstd,
|
zstd,
|
||||||
|
|
||||||
pub fn Decompress(self: CompressionType, alloc: std.mem.Allocator, rdr: std.io.AnyReader) ![]u8 {
|
pub fn decompress(self: CompressionType, alloc: std.mem.Allocator, rdr: std.io.AnyReader) ![]u8 {
|
||||||
var out = std.ArrayList(u8).init(alloc);
|
var out = std.ArrayList(u8).init(alloc);
|
||||||
defer out.deinit();
|
defer out.deinit();
|
||||||
switch (self) {
|
switch (self) {
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
|
const CompressionType = @import("decompress.zig").CompressionType;
|
||||||
|
|
||||||
const DirHeader = packed struct {
|
const DirHeader = packed struct {
|
||||||
count: u32,
|
count: u32,
|
||||||
inode_block_start: u32,
|
inode_block_start: u32,
|
||||||
@@ -43,3 +45,33 @@ pub const DirEntry = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const MetadataHeader = @import("metadata_reader.zig").MetadataHeader;
|
||||||
|
|
||||||
|
pub fn readDirEntries(alloc: std.mem.Allocator, comp: CompressionType, rdr: std.io.AnyReader, size: u32) ![]DirEntry {
|
||||||
|
var total_size: u32 = 3;
|
||||||
|
var meta_hdr: MetadataHeader = undefined;
|
||||||
|
var dir_hdr: DirHeader = 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);
|
||||||
|
while (total_size < size) {
|
||||||
|
meta_hdr = try rdr.readStruct(MetadataHeader);
|
||||||
|
if (meta_hdr.not_compressed) {
|
||||||
|
buf = try alloc.realloc(buf, meta_hdr.size);
|
||||||
|
_ = try rdr.readAll(rdr);
|
||||||
|
} else {
|
||||||
|
alloc.free(buf);
|
||||||
|
buf = try comp.Decompress(alloc, std.io.limitedReader(rdr, meta_hdr.size));
|
||||||
|
}
|
||||||
|
buf_rdr = std.io.fixedBufferStream(buf);
|
||||||
|
dir_hdr = try buf_rdr.reader().readStruct(DirHeader);
|
||||||
|
total_size += 12;
|
||||||
|
i = 0;
|
||||||
|
while (i < dir_hdr.count) : (i += 1) {
|
||||||
|
entries.append(try .init(try .init(buf_rdr, alloc), dir_hdr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return try entries.toOwnedSlice();
|
||||||
|
}
|
||||||
|
|||||||
+41
-2
@@ -1,15 +1,23 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
const inode = @import("inode.zig");
|
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 FileOpenError = error{
|
||||||
|
NotFound,
|
||||||
|
NotDirectory,
|
||||||
|
};
|
||||||
|
|
||||||
pub const File = struct {
|
pub const File = struct {
|
||||||
rdr: *Reader,
|
rdr: *Reader,
|
||||||
inode: inode.Inode,
|
inode: inode.Inode,
|
||||||
name: []const u8,
|
name: []const u8,
|
||||||
dir_entries: []const void = undefined, //TODO
|
dir_entries: []DirEntry = undefined,
|
||||||
|
|
||||||
pub fn fromRef(ref: inode.InodeRef, name: []const u8, rdr: *Reader) !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.file, 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);
|
||||||
@@ -20,4 +28,35 @@ pub const File = struct {
|
|||||||
.name = name,
|
.name = name,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fromDirEntry(rdr: *Reader, ent: DirEntry) !File {
|
||||||
|
var offset_rdr: FileOffsetReader = .init(rdr.file, rdr.super.inode_table + ent.inode_block_start);
|
||||||
|
var meta_rdr: MetadataReader = .init(
|
||||||
|
rdr.super.comp,
|
||||||
|
offset_rdr.any(),
|
||||||
|
rdr.alloc,
|
||||||
|
);
|
||||||
|
try meta_rdr.skip(ent.inode_offset);
|
||||||
|
const in = try inode.readInode(meta_rdr, rdr.super.block_size, rdr.alloc.allocator());
|
||||||
|
return .{
|
||||||
|
.rdr = rdr,
|
||||||
|
.inode = in,
|
||||||
|
.name = ent.name,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn open(self: File, path: []const u8) (anyerror || FileOpenError)!File {
|
||||||
|
switch (self.inode.header.inode_type) {
|
||||||
|
.dir, .ext_dir => {},
|
||||||
|
else => return FileOpenError.NotDirectory,
|
||||||
|
}
|
||||||
|
const clean_path: []const u8 = if (std.mem.startsWith(u8, path, "/")) {
|
||||||
|
return path[1..];
|
||||||
|
} else {
|
||||||
|
return path;
|
||||||
|
};
|
||||||
|
const path_split = std.mem.splitAny(u8, clean_path, "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn readDirEntries(self: *File) (anyerror || FileOpenError)!File {}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ const io = std.io;
|
|||||||
|
|
||||||
const CompressionType = @import("decompress.zig").CompressionType;
|
const CompressionType = @import("decompress.zig").CompressionType;
|
||||||
|
|
||||||
const MetadataHeader = packed struct {
|
pub const MetadataHeader = packed struct {
|
||||||
size: u15,
|
size: u15,
|
||||||
not_compressed: bool,
|
not_compressed: bool,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
pub const Reader = @import("squashfs.zig").Reader;
|
||||||
|
|
||||||
|
pub const File = @import("file.zig").File;
|
||||||
Reference in New Issue
Block a user