diff --git a/src/LibHac/Common/SpanHelpers.cs b/src/LibHac/Common/SpanHelpers.cs index 700ab9bd..fd0543ad 100644 --- a/src/LibHac/Common/SpanHelpers.cs +++ b/src/LibHac/Common/SpanHelpers.cs @@ -4,6 +4,33 @@ using System.Runtime.InteropServices; namespace LibHac.Common { + public static class SpanExtensions + { + /// + /// Gets the element at the specified zero-based index or gets 0 if the index is out-of-bounds. + /// + /// The containing the element to get. + /// The zero-based index of the element. + /// The element at the specified index or 0 if out-of-bounds. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte At(in this ReadOnlySpan span, int i) + { + return (uint)i >= (uint)span.Length ? (byte)0 : span[i]; + } + + /// + /// Gets the element at the specified zero-based index or gets 0 if the index is out-of-bounds. + /// + /// The containing the element to get. + /// The zero-based index of the element. + /// The element at the specified index or 0 if out-of-bounds. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte At(in this Span span, int i) + { + return (uint)i >= (uint)span.Length ? (byte)0 : span[i]; + } + } + public static class SpanHelpers { [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/LibHac/Diag/Impl/AssertImpl.cs b/src/LibHac/Diag/Impl/AssertImpl.cs index 351d2e9a..69c06d37 100644 --- a/src/LibHac/Diag/Impl/AssertImpl.cs +++ b/src/LibHac/Diag/Impl/AssertImpl.cs @@ -10,14 +10,14 @@ namespace LibHac.Diag.Impl internal static void InvokeAssertionNotNull(AssertionType assertionType, string valueText, string functionName, string fileName, int lineNumber) { - Assert.OnAssertionFailure(assertionType, valueText, functionName, fileName, lineNumber, + Assert.OnAssertionFailure(assertionType, "NotNull", functionName, fileName, lineNumber, $"{valueText} must not be nullptr."); } internal static void InvokeAssertionNull(AssertionType assertionType, string valueText, string functionName, string fileName, int lineNumber) { - Assert.OnAssertionFailure(assertionType, valueText, functionName, fileName, lineNumber, + Assert.OnAssertionFailure(assertionType, "Null", functionName, fileName, lineNumber, $"{valueText} must be nullptr."); } @@ -137,12 +137,12 @@ namespace LibHac.Diag.Impl public static bool NotNull(Span span) { - return !Unsafe.IsNullRef(ref MemoryMarshal.GetReference(span)); + return !Unsafe.IsNullRef(ref MemoryMarshal.GetReference(span)) || span.Length == 0; } public static bool NotNull(ReadOnlySpan span) { - return !Unsafe.IsNullRef(ref MemoryMarshal.GetReference(span)); + return !Unsafe.IsNullRef(ref MemoryMarshal.GetReference(span)) || span.Length == 0; } public static bool WithinRange(int value, int lowerInclusive, int upperExclusive) diff --git a/src/LibHac/Util/StringUtils.cs b/src/LibHac/Util/StringUtils.cs index 52d0154b..145d3497 100644 --- a/src/LibHac/Util/StringUtils.cs +++ b/src/LibHac/Util/StringUtils.cs @@ -22,6 +22,22 @@ namespace LibHac.Util return i; } + public static int Copy(Span dest, ReadOnlySpan source, int maxLen) + { + int maxLenLocal = Math.Min(Math.Min(dest.Length, source.Length), maxLen); + + int i; + for (i = 0; i < maxLenLocal && source[i] != 0; i++) + dest[i] = source[i]; + + if (i < dest.Length) + { + dest[i] = 0; + } + + return i; + } + public static int GetLength(ReadOnlySpan s) { int i = 0; @@ -160,6 +176,23 @@ namespace LibHac.Util return iDest; } + public static int Find(ReadOnlySpan haystack, ReadOnlySpan needle) + { + if (needle.Length == 0) + return 0; + + for (int i = 0; i <= haystack.Length - needle.Length; i++) + { + int j; + for (j = 0; j < needle.Length && haystack[i + j] == needle[j]; j++) { } + + if (j == needle.Length) + return i; + } + + return -1; + } + public static ReadOnlySpan StringToUtf8(string value) { return Encoding.UTF8.GetBytes(value).AsSpan();