Skip to content
/ zig Public
forked from ziglang/zig

Commit

Permalink
Merge pull request ziglang#19128 from ziglang/tar
Browse files Browse the repository at this point in the history
std.tar: avoid dependency on file system
  • Loading branch information
andrewrk authored Feb 29, 2024
2 parents 83d2eef + beca85e commit 3e292e5
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 14 deletions.
47 changes: 34 additions & 13 deletions lib/std/tar.zig
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,27 @@ fn nullStr(str: []const u8) []const u8 {
return str;
}

pub const IteratorOptions = struct {
/// Use a buffer with length `std.fs.MAX_PATH_BYTES` to match file system capabilities.
file_name_buffer: []u8,
/// Use a buffer with length `std.fs.MAX_PATH_BYTES` to match file system capabilities.
link_name_buffer: []u8,
diagnostics: ?*Diagnostics = null,

pub const Diagnostics = Options.Diagnostics;
};

/// Iterates over files in tar archive.
/// `next` returns each file in `reader` tar archive.
pub fn iterator(reader: anytype, diagnostics: ?*Options.Diagnostics) Iterator(@TypeOf(reader)) {
pub fn iterator(reader: anytype, options: IteratorOptions) Iterator(@TypeOf(reader)) {
return .{
.reader = reader,
.diagnostics = diagnostics,
.diagnostics = options.diagnostics,
.header_buffer = undefined,
.file_name_buffer = options.file_name_buffer,
.link_name_buffer = options.link_name_buffer,
.padding = 0,
.file = undefined,
};
}

Expand All @@ -246,14 +261,14 @@ fn Iterator(comptime ReaderType: type) type {
diagnostics: ?*Options.Diagnostics,

// buffers for heeader and file attributes
header_buffer: [Header.SIZE]u8 = undefined,
file_name_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined,
link_name_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined,
header_buffer: [Header.SIZE]u8,
file_name_buffer: []u8,
link_name_buffer: []u8,

// bytes of padding to the end of the block
padding: usize = 0,
padding: usize,
// current tar file
file: File = undefined,
file: File,

pub const File = struct {
name: []const u8, // name of file, symlink or directory
Expand Down Expand Up @@ -305,7 +320,7 @@ fn Iterator(comptime ReaderType: type) type {
}

fn initFile(self: *Self) void {
self.file = File{
self.file = .{
.name = self.file_name_buffer[0..0],
.link_name = self.link_name_buffer[0..0],
.size = 0,
Expand Down Expand Up @@ -357,10 +372,10 @@ fn Iterator(comptime ReaderType: type) type {
},
// Prefix header types
.gnu_long_name => {
self.file.name = try self.readString(@intCast(size), &self.file_name_buffer);
self.file.name = try self.readString(@intCast(size), self.file_name_buffer);
},
.gnu_long_link => {
self.file.link_name = try self.readString(@intCast(size), &self.link_name_buffer);
self.file.link_name = try self.readString(@intCast(size), self.link_name_buffer);
},
.extended_header => {
// Use just attributes from last extended header.
Expand All @@ -370,10 +385,10 @@ fn Iterator(comptime ReaderType: type) type {
while (try rdr.next()) |attr| {
switch (attr.kind) {
.path => {
self.file.name = try attr.value(&self.file_name_buffer);
self.file.name = try attr.value(self.file_name_buffer);
},
.linkpath => {
self.file.link_name = try attr.value(&self.link_name_buffer);
self.file.link_name = try attr.value(self.link_name_buffer);
},
.size => {
var buf: [pax_max_size_attr_len]u8 = undefined;
Expand Down Expand Up @@ -536,7 +551,13 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi
},
}

var iter = iterator(reader, options.diagnostics);
var file_name_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
var link_name_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
var iter = iterator(reader, .{
.file_name_buffer = &file_name_buffer,
.link_name_buffer = &link_name_buffer,
.diagnostics = options.diagnostics,
});
while (try iter.next()) |file| {
switch (file.kind) {
.directory => {
Expand Down
8 changes: 7 additions & 1 deletion lib/std/tar/test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,15 @@ test "tar run Go test cases" {
},
};

var file_name_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
var link_name_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;

for (cases) |case| {
var fsb = std.io.fixedBufferStream(case.data);
var iter = tar.iterator(fsb.reader(), null);
var iter = tar.iterator(fsb.reader(), .{
.file_name_buffer = &file_name_buffer,
.link_name_buffer = &link_name_buffer,
});
var i: usize = 0;
while (iter.next() catch |err| {
if (case.err) |e| {
Expand Down

0 comments on commit 3e292e5

Please sign in to comment.