Ejemplo n.º 1
0
        public static Writer Make(int index, NameWriter name)
        {
            return((reader, buffer) =>
            {
                if (reader.IsDBNull(index))
                {
                    return buffer;
                }

                Comma.Write(ref buffer);
                name.Write(ref buffer);

                buffer[0] = QuotationMark;
                buffer = buffer.Slice(1);
                Utf8Formatter.TryFormat(reader.GetDateTime(index), buffer, out var n, new StandardFormat('O'));

                buffer[n] = QuotationMark;
                return buffer.Slice(n + 1);
            });
        }
Ejemplo n.º 2
0
        public static void WriteHeader(ref Sequence <byte> buffer, ReadOnlySpan <byte> headerName, long headerValue)
        {
            var segment = buffer.GetMemory().Span;
            int written = 0;

            headerName.CopyTo(segment);
            written += headerName.Length;

            segment.Slice(written)[0] = s_headerSeparator;
            written += 1;

            if (!Utf8Formatter.TryFormat(headerValue, segment.Slice(written), out int formatted))
            {
                throw new NotImplementedException("resise buffer");
            }
            written += formatted;

            s_crlf.CopyTo(segment.Slice(written));
            written += s_crlf.Length;
        }
Ejemplo n.º 3
0
        public static Writer Make(int index, NameWriter name)
        {
            return((reader, buffer, pos) =>
            {
                if (reader.IsDBNull(index))
                {
                    return pos;
                }

                Comma.Write(buffer, ref pos);
                name.Write(buffer, ref pos);

                buffer[pos++] = QuotationMark;
                var value = reader.GetFieldValue <DateTimeOffset>(index);
                Utf8Formatter.TryFormat(value, buffer.Slice(pos, 64), out var n, new StandardFormat('O'));
                pos = pos + n;
                buffer[pos] = QuotationMark;
                return pos + 1;
            });
        }
Ejemplo n.º 4
0
        private Result GetSubFileCount(out int fileCount, U8Span dirPath)
        {
            fileCount = default;

            FsPath buffer;

            unsafe { _ = &buffer; } // workaround for CS0165

            int pathLen = StringUtils.Copy(buffer.Str, dirPath);

            // Make sure we have at least 3 bytes for the sub file name
            if (pathLen + 3 > PathTools.MaxPathLength)
            {
                return(ResultFs.TooLongPath.Log());
            }

            buffer.Str[pathLen] = StringTraits.DirectorySeparator;
            Span <byte> subFileName = buffer.Str.Slice(pathLen + 1);

            Result rc;
            int    count;

            for (count = 0; ; count++)
            {
                Utf8Formatter.TryFormat(count, subFileName, out _, new StandardFormat('D', 2));

                rc = BaseFileSystem.GetEntryType(out _, buffer);
                if (rc.IsFailure())
                {
                    break;
                }
            }

            if (!ResultFs.PathNotFound.Includes(rc))
            {
                return(rc);
            }

            fileCount = count;
            return(Result.Success);
        }
        // ToDo benchmark - split writes into chunks?

        public async Task WriteAsync(Memory <byte> bytes)
        {
            if (_stream is null)
            {
                Write(bytes.Span);
                return;
            }

            int required = BEncodingHelpers.DigitCount(bytes.Length);

            if (_memory.Length - BytesPending < required)
            {
                Grow(required);
            }

            bool success = Utf8Formatter.TryFormat(bytes.Length, _memory.Span.Slice(BytesPending), out int written);

            Debug.Assert(success);
            Debug.Assert(written == required);
            BytesPending += written;

            _arrayBufferWriter.Advance(BytesPending);
            Debug.Assert(BytesPending == _arrayBufferWriter.WrittenCount);
            await _stream.WriteAsync(_arrayBufferWriter.WrittenMemory).ConfigureAwait(false);

            _arrayBufferWriter.Clear();
            _memory = _arrayBufferWriter.GetMemory(DefaultGrowthSize);

            BytesCommitted += BytesPending + bytes.Length;
            BytesPending    = 0;

            while (bytes.Length > 0)
            {
                int chunkSize = Math.Min(bytes.Length, 4096);
                await _stream.WriteAsync(bytes.Slice(0, chunkSize)).ConfigureAwait(false);

                bytes = bytes.Slice(chunkSize);
            }

            await _stream.FlushAsync().ConfigureAwait(false);
        }
