using System;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Text;
namespace LibGit2Sharp.Core
{
///
/// This marshaler is to be used for capturing a UTF-8 string owned by libgit2 and
/// converting it to a managed String instance. The marshaler will not attempt to
/// free the native pointer after conversion, because the memory is owned by libgit2.
///
/// Use this marshaler for return values, for example:
/// [return: MarshalAs(UnmanagedType.CustomMarshaler,
/// MarshalCookie = UniqueId.UniqueIdentifier,
/// MarshalTypeRef = typeof(LaxUtf8NoCleanupMarshaler))]
///
internal class LaxUtf8NoCleanupMarshaler : LaxUtf8Marshaler
{
private static readonly LaxUtf8NoCleanupMarshaler staticInstance = new LaxUtf8NoCleanupMarshaler();
public new static ICustomMarshaler GetInstance(String cookie)
{
return staticInstance;
}
#region ICustomMarshaler
public override void CleanUpNativeData(IntPtr pNativeData)
{
}
#endregion
}
///
/// This marshaler is to be used for sending managed String instances to libgit2.
/// The marshaler will allocate a buffer in native memory to hold the UTF-8 string
/// and perform the encoding conversion using that buffer as the target. The pointer
/// received by libgit2 will be to this buffer. After the function call completes, the
/// native buffer is freed.
///
/// Use this marshaler for function parameters, for example:
/// [DllImport(libgit2)]
/// internal static extern int git_tag_delete(RepositorySafeHandle repo,
/// [MarshalAs(UnmanagedType.CustomMarshaler,
/// MarshalCookie = UniqueId.UniqueIdentifier,
/// MarshalTypeRef = typeof(StrictUtf8Marshaler))] String tagName);
///
internal class StrictUtf8Marshaler : EncodingMarshaler
{
private static readonly StrictUtf8Marshaler staticInstance;
private static readonly Encoding encoding;
static StrictUtf8Marshaler()
{
encoding = new UTF8Encoding(false, true);
staticInstance = new StrictUtf8Marshaler();
}
public StrictUtf8Marshaler() : base(encoding)
{ }
public static ICustomMarshaler GetInstance(String cookie)
{
return staticInstance;
}
#region ICustomMarshaler
public override Object MarshalNativeToManaged(IntPtr pNativeData)
{
throw new InvalidOperationException(
string.Format(CultureInfo.InvariantCulture, "{0} cannot be used to retrieve data from libgit2.", GetType().Name));
}
#endregion
public static IntPtr FromManaged(String value)
{
return FromManaged(encoding, value);
}
}
///
/// This marshaler is to be used for capturing a UTF-8 string allocated by libgit2 and
/// converting it to a managed String instance. The marshaler will free the native pointer
/// after conversion.
///
internal class LaxUtf8Marshaler : EncodingMarshaler
{
private static readonly LaxUtf8Marshaler staticInstance = new LaxUtf8Marshaler();
private static readonly Encoding encoding = new UTF8Encoding(false, false);
public LaxUtf8Marshaler() : base(encoding)
{ }
public static ICustomMarshaler GetInstance(String cookie)
{
return staticInstance;
}
#region ICustomMarshaler
public override IntPtr MarshalManagedToNative(object managedObj)
{
throw new InvalidOperationException(
string.Format(CultureInfo.InvariantCulture, "{0} cannot be used to pass data to libgit2.", GetType().Name));
}
#endregion
public static string FromNative(IntPtr pNativeData)
{
return FromNative(encoding, pNativeData);
}
public static string FromNative(IntPtr pNativeData, int length)
{
return FromNative(encoding, pNativeData, length);
}
public static string FromBuffer(byte[] buffer)
{
return FromBuffer(encoding, buffer);
}
public static string FromBuffer(byte[] buffer, int length)
{
return FromBuffer(encoding, buffer, length);
}
}
}