Skip to content

git_strarray marshaling improvements #773

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 25, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion LibGit2Sharp/Core/GitCheckoutOpts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ internal struct GitCheckoutOpts
public progress_cb progress_cb;
public IntPtr progress_payload;

public GitStrArrayIn paths;
public GitStrArray paths;

public IntPtr baseline;
public IntPtr target_directory;
Expand Down
20 changes: 4 additions & 16 deletions LibGit2Sharp/Core/GitCheckoutOptsWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public GitCheckoutOptsWrapper(IConvertableToGitCheckoutOpts options, FilePath[]

if (paths != null)
{
PathArray = GitStrArrayIn.BuildFrom(paths);
PathArray = GitStrArrayManaged.BuildFrom(paths);
}

Options = new GitCheckoutOpts
Expand All @@ -32,7 +32,7 @@ public GitCheckoutOptsWrapper(IConvertableToGitCheckoutOpts options, FilePath[]
progress_cb = Callbacks.CheckoutProgressCallback,
notify_cb = Callbacks.CheckoutNotifyCallback,
notify_flags = options.CheckoutNotifyFlags,
paths = PathArray,
paths = PathArray.Array,
};
}

Expand All @@ -50,23 +50,11 @@ public GitCheckoutOptsWrapper(IConvertableToGitCheckoutOpts options, FilePath[]
/// <summary>
/// Keep the paths around so we can dispose them.
/// </summary>
private GitStrArrayIn PathArray;
private GitStrArrayManaged PathArray;

public void Dispose()
{
Dispose(true);
}

private void Dispose(bool disposing)
{
if (disposing)
{
if (PathArray != null)
{
PathArray.Dispose();
PathArray = null;
}
}
PathArray.Dispose();
}

/// <summary>
Expand Down
7 changes: 1 addition & 6 deletions LibGit2Sharp/Core/GitDiff.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ internal class GitDiffOptions : IDisposable
/* options controlling which files are in the diff */

public SubmoduleIgnore IgnoreSubmodules;
public GitStrArrayIn PathSpec;
public GitStrArrayManaged PathSpec;
public diff_notify_cb NotifyCallback;
public IntPtr NotifyPayload;

Expand All @@ -204,11 +204,6 @@ internal class GitDiffOptions : IDisposable

public void Dispose()
{
if (PathSpec == null)
{
return;
}

PathSpec.Dispose();
}
}
Expand Down
7 changes: 1 addition & 6 deletions LibGit2Sharp/Core/GitStatusOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,10 @@ internal class GitStatusOptions : IDisposable
public GitStatusShow Show;
public GitStatusOptionFlags Flags;

GitStrArrayIn PathSpec;
GitStrArrayManaged PathSpec;

public void Dispose()
{
if (PathSpec == null)
{
return;
}

PathSpec.Dispose();
}
}
Expand Down
30 changes: 30 additions & 0 deletions LibGit2Sharp/Core/GitStrArray.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace LibGit2Sharp.Core
{
[StructLayout(LayoutKind.Sequential)]
internal struct GitStrArray
{
/// <summary>
/// A pointer to an array of null-terminated strings.
/// </summary>
public IntPtr Strings;

/// <summary>
/// The number of strings in the array.
/// </summary>
public UIntPtr Count;

/// <summary>
/// Resets the GitStrArray to default values.
/// </summary>
public void Reset()
{
Strings = IntPtr.Zero;
Count = UIntPtr.Zero;
}
}
}
62 changes: 0 additions & 62 deletions LibGit2Sharp/Core/GitStrArrayIn.cs

This file was deleted.

62 changes: 62 additions & 0 deletions LibGit2Sharp/Core/GitStrArrayManaged.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System;
using System.Runtime.InteropServices;

namespace LibGit2Sharp.Core
{
/// <summary>
/// A git_strarray where the string array and strings themselves were allocated
/// with LibGit2Sharp's allocator (Marshal.AllocHGlobal).
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct GitStrArrayManaged : IDisposable
{
public GitStrArray Array;

public static GitStrArrayManaged BuildFrom(string[] strings)
{
return BuildFrom(strings, StrictUtf8Marshaler.FromManaged);
}

public static GitStrArrayManaged BuildFrom(FilePath[] paths)
{
return BuildFrom(paths, StrictFilePathMarshaler.FromManaged);
}

private static GitStrArrayManaged BuildFrom<T>(T[] input, Func<T, IntPtr> marshaler)
{
var pointers = new IntPtr[input.Length];

for (int i = 0; i < input.Length; i++)
{
var item = input[i];
pointers[i] = marshaler(item);
}

var toReturn = new GitStrArrayManaged();

toReturn.Array.Strings = Marshal.AllocHGlobal(checked(IntPtr.Size * input.Length));
Marshal.Copy(pointers, 0, toReturn.Array.Strings, input.Length);
toReturn.Array.Count = new UIntPtr((uint)input.Length);

return toReturn;
}

public void Dispose()
{
var count = checked((int)Array.Count.ToUInt32());

for (int i = 0; i < count; i++)
{
EncodingMarshaler.Cleanup(Marshal.ReadIntPtr(Array.Strings, i * IntPtr.Size));
}

if (Array.Strings != IntPtr.Zero)
{
Marshal.FreeHGlobal(Array.Strings);
}

// Now that we've freed the memory, zero out the structure.
Array.Reset();
}
}
}
44 changes: 44 additions & 0 deletions LibGit2Sharp/Core/GitStrArrayNative.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace LibGit2Sharp.Core
{
/// <summary>
/// A git_strarray where the string array and strings themselves were allocated
/// with libgit2's allocator. Only libgit2 can free this git_strarray.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
internal struct GitStrArrayNative : IDisposable
{
public GitStrArray Array;

/// <summary>
/// Enumerates each string from the array using the UTF-8 marshaler.
/// </summary>
public String[] ReadStrings()
{
var count = checked((int)Array.Count.ToUInt32());

String[] toReturn = new String[count];

for (int i = 0; i < count; i++)
{
toReturn[i] = LaxUtf8Marshaler.FromNative(Marshal.ReadIntPtr(Array.Strings, i * IntPtr.Size));
}

return toReturn;
}

public void Dispose()
{
if (Array.Strings != IntPtr.Zero)
{
NativeMethods.git_strarray_free(ref Array);
}

// Now that we've freed the memory, zero out the structure.
Array.Reset();
}
}
}
47 changes: 0 additions & 47 deletions LibGit2Sharp/Core/GitStrArrayOut.cs

This file was deleted.

Loading