blob: 7d5eb36681fd9971ba753d0fd218f1ee48b3d7ef (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
using System.IO.Compression;
using System.Text.Json.Serialization;
using LibGit.Extensions;
using LibGit.Interfaces;
namespace LibGit;
public class TreeObject
{
[JsonIgnore] public IRepoSource RepoSource { get; }
public string ObjectId { get; }
public TreeObject(IRepoSource repoSource, string objectId)
{
RepoSource = repoSource;
ObjectId = objectId;
}
private const bool _debug = false;
public string Length { get; set; }
public Dictionary<string, TreeObjectEntry> Entries { get; set; } = new();
public TreeObject ReadFromZlibCompressedObjFile(Stream bytes)
{
if (_debug) Console.WriteLine($"Decompressing {GetType().Name}");
using ZLibStream stream = new ZLibStream(bytes, CompressionMode.Decompress);
using var result = new MemoryStream();
stream.CopyTo(result);
stream.Flush();
stream.Close();
return ReadFromDecompressedObjFile(result);
}
public TreeObject ReadFromDecompressedObjFile(Stream data)
{
if (_debug) Console.WriteLine("Parsing tree object");
// var data = new Queue<byte>(bytes.ToArray());
int iters = 0;
data.Seek(0, SeekOrigin.Begin);
if (_debug) Console.WriteLine($"Iteration {iters}: starting pos: {data.Position}/+{data.Remaining()}/{data.Length}");
Length = data.ReadNullTerminatedField(asciiPrefix: "tree ").AsString();
while (data.Remaining() > 20)
{
if (_debug) Console.WriteLine($"readTree.Iteration {iters} ({data.Position}/+{data.Remaining()}/{data.Length})");
var entry = ReadFileEntry(data);
Entries.Add(entry.Key, entry.Value);
}
if (data.Remaining() > 0)
{
Console.WriteLine($"--parseTree: Unparsed data after {iters} iteration(s) of parsing TreeObject--");
Console.WriteLine(this.ToJson());
Console.WriteLine("--HexDump of remaining data--");
data.Peek(data.Remaining()).HexDump();
//Console.WriteLine($"Unparsed data: {Encoding.UTF8.GetString(data.ToArray())}");
}
data.Close();
if (_debug)
{
Console.WriteLine($"-- Read tree object of size {Length} --");
foreach (var x in Entries.ToList())
{
Console.WriteLine($"{x.Value.Mode} {x.Value.Hash} {x.Key}");
}
foreach (var x in Entries.ToList())
{
Console.WriteLine($"Path: {x.Key}");
Console.WriteLine($"Mode: {x.Value.Mode}");
Console.WriteLine($"Hash: {x.Value.Hash}");
}
}
return this;
}
//parsing
private static KeyValuePair<string, TreeObjectEntry> ReadFileEntry(Stream data)
{
if (_debug) Console.WriteLine($"--tree.ReadFileEntry--");
var path = "";
TreeObjectEntry entry = new();
//entry format: <mode> <path>\0<hash>
entry.Mode = data.ReadSpaceTerminatedField().AsString();
path = data.ReadNullTerminatedField().AsString();
entry.Hash = string.Join("", data.ReadBytes(20).Select(x => $"{x:x2}"));
return new KeyValuePair<string, TreeObjectEntry>(path, entry);
}
public class TreeObjectEntry
{
public string Mode { get; set; }
public string Hash { get; set; }
}
}
|