| ... | ... | @@ -5,6 +5,7 @@ const time = @import("time"); |
| 5 | 5 | const extras = @import("extras"); |
| 6 | 6 | const tracer = @import("tracer"); |
| 7 | 7 | const nfs = @import("nfs"); |
| 8 | const nio = @import("nio"); |
| 8 | 9 | |
| 9 | 10 | pub const Id = []const u8; |
| 10 | 11 | |
| ... | ... | @@ -109,6 +110,28 @@ pub fn getObject(alloc: std.mem.Allocator, dir: nfs.Dir, obj: Id) !string { |
| 109 | 110 | const t = tracer.trace(@src(), " {s}", .{obj}); |
| 110 | 111 | defer t.end(); |
| 111 | 112 | |
| 113 | if (obj.len == 40) blk: { //sha1 object |
| 114 | var sub_path: [49:0]u8 = "objects/00/00000000000000000000000000000000000000".*; |
| 115 | @memcpy(sub_path[8..][0..2], obj[0..2]); |
| 116 | @memcpy(sub_path[11..], obj[2..]); |
| 117 | const objfile = dir.openFile(&sub_path, .{}) catch |err| switch (err) { |
| 118 | error.ENOENT => break :blk, |
| 119 | else => |e| return e, |
| 120 | }; |
| 121 | defer objfile.close(); |
| 122 | var bufr = nio.BufferedReader(4096, nfs.File).init(objfile); |
| 123 | var list = std.ArrayList(u8).init(alloc); |
| 124 | defer list.deinit(); |
| 125 | try list.ensureUnusedCapacity(512); |
| 126 | try std.compress.flate.inflate.decompress(.zlib, bufr.anyReadable(), list.writer()); |
| 127 | const header = list.items[0..std.mem.indexOfScalar(u8, list.items, 0).?]; |
| 128 | const _type = header[0..std.mem.indexOfScalar(u8, header, ' ').?]; |
| 129 | const content_len = try extras.parseDigits(u64, header[_type.len + 1 ..], 10); |
| 130 | std.debug.assert(list.items[header.len + 1 ..].len == content_len); |
| 131 | list.replaceRangeAssumeCapacity(0, header.len + 1, ""); |
| 132 | return list.toOwnedSlice(); |
| 133 | } |
| 134 | |
| 112 | 135 | const result = try std.process.Child.run(.{ |
| 113 | 136 | .allocator = alloc, |
| 114 | 137 | .cwd_dir = dir.to_std(), |