Skip to content

Commit f8f29a9

Browse files
committed
Make ObjectDatabase.CreateBlob() able to accept a BinaryReader
1 parent 3916ea5 commit f8f29a9

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

LibGit2Sharp.Tests/ObjectDatabaseFixture.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.IO;
2+
using System.Text;
23
using LibGit2Sharp.Tests.TestHelpers;
34
using Xunit;
45
using Xunit.Extensions;
@@ -76,6 +77,42 @@ public void CanCreateABlobIntoTheDatabaseOfABareRepository()
7677
}
7778
}
7879

80+
[Theory]
81+
[InlineData("321cbdf08803c744082332332838df6bd160f8f9", null)]
82+
[InlineData("321cbdf08803c744082332332838df6bd160f8f9", "dummy.data")]
83+
[InlineData("e9671e138a780833cb689753570fd10a55be84fb", "dummy.txt")]
84+
[InlineData("e9671e138a780833cb689753570fd10a55be84fb", "dummy.guess")]
85+
public void CanCreateABlobFromABinaryReader(string expectedSha, string hintPath)
86+
{
87+
TemporaryCloneOfTestRepo scd = BuildTemporaryCloneOfTestRepo();
88+
89+
var sb = new StringBuilder();
90+
for (int i = 0; i < 6; i++)
91+
{
92+
sb.Append("libgit2\n\r\n");
93+
}
94+
95+
using (var repo = new Repository(scd.RepositoryPath))
96+
{
97+
CreateAttributesFiles(Path.Combine(repo.Info.Path, "info"), "attributes");
98+
99+
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(sb.ToString())))
100+
using (var binReader = new BinaryReader(stream))
101+
{
102+
Blob blob = repo.ObjectDatabase.CreateBlob(binReader, hintPath);
103+
Assert.Equal(expectedSha, blob.Sha);
104+
}
105+
}
106+
}
107+
108+
private static void CreateAttributesFiles(string where, string filename)
109+
{
110+
const string attributes = "* text=auto\n*.txt text\n*.data binary\n";
111+
112+
Directory.CreateDirectory(where);
113+
File.WriteAllText(Path.Combine(where, filename), attributes);
114+
}
115+
79116
[Theory]
80117
[InlineData("README")]
81118
[InlineData("README AS WELL")]

LibGit2Sharp/Core/NativeMethods.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,19 @@ public static extern int git_blob_create_fromfile(
7979
RepositorySafeHandle repo,
8080
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(FilePathMarshaler))] FilePath path);
8181

82+
internal delegate int source_callback(
83+
IntPtr content,
84+
int max_length,
85+
IntPtr data);
86+
87+
[DllImport(libgit2)]
88+
public static extern int git_blob_create_fromchunks(
89+
ref GitOid oid,
90+
RepositorySafeHandle repositoryPtr,
91+
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(FilePathMarshaler))] FilePath hintpath,
92+
source_callback fileCallback,
93+
IntPtr data);
94+
8295
[DllImport(libgit2)]
8396
public static extern IntPtr git_blob_rawcontent(GitObjectSafeHandle blob);
8497

LibGit2Sharp/ObjectDatabase.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.IO;
44
using System.Linq;
5+
using System.Runtime.InteropServices;
56
using LibGit2Sharp.Core;
67
using LibGit2Sharp.Core.Handles;
78

@@ -67,6 +68,44 @@ public virtual Blob CreateBlob(string path)
6768
return repo.Lookup<Blob>(new ObjectId(oid));
6869
}
6970

71+
private class Processor
72+
{
73+
private readonly BinaryReader _reader;
74+
75+
public Processor(BinaryReader reader)
76+
{
77+
_reader = reader;
78+
}
79+
80+
public int Provider(IntPtr content, int max_length, IntPtr data)
81+
{
82+
var local = new byte[max_length];
83+
int numberOfReadBytes = _reader.Read(local, 0, max_length);
84+
85+
Marshal.Copy(local, 0, content, numberOfReadBytes);
86+
87+
return numberOfReadBytes;
88+
}
89+
}
90+
91+
/// <summary>
92+
/// Inserts a <see cref="Blob"/> into the object database, created from the content of a data provider.
93+
/// </summary>
94+
/// <param name="reader">The reader that will provide the content of the blob to be created.</param>
95+
/// <param name="hintpath">The hintpath is used to determine what git filters should be applied to the object before it can be placed to the object database.</param>
96+
/// <returns>The created <see cref="Blob"/>.</returns>
97+
public virtual Blob CreateBlob(BinaryReader reader, string hintpath = null)
98+
{
99+
Ensure.ArgumentNotNull(reader, "reader");
100+
101+
var oid = new GitOid();
102+
103+
var proc = new Processor(reader);
104+
Ensure.Success(NativeMethods.git_blob_create_fromchunks(ref oid, repo.Handle, hintpath, proc.Provider, IntPtr.Zero));
105+
106+
return repo.Lookup<Blob>(new ObjectId(oid));
107+
}
108+
70109
/// <summary>
71110
/// Inserts a <see cref = "Tree"/> into the object database, created from a <see cref = "TreeDefinition"/>.
72111
/// </summary>

0 commit comments

Comments
 (0)