Welcome to mirror list, hosted at ThFree Co, Russian Federation.

ObjectBuilder.cs « LibGit2Sharp - github.com/mono/libgit2sharp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 0c951998ad42c2648cc6e43b0d7514132c9c0aae (plain)
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
102
103
104
105
106
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using LibGit2Sharp.Wrapper;

namespace LibGit2Sharp
{
    public class ObjectBuilder : IBuilder
    {
        private readonly IDictionary<ObjectType, Func<IntPtr, GitObject>> _builderMapper;

        public ObjectBuilder()
        {
            _builderMapper = InitMapper();
        }

        private IDictionary<ObjectType, Func<IntPtr, GitObject>> InitMapper()
        {
            var map =  new Dictionary<ObjectType, Func<IntPtr, GitObject>>();
            map.Add(ObjectType.Commit, BuildCommit);
            map.Add(ObjectType.Tag, BuildTag);
            map.Add(ObjectType.Tree, BuildTree);
            map.Add(ObjectType.Blob, BuildBlob);
            return map;
        }

        private GitObject BuildTag(IntPtr gitObjectPtr)
        {
            var gitTag = (git_tag)Marshal.PtrToStructure(gitObjectPtr, typeof(git_tag));
            
            Signature tagTagger = BuildSignature(gitTag.tagger);
            GitObject tagTarget = BuildFrom(gitTag.target, (ObjectType)gitTag.type);

            return new Tag(ObjectId.ToString(gitTag.tag.id.id), gitTag.tag_name, tagTarget, tagTagger, gitTag.message);
        }

        private static GitObject BuildCommit(IntPtr gitObjectPtr)
        {
            var gitCommit = (git_commit)Marshal.PtrToStructure(gitObjectPtr, typeof(git_commit));

            Signature commitAuthor = BuildSignature(gitCommit.author);
            Signature commitCommitter = BuildSignature(gitCommit.committer);
            var commitTree = (Tree)BuildTree(gitCommit.tree);

            var numberOfParents = (int)gitCommit.parents.length;
            IList<GitObject> parents = new List<GitObject>(numberOfParents);

            for (int i = 0; i < numberOfParents; i++)
            {
                IntPtr nextParentPtrPtr = IntPtr.Add(gitCommit.parents.contents, i * Marshal.SizeOf(typeof(IntPtr)));
                IntPtr parentPtr = Marshal.ReadIntPtr(nextParentPtrPtr);
                var parentGitObject = BuildGitObject(parentPtr);
                parents.Add(parentGitObject);
            }

            return new Commit(ObjectId.ToString(gitCommit.commit.id.id), commitAuthor, commitCommitter, gitCommit.message, gitCommit.message_short, commitTree, parents);
        }

        private static GitObject BuildTree(IntPtr gitObjectPtr)
        {
            var gitTree = (git_tree)Marshal.PtrToStructure(gitObjectPtr, typeof(git_tree));
            return new Tree(ObjectId.ToString(gitTree.tree.id.id));
        }


        private static GitObject BuildBlob(IntPtr gitObjectPtr)
        {
            throw new NotImplementedException();
            //var gitBlob = (git_blob)Marshal.PtrToStructure(gitObjectPtr, typeof(git_blob));
            //return new Blob(...)
        }

        private static Signature BuildSignature(IntPtr gitObjectPtr)
        {
            if (gitObjectPtr == IntPtr.Zero)
            {
                return null; // TODO: Fix full parsing of commits.
            }

            var gitPerson = (git_signature)Marshal.PtrToStructure(gitObjectPtr, typeof(git_signature));
            return new Signature(gitPerson.name, gitPerson.email, new GitDate((int)gitPerson.time, gitPerson.offset));
        }

        private static GitObject BuildGitObject(IntPtr gitObjectPtr)
        {
            var gitObject = (git_object)Marshal.PtrToStructure(gitObjectPtr, typeof(git_object));
            return new GitObject(ObjectId.ToString(gitObject.id.id), (ObjectType)gitObject.source.raw.type);
        }

        public GitObject BuildFrom(IntPtr gitObjectPtr, ObjectType type)
        {
            if (gitObjectPtr == IntPtr.Zero)
            {
                throw new ArgumentNullException("gitObjectPtr");
            }

            if (!_builderMapper.Keys.Contains(type))
            {
                return BuildGitObject(gitObjectPtr);
            }

            return _builderMapper[type](gitObjectPtr);
        }
    }
}