private static void BuildPart(string input, Span <char> output, ref int currentPosition) { var productLength = input?.Length ?? 0; // check if empty string, if so, unknown if (productLength == 0 || MemoryExtensions.IsWhiteSpace(input)) { UnknownPart.CopyTo(output.Slice(currentPosition)); currentPosition += UnknownPart.Length; } else { // check valid var isValid = true; foreach (var c in input) { if (!char.IsLetterOrDigit(c) && c != ' ') { isValid = false; break; } } if (!isValid) // not valid { InvalidPart.CopyTo(output.Slice(currentPosition)); currentPosition += InvalidPart.Length; } else { // if valid, lowercase MemoryExtensions.ToLowerInvariant(input, output.Slice(currentPosition)); currentPosition += productLength; } } output[currentPosition++] = JoinChar; }
public static string GenerateSafeObjectKey(EventContext eventContext) { var length = CalculateLength(eventContext); var objectKeySpan = length <= MaxStackAllocationSize ? stackalloc char[length] : new char[length]; // this allocations. If we actually expected this to // ever be the case using the ArrayPool would be more efficient. var currentPosition = 0; BuildPart(eventContext.Product, objectKeySpan, ref currentPosition); BuildPart(eventContext.SiteKey, objectKeySpan, ref currentPosition); BuildPart(eventContext.EventName, objectKeySpan, ref currentPosition); RemoveSpaces(objectKeySpan, ref currentPosition); if (eventContext.EventDateUtc != default) { eventContext.EventDateUtc.TryFormat(objectKeySpan.Slice(currentPosition), out var bytesWritten, DateFormat, CultureInfo.InvariantCulture); currentPosition += bytesWritten; } MemoryExtensions.ToLowerInvariant(eventContext.MessageId, objectKeySpan.Slice(currentPosition)); currentPosition += eventContext.MessageId.Length; JsonSuffix.CopyTo(objectKeySpan.Slice(currentPosition)); // copy suffix var key = objectKeySpan.ToString(); // allocate the final string return(key); }
public static IEnumerable <object[]> MemoryExtensionsToUpperLowerOverlapping() { // full overlap, overlap in the middle, overlap at start, overlap at the end yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => ((ReadOnlySpan <char>)buffer).ToLower(buffer, null) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => ((ReadOnlySpan <char>)buffer).ToLower(buffer.Slice(1, 1), null) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => ((ReadOnlySpan <char>)buffer).ToLower(buffer.Slice(0, 1), null) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => ((ReadOnlySpan <char>)buffer).ToLower(buffer.Slice(2, 1), null) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => MemoryExtensions.ToLower(buffer, buffer, null) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => MemoryExtensions.ToLower(buffer, buffer.Slice(1, 1), null) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => MemoryExtensions.ToLower(buffer, buffer.Slice(0, 1), null) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => MemoryExtensions.ToLower(buffer, buffer.Slice(2, 1), null) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => ((ReadOnlySpan <char>)buffer).ToLowerInvariant(buffer) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => ((ReadOnlySpan <char>)buffer).ToLowerInvariant(buffer.Slice(1, 1)) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => ((ReadOnlySpan <char>)buffer).ToLowerInvariant(buffer.Slice(0, 1)) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => ((ReadOnlySpan <char>)buffer).ToLowerInvariant(buffer.Slice(2, 1)) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => MemoryExtensions.ToLowerInvariant(buffer, buffer) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => MemoryExtensions.ToLowerInvariant(buffer, buffer.Slice(1, 1)) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => MemoryExtensions.ToLowerInvariant(buffer, buffer.Slice(0, 1)) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => MemoryExtensions.ToLowerInvariant(buffer, buffer.Slice(2, 1)) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => ((ReadOnlySpan <char>)buffer).ToUpper(buffer, null) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => ((ReadOnlySpan <char>)buffer).ToUpper(buffer.Slice(1, 1), null) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => ((ReadOnlySpan <char>)buffer).ToUpper(buffer.Slice(0, 1), null) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => ((ReadOnlySpan <char>)buffer).ToUpper(buffer.Slice(2, 1), null) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => MemoryExtensions.ToUpper(buffer, buffer, null) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => MemoryExtensions.ToUpper(buffer, buffer.Slice(1, 1), null) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => MemoryExtensions.ToUpper(buffer, buffer.Slice(0, 1), null) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => MemoryExtensions.ToUpper(buffer, buffer.Slice(2, 1), null) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => ((ReadOnlySpan <char>)buffer).ToUpperInvariant(buffer) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => ((ReadOnlySpan <char>)buffer).ToUpperInvariant(buffer.Slice(1, 1)) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => ((ReadOnlySpan <char>)buffer).ToUpperInvariant(buffer.Slice(0, 1)) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => ((ReadOnlySpan <char>)buffer).ToUpperInvariant(buffer.Slice(2, 1)) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => MemoryExtensions.ToUpperInvariant(buffer, buffer) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => MemoryExtensions.ToUpperInvariant(buffer, buffer.Slice(1, 1)) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => MemoryExtensions.ToUpperInvariant(buffer, buffer.Slice(0, 1)) }); yield return(new TestHelpers.AssertThrowsAction <char>[] { (Span <char> buffer) => MemoryExtensions.ToUpperInvariant(buffer, buffer.Slice(2, 1)) }); }