mirror of
https://github.com/ziglang/zig.git
synced 2026-02-15 13:58:27 +00:00
zig std: implement tar format
This commit is contained in:
parent
c427685a13
commit
6b84c8e04c
@ -1,6 +1,7 @@
|
||||
const builtin = @import("builtin");
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const assert = std.debug.assert;
|
||||
|
||||
pub fn main() !void {
|
||||
var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||
@ -140,7 +141,6 @@ fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void {
|
||||
},
|
||||
});
|
||||
const w = response.writer();
|
||||
try w.writeAll("tar header");
|
||||
|
||||
var std_dir = try context.lib_dir.openDir("std", .{ .iterate = true });
|
||||
defer std_dir.close();
|
||||
@ -159,13 +159,27 @@ fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void {
|
||||
else => continue,
|
||||
}
|
||||
|
||||
try w.writeAll(entry.path);
|
||||
|
||||
var file = try std_dir.openFile(entry.path, .{});
|
||||
defer file.close();
|
||||
|
||||
const stat = try file.stat();
|
||||
const padding = p: {
|
||||
const remainder = stat.size % 512;
|
||||
break :p if (remainder > 0) 512 - remainder else 0;
|
||||
};
|
||||
comptime assert(@sizeOf(TarHeader) == 512);
|
||||
|
||||
var file_header = TarHeader.init();
|
||||
file_header.typeflag = .regular;
|
||||
try file_header.setPath("std", entry.path);
|
||||
try file_header.setSize(stat.size);
|
||||
try file_header.updateChecksum();
|
||||
try w.writeAll(std.mem.asBytes(&file_header));
|
||||
try w.writeFile(file);
|
||||
try w.writeByteNTimes(0, padding);
|
||||
}
|
||||
// intentionally omitting the pointless trailer
|
||||
//try w.writeByteNTimes(0, 512 * 2);
|
||||
try response.end();
|
||||
}
|
||||
|
||||
@ -369,3 +383,77 @@ fn openBrowserTabThread(gpa: Allocator, url: []const u8) !void {
|
||||
try child.spawn();
|
||||
_ = try child.wait();
|
||||
}
|
||||
|
||||
/// Forked from https://github.com/mattnite/tar/blob/main/src/main.zig which is
|
||||
/// MIT licensed.
|
||||
pub const TarHeader = extern struct {
|
||||
name: [100]u8,
|
||||
mode: [7:0]u8,
|
||||
uid: [7:0]u8,
|
||||
gid: [7:0]u8,
|
||||
size: [11:0]u8,
|
||||
mtime: [11:0]u8,
|
||||
checksum: [7:0]u8,
|
||||
typeflag: FileType,
|
||||
linkname: [100]u8,
|
||||
magic: [5:0]u8,
|
||||
version: [2]u8,
|
||||
uname: [31:0]u8,
|
||||
gname: [31:0]u8,
|
||||
devmajor: [7:0]u8,
|
||||
devminor: [7:0]u8,
|
||||
prefix: [155]u8,
|
||||
pad: [12]u8,
|
||||
|
||||
const FileType = enum(u8) {
|
||||
regular = '0',
|
||||
hard_link = '1',
|
||||
symbolic_link = '2',
|
||||
character = '3',
|
||||
block = '4',
|
||||
directory = '5',
|
||||
fifo = '6',
|
||||
reserved = '7',
|
||||
pax_global = 'g',
|
||||
extended = 'x',
|
||||
_,
|
||||
};
|
||||
|
||||
fn init() TarHeader {
|
||||
var ret = std.mem.zeroes(TarHeader);
|
||||
ret.magic = [_:0]u8{ 'u', 's', 't', 'a', 'r' };
|
||||
ret.version = [_:0]u8{ '0', '0' };
|
||||
return ret;
|
||||
}
|
||||
|
||||
fn setPath(self: *TarHeader, prefix: []const u8, path: []const u8) !void {
|
||||
if (prefix.len + 1 + path.len > 100) {
|
||||
var i: usize = 0;
|
||||
while (i < path.len and path.len - i > 100) {
|
||||
while (path[i] != '/') : (i += 1) {}
|
||||
}
|
||||
|
||||
_ = try std.fmt.bufPrint(&self.prefix, "{s}/{s}", .{ prefix, path[0..i] });
|
||||
_ = try std.fmt.bufPrint(&self.name, "{s}", .{path[i + 1 ..]});
|
||||
} else {
|
||||
_ = try std.fmt.bufPrint(&self.name, "{s}/{s}", .{ prefix, path });
|
||||
}
|
||||
}
|
||||
|
||||
fn setSize(self: *TarHeader, size: u64) !void {
|
||||
_ = try std.fmt.bufPrint(&self.size, "{o:0>11}", .{size});
|
||||
}
|
||||
|
||||
fn updateChecksum(self: *TarHeader) !void {
|
||||
const offset = @offsetOf(TarHeader, "checksum");
|
||||
var checksum: usize = 0;
|
||||
for (std.mem.asBytes(self), 0..) |val, i| {
|
||||
checksum += if (i >= offset and i < offset + @sizeOf(@TypeOf(self.checksum)))
|
||||
' '
|
||||
else
|
||||
val;
|
||||
}
|
||||
|
||||
_ = try std.fmt.bufPrint(&self.checksum, "{o:0>7}", .{checksum});
|
||||
}
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user