Ejemplo n.º 6
0
        public static IEnumerable <object[]> GetPropertiesToWrite()
        {
            yield return(new object[] { new JwtMember(JsonEncodedText.Encode("object"), new object()), "{\"object\":{}}" });

            yield return(new object[] { new JwtMember(JsonEncodedText.Encode("array"), new List <object>()), "{\"array\":[]}" });

            yield return(new object[] { new JwtMember(JsonEncodedText.Encode("int64"), 1L), "{\"int64\":1}" });

            yield return(new object[] { new JwtMember(JsonEncodedText.Encode("int32"), 1), "{\"int32\":1}" });

            yield return(new object[] { new JwtMember(JsonEncodedText.Encode("int16"), (short)1), "{\"int16\":1}" });

            yield return(new object[] { new JwtMember(JsonEncodedText.Encode("int8"), (byte)1), "{\"int8\":1}" });

#if NETCOREAPP2_1 || NETFRAMEWORK || NETSTANDARD
            yield return(new object[] { new JwtMember(JsonEncodedText.Encode("float"), 1.0f), "{\"float\":1}" });

            yield return(new object[] { new JwtMember(JsonEncodedText.Encode("float"), 1.1f), "{\"float\":" + ((double)1.1f).ToString("G9", CultureInfo.InvariantCulture) + "}" });

            yield return(new object[] { new JwtMember(JsonEncodedText.Encode("double"), 1.0d), "{\"double\":1}" });

            yield return(new object[] { new JwtMember(JsonEncodedText.Encode("double"), 1.1d), "{\"double\":" + (1.1d).ToString("G17", CultureInfo.InvariantCulture) + "}" });
#else
            byte[] destination = new byte[256];
            Utf8Formatter.TryFormat(1.0f, destination, out int bytesWritten);
            yield return(new object[] { new JwtMember(JsonEncodedText.Encode("float"), 1.0f), "{\"float\":" + Encoding.UTF8.GetString(destination.AsSpan().Slice(0, bytesWritten)) + "}" });

            Utf8Formatter.TryFormat(1.1f, destination, out bytesWritten);
            yield return(new object[] { new JwtMember(JsonEncodedText.Encode("float"), 1.1f), "{\"float\":" + Encoding.UTF8.GetString(destination.AsSpan().Slice(0, bytesWritten)) + "}" });

            Utf8Formatter.TryFormat(1.0d, destination, out bytesWritten);
            yield return(new object[] { new JwtMember(JsonEncodedText.Encode("double"), 1.0d), "{\"double\":" + Encoding.UTF8.GetString(destination.AsSpan().Slice(0, bytesWritten)) + "}" });

            Utf8Formatter.TryFormat(1.1d, destination, out bytesWritten);
            yield return(new object[] { new JwtMember(JsonEncodedText.Encode("double"), 1.1d), "{\"double\":" + Encoding.UTF8.GetString(destination.AsSpan().Slice(0, bytesWritten)) + "}" });
#endif
            yield return(new object[] { new JwtMember(JsonEncodedText.Encode("string"), "hello"), "{\"string\":\"hello\"}" });

            //yield return new object[] { new JwtMember("utf8String", new[] { (byte)'h', (byte)'e', (byte)'l', (byte)'l', (byte)'o' }), "{\"utf8String\":\"hello\"}" };
            yield return(new object[] { new JwtMember(JsonEncodedText.Encode("boolean"), true), "{\"boolean\":true}" });
        }
        private void WriteStringValueIndented(DateTime value)
        {
            int indent = Indentation;

            Debug.Assert(indent <= 2 * JsonConstants.MaxWriterDepth);

            // 2 quotes, and optionally, 1 list separator and 1-2 bytes for new line
            int maxRequired = indent + JsonConstants.MaximumFormatDateTimeOffsetLength + 3 + s_newLineLength;

            if (_memory.Length - BytesPending < maxRequired)
            {
                Grow(maxRequired);
            }

            Span <byte> output = _memory.Span;

            if (_currentDepth < 0)
            {
                output[BytesPending++] = JsonConstants.ListSeparator;
            }

            if (_tokenType != JsonTokenType.None)
            {
                WriteNewLine(output);
            }

            JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent);
            BytesPending += indent;

            output[BytesPending++] = JsonConstants.Quote;

            Span <byte> tempSpan = stackalloc byte[JsonConstants.MaximumFormatDateTimeOffsetLength];
            bool        result   = Utf8Formatter.TryFormat(value, tempSpan, out int bytesWritten, s_dateTimeStandardFormat);

            Debug.Assert(result);
            JsonWriterHelper.TrimDateTimeOffset(tempSpan.Slice(0, bytesWritten), out bytesWritten);
            tempSpan.Slice(0, bytesWritten).CopyTo(output.Slice(BytesPending));
            BytesPending += bytesWritten;

            output[BytesPending++] = JsonConstants.Quote;
        }
Ejemplo n.º 8
0
        public void Write(ulong number)
        {
            // Try to format directly
            if (Utf8Formatter.TryFormat(number, Span, out int bytesWritten))
            {
                Advance(bytesWritten);
            }
            else
            {
                // Ask for at least 20 bytes
                Ensure(20);

                Debug.Assert(Span.Length >= 20, "Buffer is < 20 bytes");

                // Try again
                if (Utf8Formatter.TryFormat(number, Span, out bytesWritten))
                {
                    Advance(bytesWritten);
                }
            }
        }
