diff options
author | TheArcaneBrony <myrainbowdash949@gmail.com> | 2023-06-05 03:25:53 +0200 |
---|---|---|
committer | TheArcaneBrony <myrainbowdash949@gmail.com> | 2023-06-05 03:25:53 +0200 |
commit | 51d820e22a4517dbb06d38a4f07f7c48522ef811 (patch) | |
tree | 4a7749cf77223dff2414fd4b73cb17df43d7449e /LibGit/TreeObject.cs | |
download | GitTools-master.tar.xz |
Diffstat (limited to 'LibGit/TreeObject.cs')
-rw-r--r-- | LibGit/TreeObject.cs | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/LibGit/TreeObject.cs b/LibGit/TreeObject.cs new file mode 100644 index 0000000..7d5eb36 --- /dev/null +++ b/LibGit/TreeObject.cs @@ -0,0 +1,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; } + } +} \ No newline at end of file |