using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using LibGit2Sharp.Core;
using LibGit2Sharp.Core.Handles;
namespace LibGit2Sharp
{
///
/// The result of a blame operation.
///
public class BlameHunkCollection : IEnumerable
{
private readonly IRepository repo;
private readonly List hunks = new List();
///
/// For easy mocking
///
protected BlameHunkCollection() { }
internal BlameHunkCollection(Repository repo, RepositorySafeHandle repoHandle, string path, BlameOptions options)
{
this.repo = repo;
var rawopts = new GitBlameOptions
{
version = 1,
flags = options.Strategy.ToGitBlameOptionFlags(),
MinLine = (uint)options.MinLine,
MaxLine = (uint)options.MaxLine,
};
if (options.StartingAt != null)
{
rawopts.NewestCommit = repo.Committish(options.StartingAt).Oid;
}
if (options.StoppingAt != null)
{
rawopts.OldestCommit = repo.Committish(options.StoppingAt).Oid;
}
using (var blameHandle = Proxy.git_blame_file(repoHandle, path, rawopts))
{
var numHunks = NativeMethods.git_blame_get_hunk_count(blameHandle);
for (uint i = 0; i < numHunks; ++i)
{
var rawHunk = Proxy.git_blame_get_hunk_byindex(blameHandle, i);
hunks.Add(new BlameHunk(this.repo, rawHunk));
}
}
}
///
/// Access blame hunks by index.
///
/// The index of the hunk to retrieve
/// The at the given index.
public virtual BlameHunk this[int idx]
{
get { return hunks[idx]; }
}
///
/// Access blame hunks by the file line.
///
/// Line number to search for
/// The that contains the specified file line.
public virtual BlameHunk HunkForLine(int line)
{
var hunk = hunks.FirstOrDefault(x => x.ContainsLine(line));
if (hunk != null)
{
return hunk;
}
throw new ArgumentOutOfRangeException("line", "No hunk for that line");
}
///
/// Returns an enumerator that iterates through a collection.
///
///
/// An object that can be used to iterate through the collection.
///
/// 2
public virtual IEnumerator GetEnumerator()
{
return hunks.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}