Ejemplo n.º 9
0
        public void Write(ulong value)
        {
            // 22 is the worst-case required size ('i', 'e' and 20 digits)
            const int required = 22;

            if (_memory.Length - BytesPending < required)
            {
                Grow(required);
            }

            var span = _memory.Span;

            span[BytesPending++] = BEncodingConstants.OpenInteger;

            bool success = Utf8Formatter.TryFormat(value, span.Slice(BytesPending), out int written);

            Debug.Assert(success);
            BytesPending += written;

            span[BytesPending++] = BEncodingConstants.End;
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Creates an <see cref="IdSpan"/> representing a <see cref="long"/> key.
        /// </summary>
        public static IdSpan CreateIntegerKey(long key, string keyExtension)
        {
            if (string.IsNullOrWhiteSpace(keyExtension))
            {
                return(CreateIntegerKey(key));
            }

            Span <byte> tmp = stackalloc byte[sizeof(long) * 2];

            Utf8Formatter.TryFormat(key, tmp, out var len, 'X');
            Debug.Assert(len > 0);

            var extLen = Encoding.UTF8.GetByteCount(keyExtension);
            var buf    = new byte[len + 1 + extLen];

            tmp.Slice(0, len).CopyTo(buf);
            buf[len] = (byte)'+';
            Encoding.UTF8.GetBytes(keyExtension, 0, keyExtension.Length, buf, len + 1);

            return(new IdSpan(buf));
        }
Ejemplo n.º 11
0
        private void WriteValueFormatted(Guid value)
        {
            int indent = Indentation;

            // This is guaranteed not to overflow.
            Debug.Assert(int.MaxValue - JsonConstants.MaximumGuidLength - 3 - JsonWriterHelper.NewLineUtf8.Length - indent >= 0);

            // Calculated based on the following: ',\r\n  "value"'
            int bytesNeeded = 3 + JsonWriterHelper.NewLineUtf8.Length + indent + JsonConstants.MaximumGuidLength;

            Span <byte> byteBuffer = WriteValueFormatted(bytesNeeded, indent, out int idx);

            byteBuffer[idx++] = JsonConstants.Quote;
            bool result = Utf8Formatter.TryFormat(value, byteBuffer.Slice(idx), out int bytesWritten);

            Debug.Assert(result);
            idx += bytesWritten;
            byteBuffer[idx++] = JsonConstants.Quote;

            Advance(idx);
        }
        private void WriteNumberValueMinimized(long value)
        {
            int maxRequired = JsonConstants.MaximumFormatInt64Length + 1; // Optionally, 1 list separator

            if (_memory.Length - BytesPending < maxRequired)
            {
                Grow(maxRequired);
            }

            Span <byte> output = _memory.Span;

            if (_currentDepth < 0)
            {
                output[BytesPending++] = JsonConstants.ListSeparator;
            }

            bool result = Utf8Formatter.TryFormat(value, output.Slice(BytesPending), out int bytesWritten);

            Debug.Assert(result);
            BytesPending += bytesWritten;
        }
Ejemplo n.º 13
0
        internal Result GetConcatenationFileSize(out long size, ReadOnlySpan <byte> path)
        {
            UnsafeHelpers.SkipParamInit(out size);
            Unsafe.SkipInit(out FsPath buffer);

            int pathLen = StringUtils.Copy(buffer.Str, path);

            // Make sure we have at least 3 bytes for the sub file name
            if (pathLen + 3 > PathTools.MaxPathLength)
            {
                return(ResultFs.TooLongPath.Log());
            }

            buffer.Str[pathLen] = StringTraits.DirectorySeparator;
            Span <byte> subFileName = buffer.Str.Slice(pathLen + 1);

            Result rc;
            long   totalSize = 0;

            for (int i = 0; ; i++)
            {
                Utf8Formatter.TryFormat(i, subFileName, out _, new StandardFormat('D', 2));

                rc = BaseFileSystem.GetFileSize(out long fileSize, buffer);
                if (rc.IsFailure())
                {
                    break;
                }

                totalSize += fileSize;
            }

            if (!ResultFs.PathNotFound.Includes(rc))
            {
                return(rc);
            }

            size = totalSize;
            return(Result.Success);
        }
Ejemplo n.º 14
0
        private void WriteStringValueIndented(Guid value)
        {
            int indent = Indentation;

            Debug.Assert(indent <= 2 * JsonConstants.MaxWriterDepth);

            // 2 quotes, and optionally, 1 list separator and 1-2 bytes for new line
            int maxRequired = indent + JsonConstants.MaximumFormatGuidLength + 3 + s_newLineLength;

            if (_memory.Length - BytesPending < maxRequired)
            {
                Grow(maxRequired);
            }

            Span <byte> output = _memory.Span;

            if (_currentDepth < 0)
            {
                output[BytesPending++] = JsonConstants.ListSeparator;
            }

            if (_tokenType != JsonTokenType.PropertyName)
            {
                if (_tokenType != JsonTokenType.None)
                {
                    WriteNewLine(output);
                }
                JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent);
                BytesPending += indent;
            }

            output[BytesPending++] = JsonConstants.Quote;

            bool result = Utf8Formatter.TryFormat(value, output.Slice(BytesPending), out int bytesWritten);

            Debug.Assert(result);
            BytesPending += bytesWritten;

            output[BytesPending++] = JsonConstants.Quote;
        }
Ejemplo n.º 15
0
        private static void WriteWideRgb <TPixel>(Configuration configuration, Stream stream, ImageFrame <TPixel> image)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            int width  = image.Width;
            int height = image.Height;
            Buffer2D <TPixel> pixelBuffer = image.PixelBuffer;
            MemoryAllocator   allocator   = configuration.MemoryAllocator;

            using IMemoryOwner <Rgb48> row = allocator.Allocate <Rgb48>(width);
            Span <Rgb48> rowSpan           = row.GetSpan();

            using IMemoryOwner <byte> plainMemory = allocator.Allocate <byte>(width * MaxCharsPerPixelRgbWide);
            Span <byte> plainSpan = plainMemory.GetSpan();

            for (int y = 0; y < height; y++)
            {
                Span <TPixel> pixelSpan = pixelBuffer.DangerousGetRowSpan(y);
                PixelOperations <TPixel> .Instance.ToRgb48(
                    configuration,
                    pixelSpan,
                    rowSpan);

                int written = 0;
                for (int x = 0; x < width; x++)
                {
                    Utf8Formatter.TryFormat(rowSpan[x].R, plainSpan.Slice(written), out int bytesWritten, DecimalFormat);
                    written += bytesWritten;
                    plainSpan[written++] = Space;
                    Utf8Formatter.TryFormat(rowSpan[x].G, plainSpan.Slice(written), out bytesWritten, DecimalFormat);
                    written += bytesWritten;
                    plainSpan[written++] = Space;
                    Utf8Formatter.TryFormat(rowSpan[x].B, plainSpan.Slice(written), out bytesWritten, DecimalFormat);
                    written += bytesWritten;
                    plainSpan[written++] = Space;
                }

                plainSpan[written - 1] = NewLine;
                stream.Write(plainSpan, 0, written);
            }
        }
Ejemplo n.º 16
0
        private static void Utf8Parser_TryParseDouble(ReadOnlySpan <byte> data)
        {
            Span <byte> to = stackalloc byte[1024];

            if (Utf8Parser.TryParse(data, out double d1, out _))
            {
                if (double.IsNaN(d1))
                {
                    return;
                }

                if (!Utf8Formatter.TryFormat(d1, to, out int written))
                {
                    throw new Exception();
                }

                if (!Utf8Parser.TryParse(to.Slice(0, written), out double d2, out _))
                {
                    throw new Exception();
                }
            }
        }
