From: Patrick Schönberger Date: Mon, 20 May 2024 17:47:34 +0000 (+0200) Subject: trying to refactor main.zig, decided to redo instead X-Git-Url: https://gitweb.ps.run/ziggit/commitdiff_plain/4f438320703c7131ab3564cc2d4d17cd7563b8fd?ds=sidebyside trying to refactor main.zig, decided to redo instead --- diff --git a/main.zig b/main.zig index 42a5a4f..cf30d71 100644 --- a/main.zig +++ b/main.zig @@ -151,6 +151,49 @@ fn applyDelta(alloc: std.mem.Allocator, baseData: []const u8, deltaData: []const return result; } +fn parseObject(alloc: std.mem.Allocator, objectType: u3, objectData: []const u8) !git.Object { + if (objectType == 3) { + return .{ + .data = objectData, + .blob = .{ + .data = objectData[0..@min(objectData.len, 1000)], + }, + }; + } else if (objectType == 2) { + var treeEntries = git.Tree.init(alloc); + + var counter: u64 = 0; + while (counter < objectData.len) { + const modeLen = std.mem.indexOfScalar(u8, objectData[counter..objectData.len], ' ') orelse break; + const mode = objectData[counter .. counter + modeLen]; + counter += modeLen + 1; + + var nameLen: u64 = 0; + while (counter + nameLen < objectData.len and objectData[counter + nameLen] != 0) { + nameLen += 1; + } + const name = objectData[counter .. counter + nameLen]; + counter += nameLen + 1; + + if (counter + 20 <= objectData.len) { + const hash: u160 = std.mem.readVarInt(u160, objectData[counter .. counter + 20], .big); + counter += 20; + + treeEntries.append(.{ + .mode = alloc.dupe(u8, mode), + .name = alloc.dupe(u8, name), + .hash = hash, + }); + } + } + return .{ + .tree = treeEntries, + }; + } else { + std.debug.print("type: {}\n{s}\n", .{ objectType, objectData }); + } +} + const PackFile = struct { alloc: std.mem.Allocator, version: i32, @@ -214,7 +257,7 @@ const PackFile = struct { return null; } - pub fn getObject(self: @This(), index: u64) !GitObject { + pub fn getObject(self: @This(), alloc: std.mem.Allocator, index: u64) !git.Object { var objectType: u3 = @truncate(self.packBuffer[index] >> 4); const objectSize = getSize(self.packBuffer[index..self.packBuffer.len], true); @@ -233,8 +276,9 @@ const PackFile = struct { const baseIndex = index - offsetSize.offset; - const baseObject = try self.getObject(baseIndex); + const baseObject = try self.getObject(alloc, baseIndex); defer self.alloc.free(baseObject.data); + const deltaData = try decompress( self.alloc, self.packBuffer[index + objectSize.bytelen + offsetSize.bytelen .. self.packBuffer.len], @@ -273,23 +317,84 @@ const PackFile = struct { ); } - // const objectStart = objectSize.bytelen; - // objectData = self.packBuffer[objectStart .. objectStart + objectSize]; - - return .{ - .type = objectType, - .data = objectData, - }; + return try parseObject(alloc, objectType, objectData); } }; -pub fn main() !void { - const packPath = "../microwindows/.git/objects/pack/pack-a2e25318e6fc668e1264fdaa11fb7223d5627143.pack"; - const idxPath = "../microwindows/.git/objects/pack/pack-a2e25318e6fc668e1264fdaa11fb7223d5627143.idx"; +const git = struct { + const Blob = struct { + data: []u8, + }; + const TreeEntry = struct { + mode: []u8, + name: []u8, + hash: u160, + }; + const Tree = std.ArrayList(TreeEntry); + const Commit = struct { + author: []u8, + message: []u8, + parent: u160, + Tree: u160, + }; + const Object = struct { + usingnamespace union(enum) { + blob: Blob, + tree: Tree, + commit: Commit, + }; + data: []const u8, + }; + const Repo = struct { + pub fn init(alloc: std.mem.Allocator, path: []const u8) !@This() { + const gitDir = try std.fs.cwd().openDir(path, .{}); + + var objects = std.AutoHashMap(u160, Object).init(alloc); + + var iter = gitDir.iterate(); + while (try iter.next()) |dirEntry| { + if (std.mem.endsWith(u8, dirEntry.name, ".idx")) { + var packPathBuffer: [128]u8 = undefined; + const idxPath = try gitDir.realpathAlloc(alloc, dirEntry.name); + const packPath = try std.fmt.bufPrint( + &packPathBuffer, + "{s}.pack", + .{idxPath[0 .. idxPath.len - 4]}, + ); + + const packBuffer = try std.fs.cwd().readFileAlloc(alloc, packPath, 1024 * 1024 * 1024 * 1024); + const idxBuffer = try std.fs.cwd().readFileAlloc(alloc, idxPath, 1024 * 1024 * 1024 * 1024); + defer alloc.free(packBuffer); + defer alloc.free(idxBuffer); + + const pf = try PackFile.init(alloc, packBuffer, idxBuffer); + defer pf.deinit(); + + for (0..pf.objectNames.items.len) |i| { + try objects.put( + pf.objectNames.items[i], + try pf.getObject(alloc, pf.objectOffsets.items[i]), + ); + } + } + } + return .{ + .alloc = alloc, + .objects = objects, + }; + } - const packBytes = 35920363; - const idxBytes = 392036; + pub fn deinit(self: *@This()) void { + self.objects.deinit(); + } + alloc: std.mem.Allocator, + objects: std.AutoHashMap(u160, Object), + }; +}; + +pub fn main() !void { + // allocator var allocator = std.heap.GeneralPurposeAllocator(.{}){}; const alloc = allocator.allocator(); defer { @@ -297,94 +402,42 @@ pub fn main() !void { std.debug.print("{}\n", .{res}); } - const packBuffer = try std.fs.cwd().readFileAlloc(alloc, packPath, packBytes); - const idxBuffer = try std.fs.cwd().readFileAlloc(alloc, idxPath, idxBytes); - defer alloc.free(packBuffer); - defer alloc.free(idxBuffer); - - const print = std.debug.print; - - const pf = try PackFile.init(alloc, packBuffer, idxBuffer); - defer pf.deinit(); - - print("{} objects\n", .{pf.objectNames.items.len}); + // open repo + var repo = try git.Repo.init(alloc, "../microwindows/.git/"); + // input const r = std.io.getStdIn().reader(); var inputBuffer = std.mem.zeroes([1024]u8); + // print HEAD + // const head = repo.getHead(); + // const headObject = head.getObject(); + // std.debug.print("HEAD: {x:0>40}\n", .{headObject.id}); + + // main loop while (true) { + // read line const input = r.readUntilDelimiter(&inputBuffer, '\n') catch continue; + // parse object id const id = std.fmt.parseInt(u160, input, 16) catch continue; - if (pf.findObjectOffset(id)) |offset| { - const o = try pf.getObject(offset); - - if (o.type == 3) { - std.debug.print("object data: {s}\n\n", .{o.data[0..@min(o.data.len, 1000)]}); - } else if (o.type == 2) { - var counter: u64 = 0; - while (counter < o.data.len) { - const modeLen = std.mem.indexOfScalar(u8, o.data[counter..o.data.len], ' ') orelse break; - const mode = o.data[counter .. counter + modeLen]; - counter += modeLen + 1; - - var nameLen: u64 = 0; - while (counter + nameLen < o.data.len and o.data[counter + nameLen] != 0) { - nameLen += 1; - } - const name = o.data[counter .. counter + nameLen]; - counter += nameLen + 1; - - if (counter + 20 <= o.data.len) { - const hash: u160 = std.mem.readVarInt(u160, o.data[counter .. counter + 20], .big); - counter += 20; - - std.debug.print("{s} {s} {x:0>40}\n", .{ mode, name, hash }); + // print object + if (repo.objects.get(id)) |o| { + switch (o) { + .Blob => |blob| { + std.debug.print("blob: {s}\n\n", .{blob.data}); + }, + .Tree => |tree| { + for (tree.entries) |entry| { + std.debug.print("{s} {s} {x:0>40}\n", .{ entry.mode, entry.name, entry.hash }); } - } - print("\n", .{}); - } else { - std.debug.print("type: {}\n{s}\n", .{ o.type, o.data }); + std.debug.print("\n", .{}); + }, + .Commit => |commit| { + std.debug.print("commit: {}", .{commit}); + }, } } } - - // for (0..pf.objectNames.items.len) |i| { - // print("object {x:0>40}:\n", .{pf.objectNames.items[i]}); - // const o = try pf.getObject(pf.objectOffsets.items[i]); - // defer alloc.free(o.data); - - // if (o.type == 3) { - // std.debug.print("object data: {s}\n\n", .{o.data[0..@min(o.data.len, 1000)]}); - // } else if (o.type == 2) { - // var counter: u64 = 0; - // while (counter < o.data.len) { - // const modeLen = std.mem.indexOfScalar(u8, o.data[counter..o.data.len], ' ') orelse break; - // const mode = o.data[counter .. counter + modeLen]; - // counter += modeLen + 1; - - // var nameLen: u64 = 0; - // while (counter + nameLen < o.data.len and o.data[counter + nameLen] != 0) { - // nameLen += 1; - // } - // const name = o.data[counter .. counter + nameLen]; - // counter += nameLen + 1; - - // if (counter + 20 <= o.data.len) { - // const hash: u160 = std.mem.readVarInt(u160, o.data[counter .. counter + 20], .big); - // counter += 20; - - // std.debug.print("{s} {s} {x:0>40}\n", .{ mode, name, hash }); - // } - // } - // print("\n", .{}); - // } else { - // std.debug.print("type: {}\n", .{o.type}); - // } - - // if (o.type == 4) { - // std.debug.print("type: {}\ndata: {s}\n\n", .{ o.type, o.data }); - // } - // } }