8000 Disentangle the reference and config iterators · vrkcse2011/libgit2sharp@43521a6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 43521a6

Browse files
committed
Disentangle the reference and config iterators
While these both work roughly in the same manner (as they both represent iterators) the actual code duplication between these two is rather small as each `_next()` method is different and how we return the managed values is different. The net reduction in lines of code indicates that this is indeed the case.
1 parent 966ec5a commit 43521a6

File tree

4 files changed

+57
-96
lines changed

4 files changed

+57
-96
lines changed

LibGit2Sharp/Configuration.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ public virtual IEnumerable<ConfigurationEntry<string>> Find(string regexp, Confi
679679
using (ConfigurationSafeHandle snapshot = Snapshot())
680680
using (ConfigurationSafeHandle h = RetrieveConfigurationHandle(level, true, snapshot))
681681
{
682-
return Proxy.git_config_iterator_glob(h, regexp, BuildConfigEntry).ToList();
682+
return Proxy.git_config_iterator_glob(h, regexp).ToList();
683683
}
684684
}
685685

@@ -732,7 +732,7 @@ private IEnumerable<ConfigurationEntry<string>> BuildConfigEntries()
732732
return Proxy.git_config_foreach(configHandle, BuildConfigEntry);
733733
}
734734

735-
private static unsafe ConfigurationEntry<string> BuildConfigEntry(IntPtr entryPtr)
735+
internal static unsafe ConfigurationEntry<string> BuildConfigEntry(IntPtr entryPtr)
736736
{
737737
var entry = (GitConfigEntry*)entryPtr.ToPointer();
738738
return new ConfigurationEntry<string>(LaxUtf8Marshaler.FromNative(entry->namePtr),

LibGit2Sharp/Core/Handles/GitReferenceHandle.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ internal GitReferenceHandle(git_reference* refPtr)
1111
this.ptr = refPtr;
1212
}
1313

14+
internal GitReferenceHandle(IntPtr refPtr)
15+
{
16+
this.ptr = (git_reference*) refPtr.ToPointer();
17+
}
18+
1419
~GitReferenceHandle()
1520
{
1621
Dispose();
@@ -31,7 +36,7 @@ internal bool IsNull
3136

3237
public void Dispose()
3338
{
34-
NativeMethods.git_reference_free(new IntPtr(ptr));
39+
NativeMethods.git_reference_free(ptr);
3540
ptr = null;
3641
}
3742
}

LibGit2Sharp/Core/NativeMethods.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1013,7 +1013,7 @@ internal static extern int git_reference_foreach_glob(
10131013
IntPtr payload);
10141014

10151015
[DllImport(libgit2)]
1016-
internal static extern void git_reference_free(IntPtr reference);
1016+
internal static extern unsafe void git_reference_free(git_reference* reference);
10171017

10181018
[DllImport(libgit2)]
10191019
internal static extern int git_reference_is_valid_name(

LibGit2Sharp/Core/Proxy.cs

Lines changed: 48 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -209,22 +209,33 @@ public static unsafe void git_branch_delete(GitReferenceHandle reference)
209209
Ensure.ZeroResult(res);
210210
}
211211

212-
public static unsafe IEnumerable<Branch> git_branch_iterator(Repository repo, GitBranchType branchType)
213-
{
214-
return git_iterator((out BranchIteratorSafeHandle iter_out) =>
215-
NativeMethods.git_branch_iterator_new(out iter_out, repo.Handle, branchType),
216-
(BranchIteratorSafeHandle iter, out IntPtr refPtr, out int res) =>
217-
{
218-
GitBranchType type_out;
219-
res = NativeMethods.git_branch_next(out refPtr, out type_out, iter);
220-
return new { BranchType = type_out };
221-
},
222-
(handle, payload) =>
223-
{
224-
git_reference* refPtr = (git_reference*)handle.ToPointer();
225-
var reference = Reference.BuildFromPtr<Reference>(refPtr, repo);
226-
return new Branch(repo, reference, reference.CanonicalName);
227-
});
212+
public static IEnumerable<Branch> git_branch_iterator(Repository repo, GitBranchType branchType)
213+
{
214+
BranchIteratorSafeHandle iter;
215+
var res = NativeMethods.git_branch_iterator_new(out iter, repo.Handle, branchType);
216+
Ensure.ZeroResult(res);
217+
218+
using (iter)
219+
{
220+
while (true)
221+
{
222+
IntPtr refPtr = IntPtr.Zero;
223+
GitBranchType _branchType;
224+
res = NativeMethods.git_branch_next(out refPtr, out _branchType, iter);
225+
if (res == (int)GitErrorCode.IterOver)
226+
{
227+
yield break;
228+
}
229+
Ensure.ZeroResult(res);
230+
231+
Reference reference;
232+
using (var refHandle = new GitReferenceHandle(refPtr))
233+
{
234+
reference = Reference.BuildFromPtr<Reference>(refHandle, repo);
235+
}
236+
yield return new Branch(repo, reference, reference.CanonicalName);
237+
}
238+
}
228239
}
229240

230241
public static void git_branch_iterator_free(IntPtr iter)
@@ -583,22 +594,28 @@ public static ICollection<TResult> git_config_foreach<TResult>(
583594
return git_foreach(resultSelector, c => NativeMethods.git_config_foreach(config, (e, p) => c(e, p), IntPtr.Zero));
584595
}
585596

586-
public static unsafe IEnumerable<ConfigurationEntry<string>> git_config_iterator_glob(
597+
public static IEnumerable<ConfigurationEntry<string>> git_config_iterator_glob(
587598
ConfigurationSafeHandle config,
588-
string regexp,
589-
Func<IntPtr, ConfigurationEntry<string>> resultSelector)
590-
{
591-
return git_iterator((out ConfigurationIteratorSafeHandle iter) =>
592-
NativeMethods.git_config_iterator_glob_new(out iter, config, regexp),
593-
(ConfigurationIteratorSafeHandle iter, out IntPtr handle, out int res) =>
594-
{
595-
handle = IntPtr.Zero;
596-
IntPtr entry;
597-
res = NativeMethods.git_config_next(out entry, iter);
598-
return new { EntryPtr = entry };
599-
},
600-
(handle, payload) =>
601-
resultSelector(payload.EntryPtr));
599+
string regexp)
600+
{
601+
ConfigurationIteratorSafeHandle iter;
602+
var res = NativeMethods.git_config_iterator_glob_new(out iter, config, regexp);
603+
Ensure.ZeroResult(res);
604+
using (iter)
605+
{
606+
while (true)
607+
{
608+
IntPtr entry;
609+
res = NativeMethods.git_config_next(out entry, iter);
610+
if (res == (int)GitErrorCode.IterOver)
611+
{
612+
yield break;
613+
}
614+
Ensure.ZeroResult(res);
615+
616+
yield return Configuration.BuildConfigEntry(entry);
617+
}
618+
}
602619
}
603620

604621
public static void git_config_iterator_free(IntPtr iter)
@@ -1809,11 +1826,6 @@ public static ICollection<TResult> git_reference_foreach_glob<TResult>(
18091826
return git_foreach(resultSelector, c => NativeMethods.git_reference_foreach_glob(repo, glob, (x, p) => c(x, p), IntPtr.Zero));
18101827
}
18111828

1812-
public static void git_reference_free(IntPtr reference)
1813-
{
1814-
NativeMethods.git_reference_free(reference);
1815-
}
1816-
18171829
public static bool git_reference_is_valid_name(string refname)
18181830
{
18191831
int res = NativeMethods.git_reference_is_valid_name(refname);
@@ -3380,62 +3392,6 @@ private static ICollection<TResult> git_foreach<T1, T2, T3, T4, TResult>(
33803392
return result;
33813393
}
33823394

3383-
private delegate int IteratorNew<THandle>(out THandle iter);
3384-
3385-
private delegate TPayload IteratorNext<in TIterator, THandle, out TPayload>(TIterator iter, out THandle next, out int res);
3386-
3387-
private static THandle git_iterator_new<THandle>(IteratorNew<THandle> newFunc)
3388-
where THandle : SafeHandleBase
3389-
{
3390-
THandle iter;
3391-
Ensure.ZeroResult(newFunc(out iter));
3392-
return iter;
3393-
}
3394-
3395-
private static IEnumerable<TResult> git_iterator_next<TIterator, TPayload, TResult>(
3396-
TIterator iter,
3397-
IteratorNext<TIterator, IntPtr, TPayload> nextFunc,
3398-
Func<IntPtr, TPayload, TResult> resultSelector)
3399-
{
3400-
while (true)
3401-
{
3402-
var next = IntPtr.Zero;
3403-
try
3404-
{
3405-
int res;
3406-
var payload = nextFunc(iter, out next, out res);
3407-
3408-
if (res == (int)GitErrorCode.IterOver)
3409-
{
3410-
yield break;
3411-
}
3412-
3413-
Ensure.ZeroResult(res);
3414-
yield return resultSelector(next, payload);
3415-
}
3416-
finally
3417-
{
3418-
NativeMethods.git_reference_free(next);
3419-
}
3420-
}
3421-
}
3422-
3423-
private static IEnumerable<TResult> git_iterator<TIterator, TPayload, TResult>(
3424-
IteratorNew<TIterator> newFunc,
3425-
IteratorNext<TIterator, IntPtr, TPayload> nextFunc,
3426-
Func<IntPtr, TPayload, TResult> resultSelector
3427-
)
3428-
where TIterator : SafeHandleBase
3429-
{
3430-
using (var iter = git_iterator_new(newFunc))
3431-
{
3432-
foreach (var next in git_iterator_next(iter, nextFunc, resultSelector))
3433-
{
3434-
yield return next;
3435-
}
3436-
}
3437-
}
3438-
34393395
private static bool RepositoryStateChecker(RepositorySafeHandle repo, Func<RepositorySafeHandle, int> checker)
34403396
{
34413397
int res = checker(repo);

0 commit comments

Comments
 (0)
0