Ejemplo n.º 17
0
        private void WriteArrayFast(ref ReadOnlySpan <byte> propertyName, ref ReadOnlySpan <float> values)
        {
            if (values.Length > 0 && values.Length < (int.MaxValue - 5 - propertyName.Length) / (JsonConstants.MaximumSingleLength + 1))
            {
                // Calculated based on the following: '"propertyName":[number0,number1,...,numberN]'
                int bytesNeeded = propertyName.Length + 5 + (values.Length * (1 + JsonConstants.MaximumSingleLength) - 1);

                if (_currentDepth >= 0)
                {
                    bytesNeeded--;
                }

                Ensure(bytesNeeded);

                WritePropertyName(ref propertyName, bytesNeeded, out int idx);

                _buffer[idx++] = JsonConstants.OpenBracket;

                bool result = Utf8Formatter.TryFormat(values[0], _buffer.Slice(idx), out int bytesWritten);
                Debug.Assert(result);
                idx += bytesWritten;

                for (int i = 1; i < values.Length; i++)
                {
                    _buffer[idx++] = JsonConstants.ListSeperator;
                    result         = Utf8Formatter.TryFormat(values[i], _buffer.Slice(idx), out bytesWritten);
                    Debug.Assert(result);
                    idx += bytesWritten;
                }

                _buffer[idx++] = JsonConstants.CloseBracket;

                Advance(idx);
            }
            else
            {
                WriteArrayFastIterate(ref propertyName, ref values);
            }
        }
Ejemplo n.º 18
0
        private void WriteStringMinimized(ReadOnlySpan <byte> escapedPropertyName, DateTimeOffset value)
        {
            Debug.Assert(escapedPropertyName.Length < int.MaxValue - JsonConstants.MaximumFormatDateTimeOffsetLength - 6);

            int minRequired = escapedPropertyName.Length + JsonConstants.MaximumFormatDateTimeOffsetLength + 5; // 2 quotes for property name, 2 quotes for date, and 1 colon
            int maxRequired = minRequired + 1;                                                                  // Optionally, 1 list separator

            if (_memory.Length - BytesPending < maxRequired)
            {
                Grow(maxRequired);
            }

            Span <byte> output = _memory.Span;

            if (_currentDepth < 0)
            {
                output[BytesPending++] = JsonConstants.ListSeparator;
            }
            output[BytesPending++] = JsonConstants.Quote;

            escapedPropertyName.CopyTo(output.Slice(BytesPending));
            BytesPending += escapedPropertyName.Length;

            output[BytesPending++] = JsonConstants.Quote;
            output[BytesPending++] = JsonConstants.KeyValueSeperator;

            output[BytesPending++] = JsonConstants.Quote;

            Span <byte> tempSpan = stackalloc byte[JsonConstants.MaximumFormatDateTimeOffsetLength];
            bool        result   = Utf8Formatter.TryFormat(value, tempSpan, out int bytesWritten, s_dateTimeStandardFormat);

            Debug.Assert(result);
            JsonWriterHelper.TrimDateTimeOffset(tempSpan.Slice(0, bytesWritten), out bytesWritten);
            tempSpan.Slice(0, bytesWritten).CopyTo(output.Slice(BytesPending));
            BytesPending += bytesWritten;

            output[BytesPending++] = JsonConstants.Quote;
        }
Ejemplo n.º 19
0
        private void WriteStringMinimized(ReadOnlySpan <char> escapedPropertyName, DateTimeOffset value)
        {
            Debug.Assert(escapedPropertyName.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - JsonConstants.MaximumFormatDateTimeOffsetLength - 6);

            // All ASCII, 2 quotes for property name, 2 quotes for date, and 1 colon => escapedPropertyName.Length + JsonConstants.MaximumFormatDateTimeOffsetLength + 5
            // Optionally, 1 list separator, and up to 3x growth when transcoding
            int maxRequired = (escapedPropertyName.Length * JsonConstants.MaxExpansionFactorWhileTranscoding) + JsonConstants.MaximumFormatDateTimeOffsetLength + 6;

            if (_memory.Length - BytesPending < maxRequired)
            {
                Grow(maxRequired);
            }

            Span <byte> output = _memory.Span;

            if (_currentDepth < 0)
            {
                output[BytesPending++] = JsonConstants.ListSeparator;
            }
            output[BytesPending++] = JsonConstants.Quote;

            TranscodeAndWrite(escapedPropertyName, output);

            output[BytesPending++] = JsonConstants.Quote;
            output[BytesPending++] = JsonConstants.KeyValueSeperator;

            output[BytesPending++] = JsonConstants.Quote;

            Span <byte> tempSpan = stackalloc byte[JsonConstants.MaximumFormatDateTimeOffsetLength];
            bool        result   = Utf8Formatter.TryFormat(value, tempSpan, out int bytesWritten, s_dateTimeStandardFormat);

            Debug.Assert(result);
            JsonWriterHelper.TrimDateTimeOffset(tempSpan.Slice(0, bytesWritten), out bytesWritten);
            tempSpan.Slice(0, bytesWritten).CopyTo(output.Slice(BytesPending));
            BytesPending += bytesWritten;

            output[BytesPending++] = JsonConstants.Quote;
        }
