зеркало из https://github.com/github/libgit2sharp.git
Refactor OdbBackEnd
This commit is contained in:
Родитель
7eb9ccfbff
Коммит
7ea504a6ef
|
@ -193,6 +193,21 @@ namespace LibGit2Sharp
|
||||||
public static readonly GitOdbBackend.foreach_callback ForEachCallback = Foreach;
|
public static readonly GitOdbBackend.foreach_callback ForEachCallback = Foreach;
|
||||||
public static readonly GitOdbBackend.free_callback FreeCallback = Free;
|
public static readonly GitOdbBackend.free_callback FreeCallback = Free;
|
||||||
|
|
||||||
|
private static OdbBackend MarshalOdbBackend(IntPtr backendPtr)
|
||||||
|
{
|
||||||
|
|
||||||
|
var intPtr = Marshal.ReadIntPtr(backendPtr, GitOdbBackend.GCHandleOffset);
|
||||||
|
var odbBackend = GCHandle.FromIntPtr(intPtr).Target as OdbBackend;
|
||||||
|
|
||||||
|
if (odbBackend == null)
|
||||||
|
{
|
||||||
|
Proxy.giterr_set_str(GitErrorCategory.Reference, "Cannot retrieve the managed OdbBackend.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return odbBackend;
|
||||||
|
}
|
||||||
|
|
||||||
private unsafe static int Read(
|
private unsafe static int Read(
|
||||||
out IntPtr buffer_p,
|
out IntPtr buffer_p,
|
||||||
out UIntPtr len_p,
|
out UIntPtr len_p,
|
||||||
|
@ -204,50 +219,53 @@ namespace LibGit2Sharp
|
||||||
len_p = UIntPtr.Zero;
|
len_p = UIntPtr.Zero;
|
||||||
type_p = GitObjectType.Bad;
|
type_p = GitObjectType.Bad;
|
||||||
|
|
||||||
OdbBackend odbBackend = GCHandle.FromIntPtr(Marshal.ReadIntPtr(backend, GitOdbBackend.GCHandleOffset)).Target as OdbBackend;
|
OdbBackend odbBackend = MarshalOdbBackend(backend);
|
||||||
|
if (odbBackend == null)
|
||||||
if (odbBackend != null)
|
{
|
||||||
|
return (int)GitErrorCode.Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream dataStream = null;
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
Stream dataStream = null;
|
|
||||||
ObjectType objectType;
|
ObjectType objectType;
|
||||||
|
int toReturn = odbBackend.Read(oid.Id, out dataStream, out objectType);
|
||||||
|
|
||||||
try
|
if (toReturn != 0)
|
||||||
{
|
{
|
||||||
int toReturn = odbBackend.Read(oid.Id, out dataStream, out objectType);
|
|
||||||
|
|
||||||
if (0 == toReturn)
|
|
||||||
{
|
|
||||||
// Caller is expected to give us back a stream created with the Allocate() method.
|
|
||||||
UnmanagedMemoryStream memoryStream = dataStream as UnmanagedMemoryStream;
|
|
||||||
|
|
||||||
if (null == memoryStream)
|
|
||||||
{
|
|
||||||
return (int)GitErrorCode.Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
len_p = new UIntPtr((ulong)memoryStream.Capacity);
|
|
||||||
type_p = objectType.ToGitObjectType();
|
|
||||||
|
|
||||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
|
||||||
buffer_p = new IntPtr(memoryStream.PositionPointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
|
// Caller is expected to give us back a stream created with the Allocate() method.
|
||||||
|
var memoryStream = dataStream as UnmanagedMemoryStream;
|
||||||
|
|
||||||
|
if (memoryStream == null)
|
||||||
{
|
{
|
||||||
Proxy.giterr_set_str(GitErrorCategory.Odb, ex);
|
return (int)GitErrorCode.Error;
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
|
len_p = new UIntPtr((ulong)memoryStream.Capacity);
|
||||||
|
type_p = objectType.ToGitObjectType();
|
||||||
|
|
||||||
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
buffer_p = new IntPtr(memoryStream.PositionPointer);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Proxy.giterr_set_str(GitErrorCategory.Odb, ex);
|
||||||
|
return (int)GitErrorCode.Error;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (dataStream != null)
|
||||||
{
|
{
|
||||||
if (null != dataStream)
|
dataStream.Dispose();
|
||||||
{
|
|
||||||
dataStream.Dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)GitErrorCode.Error;
|
return (int)GitErrorCode.Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe static int ReadPrefix(
|
private unsafe static int ReadPrefix(
|
||||||
|
@ -264,61 +282,64 @@ namespace LibGit2Sharp
|
||||||
len_p = UIntPtr.Zero;
|
len_p = UIntPtr.Zero;
|
||||||
type_p = GitObjectType.Bad;
|
type_p = GitObjectType.Bad;
|
||||||
|
|
||||||
OdbBackend odbBackend = GCHandle.FromIntPtr(Marshal.ReadIntPtr(backend, GitOdbBackend.GCHandleOffset)).Target as OdbBackend;
|
OdbBackend odbBackend = MarshalOdbBackend(backend);
|
||||||
|
if (odbBackend == null)
|
||||||
if (odbBackend != null)
|
|
||||||
{
|
{
|
||||||
|
return (int)GitErrorCode.Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream dataStream = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// The length of short_oid is described in characters (40 per full ID) vs. bytes (20)
|
||||||
|
// which is what we care about.
|
||||||
|
var oidLen = (int)len;
|
||||||
|
|
||||||
|
// Ensure we allocate enough space to cope with odd-sized prefix
|
||||||
|
int arraySize = (oidLen + 1) >> 1;
|
||||||
|
var shortOidArray = new byte[arraySize];
|
||||||
|
Array.Copy(short_oid.Id, shortOidArray, arraySize);
|
||||||
|
|
||||||
byte[] oid;
|
byte[] oid;
|
||||||
Stream dataStream = null;
|
|
||||||
ObjectType objectType;
|
ObjectType objectType;
|
||||||
|
|
||||||
try
|
int toReturn = odbBackend.ReadPrefix(shortOidArray, oidLen, out oid, out dataStream, out objectType);
|
||||||
|
|
||||||
|
if (toReturn != 0)
|
||||||
{
|
{
|
||||||
// The length of short_oid is described in characters (40 per full ID) vs. bytes (20)
|
|
||||||
// which is what we care about.
|
|
||||||
var oidLen = (int)len;
|
|
||||||
|
|
||||||
// Ensure we allocate enough space to cope with odd-sized prefix
|
|
||||||
int arraySize = (oidLen + 1) >> 1;
|
|
||||||
var shortOidArray = new byte[arraySize];
|
|
||||||
Array.Copy(short_oid.Id, shortOidArray, arraySize);
|
|
||||||
|
|
||||||
int toReturn = odbBackend.ReadPrefix(shortOidArray, oidLen, out oid, out dataStream, out objectType);
|
|
||||||
|
|
||||||
if (0 == toReturn)
|
|
||||||
{
|
|
||||||
// Caller is expected to give us back a stream created with the Allocate() method.
|
|
||||||
UnmanagedMemoryStream memoryStream = dataStream as UnmanagedMemoryStream;
|
|
||||||
|
|
||||||
if (null == memoryStream)
|
|
||||||
{
|
|
||||||
return (int)GitErrorCode.Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
out_oid.Id = oid;
|
|
||||||
len_p = new UIntPtr((ulong)memoryStream.Capacity);
|
|
||||||
type_p = objectType.ToGitObjectType();
|
|
||||||
|
|
||||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
|
||||||
buffer_p = new IntPtr(memoryStream.PositionPointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
|
// Caller is expected to give us back a stream created with the Allocate() method.
|
||||||
|
var memoryStream = dataStream as UnmanagedMemoryStream;
|
||||||
|
|
||||||
|
if (memoryStream == null)
|
||||||
{
|
{
|
||||||
Proxy.giterr_set_str(GitErrorCategory.Odb, ex);
|
return (int)GitErrorCode.Error;
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
|
out_oid.Id = oid;
|
||||||
|
len_p = new UIntPtr((ulong)memoryStream.Capacity);
|
||||||
|
type_p = objectType.ToGitObjectType();
|
||||||
|
|
||||||
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
buffer_p = new IntPtr(memoryStream.PositionPointer);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Proxy.giterr_set_str(GitErrorCategory.Odb, ex);
|
||||||
|
return (int)GitErrorCode.Error;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (null != dataStream)
|
||||||
{
|
{
|
||||||
if (null != dataStream)
|
dataStream.Dispose();
|
||||||
{
|
|
||||||
dataStream.Dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)GitErrorCode.Error;
|
return (int)GitErrorCode.Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int ReadHeader(
|
private static int ReadHeader(
|
||||||
|
@ -330,32 +351,33 @@ namespace LibGit2Sharp
|
||||||
len_p = UIntPtr.Zero;
|
len_p = UIntPtr.Zero;
|
||||||
type_p = GitObjectType.Bad;
|
type_p = GitObjectType.Bad;
|
||||||
|
|
||||||
OdbBackend odbBackend = GCHandle.FromIntPtr(Marshal.ReadIntPtr(backend, GitOdbBackend.GCHandleOffset)).Target as OdbBackend;
|
OdbBackend odbBackend = MarshalOdbBackend(backend);
|
||||||
|
if (odbBackend == null)
|
||||||
|
{
|
||||||
|
return (int)GitErrorCode.Error;
|
||||||
|
}
|
||||||
|
|
||||||
if (odbBackend != null)
|
try
|
||||||
{
|
{
|
||||||
int length;
|
int length;
|
||||||
ObjectType objectType;
|
ObjectType objectType;
|
||||||
|
int toReturn = odbBackend.ReadHeader(oid.Id, out length, out objectType);
|
||||||
|
|
||||||
try
|
if (toReturn != 0)
|
||||||
{
|
{
|
||||||
int toReturn = odbBackend.ReadHeader(oid.Id, out length, out objectType);
|
|
||||||
|
|
||||||
if (0 == toReturn)
|
|
||||||
{
|
|
||||||
len_p = new UIntPtr((uint)length);
|
|
||||||
type_p = objectType.ToGitObjectType();
|
|
||||||
}
|
|
||||||
|
|
||||||
return toReturn;
|
return toReturn;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
len_p = new UIntPtr((uint)length);
|
||||||
Proxy.giterr_set_str(GitErrorCategory.Odb, ex);
|
type_p = objectType.ToGitObjectType();
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Proxy.giterr_set_str(GitErrorCategory.Odb, ex);
|
||||||
|
return (int)GitErrorCode.Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)GitErrorCode.Error;
|
return (int)GitErrorCode.Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static unsafe int Write(
|
private static unsafe int Write(
|
||||||
|
@ -365,27 +387,29 @@ namespace LibGit2Sharp
|
||||||
UIntPtr len,
|
UIntPtr len,
|
||||||
GitObjectType type)
|
GitObjectType type)
|
||||||
{
|
{
|
||||||
OdbBackend odbBackend = GCHandle.FromIntPtr(Marshal.ReadIntPtr(backend, GitOdbBackend.GCHandleOffset)).Target as OdbBackend;
|
if (len.ToUInt64() > long.MaxValue)
|
||||||
|
|
||||||
ObjectType objectType = type.ToObjectType();
|
|
||||||
|
|
||||||
if (odbBackend != null &&
|
|
||||||
len.ToUInt64() < long.MaxValue)
|
|
||||||
{
|
{
|
||||||
try
|
return (int)GitErrorCode.Error;
|
||||||
{
|
|
||||||
using (UnmanagedMemoryStream stream = new UnmanagedMemoryStream((byte*)data, (long)len.ToUInt64()))
|
|
||||||
{
|
|
||||||
return odbBackend.Write(oid.Id, stream, (long)len.ToUInt64(), objectType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Proxy.giterr_set_str(GitErrorCategory.Odb, ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)GitErrorCode.Error;
|
OdbBackend odbBackend = MarshalOdbBackend(backend);
|
||||||
|
if (odbBackend == null)
|
||||||
|
{
|
||||||
|
return (int)GitErrorCode.Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (var stream = new UnmanagedMemoryStream((byte*)data, (long)len.ToUInt64()))
|
||||||
|
{
|
||||||
|
return odbBackend.Write(oid.Id, stream, (long)len.ToUInt64(), type.ToObjectType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Proxy.giterr_set_str(GitErrorCategory.Odb, ex);
|
||||||
|
return (int)GitErrorCode.Error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int WriteStream(
|
private static int WriteStream(
|
||||||
|
@ -396,33 +420,36 @@ namespace LibGit2Sharp
|
||||||
{
|
{
|
||||||
stream_out = IntPtr.Zero;
|
stream_out = IntPtr.Zero;
|
||||||
|
|
||||||
OdbBackend odbBackend = GCHandle.FromIntPtr(Marshal.ReadIntPtr(backend, GitOdbBackend.GCHandleOffset)).Target as OdbBackend;
|
if (length.ToUInt64() > long.MaxValue)
|
||||||
|
{
|
||||||
|
return (int)GitErrorCode.Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
OdbBackend odbBackend = MarshalOdbBackend(backend);
|
||||||
|
if (odbBackend == null)
|
||||||
|
{
|
||||||
|
return (int)GitErrorCode.Error;
|
||||||
|
}
|
||||||
|
|
||||||
ObjectType objectType = type.ToObjectType();
|
ObjectType objectType = type.ToObjectType();
|
||||||
|
|
||||||
if (odbBackend != null &&
|
try
|
||||||
length.ToUInt64() < long.MaxValue)
|
|
||||||
{
|
{
|
||||||
OdbBackendStream stream;
|
OdbBackendStream stream;
|
||||||
|
int toReturn = odbBackend.WriteStream((long)length.ToUInt64(), objectType, out stream);
|
||||||
|
|
||||||
try
|
if (toReturn == 0)
|
||||||
{
|
{
|
||||||
int toReturn = odbBackend.WriteStream((long)length.ToUInt64(), objectType, out stream);
|
stream_out = stream.GitOdbBackendStreamPointer;
|
||||||
|
|
||||||
if (0 == toReturn)
|
|
||||||
{
|
|
||||||
stream_out = stream.GitOdbBackendStreamPointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
return toReturn;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Proxy.giterr_set_str(GitErrorCategory.Odb, ex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Proxy.giterr_set_str(GitErrorCategory.Odb, ex);
|
||||||
|
return (int)GitErrorCode.Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)GitErrorCode.Error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int ReadStream(
|
private static int ReadStream(
|
||||||
|
@ -432,51 +459,50 @@ namespace LibGit2Sharp
|
||||||
{
|
{
|
||||||
stream_out = IntPtr.Zero;
|
stream_out = IntPtr.Zero;
|
||||||
|
|
||||||
OdbBackend odbBackend = GCHandle.FromIntPtr(Marshal.ReadIntPtr(backend, GitOdbBackend.GCHandleOffset)).Target as OdbBackend;
|
OdbBackend odbBackend = MarshalOdbBackend(backend);
|
||||||
|
if (odbBackend == null)
|
||||||
if (odbBackend != null)
|
|
||||||
{
|
{
|
||||||
OdbBackendStream stream;
|
return (int)GitErrorCode.Error;
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
int toReturn = odbBackend.ReadStream(oid.Id, out stream);
|
|
||||||
|
|
||||||
if (0 == toReturn)
|
|
||||||
{
|
|
||||||
stream_out = stream.GitOdbBackendStreamPointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
return toReturn;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Proxy.giterr_set_str(GitErrorCategory.Odb, ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)GitErrorCode.Error;
|
try
|
||||||
|
{
|
||||||
|
OdbBackendStream stream;
|
||||||
|
int toReturn = odbBackend.ReadStream(oid.Id, out stream);
|
||||||
|
|
||||||
|
if (toReturn == 0)
|
||||||
|
{
|
||||||
|
stream_out = stream.GitOdbBackendStreamPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
return toReturn;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Proxy.giterr_set_str(GitErrorCategory.Odb, ex);
|
||||||
|
return (int)GitErrorCode.Error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool Exists(
|
private static bool Exists(
|
||||||
IntPtr backend,
|
IntPtr backend,
|
||||||
ref GitOid oid)
|
ref GitOid oid)
|
||||||
{
|
{
|
||||||
OdbBackend odbBackend = GCHandle.FromIntPtr(Marshal.ReadIntPtr(backend, GitOdbBackend.GCHandleOffset)).Target as OdbBackend;
|
OdbBackend odbBackend = MarshalOdbBackend(backend);
|
||||||
|
if (odbBackend == null)
|
||||||
if (odbBackend != null)
|
|
||||||
{
|
{
|
||||||
try
|
return false; // Weird
|
||||||
{
|
|
||||||
return odbBackend.Exists(oid.Id);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Proxy.giterr_set_str(GitErrorCategory.Odb, ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
try
|
||||||
|
{
|
||||||
|
return odbBackend.Exists(oid.Id);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Proxy.giterr_set_str(GitErrorCategory.Odb, ex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int Foreach(
|
private static int Foreach(
|
||||||
|
@ -484,39 +510,39 @@ namespace LibGit2Sharp
|
||||||
GitOdbBackend.foreach_callback_callback cb,
|
GitOdbBackend.foreach_callback_callback cb,
|
||||||
IntPtr data)
|
IntPtr data)
|
||||||
{
|
{
|
||||||
OdbBackend odbBackend = GCHandle.FromIntPtr(Marshal.ReadIntPtr(backend, GitOdbBackend.GCHandleOffset)).Target as OdbBackend;
|
OdbBackend odbBackend = MarshalOdbBackend(backend);
|
||||||
|
if (odbBackend == null)
|
||||||
if (odbBackend != null)
|
|
||||||
{
|
{
|
||||||
try
|
return (int)GitErrorCode.Error;
|
||||||
{
|
|
||||||
return odbBackend.ForEach(new ForeachState(cb, data).ManagedCallback);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Proxy.giterr_set_str(GitErrorCategory.Odb, ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)GitErrorCode.Error;
|
try
|
||||||
|
{
|
||||||
|
return odbBackend.ForEach(new ForeachState(cb, data).ManagedCallback);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Proxy.giterr_set_str(GitErrorCategory.Odb, ex);
|
||||||
|
return (int)GitErrorCode.Error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void Free(
|
private static void Free(
|
||||||
IntPtr backend)
|
IntPtr backend)
|
||||||
{
|
{
|
||||||
GCHandle gcHandle = GCHandle.FromIntPtr(Marshal.ReadIntPtr(backend, GitOdbBackend.GCHandleOffset));
|
OdbBackend odbBackend = MarshalOdbBackend(backend);
|
||||||
OdbBackend odbBackend = gcHandle.Target as OdbBackend;
|
if (odbBackend == null)
|
||||||
|
|
||||||
if (odbBackend != null)
|
|
||||||
{
|
{
|
||||||
try
|
return;
|
||||||
{
|
}
|
||||||
odbBackend.Dispose();
|
|
||||||
}
|
try
|
||||||
catch (Exception ex)
|
{
|
||||||
{
|
odbBackend.Dispose();
|
||||||
Proxy.giterr_set_str(GitErrorCategory.Odb, ex);
|
}
|
||||||
}
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Proxy.giterr_set_str(GitErrorCategory.Odb, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче