예제 #1
0
        private void WriteValueUtf8(ReadOnlySpan <byte> valueSpanByte, int bytesNeeded)
        {
            Span <byte> byteBuffer = EnsureBuffer(bytesNeeded);
            int         idx        = 0;

            if (!_firstItem)
            {
                byteBuffer[idx++] = JsonConstants.ListSeperator;
            }

            if (_prettyPrint)
            {
                idx += AddNewLineAndIndentation(byteBuffer.Slice(idx));
            }

            byteBuffer[idx++] = JsonConstants.Quote;


            OperationStatus status = Encodings.Utf16.ToUtf8(valueSpanByte, byteBuffer.Slice(idx), out int consumed, out int written);

            Debug.Assert(consumed == valueSpanByte.Length);
            if (status != OperationStatus.Done)
            {
                JsonThrowHelper.ThrowFormatException();
            }

            idx += written;

            byteBuffer[idx++] = JsonConstants.Quote;

            _bufferWriter.Advance(idx);
            _firstItem = false;
        }
예제 #2
0
        private void WriteValueUtf8(ReadOnlySpan <byte> valueSpanByte, int bytesNeeded)
        {
            Span <byte> byteBuffer = EnsureBuffer(bytesNeeded);
            int         idx        = 0;

            if (_indent < 0)
            {
                byteBuffer[idx++] = JsonConstants.ListSeperator;
            }

            byteBuffer[idx++] = JsonConstants.Quote;

            OperationStatus status = Encodings.Utf16.ToUtf8(valueSpanByte, byteBuffer.Slice(idx), out int consumed, out int written);

            if (status != OperationStatus.Done)
            {
                JsonThrowHelper.ThrowFormatException();
            }
            Debug.Assert(consumed == valueSpanByte.Length);

            idx += written;

            byteBuffer[idx++] = JsonConstants.Quote;

            _bufferWriter.Advance(idx);
            _indent |= 1 << 31;
        }
예제 #3
0
        private bool TryWriteAttributeUtf8(ReadOnlySpan <byte> nameSpanByte, ReadOnlySpan <byte> valueSpanByte)
        {
            int idx = 0;

            try
            {
                Span <byte> byteBuffer = _bufferWriter.Buffer;

                if (_indent < 0)
                {
                    byteBuffer[idx++] = JsonConstants.ListSeperator;
                }

                byteBuffer[idx++] = JsonConstants.Quote;

                OperationStatus status = Encodings.Utf16.ToUtf8(nameSpanByte, byteBuffer.Slice(idx), out int consumed, out int written);
                if (status == OperationStatus.DestinationTooSmall)
                {
                    return(false);
                }
                if (status != OperationStatus.Done)
                {
                    JsonThrowHelper.ThrowFormatException();
                }
                Debug.Assert(consumed == nameSpanByte.Length);
                idx += written;

                byteBuffer[idx++] = JsonConstants.Quote;

                byteBuffer[idx++] = JsonConstants.KeyValueSeperator;

                byteBuffer[idx++] = JsonConstants.Quote;

                status = Encodings.Utf16.ToUtf8(valueSpanByte, byteBuffer.Slice(idx), out consumed, out written);
                if (status == OperationStatus.DestinationTooSmall)
                {
                    return(false);
                }
                if (status != OperationStatus.Done)
                {
                    JsonThrowHelper.ThrowFormatException();
                }
                Debug.Assert(consumed == valueSpanByte.Length);
                idx += written;

                byteBuffer[idx++] = JsonConstants.Quote;
            }
            catch (IndexOutOfRangeException)
            {
                return(false);
            }

            _bufferWriter.Advance(idx);
            _indent |= 1 << 31;
            return(true);
        }
예제 #4
0
        private bool TryWriteAttributeUtf8(ReadOnlySpan <byte> nameSpanByte, long value)
        {
            int idx = 0;

            try
            {
                Span <byte> byteBuffer = _bufferWriter.Buffer;

                if (_indent < 0)
                {
                    byteBuffer[idx++] = JsonConstants.ListSeperator;
                }

                byteBuffer[idx++] = JsonConstants.Quote;

                OperationStatus status = Encodings.Utf16.ToUtf8(nameSpanByte, byteBuffer.Slice(idx), out int consumed, out int written);
                if (status == OperationStatus.DestinationTooSmall)
                {
                    return(false);
                }
                if (status != OperationStatus.Done)
                {
                    JsonThrowHelper.ThrowFormatException();
                }
                Debug.Assert(consumed == nameSpanByte.Length);
                idx += written;

                byteBuffer[idx++] = JsonConstants.Quote;

                byteBuffer[idx++] = JsonConstants.KeyValueSeperator;

                if (!JsonWriterHelper.TryFormatInt64Default(value, byteBuffer.Slice(idx), out int bytesWritten))
                {
                    return(false);
                }
                // Using Utf8Formatter with default StandardFormat is roughly 30% slower (17 ns versus 12 ns)
                // See: https://github.com/dotnet/corefx/issues/25425
                //if (!Utf8Formatter.TryFormat(value, byteBuffer.Slice(idx), out int bytesWritten)) return false;
                idx += bytesWritten;
            }
            catch (IndexOutOfRangeException)
            {
                return(false);
            }

            _bufferWriter.Advance(idx);
            _indent |= 1 << 31;
            return(true);
        }
예제 #5
0
        private void WriteStartUtf8Pretty(ReadOnlySpan <byte> nameSpanByte, int bytesNeeded, byte token)
        {
            int         indent     = _indent & RemoveFlagsBitMask;
            Span <byte> byteBuffer = EnsureBuffer(bytesNeeded);
            int         idx        = 0;

            if (_indent < 0)
            {
                byteBuffer[idx++] = JsonConstants.ListSeperator;
            }

            // \r\n versus \n, depending on OS
            if (JsonWriterHelper.NewLineUtf8.Length == 2)
            {
                byteBuffer[idx++] = JsonConstants.CarriageReturn;
            }

            byteBuffer[idx++] = JsonConstants.LineFeed;

            while (indent-- > 0)
            {
                byteBuffer[idx++] = JsonConstants.Space;
                byteBuffer[idx++] = JsonConstants.Space;
            }

            byteBuffer[idx++] = JsonConstants.Quote;

            OperationStatus status = Encodings.Utf16.ToUtf8(nameSpanByte, byteBuffer.Slice(idx), out int consumed, out int written);

            Debug.Assert(consumed == nameSpanByte.Length);
            if (status != OperationStatus.Done)
            {
                JsonThrowHelper.ThrowFormatException();
            }

            idx += written;

            byteBuffer[idx++] = JsonConstants.Quote;

            byteBuffer[idx++] = JsonConstants.KeyValueSeperator;

            byteBuffer[idx++] = JsonConstants.Space;

            byteBuffer[idx++] = token;

            _bufferWriter.Advance(idx);
        }
예제 #6
0
        private void WriteAttributeUtf8Pretty(ReadOnlySpan <byte> nameSpan, long value)
        {
            // quote {name} quote colon, hence 3
            int bytesNeeded = 3;

            if (_indent < 0)
            {
                bytesNeeded++;
            }

            if (Encodings.Utf16.ToUtf8Length(nameSpan, out int bytesNeededName) != OperationStatus.Done)
            {
                JsonThrowHelper.ThrowArgumentExceptionInvalidUtf8String();
            }
            bytesNeeded += bytesNeededName;

            // For the new line, \r\n or \n, and the space after the colon
            bytesNeeded += JsonWriterHelper.NewLineUtf8.Length + 1 + (_indent & RemoveFlagsBitMask) * 2;

            bool insertNegationSign = false;

            if (value < 0)
            {
                insertNegationSign = true;
                value        = -value;
                bytesNeeded += 1;
            }

            int digitCount = JsonWriterHelper.CountDigits((ulong)value);

            bytesNeeded += digitCount;
            Span <byte> byteBuffer = EnsureBuffer(bytesNeeded);

            int idx = 0;

            if (_indent < 0)
            {
                byteBuffer[idx++] = JsonConstants.ListSeperator;
            }

            idx += AddNewLineAndIndentation(byteBuffer.Slice(idx));

            byteBuffer[idx++] = JsonConstants.Quote;

            OperationStatus status = Encodings.Utf16.ToUtf8(nameSpan, byteBuffer.Slice(idx), out int consumed, out int written);

            if (status != OperationStatus.Done)
            {
                JsonThrowHelper.ThrowFormatException();
            }
            Debug.Assert(consumed == nameSpan.Length);
            idx += written;

            byteBuffer[idx++] = JsonConstants.Quote;

            byteBuffer[idx++] = JsonConstants.KeyValueSeperator;

            byteBuffer[idx++] = JsonConstants.Space;

            _indent |= 1 << 31;

            if (insertNegationSign)
            {
                byteBuffer[idx++] = (byte)'-';
            }

            JsonWriterHelper.WriteDigitsUInt64D((ulong)value, byteBuffer.Slice(idx, digitCount));

            _bufferWriter.Advance(bytesNeeded);
        }
예제 #7
0
        private void WriteStartUtf8Pretty(ReadOnlySpan <byte> nameSpanByte, byte token)
        {
            // quote {name} quote colon open-brace, hence 4
            int bytesNeeded = 4;

            if (_indent < 0)
            {
                bytesNeeded++;
            }

            if (Encodings.Utf16.ToUtf8Length(nameSpanByte, out int bytesNeededValue) != OperationStatus.Done)
            {
                JsonThrowHelper.ThrowArgumentExceptionInvalidUtf8String();
            }
            bytesNeeded += bytesNeededValue;

            int indent = _indent & RemoveFlagsBitMask;

            // For the new line, \r\n or \n, and the space after the colon
            bytesNeeded += JsonWriterHelper.NewLineUtf8.Length + 1 + indent * 2;

            Span <byte> byteBuffer = EnsureBuffer(bytesNeeded);
            int         idx        = 0;

            if (_indent < 0)
            {
                byteBuffer[idx++] = JsonConstants.ListSeperator;
            }

            // \r\n versus \n, depending on OS
            if (JsonWriterHelper.NewLineUtf8.Length == 2)
            {
                byteBuffer[idx++] = JsonConstants.CarriageReturn;
            }

            byteBuffer[idx++] = JsonConstants.LineFeed;

            while (indent-- > 0)
            {
                byteBuffer[idx++] = JsonConstants.Space;
                byteBuffer[idx++] = JsonConstants.Space;
            }

            byteBuffer[idx++] = JsonConstants.Quote;

            OperationStatus status = Encodings.Utf16.ToUtf8(nameSpanByte, byteBuffer.Slice(idx), out int consumed, out int written);

            Debug.Assert(consumed == nameSpanByte.Length);
            if (status != OperationStatus.Done)
            {
                JsonThrowHelper.ThrowFormatException();
            }

            idx += written;

            byteBuffer[idx++] = JsonConstants.Quote;

            byteBuffer[idx++] = JsonConstants.KeyValueSeperator;

            byteBuffer[idx++] = JsonConstants.Space;

            byteBuffer[idx++] = token;

            _bufferWriter.Advance(idx);
        }