Skip to content

Commit 61e9f3b

Browse files
committed
Simplify consumption of _foreach methods
1 parent 67fa534 commit 61e9f3b

File tree

6 files changed

+54
-125
lines changed

6 files changed

+54
-125
lines changed

LibGit2Sharp/BranchCollection.cs

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -89,39 +89,12 @@ private Branch BuildFromReferenceName(string canonicalName)
8989
/// <returns>An <see cref = "IEnumerator{T}" /> object that can be used to iterate through the collection.</returns>
9090
public virtual IEnumerator<Branch> GetEnumerator()
9191
{
92-
return new BranchNameEnumerable(repo.Handle, GitBranchType.GIT_BRANCH_LOCAL | GitBranchType.GIT_BRANCH_REMOTE)
92+
return Proxy.git_branch_foreach(repo.Handle, GitBranchType.GIT_BRANCH_LOCAL | GitBranchType.GIT_BRANCH_REMOTE, (b, t) => Utf8Marshaler.FromNative(b))
9393
.Select(n => this[n])
9494
.OrderBy(b => b.CanonicalName, StringComparer.Ordinal)
9595
.GetEnumerator();
9696
}
9797

98-
private class BranchNameEnumerable : IEnumerable<string>
99-
{
100-
private readonly List<string> list = new List<string>();
101-
102-
public BranchNameEnumerable(RepositorySafeHandle handle, GitBranchType gitBranchType)
103-
{
104-
Proxy.git_branch_foreach(handle, gitBranchType, Callback);
105-
}
106-
107-
private int Callback(IntPtr branchName, GitBranchType branchType, IntPtr payload)
108-
{
109-
string name = Utf8Marshaler.FromNative(branchName);
110-
list.Add(name);
111-
return 0;
112-
}
113-
114-
public IEnumerator<string> GetEnumerator()
115-
{
116-
return list.GetEnumerator();
117-
}
118-
119-
IEnumerator IEnumerable.GetEnumerator()
120-
{
121-
return GetEnumerator();
122-
}
123-
}
124-
12598
/// <summary>
12699
/// Returns an enumerator that iterates through the collection.
127100
/// </summary>

LibGit2Sharp/Configuration.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -379,14 +379,11 @@ private static Action<string, object, ConfigurationSafeHandle> GetUpdater<T>(Act
379379

380380
IEnumerator<ConfigurationEntry> IEnumerable<ConfigurationEntry>.GetEnumerator()
381381
{
382-
var values = new List<ConfigurationEntry>();
383-
Proxy.git_config_foreach(LocalHandle, (namePtr, valuePtr, _) => {
382+
return Proxy.git_config_foreach(LocalHandle, (namePtr, valuePtr) => {
384383
var name = Utf8Marshaler.FromNative(namePtr);
385384
var value = Utf8Marshaler.FromNative(valuePtr);
386-
values.Add(new ConfigurationEntry(name, value));
387-
return 0;
388-
});
389-
return values.GetEnumerator();
385+
return new ConfigurationEntry(name, value);
386+
}).GetEnumerator();
390387
}
391388

392389
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()

LibGit2Sharp/Core/Proxy.cs

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -126,16 +126,12 @@ public static void git_branch_delete(ReferenceSafeHandle reference)
126126
}
127127
}
128128

129-
public static void git_branch_foreach(
129+
public static ICollection<TResult> git_branch_foreach<TResult>(
130130
RepositorySafeHandle repo,
131131
GitBranchType branch_type,
132-
NativeMethods.branch_foreach_callback callback)
132+
Func<IntPtr, GitBranchType, TResult> resultSelector)
133133
{
134-
using (ThreadAffinity())
135-
{
136-
int res = NativeMethods.git_branch_foreach(repo, branch_type, callback, IntPtr.Zero);
137-
Ensure.Success(res);
138-
}
134+
return git_foreach(resultSelector, c => NativeMethods.git_branch_foreach(repo, branch_type, (x, y, p) => c(x, y, p), IntPtr.Zero));
139135
}
140136

141137
public static void git_branch_move(ReferenceSafeHandle reference, string new_branch_name, bool force)
@@ -432,15 +428,11 @@ public static void git_config_set_string(ConfigurationSafeHandle config, string
432428
}
433429
}
434430

435-
public static void git_config_foreach(
431+
public static ICollection<TResult> git_config_foreach<TResult>(
436432
ConfigurationSafeHandle config,
437-
NativeMethods.config_foreach_callback callback)
433+
Func<IntPtr, IntPtr, TResult> resultSelector)
438434
{
439-
using (ThreadAffinity())
440-
{
441-
int res = NativeMethods.git_config_foreach(config, callback, IntPtr.Zero);
442-
Ensure.Success(res);
443-
}
435+
return git_foreach(resultSelector, c => NativeMethods.git_config_foreach(config, (x, y, p) => c(x, y, p), IntPtr.Zero));
444436
}
445437

