// Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; namespace SixLabors { /// /// Provides methods to protect against invalid parameters. /// [DebuggerStepThrough] internal static class Guard { /// /// Ensures that the value is not null. /// /// The target object, which cannot be null. /// The name of the parameter that is to be checked. /// The type of the value. /// is null. [MethodImpl(MethodImplOptions.AggressiveInlining)] [DebuggerStepThrough] public static void NotNull(TValue value, string parameterName) where TValue : class { if (value is null) { ThrowArgumentNullException(parameterName); } } /// /// Ensures that the target value is not null, empty, or whitespace. /// /// The target string, which should be checked against being null or empty. /// Name of the parameter. /// is null. /// is empty or contains only blanks. [MethodImpl(MethodImplOptions.AggressiveInlining)] [DebuggerStepThrough] public static void NotNullOrWhiteSpace(string value, string parameterName) { if (value is null) { ThrowArgumentNullException(parameterName); } if (string.IsNullOrWhiteSpace(value)) { ThrowArgumentException("Must not be empty or whitespace.", parameterName); } } /// /// Ensures that the specified value is less than a maximum value. /// /// The target value, which should be validated. /// The maximum value. /// The name of the parameter that is to be checked. /// The type of the value. /// /// is greater than the maximum value. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [DebuggerStepThrough] public static void MustBeLessThan(TValue value, TValue max, string parameterName) where TValue : IComparable { if (value.CompareTo(max) >= 0) { ThrowArgumentOutOfRangeException(parameterName, $"Value {value} must be less than {max}."); } } /// /// Verifies that the specified value is less than or equal to a maximum value /// and throws an exception if it is not. /// /// The target value, which should be validated. /// The maximum value. /// The name of the parameter that is to be checked. /// The type of the value. /// /// is greater than the maximum value. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [DebuggerStepThrough] public static void MustBeLessThanOrEqualTo(TValue value, TValue max, string parameterName) where TValue : IComparable { if (value.CompareTo(max) > 0) { ThrowArgumentOutOfRangeException(parameterName, $"Value {value} must be less than or equal to {max}."); } } /// /// Verifies that the specified value is greater than a minimum value /// and throws an exception if it is not. /// /// The target value, which should be validated. /// The minimum value. /// The name of the parameter that is to be checked. /// The type of the value. /// /// is less than the minimum value. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [DebuggerStepThrough] public static void MustBeGreaterThan(TValue value, TValue min, string parameterName) where TValue : IComparable { if (value.CompareTo(min) <= 0) { ThrowArgumentOutOfRangeException( parameterName, $"Value {value} must be greater than {min}."); } } /// /// Verifies that the specified value is greater than or equal to a minimum value /// and throws an exception if it is not. /// /// The target value, which should be validated. /// The minimum value. /// The name of the parameter that is to be checked. /// The type of the value. /// /// is less than the minimum value. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [DebuggerStepThrough] public static void MustBeGreaterThanOrEqualTo(TValue value, TValue min, string parameterName) where TValue : IComparable { if (value.CompareTo(min) < 0) { ThrowArgumentOutOfRangeException(parameterName, $"Value {value} must be greater than or equal to {min}."); } } /// /// Verifies that the specified value is greater than or equal to a minimum value and less than /// or equal to a maximum value and throws an exception if it is not. /// /// The target value, which should be validated. /// The minimum value. /// The maximum value. /// The name of the parameter that is to be checked. /// The type of the value. /// /// is less than the minimum value of greater than the maximum value. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [DebuggerStepThrough] public static void MustBeBetweenOrEqualTo(TValue value, TValue min, TValue max, string parameterName) where TValue : IComparable { if (value.CompareTo(min) < 0 || value.CompareTo(max) > 0) { ThrowArgumentOutOfRangeException(parameterName, $"Value {value} must be greater than or equal to {min} and less than or equal to {max}."); } } /// /// Verifies, that the method parameter with specified target value is true /// and throws an exception if it is found to be so. /// /// The target value, which cannot be false. /// The name of the parameter that is to be checked. /// The error message, if any to add to the exception. /// /// is false. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [DebuggerStepThrough] public static void IsTrue(bool target, string parameterName, string message) { if (!target) { ThrowArgumentException(message, parameterName); } } /// /// Verifies, that the method parameter with specified target value is false /// and throws an exception if it is found to be so. /// /// The target value, which cannot be true. /// The name of the parameter that is to be checked. /// The error message, if any to add to the exception. /// /// is true. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [DebuggerStepThrough] public static void IsFalse(bool target, string parameterName, string message) { if (target) { ThrowArgumentException(message, parameterName); } } /// /// Verifies, that the `source` span has the length of 'minLength', or longer. /// /// The element type of the spans. /// The source span. /// The minimum length. /// The name of the parameter that is to be checked. /// /// has less than items. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [DebuggerStepThrough] public static void MustBeSizedAtLeast(ReadOnlySpan source, int minLength, string parameterName) { if (source.Length < minLength) { ThrowArgumentException($"Span-s must be at least of length {minLength}!", parameterName); } } /// /// Verifies, that the `source` span has the length of 'minLength', or longer. /// /// The element type of the spans. /// The target span. /// The minimum length. /// The name of the parameter that is to be checked. /// /// has less than items. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [DebuggerStepThrough] public static void MustBeSizedAtLeast(Span source, int minLength, string parameterName) { if (source.Length < minLength) { ThrowArgumentException($"The size must be at least {minLength}.", parameterName); } } /// /// Verifies that the 'destination' span is not shorter than 'source'. /// /// The source element type. /// The destination element type. /// The source span. /// The destination span. /// The name of the argument for 'destination'. [MethodImpl(MethodImplOptions.AggressiveInlining)] [DebuggerStepThrough] public static void DestinationShouldNotBeTooShort( ReadOnlySpan source, Span destination, string destinationParamName) { if (destination.Length < source.Length) { ThrowArgumentException($"Destination span is too short!", destinationParamName); } } /// /// Verifies that the 'destination' span is not shorter than 'source'. /// /// The source element type. /// The destination element type. /// The source span. /// The destination span. /// The name of the argument for 'destination'. [MethodImpl(MethodImplOptions.AggressiveInlining)] [DebuggerStepThrough] public static void DestinationShouldNotBeTooShort( Span source, Span destination, string destinationParamName) { if (destination.Length < source.Length) { ThrowArgumentException($"Destination span is too short!", destinationParamName); } } [MethodImpl(MethodImplOptions.NoInlining)] private static void ThrowArgumentException(string message, string parameterName) { throw new ArgumentException(message, parameterName); } [MethodImpl(MethodImplOptions.NoInlining)] private static void ThrowArgumentOutOfRangeException(string parameterName, string message) { throw new ArgumentOutOfRangeException(parameterName, message); } [MethodImpl(MethodImplOptions.NoInlining)] private static void ThrowArgumentNullException(string parameterName) { throw new ArgumentNullException(parameterName); } } }