Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
        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);
        }
Beispiel #12
0
        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);
        }
Beispiel #13
0
        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);
        }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        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);
        }