pckFile: std.fs.File,
objectOffsets: std.AutoArrayHashMap(Id, u32),
- pub fn open(alloc: Alloc, dir: std.fs.Dir) !PackFile {
+ pub fn open(alloc: Alloc, dir: std.fs.Dir) !?PackFile {
var self = PackFile{
.alloc = alloc,
.idxFile = undefined,
var packDir = try dir.openDir("objects/pack", .{ .iterate = true });
defer packDir.close();
+ var packFileFound = false;
+
var packIt = packDir.iterate();
while (try packIt.next()) |f| {
if (std.mem.endsWith(u8, f.name, ".idx")) {
self.pckFile = try packDir.openFile(pckFilename.constSlice(), .{});
try self.parseIndex();
+
+ packFileFound = true;
}
}
+ if (!packFileFound)
+ return null;
+
return self;
}
};
}
- fn decompress(alloc: Alloc, reader: Reader, size: usize) ![]u8 {
- const outBuffer = try alloc.alloc(u8, size);
- errdefer alloc.free(outBuffer);
-
- var outFbs = std.io.fixedBufferStream(outBuffer);
- const writer = outFbs.writer();
-
- try std.compress.zlib.decompress(reader, writer);
-
- return outBuffer;
- }
-
fn applyDelta(alloc: Alloc, baseData: []const u8, deltData: []const u8) ![]u8 {
var fbs = std.io.fixedBufferStream(deltData);
const deltDataReader = fbs.reader().any();
return result;
}
- fn ofsDelta(self: *PackFile, offset: i64, size: usize) anyerror!Object {
+ fn ofsDelta(self: *PackFile, offset: i64) anyerror!Object {
const pckReader = self.pckFile.reader().any();
const pos = try self.pckFile.getPos();
defer self.alloc.free(baseObject.data);
try self.pckFile.seekTo(pos);
- const deltaData = try decompress(self.alloc, pckReader, size);
+ const deltaData = try decompress(self.alloc, pckReader);
defer self.alloc.free(deltaData);
const objectData = try applyDelta(self.alloc, baseObject.data, deltaData);
const offset = try getOffset(reader);
return try self.ofsDelta(
@intCast(offset.offset + objectSize.bytelen + offset.bytelen),
- objectSize.size,
);
} else {
- const objectData = try decompress(self.alloc, reader, objectSize.size);
+ const objectData = try decompress(self.alloc, reader);
return Object.init(objectKind, objectData);
}
}
const Repo = struct {
alloc: Alloc,
dir: std.fs.Dir,
- packfile: PackFile,
+ packfile: ?PackFile,
pub fn open(alloc: Alloc, path: []const u8) !Repo {
const dir = try std.fs.cwd().openDir(path, .{});
pub fn close(self: *Repo) void {
self.dir.close();
- self.packfile.close();
+ if (self.packfile != null) {
+ self.packfile.?.close();
+ }
}
pub fn getHead(self: *Repo) !Id {
}
test "get tree" {
- var repo = try Repo.open(std.testing.allocator, "../microwindows/.git");
+ var repo = try Repo.open(std.testing.allocator, "../imgui/.git");
defer repo.close();
- if (try repo.getObject(0xe59b68a950b643f9ea50997b3cf359a5956e852c)) |o| {
+ if (try repo.getObject(0xceb2b2c62d6f8f3686dcacecd5be931839b02c77)) |o| {
defer std.testing.allocator.free(o.data);
std.debug.print("tree: {s}\n", .{o.data});
}
}
// test "list commits" {
-// var repo = Repo.open(std.testing.allocator, "../microwindows/.git");
+// var repo = Repo.open(std.testing.allocator, "../imgui/.git");
// defer repo.close();
// const head = repo.getObject(repo.head);
// }
// test "tree" {
-// var repo = Repo.open(std.testing.allocator, "../microwindows/.git");
+// var repo = Repo.open(std.testing.allocator, "../imgui/.git");
// defer repo.close();
// const head = repo.getObject(repo.head);
// }
// test "blob" {
-// var repo = Repo.open(std.testing.allocator, "../microwindows/.git");
+// var repo = Repo.open(std.testing.allocator, "../imgui/.git");
// defer repo.close();
// const head = repo.getObject(repo.head);