446438
#endregion
@@ -725,13 +717,9 @@ public static string git_note_default_ref(RepositorySafeHandle repo)
725717
}
726718
}
727719

728-
public static void git_note_foreach(RepositorySafeHandle repo, string notes_ref, NativeMethods.notes_foreach_callback callback)
720+
public static ICollection<TResult> git_note_foreach<TResult>(RepositorySafeHandle repo, string notes_ref, Func<GitNoteData, TResult> resultSelector)
729721
{
730-
using (ThreadAffinity())
731-
{
732-
int res = NativeMethods.git_note_foreach(repo, notes_ref, callback, IntPtr.Zero);
733-
Ensure.Success(res);
734-
}
722+
return git_foreach(resultSelector, c => NativeMethods.git_note_foreach(repo, notes_ref, (x, p) => c(x, p), IntPtr.Zero));
735723
}
736724

737725
public static void git_note_free(IntPtr note)
@@ -905,17 +893,13 @@ public static void git_reference_delete(ReferenceSafeHandle reference)
905893
}
906894
}
907895

908-
public static void git_reference_foreach_glob(
896+
public static ICollection<TResult> git_reference_foreach_glob<TResult>(
909897
RepositorySafeHandle repo,
910898
string glob,
911899
GitReferenceType flags,
912-
NativeMethods.ref_glob_callback callback)
900+
Func<IntPtr, TResult> resultSelector)
913901
{
914-
using (ThreadAffinity())
915-
{
916-
int res = NativeMethods.git_reference_foreach_glob(repo, glob, flags, callback, IntPtr.Zero);
917-
Ensure.Success(res);
918-
}
902+
return git_foreach(resultSelector, c => NativeMethods.git_reference_foreach_glob(repo, glob, flags, (x, p) => c(x, p), IntPtr.Zero));
919903
}
920904

921905
public static void git_reference_free(IntPtr reference)
@@ -1369,13 +1353,9 @@ public static FileStatus git_status_file(RepositorySafeHandle repo, FilePath pat
13691353
}
13701354
}
13711355

1372-
public static void git_status_foreach(RepositorySafeHandle repo, NativeMethods.status_callback callback)
1356+
public static ICollection<TResult> git_status_foreach<TResult>(RepositorySafeHandle repo, Func<IntPtr, uint, TResult> resultSelector)
13731357
{
1374-
using (ThreadAffinity())
1375-
{
1376-
int res = NativeMethods.git_status_foreach(repo, callback, IntPtr.Zero);
1377-
Ensure.Success(res);
1378-
}
1358+
return git_foreach(resultSelector, c => NativeMethods.git_status_foreach(repo, (x, y, p) => c(x, y, p), IntPtr.Zero));
13791359
}
13801360

13811361
#endregion
@@ -1573,6 +1553,36 @@ public static ObjectId git_treebuilder_write(RepositorySafeHandle repo, TreeBuil
15731553

15741554
#endregion
15751555

1556+
private static ICollection<TResult> git_foreach<T, TResult>(Func<T, TResult> resultSelector, Func<Func<T, IntPtr, int>, int> iterator)
1557+
{
1558+
using (ThreadAffinity())
1559+
{
1560+
var result = new List<TResult>();
1561+
var res = iterator((x, payload) =>
1562+
{
1563+
result.Add(resultSelector(x));
1564+
return 0;
1565+
});
1566+
Ensure.Success(res);
1567+
return result;
1568+
}
1569+
}
1570+
1571+
private static ICollection<TResult> git_foreach<T1, T2, TResult>(Func<T1, T2, TResult> resultSelector, Func<Func<T1, T2, IntPtr, int>, int> iterator)
1572+
{
1573+
using (ThreadAffinity())
1574+
{
1575+
var result = new List<TResult>();
1576+
var res = iterator((x, y, payload) =>
1577+
{
1578+
result.Add(resultSelector(x, y));
1579+
return 0;
1580+
});
1581+
Ensure.Success(res);
1582+
return result;
1583+
}
1584+
}
1585+
15761586
private static unsafe class Libgit2UnsafeHelper
15771587
{
15781588
public static IList<string> BuildListOf(UnSafeNativeMethods.git_strarray strArray)

LibGit2Sharp/NoteCollection.cs

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,8 @@ public virtual IEnumerable<Note> this[string @namespace]
109109
Ensure.ArgumentNotNull(@namespace, "@namespace");
110110

111111
string canonicalNamespace = NormalizeToCanonicalName(@namespace);
112-
var notesOidRetriever = new NotesOidRetriever(repo, canonicalNamespace);
113112

114-
return notesOidRetriever.Retrieve().Select(oid => RetrieveNote(new ObjectId(oid), canonicalNamespace));
113+
return Proxy.git_note_foreach(repo.Handle, canonicalNamespace, n => RetrieveNote(new ObjectId(n.TargetOid), canonicalNamespace));
115114
}
116115
}
117116

