Skip to content

Commit 1abf368

Browse files
committed
ObjectDatabase: Add Write(Stream, ...)
Provide a mechanism to write a stream directly to an object database.
1 parent 923bd83 commit 1abf368

File tree

2 files changed

+54
-31
lines changed

2 files changed

+54
-31
lines changed

LibGit2Sharp.Tests/ObjectDatabaseFixture.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,19 @@ public void CanWriteABlobFromAByteArray()
133133
}
134134
}
135135

136+
[Fact]
137+
public void CanWriteABlobFromAStream()
138+
{
139+
var ba = Encoding.ASCII.GetBytes("libgit2\r\n");
140+
141+
using (var stream = new MemoryStream(ba))
142+
using (var repo = new Repository(InitNewRepository()))
143+
{
144+
var id = repo.ObjectDatabase.Write<Blob>(stream, stream.Length);
145+
Assert.Equal(new ObjectId("99115ea359379a218c47cffc83cd0af8c91c4061"), id);
146+
}
147+
}
148+
136149
Stream PrepareMemoryStream(int contentSize)
137150
{
138151
var sb = new StringBuilder();

LibGit2Sharp/ObjectDatabase.cs

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,45 @@ public virtual ObjectId Write<T>(byte[] data) where T : GitObject
187187
return Proxy.git_odb_write(handle, data, GitObject.TypeToKindMap[typeof(T)]);
188188
}
189189

190+
/// <summary>
191+
/// Writes an object to the object database.
192+
/// </summary>
193+
/// <param name="stream">The contents of the object</param>
194+
/// <param name="numberOfBytesToConsume">The number of bytes to consume from the stream</param>
195+
/// <typeparam name="T">The type of object to write</typeparam>
196+
public virtual ObjectId Write<T>(Stream stream, long numberOfBytesToConsume) where T : GitObject
197+
{
198+
Ensure.ArgumentNotNull(stream, "stream");
199+
200+
if (!stream.CanRead)
201+
{
202+
throw new ArgumentException("The stream cannot be read from.", "stream");
203+
}
204+
205+
using (var odbStream = Proxy.git_odb_open_wstream(handle, numberOfBytesToConsume, GitObjectType.Blob))
206+
{
207+
var buffer = new byte[4 * 1024];
208+
long totalRead = 0;
209+
210+
while (totalRead < numberOfBytesToConsume)
211+
{
212+
long left = numberOfBytesToConsume - totalRead;
213+
int toRead = left < buffer.Length ? (int)left : buffer.Length;
214+
var read = stream.Read(buffer, 0, toRead);
215+
216+
if (read == 0)
217+
{
218+
throw new EndOfStreamException("The stream ended unexpectedly");
219+
}
220+
221+
Proxy.git_odb_stream_write(odbStream, buffer, read);
222+
totalRead += read;
223+
}
224+
225+
return Proxy.git_odb_stream_finalize_write(odbStream);
226+
}
227+
}
228+
190229
/// <summary>
191230
/// Inserts a <see cref="Blob"/> into the object database, created from the content of a stream.
192231
/// <para>Optionally, git filters will be applied to the content before storing it.</para>
@@ -294,37 +333,8 @@ private unsafe Blob CreateBlob(Stream stream, string hintpath, long? numberOfByt
294333
/// <returns>The created <see cref="Blob"/>.</returns>
295334
public virtual Blob CreateBlob(Stream stream, long numberOfBytesToConsume)
296335
{
297-
Ensure.ArgumentNotNull(stream, "stream");
298-
299-
if (!stream.CanRead)
300-
{
301-
throw new ArgumentException("The stream cannot be read from.", "stream");
302-
}
303-
304-
using (var odbStream = Proxy.git_odb_open_wstream(handle, numberOfBytesToConsume, GitObjectType.Blob))
305-
{
306-
var buffer = new byte[4 * 1024];
307-
long totalRead = 0;
308-
309-
while (totalRead < numberOfBytesToConsume)
310-
{
311-
long left = numberOfBytesToConsume - totalRead;
312-
int toRead = left < buffer.Length ? (int)left : buffer.Length;
313-
var read = stream.Read(buffer, 0, toRead);
314-
315-
if (read == 0)
316-
{
317-
throw new EndOfStreamException("The stream ended unexpectedly");
318-
}
319-
320-
Proxy.git_odb_stream_write(odbStream, buffer, read);
321-
totalRead += read;
322-
}
323-
324-
var id = Proxy.git_odb_stream_finalize_write(odbStream);
325-
326-
return repo.Lookup<Blob>(id);
327-
}
336+
var id = Write<Blob>(stream, numberOfBytesToConsume);
337+
return repo.Lookup<Blob>(id);
328338
}
329339

330340
/// <summary>

0 commit comments

Comments
 (0)