Ejemplo n.º 20
0
        private static void Utf8Parser_TryParseTimeSpan(ReadOnlySpan <byte> data)
        {
            Span <byte> to = stackalloc byte[1024];

            if (Utf8Parser.TryParse(data, out TimeSpan t1, out _))
            {
                var format = 'c';

                if (!Utf8Formatter.TryFormat(t1, to, out int written, format))
                {
                    throw new Exception();
                }

                if (!Utf8Parser.TryParse(to.Slice(0, written), out TimeSpan t2, out _, format))
                {
                    throw new Exception();
                }

                if (t1 != t2)
                {
                    throw new Exception();
                }
            }
        }
            public static void WriteDateTime(Utf8JsonWriter writer, DateTime value)
            {
                long unixTime = Convert.ToInt64((value.ToUniversalTime() - s_Epoch).TotalMilliseconds);

                int stackSize = 64;

                while (true)
                {
                    Span <byte> span = stackSize <= 1024 ? stackalloc byte[stackSize] : new byte[stackSize];

                    if (!Utf8Formatter.TryFormat(unixTime, span.Slice(7), out int bytesWritten, new StandardFormat('D')))
                    {
                        stackSize *= 2;
                        continue;
                    }

                    Start.CopyTo(span);
                    End.CopyTo(span.Slice(7 + bytesWritten));

                    writer.WriteStringValue(
                        CreateJsonEncodedTextFunc(span.Slice(0, 10 + bytesWritten).ToArray()));
                    break;
                }
            }
