using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
namespace LibGit2Sharp.Core
{
///
/// Ensure input parameters
///
[DebuggerStepThrough]
internal static class Ensure
{
///
/// Checks an argument to ensure it isn't null.
///
/// The argument value to check.
/// The name of the argument.
public static void ArgumentNotNull(object argumentValue, string argumentName)
{
if (argumentValue == null)
{
throw new ArgumentNullException(argumentName);
}
}
///
/// Checks an array argument to ensure it isn't null or empty.
///
/// The argument value to check.
/// The name of the argument.
public static void ArgumentNotNullOrEmptyEnumerable(IEnumerable argumentValue, string argumentName)
{
ArgumentNotNull(argumentValue, argumentName);
if (!argumentValue.Any())
{
throw new ArgumentException("Enumerable cannot be empty", argumentName);
}
}
///
/// Checks a string argument to ensure it isn't null or empty.
///
/// The argument value to check.
/// The name of the argument.
public static void ArgumentNotNullOrEmptyString(string argumentValue, string argumentName)
{
ArgumentNotNull(argumentValue, argumentName);
if (String.IsNullOrWhiteSpace (argumentValue))
{
throw new ArgumentException("String cannot be empty", argumentName);
}
}
///
/// Checks a string argument to ensure it doesn't contain a zero byte.
///
/// The argument value to check.
/// The name of the argument.
public static void ArgumentDoesNotContainZeroByte(string argumentValue, string argumentName)
{
if (string.IsNullOrEmpty(argumentValue))
{
return;
}
int zeroPos = -1;
for (var i = 0; i < argumentValue.Length; i++)
{
if (argumentValue[i] == '\0')
{
zeroPos = i;
break;
}
}
if (zeroPos == -1)
{
return;
}
throw new ArgumentException(
string.Format(CultureInfo.InvariantCulture,
"Zero bytes ('\\0') are not allowed. A zero byte has been found at position {0}.", zeroPos), argumentName);
}
///
/// Checks an argument to ensure it isn't a IntPtr.Zero (aka null).
///
/// The argument value to check.
/// The name of the argument.
public static void ArgumentNotZeroIntPtr(IntPtr argumentValue, string argumentName)
{
if (argumentValue == IntPtr.Zero)
{
throw new ArgumentNullException(argumentName);
}
}
///
/// Checks a pointer argument to ensure it is the expected pointer value.
///
/// The argument value to check.
/// The expected value.
/// The name of the argument.
public static void ArgumentIsExpectedIntPtr(IntPtr argumentValue, IntPtr expectedValue, string argumentName)
{
if (argumentValue != expectedValue)
{
throw new ArgumentException("Unexpected IntPtr value", argumentName);
}
}
private static readonly Dictionary>
GitErrorsToLibGit2SharpExceptions =
new Dictionary>
{
{ GitErrorCode.User, (m, r, c) => new UserCancelledException(m, r, c) },
{ GitErrorCode.BareRepo, (m, r, c) => new BareRepositoryException(m, r, c) },
{ GitErrorCode.Exists, (m, r, c) => new NameConflictException(m, r, c) },
{ GitErrorCode.InvalidSpecification, (m, r, c) => new InvalidSpecificationException(m, r, c) },
{ GitErrorCode.UnmergedEntries, (m, r, c) => new UnmergedIndexEntriesException(m, r, c) },
{ GitErrorCode.NonFastForward, (m, r, c) => new NonFastForwardException(m, r, c) },
{ GitErrorCode.Conflict, (m, r, c) => new CheckoutConflictException(m, r, c) },
{ GitErrorCode.LockedFile, (m, r, c) => new LockedFileException(m, r, c) },
{ GitErrorCode.NotFound, (m, r, c) => new NotFoundException(m, r, c) },
{ GitErrorCode.Peel, (m, r, c) => new PeelException(m, r, c) },
};
private static unsafe void HandleError(int result)
{
string errorMessage;
GitErrorCategory errorCategory = GitErrorCategory.Unknown;
GitError* error = NativeMethods.giterr_last();
if (error == null)
{
errorMessage = "No error message has been provided by the native library";
}
else
{
errorMessage = LaxUtf8Marshaler.FromNative(error->Message);
}
Func exceptionBuilder;
if (!GitErrorsToLibGit2SharpExceptions.TryGetValue((GitErrorCode)result, out exceptionBuilder))
{
exceptionBuilder = (m, r, c) => new LibGit2SharpException(m, r, c);
}
throw exceptionBuilder(errorMessage, (GitErrorCode)result, errorCategory);
}
///
/// Check that the result of a C call was successful
///
/// The native function is expected to return strictly 0 for
/// success or a negative value in the case of failure.
///
///
/// The result to examine.
public static void ZeroResult(int result)
{
if (result == (int)GitErrorCode.Ok)
{
return;
}
HandleError(result);
}
///
/// Check that the result of a C call returns a boolean value.
///
/// The native function is expected to return strictly 0 or 1.
///
///
/// The result to examine.
public static void BooleanResult(int result)
{
if (result == 0 || result == 1)
{
return;
}
HandleError(result);
}
///
/// Check that the result of a C call that returns an integer
/// value was successful.
///
/// The native function is expected to return 0 or a positive
/// value for success or a negative value in the case of failure.
///
///
/// The result to examine.
public static void Int32Result(int result)
{
if (result >= (int)GitErrorCode.Ok)
{
return;
}
HandleError(result);
}
///
/// Checks an argument by applying provided checker.
///
/// The argument value to check.
/// The predicate which has to be satisfied
/// The name of the argument.
public static void ArgumentConformsTo(T argumentValue, Func checker, string argumentName)
{
if (checker(argumentValue))
{
return;
}
throw new ArgumentException(argumentName);
}
///
/// Checks an argument is a positive integer.
///
/// The argument value to check.
/// The name of the argument.
public static void ArgumentPositiveInt32(long argumentValue, string argumentName)
{
if (argumentValue >= 0 && argumentValue <= uint.MaxValue)
{
return;
}
throw new ArgumentException(argumentName);
}
///
/// Check that the result of a C call that returns a non-null GitObject
/// using the default exception builder.
///
/// The native function is expected to return a valid object value.
///
///
/// The to examine.
/// The identifier to examine.
public static void GitObjectIsNotNull(GitObject gitObject, string identifier)
{
if (gitObject != null)
{
return;
}
var messageFormat = "No valid git object identified by '{0}' exists in the repository.";
if (string.Equals("HEAD", identifier, StringComparison.Ordinal))
{
throw new UnbornBranchException(messageFormat, identifier);
}
throw new NotFoundException(messageFormat, identifier);
}
}
}