aboutsummaryrefslogtreecommitdiff
path: root/src/libarchive
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-10-15 19:44:53 -0700
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2021-10-15 19:44:53 -0700
commit10696680ff9012f7ca07ae2c1de5ed710647b4f9 (patch)
tree1732ddd3dd2a7605da8ff5f181156e9e734aaa99 /src/libarchive
parent7e159cb5cdfc288c1aab7b0f810f5b54438b9f19 (diff)
downloadbun-10696680ff9012f7ca07ae2c1de5ed710647b4f9.tar.gz
bun-10696680ff9012f7ca07ae2c1de5ed710647b4f9.tar.zst
bun-10696680ff9012f7ca07ae2c1de5ed710647b4f9.zip
Polish
Diffstat (limited to 'src/libarchive')
-rw-r--r--src/libarchive/libarchive.zig30
1 files changed, 26 insertions, 4 deletions
diff --git a/src/libarchive/libarchive.zig b/src/libarchive/libarchive.zig
index 117f2809f..ef8a2acfa 100644
--- a/src/libarchive/libarchive.zig
+++ b/src/libarchive/libarchive.zig
@@ -408,6 +408,17 @@ pub const Archive = struct {
pub const Context = struct {
pluckers: []Plucker = &[_]Plucker{},
overwrite_list: std.StringArrayHashMap(void),
+ all_files: EntryMap,
+ pub const EntryMap = std.ArrayHashMap(u64, [*c]u8, U64Context, false);
+
+ pub const U64Context = struct {
+ pub fn hash(ctx: @This(), k: u64) u32 {
+ return @truncate(u32, k);
+ }
+ pub fn eql(ctx: @This(), a: u64, b: u64) bool {
+ return a == b;
+ }
+ };
};
pub const Plucker = struct {
@@ -512,6 +523,8 @@ pub const Archive = struct {
file_buffer: []const u8,
root: []const u8,
ctx: ?*Archive.Context,
+ comptime FilePathAppender: type,
+ appender: FilePathAppender,
comptime depth_to_skip: usize,
comptime close_handles: bool,
comptime log: bool,
@@ -552,17 +565,19 @@ pub const Archive = struct {
var pathname: [:0]const u8 = std.mem.sliceTo(lib.archive_entry_pathname(entry).?, 0);
var tokenizer = std.mem.tokenize(u8, std.mem.span(pathname), std.fs.path.sep_str);
comptime var depth_i: usize = 0;
+
inline while (depth_i < depth_to_skip) : (depth_i += 1) {
if (tokenizer.next() == null) continue :loop;
}
var pathname_ = tokenizer.rest();
- pathname = std.mem.sliceTo(pathname_.ptr[0..pathname_.len :0], 0);
- const dirname = std.fs.path.dirname(std.mem.span(pathname)) orelse "";
+ pathname = @intToPtr([*]const u8, @ptrToInt(pathname_.ptr))[0..pathname_.len :0];
const mask = lib.archive_entry_filetype(entry);
const size = @intCast(usize, std.math.max(lib.archive_entry_size(entry), 0));
if (size > 0) {
+ const slice = std.mem.span(pathname);
+
if (comptime log) {
Output.prettyln(" {s}", .{pathname});
}
@@ -570,7 +585,7 @@ pub const Archive = struct {
const file = dir.createFileZ(pathname, .{ .truncate = true }) catch |err| brk: {
switch (err) {
error.FileNotFound => {
- dir.makePath(dirname) catch {};
+ try dir.makePath(std.fs.path.dirname(slice) orelse return err);
break :brk try dir.createFileZ(pathname, .{ .truncate = true });
},
else => {
@@ -584,10 +599,17 @@ pub const Archive = struct {
if (ctx) |ctx_| {
const hash: u64 = if (ctx_.pluckers.len > 0)
- std.hash.Wyhash.hash(0, std.mem.span(pathname))
+ std.hash.Wyhash.hash(0, slice)
else
@as(u64, 0);
+ if (comptime FilePathAppender != void) {
+ var result = ctx.?.all_files.getOrPutAdapted(hash, Context.U64Context{}) catch unreachable;
+ if (!result.found_existing) {
+ result.value_ptr.* = (try appender.appendMutable(@TypeOf(slice), slice)).ptr;
+ }
+ }
+
for (ctx_.pluckers) |*plucker_| {
if (plucker_.filename_hash == hash) {
try plucker_.contents.inflate(size);