public static bool TryEncode(ReadOnlySpan <byte> input, Span <byte> output, out int written) { written = 0; for (int inputIndex = 0; inputIndex < input.Length; inputIndex++) { var next = input[inputIndex]; if (next > 0x7F) { throw new NotImplementedException(); } if (written >= output.Length) { written = 0; return(false); } if (IsAllowed[next]) { output[written++] = input[inputIndex]; } else { output[written++] = (byte)'%'; if (!PrimitiveFormatter.TryFormat(next, output.Slice(written), out int formatted, 'X')) { written = 0; return(false); } written += formatted; } } return(true); }
static void Validate <T>(ulong value, TextFormat format, TextEncoder encoder) { var formatString = format.Precision == 255 ? $"{format.Symbol}" : $"{format.Symbol}{format.Precision}"; var span = new Span <byte>(new byte[128]); string expected; int written; if (typeof(T) == typeof(ulong)) { expected = value.ToString(formatString, CultureInfo.InvariantCulture); Assert.True(PrimitiveFormatter.TryFormat(value, span, out written, format, encoder)); } else if (typeof(T) == typeof(uint)) { expected = ((uint)value).ToString(formatString, CultureInfo.InvariantCulture); Assert.True(PrimitiveFormatter.TryFormat((uint)value, span, out written, format, encoder)); } else if (typeof(T) == typeof(ushort)) { expected = ((ushort)value).ToString(formatString, CultureInfo.InvariantCulture); Assert.True(PrimitiveFormatter.TryFormat((ushort)value, span, out written, format, encoder)); } else if (typeof(T) == typeof(byte)) { expected = ((byte)value).ToString(formatString, CultureInfo.InvariantCulture); Assert.True(PrimitiveFormatter.TryFormat((byte)value, span, out written, format, encoder)); } else if (typeof(T) == typeof(long)) { expected = ((long)value).ToString(formatString, CultureInfo.InvariantCulture); Assert.True(PrimitiveFormatter.TryFormat((long)value, span, out written, format, encoder)); } else if (typeof(T) == typeof(int)) { expected = ((int)value).ToString(formatString, CultureInfo.InvariantCulture); Assert.True(PrimitiveFormatter.TryFormat((int)value, span, out written, format, encoder)); } else if (typeof(T) == typeof(short)) { expected = ((short)value).ToString(formatString, CultureInfo.InvariantCulture); Assert.True(PrimitiveFormatter.TryFormat((short)value, span, out written, format, encoder)); } else if (typeof(T) == typeof(sbyte)) { expected = ((sbyte)value).ToString(formatString, CultureInfo.InvariantCulture); Assert.True(PrimitiveFormatter.TryFormat((sbyte)value, span, out written, format, encoder)); } else { throw new NotSupportedException(); } string actual = TestHelper.SpanToString(span.Slice(0, written), encoder); Assert.Equal(expected, actual); }
static void TestGuidFormat(Guid guid, char format, TextEncoder encoder) { var expected = guid.ToString(format.ToString()); var span = new Span <byte>(new byte[128]); Assert.True(PrimitiveFormatter.TryFormat(guid, span, out int written, format, encoder)); var actual = TestHelper.SpanToString(span.Slice(0, written), encoder); Assert.Equal(expected, actual); }
static void TestTimeSpanFormat(TimeSpan ts, char format, SymbolTable symbolTable) { var expected = ts.ToString(format.ToString(), CultureInfo.InvariantCulture); var span = new Span <byte>(new byte[256]); Assert.True(PrimitiveFormatter.TryFormat(ts, span, out int written, format, symbolTable)); var actual = TestHelper.SpanToString(span.Slice(0, written), symbolTable); Assert.Equal(expected, actual); }
static void TestDateTimeFormat(DateTime dt, char format, TextEncoder encoder) { var expected = dt.ToString(format.ToString(), CultureInfo.InvariantCulture); var span = new Span <byte>(new byte[256]); Assert.True(PrimitiveFormatter.TryFormat(dt, span, out int written, format, encoder)); var actual = TestHelper.SpanToString(span.Slice(0, written), encoder); Assert.Equal(expected, actual); }
static void TestDateTimeOffsetFormat(DateTimeOffset dto, char formatChar, TextEncoder encoder) { TextFormat format = (formatChar == 0) ? default(TextFormat) : formatChar; string expected = (format.IsDefault) ? dto.ToString(CultureInfo.InvariantCulture) : dto.ToString(formatChar.ToString(), CultureInfo.InvariantCulture); var span = new Span <byte>(new byte[256]); Assert.True(PrimitiveFormatter.TryFormat(dto, span, out int written, format, encoder)); var actual = TestHelper.SpanToString(span.Slice(0, written), encoder); Assert.Equal(expected, actual); }
int WriteChunkPrefix(Span <byte> chunkPrefixBuffer, int chunkLength) { if (!PrimitiveFormatter.TryFormat(chunkLength, chunkPrefixBuffer, out var written, 'X')) { throw new Exception("cannot format chunk length"); } for (int i = written - 1; i >= 0; i--) { chunkPrefixBuffer[ChunkPrefixSize - written + i - 2] = chunkPrefixBuffer[i]; } chunkPrefixBuffer[ChunkPrefixSize - 2] = 13; chunkPrefixBuffer[ChunkPrefixSize - 1] = 10; return(written + 2); }
public bool TryFormat(Span <byte> buffer, out int bytesWritten, ParsedFormat format, SymbolTable symbolTable) { if (!PrimitiveFormatter.TryFormat(_age, buffer, out bytesWritten, format, symbolTable)) { return(false); } char symbol = _inMonths ? 'm' : 'y'; if (!symbolTable.TryEncode((byte)symbol, buffer.Slice(bytesWritten), out int written)) { return(false); } bytesWritten += written; return(true); }
public bool TryFormat(Span <byte> buffer, Format.Parsed format, EncodingData encoding, out int bytesWritten) { if (!PrimitiveFormatter.TryFormat(_age, buffer, format, encoding, out bytesWritten)) { return(false); } char symbol = _inMonths ? 'm' : 'y'; int symbolBytes; if (!PrimitiveFormatter.TryFormat(symbol, buffer.Slice(bytesWritten), format, encoding, out symbolBytes)) { return(false); } bytesWritten += symbolBytes; return(true); }
public bool TryFormat(Span <byte> buffer, out int bytesWritten, TextFormat format, EncodingData encoding) { if (!PrimitiveFormatter.TryFormat(_age, buffer, out bytesWritten, format, encoding)) { return(false); } char symbol = _inMonths ? 'm' : 'y'; int symbolBytes; if (!encoding.TextEncoder.TryEncodeChar(symbol, buffer.Slice(bytesWritten), out symbolBytes)) { return(false); } bytesWritten += symbolBytes; return(true); }
static void TestDateTimeFormat(DateTime dt, char format, SymbolTable symbolTable) { string expected; if (format == 'l') { expected = dt.ToString("R", CultureInfo.InvariantCulture).ToLowerInvariant(); } else { expected = dt.ToString(format.ToString(), CultureInfo.InvariantCulture); } var span = new Span <byte>(new byte[256]); Assert.True(PrimitiveFormatter.TryFormat(dt, span, out int written, format, symbolTable)); var actual = TestHelper.SpanToString(span.Slice(0, written), symbolTable); Assert.Equal(expected, actual); }
public bool TryFormat(Span <byte> buffer, out int bytesWritten, TextFormat format, TextEncoder encoder) { if (!PrimitiveFormatter.TryFormat(_age, buffer, out bytesWritten, format, encoder)) { return(false); } char symbol = _inMonths ? 'm' : 'y'; int consumed; int symbolBytes; unsafe { ReadOnlySpan <char> symbolSpan = new ReadOnlySpan <char>(&symbol, 1); if (!encoder.TryEncode(symbolSpan, buffer.Slice(bytesWritten), out consumed, out symbolBytes)) { return(false); } } bytesWritten += symbolBytes; return(true); }
static void TestDateTimeOffsetFormat(DateTimeOffset dto, char formatChar, SymbolTable symbolTable) { ParsedFormat format = (formatChar == 0) ? default(ParsedFormat) : formatChar; string expected; if (formatChar == 'l') { expected = dto.ToString("R", CultureInfo.InvariantCulture).ToLowerInvariant(); } else { expected = (format.IsDefault) ? dto.ToString(CultureInfo.InvariantCulture) : dto.ToString(formatChar.ToString(), CultureInfo.InvariantCulture); } var span = new Span <byte>(new byte[256]); Assert.True(PrimitiveFormatter.TryFormat(dto, span, out int written, format, symbolTable)); var actual = TestHelper.SpanToString(span.Slice(0, written), symbolTable); Assert.Equal(expected, actual); }
public static bool TryWrite(Span <byte> output, Sha256 hash, string verb, string canonicalizedResource, DateTime utc, out int bytesWritten) { int written, consumed; bytesWritten = 0; if (verb.Equals("GET", StringComparison.Ordinal)) { if (output.Length < 3) { bytesWritten = 0; return(false); } s_GET.CopyTo(output); bytesWritten += s_GET.Length; } else { if (Utf16.ToUtf8(verb.AsReadOnlySpan().AsBytes(), output, out consumed, out written) != TransformationStatus.Done) { bytesWritten = 0; return(false); } output[written] = (byte)'\n'; bytesWritten += written + 1; } var free = output.Slice(bytesWritten); s_emptyHeaders.CopyTo(free); bytesWritten += s_emptyHeaders.Length; free = output.Slice(bytesWritten); if (!PrimitiveFormatter.TryFormat(utc, free, out written, 'R')) { bytesWritten = 0; return(false); } free[written] = (byte)'\n'; bytesWritten += written + 1; free = output.Slice(bytesWritten); if (Utf16.ToUtf8(canonicalizedResource.AsReadOnlySpan().AsBytes(), free, out consumed, out written) != TransformationStatus.Done) { bytesWritten = 0; return(false); } bytesWritten += written; var formatted = output.Slice(0, bytesWritten); hash.Append(formatted); hash.GetHash(output.Slice(0, hash.OutputSize)); if (!Base64.EncodeInPlace(output, hash.OutputSize, out written)) { bytesWritten = 0; return(false); } bytesWritten = written; return(true); }
public static bool TryWrite(Span <byte> output, Sha256 hash, string keyType, string verb, string resourceId, string resourceType, string tokenVersion, DateTime utc, out int bytesWritten) { int written, consumed, totalWritten = 0; bytesWritten = 0; Span <byte> buffer; unsafe { var pBuffer = stackalloc byte[AuthenticationHeaderBufferSize]; buffer = new Span <byte>(pBuffer, AuthenticationHeaderBufferSize); } s_type.CopyTo(buffer); totalWritten += s_type.Length; var bufferSlice = buffer.Slice(totalWritten); if (Utf16.ToUtf8(keyType.AsReadOnlySpan().AsBytes(), bufferSlice, out consumed, out written) != TransformationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } totalWritten += written; bufferSlice = buffer.Slice(totalWritten); s_ver.CopyTo(bufferSlice); totalWritten += s_ver.Length; bufferSlice = buffer.Slice(totalWritten); if (Utf16.ToUtf8(tokenVersion.AsReadOnlySpan().AsBytes(), bufferSlice, out consumed, out written) != TransformationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } totalWritten += written; bufferSlice = buffer.Slice(totalWritten); s_sig.CopyTo(bufferSlice); totalWritten += s_sig.Length; var front = buffer.Slice(0, totalWritten); var payload = buffer.Slice(totalWritten); totalWritten = 0; if (verb.Equals("GET", StringComparison.Ordinal) || verb.Equals("get", StringComparison.Ordinal)) { s_get.CopyTo(payload); totalWritten += s_get.Length; } else if (verb.Equals("POST", StringComparison.Ordinal) || verb.Equals("post", StringComparison.Ordinal)) { s_post.CopyTo(payload); totalWritten += s_post.Length; } else if (verb.Equals("DELETE", StringComparison.Ordinal) || verb.Equals("delete", StringComparison.Ordinal)) { s_delete.CopyTo(payload); totalWritten += s_delete.Length; } else { if (Utf16.ToUtf8(verb.AsReadOnlySpan().AsBytes(), payload, out consumed, out written) != TransformationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } if (Ascii.ToLowerInPlace(payload.Slice(0, written), out written) != TransformationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } payload[written] = (byte)'\n'; totalWritten += written + 1; } bufferSlice = payload.Slice(totalWritten); if (Utf16.ToUtf8(resourceType.AsReadOnlySpan().AsBytes(), bufferSlice, out consumed, out written) != TransformationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } if (Ascii.ToLowerInPlace(bufferSlice.Slice(0, written), out written) != TransformationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } bufferSlice[written] = (byte)'\n'; totalWritten += written + 1; bufferSlice = payload.Slice(totalWritten); if (Utf16.ToUtf8(resourceId.AsReadOnlySpan().AsBytes(), bufferSlice, out consumed, out written) != TransformationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } bufferSlice[written] = (byte)'\n'; totalWritten += written + 1; bufferSlice = payload.Slice(totalWritten); if (!PrimitiveFormatter.TryFormat(utc, bufferSlice, out written, 'l')) { throw new NotImplementedException("need to resize buffer"); } bufferSlice[written] = (byte)'\n'; totalWritten += written + 1; bufferSlice = payload.Slice(totalWritten); bufferSlice[0] = (byte)'\n'; totalWritten += 1; hash.Append(buffer.Slice(front.Length, totalWritten)); hash.GetHash(buffer.Slice(front.Length, hash.OutputSize)); if (!Base64.EncodeInPlace(buffer.Slice(front.Length), hash.OutputSize, out written)) { throw new NotImplementedException("need to resize buffer"); } var len = front.Length + written; if (!UrlEncoder.TryEncode(buffer.Slice(0, len), output, out bytesWritten)) { bytesWritten = 0; return(false); } return(true); }