- // parse id from file
- const id = try std.fmt.parseUnsigned(u160, idStr, 16);
-
- // open any packfiles
- var packfile = PackFile.init(alloc);
- if (dir.openDir("objects/pack", .{ .iterate = true })) |packDir| {
- var packIt = packDir.iterate();
- while (try packIt.next()) |f| {
- if (std.mem.endsWith(u8, f.name, ".idx")) {
- const idxFilename = f.name;
- var pckFilenameBuffer: [64]u8 = undefined;
- const pckFilename = try std.fmt.bufPrint(&pckFilenameBuffer, "{s}.pack", .{idxFilename[0 .. idxFilename.len - 4]});
-
- const idxFile = try packDir.openFile(idxFilename, .{});
- const pckFile = try packDir.openFile(pckFilename, .{});
- defer idxFile.close();
- defer pckFile.close();
-
- const idxReader = idxFile.reader().any();
- const pckReader = pckFile.reader().any();
-
- try packfile.parse(idxReader, pckReader);
+ return .{
+ .size = size,
+ .bytelen = nBytes,
+ };
+ }
+
+ fn getOffset(reader: Reader) !struct { offset: u64, bytelen: u64 } {
+ var offset: u64 = 0;
+ var counter: u4 = 0;
+ while (true) {
+ const byte = try reader.readByte();
+
+ const bits: u7 = @truncate(byte);
+ offset <<= 7;
+ offset += @as(u64, bits);
+
+ if (byte & 0b10000000 == 0) {
+ break;
+ }
+
+ counter += 1;
+ }
+
+ const nBytes = counter + 1;
+
+ if (nBytes >= 2) {
+ for (1..nBytes) |i| {
+ offset += std.math.pow(u64, 2, 7 * i);
+ }
+ }
+ return .{
+ .offset = offset,
+ .bytelen = nBytes,
+ };
+ }
+
+ fn applyDelta(alloc: Alloc, baseData: []const u8, deltData: []const u8) ![]u8 {
+ var fbs = std.io.fixedBufferStream(deltData);
+ const deltDataReader = fbs.reader().any();
+ const baseObjectSize = try getSize(deltDataReader, false);
+ const resultObjectSize = try getSize(deltDataReader, false);
+ const deltaDataOffset = baseObjectSize.bytelen + resultObjectSize.bytelen;
+
+ const result = try alloc.alloc(u8, resultObjectSize.size);
+ var resultCounter: u64 = 0;
+
+ var counter: u64 = 0;
+ while (true) {
+ const b = deltData[deltaDataOffset + counter];
+
+ if (b & 0b10000000 != 0) {
+ var dataOffset: u64 = 0;
+ var dataSize: u64 = 0;
+ var bitsSet: u8 = 0;
+ for (0..4) |i| { // offset bits
+ if (b & (@as(u64, 1) << @min(3, i)) != 0) {
+ dataOffset += @as(u64, deltData[deltaDataOffset + counter + 1 + bitsSet]) << @min(3 * 8, i * 8);
+ bitsSet += 1;
+ }