From d65aa4f010adbd6c8162eb08c5787550e27d3e47 Mon Sep 17 00:00:00 2001 From: vnugent Date: Wed, 19 Apr 2023 01:42:00 -0400 Subject: Fix watcher pause, add base64urlencode --- lib/Utils/src/VnEncoding.cs | 91 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) (limited to 'lib/Utils') diff --git a/lib/Utils/src/VnEncoding.cs b/lib/Utils/src/VnEncoding.cs index 4a95405..35d52a7 100644 --- a/lib/Utils/src/VnEncoding.cs +++ b/lib/Utils/src/VnEncoding.cs @@ -452,7 +452,7 @@ namespace VNLib.Utils //Calculate the base32 entropy to alloc an appropriate buffer (minium buffer of 2 chars) int entropy = Base32CalcMaxBufferSize(binBuffer.Length); //Alloc buffer for enough size (2*long bytes) is not an issue - using (UnsafeMemoryHandle charBuffer = Memory.MemoryUtil.UnsafeAlloc(entropy)) + using (UnsafeMemoryHandle charBuffer = MemoryUtil.UnsafeAlloc(entropy)) { //Encode ERRNO encoded = TryToBase32Chars(binBuffer, charBuffer.Span); @@ -890,6 +890,95 @@ namespace VNLib.Utils return Base64UrlDecode(decodeHandle.Span[..count], output); } + + /// + /// Base64url encodes the binary buffer to its utf8 binary representation + /// + /// The intput binary buffer to base64url encode + /// The data within the buffer to encode, must be smaller than the entire buffer + /// A value that indicates if base64 padding should be url encoded(true), or removed(false). + /// The number characters written to the buffer, or if a error occured. + public static ERRNO Base64UrlEncodeInPlace(Span buffer, int dataLength, bool includePadding) + { + //Convert to base64 + if (Base64.EncodeToUtf8InPlace(buffer, dataLength, out int bytesWritten) != OperationStatus.Done) + { + return ERRNO.E_FAIL; + } + + if (includePadding) + { + //Url encode in place + Base64ToUrlSafeInPlace(buffer[..bytesWritten]); + return bytesWritten; + } + else + { + //Remove padding bytes + Span nonPadded = buffer[..bytesWritten].TrimEnd((byte)0x3d); + + Base64ToUrlSafeInPlace(nonPadded); + return nonPadded.Length; + } + + } + + /// + /// Encodes the binary input buffer to its base64url safe utf8 encoding, and writes the output + /// to the supplied buffer. Be sure to call + /// to allocate the correct size buffer for encoding + /// + /// The intput binary buffer to base64url encode + /// The output buffer to write the base64url safe encodded date to + /// A value that indicates if base64 padding should be url encoded(true), or removed(false). + /// The number characters written to the buffer, or if a error occured. + public static ERRNO Base64UrlEncode(ReadOnlySpan input, Span output, bool includePadding) + { + //Write the input buffer to the output buffer + input.CopyTo(output); + + //encode in place + return Base64UrlEncodeInPlace(output, input.Length, includePadding); + } + + /// + /// Encodes the binary intput buffer to its base64url safe encoding, then converts the internal buffer + /// to its character encoding using the supplied , and writes the characters + /// to the output buffer. Defaults to UTF8 character encoding. Base64url is a subset of ASCII,UTF7,UTF8,UTF16 etc + /// so most encodings should be safe. + /// + /// The input binary intput buffer + /// The character output buffer + /// A value that indicates if base64 padding should be url encoded(true), or removed(false). + /// The encoding used to convert the binary buffer to its character representation. + /// The number of characters written to the buffer, or if a error occured + public static ERRNO Base64UrlEncode(ReadOnlySpan input, Span output, bool includePadding, Encoding? encoding = null) + { + encoding ??= Encoding.UTF8; + + //We need to alloc an intermediate buffer, get the base64 max size + int maxSize = Base64.GetMaxEncodedToUtf8Length(input.Length); + + //Alloc buffer + using UnsafeMemoryHandle buffer = MemoryUtil.UnsafeAlloc(maxSize); + + //Encode to url safe binary + ERRNO count = Base64UrlEncode(input, buffer.Span, includePadding); + + if (count <= 0) + { + return count; + } + + //Get char count to return to caller + int charCount = encoding.GetCharCount(buffer.Span[..(int)count]); + + //Encode to characters + encoding.GetChars(buffer.AsSpan(0, count), output); + + return charCount; + } + #endregion } } \ No newline at end of file -- cgit