@@ -227,27 +226,5 @@ public virtual void Delete(ObjectId targetId, Signature author, Signature commit
227226
{
228227
Remove(targetId, author, committer, @namespace);
229228
}
230-
231-
private class NotesOidRetriever
232-
{
233-
private readonly List<GitOid> notesOid = new List<GitOid>();
234-
235-
internal NotesOidRetriever(Repository repo, string canonicalNamespace)
236-
{
237-
Proxy.git_note_foreach(repo.Handle, canonicalNamespace, NoteListCallBack);
238-
}
239-
240-
private int NoteListCallBack(GitNoteData noteData, IntPtr intPtr)
241-
{
242-
notesOid.Add(noteData.TargetOid);
243-
244-
return 0;
245-
}
246-
247-
public IEnumerable<GitOid> Retrieve()
248-
{
249-
return notesOid;
250-
}
251-
}
252229
}
253230
}

LibGit2Sharp/ReferenceCollection.cs

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -236,35 +236,8 @@ public virtual IEnumerable<Reference> FromGlob(string pattern)
236236
{
237237
Ensure.ArgumentNotNullOrEmptyString(pattern, "pattern");
238238

239-
return new GlobedReferenceEnumerable(repo.Handle, pattern).Select(n => this[n]);
240-
}
241-
242-
private class GlobedReferenceEnumerable : IEnumerable<string>
243-
{
244-
private readonly List<string> list = new List<string>();
245-
246-
public GlobedReferenceEnumerable(RepositorySafeHandle handle, string pattern)
247-
{
248-
Proxy.git_reference_foreach_glob(handle, pattern, GitReferenceType.ListAll, Callback);
249-
list.Sort(StringComparer.Ordinal);
250-
}
251-
252-
private int Callback(IntPtr branchName, IntPtr payload)
253-
{
254-
string name = Utf8Marshaler.FromNative(branchName);
255-
list.Add(name);
256-
return 0;
257-
}
258-
259-
public IEnumerator<string> GetEnumerator()
260-
{
261-
return list.GetEnumerator();
262-
}
263-
264-
IEnumerator IEnumerable.GetEnumerator()
265-
{
266-
return GetEnumerator();
267-
}
239+
return Proxy.git_reference_foreach_glob(repo.Handle, pattern, GitReferenceType.ListAll, Utf8Marshaler.FromNative)
240+
.OrderBy(name => name, StringComparer.Ordinal).Select(n => this[n]);
268241
}
269242
}
270243
}

LibGit2Sharp/RepositoryStatus.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace LibGit2Sharp
1212
/// </summary>
1313
public class RepositoryStatus : IEnumerable<StatusEntry>
1414
{
15-
private readonly List<StatusEntry> statusEntries = new List<StatusEntry>();
15+
private readonly ICollection<StatusEntry> statusEntries;
1616
private readonly List<string> added = new List<string>();
1717
private readonly List<string> staged = new List<string>();
1818
private readonly List<string> removed = new List<string>();
@@ -46,15 +46,14 @@ protected RepositoryStatus()
4646

4747
internal RepositoryStatus(Repository repo)
4848
{
49-
Proxy.git_status_foreach(repo.Handle, StateChanged);
49+
statusEntries = Proxy.git_status_foreach(repo.Handle, StateChanged);
5050
isDirty = statusEntries.Any(entry => entry.State != FileStatus.Ignored);
5151
}
5252

53-
private int StateChanged(IntPtr filePathPtr, uint state, IntPtr payload)
53+
private StatusEntry StateChanged(IntPtr filePathPtr, uint state)
5454
{
5555
var filePath = FilePathMarshaler.FromNative(filePathPtr);
5656
var gitStatus = (FileStatus)state;
57-
statusEntries.Add(new StatusEntry(filePath.Native, gitStatus));
5857

5958
foreach (KeyValuePair<FileStatus, Action<RepositoryStatus, string>> kvp in dispatcher)
6059
{
@@ -66,7 +65,7 @@ private int StateChanged(IntPtr filePathPtr, uint state, IntPtr payload)
6665
kvp.Value(this, filePath.Native);
6766
}
6867

69-
return 0;
68+
return new StatusEntry(filePath.Native, gitStatus);
7069
}
7170

7271
/// <summary>

0 commit comments

Comments
 (0)