Ejemplo n.º 22
0
        private static object?To(Type type)
        {
            if (type == typeof(string))
            {
                return(_fromString ??
                       (_fromString = new[] { ValueBinder.Converter.Utf16Text((string value) => value.AsSpan()) }));
            }
            if (type == typeof(ReadOnlyMemory <char>))
            {
                return(_fromStringROMemory ??
                       (_fromStringROMemory = new[] { ValueBinder.Converter.Utf16Text((ReadOnlyMemory <char> value) => value.Span) }));
            }
            if (type == typeof(Memory <char>))
            {
                return(_fromStringMemory ??
                       (_fromStringMemory = new[] { ValueBinder.Converter.Utf16Text((Memory <char> value) => value.Span) }));
            }

            if (type == typeof(Guid))
            {
                return(_fromGuid ??
                       (_fromGuid = new[]
                {
                    ValueBinder.Converter.Utf8Text(
                        (Guid value, Span <byte> dest) => { if (!Utf8Formatter.TryFormat(value, dest, out _))
                                                            {
                                                                throw new FormatException();
                                                            }
                        },
                        _ => 36),
                }));
            }
            if (type == typeof(Guid?))
            {
                return(_fromGuidNull ??
                       (_fromGuidNull = new[]
Ejemplo n.º 23
0
        public void WriteValue(Decimal value)
        {
            WriteStarted(InternalState.Value);

            var span = m_output.GetSpan(Constants.MaxDecimalSize);

            if (!Utf8Formatter.TryFormat(value, span, out var bytesWritten))
            {
                ThrowFormatException(value);
            }

            // Do not serialize trailing zeroes. The current version of the Utf8Formatter we use
            // do not allow us to specify that we don't want any.
            if (span[bytesWritten - 1] == (Byte)'0')
            {
                // Find out if the decimal has a decimal point
                var pointIndex = span.Slice(0, bytesWritten).LastIndexOf((Byte)'.');

                if (pointIndex != -1)
                {
                    --bytesWritten;

                    while (span[bytesWritten - 1] == (Byte)'0')
                    {
                        --bytesWritten;
                    }

                    if (bytesWritten - 1 == pointIndex)
                    {
                        --bytesWritten;
                    }
                }
            }

            m_output.Advance(bytesWritten);
        }
Ejemplo n.º 24
0
        private static bool TryFormatUtf8(object value, Span <byte> buffer, out int bytesWritten, StandardFormat format = default)
        {
            Type t = value.GetType();

            if (t == typeof(bool))
            {
                return(Utf8Formatter.TryFormat((bool)value, buffer, out bytesWritten, format));
            }

            if (t == typeof(byte))
            {
                return(Utf8Formatter.TryFormat((byte)value, buffer, out bytesWritten, format));
            }

            if (t == typeof(sbyte))
            {
                return(Utf8Formatter.TryFormat((sbyte)value, buffer, out bytesWritten, format));
            }

            if (t == typeof(short))
            {
                return(Utf8Formatter.TryFormat((short)value, buffer, out bytesWritten, format));
            }

            if (t == typeof(ushort))
            {
                return(Utf8Formatter.TryFormat((ushort)value, buffer, out bytesWritten, format));
            }

            if (t == typeof(int))
            {
                return(Utf8Formatter.TryFormat((int)value, buffer, out bytesWritten, format));
            }

            if (t == typeof(uint))
            {
                return(Utf8Formatter.TryFormat((uint)value, buffer, out bytesWritten, format));
            }

            if (t == typeof(long))
            {
                return(Utf8Formatter.TryFormat((long)value, buffer, out bytesWritten, format));
            }

            if (t == typeof(ulong))
            {
                return(Utf8Formatter.TryFormat((ulong)value, buffer, out bytesWritten, format));
            }

            if (t == typeof(decimal))
            {
                return(Utf8Formatter.TryFormat((decimal)value, buffer, out bytesWritten, format));
            }

            if (t == typeof(double))
            {
                return(Utf8Formatter.TryFormat((double)value, buffer, out bytesWritten, format));
            }

            if (t == typeof(float))
            {
                return(Utf8Formatter.TryFormat((float)value, buffer, out bytesWritten, format));
            }

            if (t == typeof(Guid))
            {
                return(Utf8Formatter.TryFormat((Guid)value, buffer, out bytesWritten, format));
            }

            if (t == typeof(DateTime))
            {
                return(Utf8Formatter.TryFormat((DateTime)value, buffer, out bytesWritten, format));
            }

            if (t == typeof(DateTimeOffset))
            {
                return(Utf8Formatter.TryFormat((DateTimeOffset)value, buffer, out bytesWritten, format));
            }

            if (t == typeof(TimeSpan))
            {
                return(Utf8Formatter.TryFormat((TimeSpan)value, buffer, out bytesWritten, format));
            }

            throw new Exception("No formatter for type " + t);
        }
Ejemplo n.º 25
0
        // T-REC-X.680-201508 sec 46
        // T-REC-X.690-201508 sec 11.7
        private void WriteGeneralizedTimeCore(Asn1Tag tag, DateTimeOffset value, bool omitFractionalSeconds)
        {
            // GeneralizedTime under BER allows many different options:
            // * (HHmmss), (HHmm), (HH)
            // * "(value).frac", "(value),frac"
            // * frac == 0 may be omitted or emitted
            // non-UTC offset in various formats
            //
            // We're not allowing any of them.
            // Just encode as the CER/DER common restrictions.
            //
            // This results in the following formats:
            // yyyyMMddHHmmssZ
            // yyyyMMddHHmmss.f?Z
            //
            // where "f?" is anything from "f" to "fffffff" (tenth of a second down to 100ns/1-tick)
            // with no trailing zeros.
            DateTimeOffset normalized = value.ToUniversalTime();

            if (normalized.Year > 9999)
            {
                // This is unreachable since DateTimeOffset guards against this internally.
                throw new ArgumentOutOfRangeException(nameof(value));
            }

            // We're only loading in sub-second ticks.
            // Ticks are defined as 1e-7 seconds, so their printed form
            // is at the longest "0.1234567", or 9 bytes.
            Span <byte> fraction = stackalloc byte[0];

            if (!omitFractionalSeconds)
            {
                long floatingTicks = normalized.Ticks % TimeSpan.TicksPerSecond;

                if (floatingTicks != 0)
                {
                    // We're only loading in sub-second ticks.
                    // Ticks are defined as 1e-7 seconds, so their printed form
                    // is at the longest "0.1234567", or 9 bytes.
                    fraction = stackalloc byte[9];

                    decimal decimalTicks = floatingTicks;
                    decimalTicks /= TimeSpan.TicksPerSecond;

                    if (!Utf8Formatter.TryFormat(decimalTicks, fraction, out int bytesWritten, new StandardFormat('G')))
                    {
                        Debug.Fail($"Utf8Formatter.TryFormat could not format {floatingTicks} / TicksPerSecond");
                        throw new CryptographicException();
                    }

                    Debug.Assert(bytesWritten > 2, $"{bytesWritten} should be > 2");
                    Debug.Assert(fraction[0] == (byte)'0');
                    Debug.Assert(fraction[1] == (byte)'.');

                    fraction = fraction.Slice(1, bytesWritten - 1);
                }
            }

            // yyyy, MM, dd, hh, mm, ss
            const int IntegerPortionLength = 4 + 2 + 2 + 2 + 2 + 2;

            // Z, and the optional fraction.
            int totalLength = IntegerPortionLength + 1 + fraction.Length;

            // Because GeneralizedTime is IMPLICIT VisibleString it technically can have
            // a constructed form.
            // DER says character strings must be primitive.
            // CER says character strings <= 1000 encoded bytes must be primitive.
            // So we'll just make BER be primitive, too.
            Debug.Assert(!tag.IsConstructed);
            this.WriteTag(tag);
            this.WriteLength(totalLength);

            int year   = normalized.Year;
            int month  = normalized.Month;
            int day    = normalized.Day;
            int hour   = normalized.Hour;
            int minute = normalized.Minute;
            int second = normalized.Second;

            Span <byte>    baseSpan = this._buffer.AsSpan(this._offset);
            StandardFormat d4       = new StandardFormat('D', 4);
            StandardFormat d2       = new StandardFormat('D', 2);

            if (!Utf8Formatter.TryFormat(year, baseSpan.Slice(0, 4), out _, d4) ||
                !Utf8Formatter.TryFormat(month, baseSpan.Slice(4, 2), out _, d2) ||
                !Utf8Formatter.TryFormat(day, baseSpan.Slice(6, 2), out _, d2) ||
                !Utf8Formatter.TryFormat(hour, baseSpan.Slice(8, 2), out _, d2) ||
                !Utf8Formatter.TryFormat(minute, baseSpan.Slice(10, 2), out _, d2) ||
                !Utf8Formatter.TryFormat(second, baseSpan.Slice(12, 2), out _, d2))
            {
                Debug.Fail($"Utf8Formatter.TryFormat failed to build components of {normalized:O}");
                throw new CryptographicException();
            }

            this._offset += IntegerPortionLength;
            fraction.CopyTo(baseSpan.Slice(IntegerPortionLength));
            this._offset += fraction.Length;

            this._buffer[this._offset] = (byte)'Z';
            this._offset++;
        }
Ejemplo n.º 26
0
    public static bool TryWritePrimitives(Span <byte> output, Sha256 hash, string keyType, string verb, string resourceId, string resourceType, string tokenVersion, DateTime utc, out int bytesWritten)
    {
        int totalWritten = 0;

        bytesWritten = 0;

        Span <byte> buffer = stackalloc byte[AuthenticationHeaderBufferSize];

        s_type.CopyTo(buffer);
        totalWritten += s_type.Length;

        if (Encodings.Utf16.ToUtf8(keyType.AsReadOnlySpan().AsBytes(), buffer.Slice(totalWritten), out int consumed, out int written) != OperationStatus.Done)
        {
            throw new NotImplementedException("need to resize buffer");
        }
        totalWritten += written;

        s_ver.CopyTo(buffer.Slice(totalWritten));
        totalWritten += s_ver.Length;

        if (Encodings.Utf16.ToUtf8(tokenVersion.AsReadOnlySpan().AsBytes(), buffer.Slice(totalWritten), out consumed, out written) != OperationStatus.Done)
        {
            throw new NotImplementedException("need to resize buffer");
        }
        totalWritten += written;

        s_sig.CopyTo(buffer.Slice(totalWritten));
        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 (Encodings.Utf16.ToUtf8(verb.AsReadOnlySpan().AsBytes(), payload, out consumed, out written) != OperationStatus.Done)
            {
                throw new NotImplementedException("need to resize buffer");
            }
            if (Encodings.Ascii.ToLowerInPlace(payload.Slice(0, written), out written) != OperationStatus.Done)
            {
                throw new NotImplementedException("need to resize buffer");
            }

            payload[written] = (byte)'\n';
            totalWritten    += written + 1;
        }

        var bufferSlice = payload.Slice(totalWritten);

        if (Encodings.Utf16.ToUtf8(resourceType.AsReadOnlySpan().AsBytes(), bufferSlice, out consumed, out written) != OperationStatus.Done)
        {
            throw new NotImplementedException("need to resize buffer");
        }
        if (Encodings.Ascii.ToLowerInPlace(bufferSlice.Slice(0, written), out written) != OperationStatus.Done)
        {
            throw new NotImplementedException("need to resize buffer");
        }
        bufferSlice[written] = (byte)'\n';
        totalWritten        += written + 1;
        bufferSlice          = payload.Slice(totalWritten);

        if (Encodings.Utf16.ToUtf8(resourceId.AsReadOnlySpan().AsBytes(), bufferSlice, out consumed, out written) != OperationStatus.Done)
        {
            throw new NotImplementedException("need to resize buffer");
        }
        bufferSlice[written] = (byte)'\n';
        totalWritten        += written + 1;
        bufferSlice          = payload.Slice(totalWritten);

        if (!Utf8Formatter.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));
        if (!hash.TryWrite(buffer.Slice(front.Length), out written))
        {
            throw new NotImplementedException("need to resize buffer");
        }
        if (Base64.EncodeToUtf8InPlace(buffer.Slice(front.Length), written, out written) != OperationStatus.Done)
        {
            throw new NotImplementedException("need to resize buffer");
        }

        var len = front.Length + written;

        if (UrlEncoder.Utf8.Encode(buffer.Slice(0, len), output, out consumed, out bytesWritten) != OperationStatus.Done)
        {
            bytesWritten = 0;
            return(false);
        }
        return(true);
    }
        static object CreateFormatter(Type type)
        {
            if (type == typeof(System.Byte))
            {
                return(new TryFormat <System.Byte>((System.Byte x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)));
            }
            if (type == typeof(System.DateTime))
            {
                return(new TryFormat <System.DateTime>((System.DateTime x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)));
            }
            if (type == typeof(System.DateTimeOffset))
            {
                return(new TryFormat <System.DateTimeOffset>((System.DateTimeOffset x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)));
            }
            if (type == typeof(System.Decimal))
            {
                return(new TryFormat <System.Decimal>((System.Decimal x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)));
            }
            if (type == typeof(System.Double))
            {
                return(new TryFormat <System.Double>((System.Double x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)));
            }
            if (type == typeof(System.Int16))
            {
                return(new TryFormat <System.Int16>((System.Int16 x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)));
            }
            if (type == typeof(System.Int32))
            {
                return(new TryFormat <System.Int32>((System.Int32 x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)));
            }
            if (type == typeof(System.Int64))
            {
                return(new TryFormat <System.Int64>((System.Int64 x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)));
            }
            if (type == typeof(System.SByte))
            {
                return(new TryFormat <System.SByte>((System.SByte x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)));
            }
            if (type == typeof(System.Single))
            {
                return(new TryFormat <System.Single>((System.Single x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)));
            }
            if (type == typeof(System.TimeSpan))
            {
                return(new TryFormat <System.TimeSpan>((System.TimeSpan x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)));
            }
            if (type == typeof(System.UInt16))
            {
                return(new TryFormat <System.UInt16>((System.UInt16 x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)));
            }
            if (type == typeof(System.UInt32))
            {
                return(new TryFormat <System.UInt32>((System.UInt32 x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)));
            }
            if (type == typeof(System.UInt64))
            {
                return(new TryFormat <System.UInt64>((System.UInt64 x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)));
            }
            if (type == typeof(System.Guid))
            {
                return(new TryFormat <System.Guid>((System.Guid x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)));
            }
            if (type == typeof(System.Boolean))
            {
                return(new TryFormat <System.Boolean>((System.Boolean x, Span <byte> dest, out int written, StandardFormat format) => Utf8Formatter.TryFormat(x, dest, out written, format)));
            }
            if (type == typeof(System.Byte?))
            {
                return(CreateNullableFormatter <System.Byte>());
            }
            if (type == typeof(System.DateTime?))
            {
                return(CreateNullableFormatter <System.DateTime>());
            }
            if (type == typeof(System.DateTimeOffset?))
            {
                return(CreateNullableFormatter <System.DateTimeOffset>());
            }
            if (type == typeof(System.Decimal?))
            {
                return(CreateNullableFormatter <System.Decimal>());
            }
            if (type == typeof(System.Double?))
            {
                return(CreateNullableFormatter <System.Double>());
            }
            if (type == typeof(System.Int16?))
            {
                return(CreateNullableFormatter <System.Int16>());
            }
            if (type == typeof(System.Int32?))
            {
                return(CreateNullableFormatter <System.Int32>());
            }
            if (type == typeof(System.Int64?))
            {
                return(CreateNullableFormatter <System.Int64>());
            }
            if (type == typeof(System.SByte?))
            {
                return(CreateNullableFormatter <System.SByte>());
            }
            if (type == typeof(System.Single?))
            {
                return(CreateNullableFormatter <System.Single>());
            }
            if (type == typeof(System.TimeSpan?))
            {
                return(CreateNullableFormatter <System.TimeSpan>());
            }
            if (type == typeof(System.UInt16?))
            {
                return(CreateNullableFormatter <System.UInt16>());
            }
            if (type == typeof(System.UInt32?))
            {
                return(CreateNullableFormatter <System.UInt32>());
            }
            if (type == typeof(System.UInt64?))
            {
                return(CreateNullableFormatter <System.UInt64>());
            }
            if (type == typeof(System.Guid?))
            {
                return(CreateNullableFormatter <System.Guid>());
            }
            if (type == typeof(System.Boolean?))
            {
                return(CreateNullableFormatter <System.Boolean>());
            }
            if (type == typeof(System.IntPtr))
            {
                // ignore format
                return(new TryFormat <System.IntPtr>((System.IntPtr x, Span <byte> dest, out int written, StandardFormat _) => System.IntPtr.Size == 4
                    ? Utf8Formatter.TryFormat(x.ToInt32(), dest, out written, default)
                    : Utf8Formatter.TryFormat(x.ToInt64(), dest, out written, default)));
            }
            if (type == typeof(System.UIntPtr))
            {
                // ignore format
                return(new TryFormat <System.UIntPtr>((System.UIntPtr x, Span <byte> dest, out int written, StandardFormat _) => System.UIntPtr.Size == 4
                    ? Utf8Formatter.TryFormat(x.ToUInt32(), dest, out written, default)
                    : Utf8Formatter.TryFormat(x.ToUInt64(), dest, out written, default)));
            }

            return(null);
        }
Ejemplo n.º 28
0
        static async Task Main()
        {
            using var server = new EchoServer(Port);

            await Task.Yield();

            SocketConnection.AssertDependencies();



            Log("Connecting...");
            using var connection = await SocketConnection.ConnectAsync(new IPEndPoint (IPAddress.Loopback, Port));

            Log("Connected");

            Guid guid = Guid.NewGuid();

            Log($"Writing '{guid}'...");
            var output = connection.Output;
            var memory = output.GetMemory(30);

            if (!Utf8Formatter.TryFormat(guid, memory.Span, out var bytes))
            {
                throw new FormatException();
            }
            output.Advance(bytes);

            //Log($"Flushing...");
            //var flushResult = await output.FlushAsync();
            //Log($"IsCompleted:{flushResult.IsCompleted}, IsCanceled:{flushResult.IsCanceled}");

            //Log($"Reading...");
            //var input = connection.Input;
            //while (true)
            //{
            //    Log($"Reading...");
            //    var readResult = await input.ReadAsync();
            //    Log($"IsCompleted:{readResult.IsCompleted}, IsCanceled:{readResult.IsCanceled}, Length:{readResult.Buffer.Length}");
            //    if (readResult.IsCompleted || readResult.IsCanceled) break;

            //    if (readResult.Buffer.Length >= 36)
            //    {
            //        var buffer = readResult.Buffer;
            //        var len = checked((int)buffer.Length);
            //        var arr = ArrayPool<byte>.Shared.Rent(len);
            //        try
            //        {
            //            buffer.CopyTo(arr);
            //            var s = Encoding.UTF8.GetString(arr, 0, len);
            //            Log($"Received: '{s}'");
            //        }
            //        finally
            //        {
            //            ArrayPool<byte>.Shared.Return(arr);
            //        }
            //        input.AdvanceTo(readResult.Buffer.End);
            //        break;
            //    }
            //    else
            //    {
            //        input.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End);
            //    }
            //}


            //Log($"Closing output...");
            //output.Complete();
        }
Ejemplo n.º 29
0
        public static IMemoryOwner <byte> RentedSerialize(NatsMemoryPool pool, string subscriptionId, int?maxMessages)
        {
            var hint = _command.Length;

            hint += subscriptionId.Length;
            if (maxMessages != null)
            {
                if (maxMessages < 10)
                {
                    hint += 1;
                }
                else if (maxMessages < 100)
                {
                    hint += 2;
                }
                else if (maxMessages < 1_000)
                {
                    hint += 3;
                }
                else if (maxMessages < 10_000)
                {
                    hint += 4;
                }
                else if (maxMessages < 100_000)
                {
                    hint += 5;
                }
                else if (maxMessages < 1_000_000)
                {
                    hint += 6;
                }
                else if (maxMessages < 10_000_000)
                {
                    hint += 7;
                }
                else
                {
                    throw new ArgumentOutOfRangeException(nameof(maxMessages));
                }
                hint += _del.Length;
            }

            hint += _end.Length;

            var rented = pool.Rent(hint);
            var buffer = rented.Memory;

            _command.CopyTo(buffer);
            var consumed = _command.Length;

            consumed += Encoding.UTF8.GetBytes(subscriptionId, buffer.Slice(consumed).Span);
            if (maxMessages != null)
            {
                _del.CopyTo(buffer.Slice(consumed));
                consumed += _del.Length;
                Utf8Formatter.TryFormat(maxMessages.Value, buffer.Slice(consumed).Span, out var written);
                consumed += written;
            }

            _end.CopyTo(buffer.Slice(consumed));
            return(rented);
        }
Ejemplo n.º 30
0
        static bool TryWritePrimitive(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 (Encodings.Utf16.ToUtf8(MemoryMarshal.AsBytes(verb.AsSpan()), output, out consumed, out written) != OperationStatus.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 (!Utf8Formatter.TryFormat(utc, free, out written, 'R'))
            {
                bytesWritten = 0;
                return(false);
            }
            free[written] = (byte)'\n';
            bytesWritten += written + 1;
            free          = output.Slice(bytesWritten);

            if (Encodings.Utf16.ToUtf8(MemoryMarshal.AsBytes(canonicalizedResource.AsSpan()), free, out consumed, out written) != OperationStatus.Done)
            {
                bytesWritten = 0;
                return(false);
            }
            bytesWritten += written;

            var formatted = output.Slice(0, bytesWritten);

            hash.Append(formatted);
            if (!hash.TryWrite(output, out written))
            {
                throw new NotImplementedException("need to resize buffer");
            }

            if (Base64.EncodeToUtf8InPlace(output, written, out written) != OperationStatus.Done)
            {
                bytesWritten = 0;
                return(false);
            }

            bytesWritten = written;
            return(true);
        }