コード例 #1
0
        /// <summary>
        /// Reads the next JSON token value from the source transcoded as a <see cref="string"/>.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// Thrown if trying to get the value of the JSON token that is not a string
        /// (i.e. other than <see cref="JsonTokenType.String"/> or <see cref="JsonTokenType.PropertyName"/>).
        /// <seealso cref="TokenType" />
        /// </exception>
        /// <exception cref="ArgumentException">
        /// Thrown if invalid UTF-8 byte sequences are detected while transcoding.
        /// </exception>
        public string GetStringValue()
        {
            if (TokenType != JsonTokenType.String && TokenType != JsonTokenType.PropertyName)
            {
                throw ThrowHelper.GetInvalidOperationException_ExpectedString(TokenType);
            }

            ReadOnlySpan <byte> span = HasValueSequence ? ValueSequence.ToArray() : ValueSpan;

#if BUILDING_INBOX_LIBRARY
            // TODO: https://github.com/dotnet/corefx/issues/33292
            return(s_utf8Encoding.GetString(span));
#else
            if (span.IsEmpty)
            {
                return(string.Empty);
            }
            unsafe
            {
                fixed(byte *bytePtr = span)
                {
                    // TODO: https://github.com/dotnet/corefx/issues/33292
                    return(s_utf8Encoding.GetString(bytePtr, span.Length));
                }
            }
#endif
        }
コード例 #2
0
        /// <summary>
        /// Parses the current JSON token value from the source as a <see cref="Guid"/>.
        /// Returns <see langword="true"/> if the entire UTF-8 encoded token value can be successfully
        /// parsed to a <see cref="Guid"/> value. Only supports <see cref="Guid"/> values with hyphens
        /// and without any surrounding decorations.
        /// Returns <see langword="false"/> otherwise.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// Thrown if trying to get the value of a JSON token that is not a <see cref="JsonTokenType.String"/>.
        /// <seealso cref="TokenType" />
        /// </exception>
        public bool TryGetGuid(out Guid value)
        {
            if (TokenType != JsonTokenType.String)
            {
                throw ThrowHelper.GetInvalidOperationException_ExpectedString(TokenType);
            }

            return(TryGetGuidCore(out value));
        }
コード例 #3
0
        /// <summary>
        /// Parses the current JSON token value from the source as a <see cref="DateTimeOffset"/>.
        /// Returns <see langword="true"/> if the entire UTF-8 encoded token value can be successfully
        /// parsed to a <see cref="DateTimeOffset"/> value.
        /// Returns <see langword="false"/> otherwise.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// Thrown if trying to get the value of a JSON token that is not a <see cref="JsonTokenType.String"/>.
        /// <seealso cref="TokenType" />
        /// </exception>
        public bool TryGetDateTimeOffset(out DateTimeOffset value)
        {
            if (TokenType != JsonTokenType.String)
            {
                throw ThrowHelper.GetInvalidOperationException_ExpectedString(TokenType);
            }

            return(TryGetDateTimeOffsetCore(out value));
        }
コード例 #4
0
        /// <summary>
        /// Reads the next JSON token value from the source transcoded as a <see cref="string"/>.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// Thrown if trying to get the value of the JSON token that is not a string
        /// (i.e. other than <see cref="JsonTokenType.String"/> or <see cref="JsonTokenType.PropertyName"/>).
        /// <seealso cref="TokenType" />
        /// </exception>
        /// <exception cref="ArgumentException">
        /// Thrown if invalid UTF-8 byte sequences are detected while transcoding.
        /// </exception>
        public string GetStringValue()
        {
            if (TokenType != JsonTokenType.String && TokenType != JsonTokenType.PropertyName)
            {
                throw ThrowHelper.GetInvalidOperationException_ExpectedString(TokenType);
            }

            // TODO: https://github.com/dotnet/corefx/issues/33292
            return(s_utf8Encoding.GetString(ValueSpan));
        }
コード例 #5
0
        /// <summary>
        /// Parses the current JSON token value from the source as a <see cref="DateTimeOffset"/>.
        /// Returns <see langword="true"/> if the entire UTF-8 encoded token value can be successfully
        /// parsed to a <see cref="DateTimeOffset"/> value.
        /// Returns <see langword="false"/> otherwise.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// Thrown if trying to get the value of a JSON token that is not a <see cref="JsonTokenType.String"/>.
        /// <seealso cref="TokenType" />
        /// </exception>
        public bool TryGetDateTimeOffset(out DateTimeOffset value)
        {
            if (TokenType != JsonTokenType.String)
            {
                throw ThrowHelper.GetInvalidOperationException_ExpectedString(TokenType);
            }

            ReadOnlySpan <byte> span = stackalloc byte[0];

            if (HasValueSequence)
            {
                long sequenceLength = ValueSequence.Length;

                if (!JsonReaderHelper.IsValidDateTimeOffsetParseLength(sequenceLength))
                {
                    value = default;
                    return(false);
                }

                Debug.Assert(sequenceLength <= JsonConstants.MaximumEscapedDateTimeOffsetParseLength);
                Span <byte> stackSpan = stackalloc byte[(int)sequenceLength];

                ValueSequence.CopyTo(stackSpan);
                span = stackSpan;
            }
            else
            {
                if (!JsonReaderHelper.IsValidDateTimeOffsetParseLength(ValueSpan.Length))
                {
                    value = default;
                    return(false);
                }

                span = ValueSpan;
            }

            if (_stringHasEscaping)
            {
                return(JsonReaderHelper.TryGetEscapedDateTimeOffset(span, out value));
            }

            Debug.Assert(span.IndexOf(JsonConstants.BackSlash) == -1);

            if (span.Length <= JsonConstants.MaximumDateTimeOffsetParseLength &&
                JsonHelpers.TryParseAsISO(span, out DateTimeOffset tmp, out int bytesConsumed) &&
                span.Length == bytesConsumed)
            {
                value = tmp;
                return(true);
            }

            value = default;
            return(false);
        }
コード例 #6
0
        /// <summary>
        /// Reads the next JSON token value from the source and parses it to a <see cref="DateTimeOffset"/>.
        /// Returns true if the entire UTF-8 encoded token value can be successfully
        /// parsed to a <see cref="DateTimeOffset"/> value.
        /// Returns false otherwise.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// Thrown if trying to get the value of a JSON token that is not a <see cref="JsonTokenType.String"/>.
        /// <seealso cref="TokenType" />
        /// </exception>
        public bool TryGetDateTimeOffset(out DateTimeOffset value)
        {
            if (TokenType != JsonTokenType.String)
            {
                throw ThrowHelper.GetInvalidOperationException_ExpectedString(TokenType);
            }

            ReadOnlySpan <byte> span = HasValueSequence ? ValueSequence.ToArray() : ValueSpan;

            return(JsonHelpers.TryParseAsISO(span, out value, out int bytesConsumed) && span.Length == bytesConsumed);
        }
コード例 #7
0
        /// <summary>
        /// Reads the next JSON token value from the source transcoded as a <see cref="string"/>.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// Thrown if trying to get the value of the JSON token that is not a string
        /// (i.e. other than <see cref="JsonTokenType.String"/> or <see cref="JsonTokenType.PropertyName"/>).
        /// <seealso cref="TokenType" />
        /// </exception>
        /// <exception cref="ArgumentException">
        /// Thrown if invalid UTF-8 byte sequences are detected while transcoding.
        /// </exception>
        public string GetStringValue()
        {
            if (TokenType != JsonTokenType.String && TokenType != JsonTokenType.PropertyName)
            {
                throw ThrowHelper.GetInvalidOperationException_ExpectedString(TokenType);
            }

            ReadOnlySpan <byte> span = HasValueSequence ? ValueSequence.ToArray() : ValueSpan;

            // TODO: https://github.com/dotnet/corefx/issues/33292
            return(s_utf8Encoding.GetString(span));
        }
コード例 #8
0
        /// <summary>
        /// Parses the current JSON token value from the source as a <see cref="Guid"/>.
        /// Returns <see langword="true"/> if the entire UTF-8 encoded token value can be successfully
        /// parsed to a <see cref="Guid"/> value. Only supports <see cref="Guid"/> values with hyphens
        /// and without any surrounding decorations.
        /// Returns <see langword="false"/> otherwise.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// Thrown if trying to get the value of a JSON token that is not a <see cref="JsonTokenType.String"/>.
        /// <seealso cref="TokenType" />
        /// </exception>
        public bool TryGetGuid(out Guid value)
        {
            if (TokenType != JsonTokenType.String)
            {
                throw ThrowHelper.GetInvalidOperationException_ExpectedString(TokenType);
            }

            ReadOnlySpan <byte> span = stackalloc byte[0];

            if (HasValueSequence)
            {
                long sequenceLength = ValueSequence.Length;
                if (sequenceLength > JsonConstants.MaximumEscapedGuidLength)
                {
                    value = default;
                    return(false);
                }

                Debug.Assert(sequenceLength <= JsonConstants.MaximumEscapedGuidLength);
                Span <byte> stackSpan = stackalloc byte[(int)sequenceLength];

                ValueSequence.CopyTo(stackSpan);
                span = stackSpan;
            }
            else
            {
                if (ValueSpan.Length > JsonConstants.MaximumEscapedGuidLength)
                {
                    value = default;
                    return(false);
                }

                span = ValueSpan;
            }

            if (_stringHasEscaping)
            {
                return(JsonReaderHelper.TryGetEscapedGuid(span, out value));
            }

            Debug.Assert(span.IndexOf(JsonConstants.BackSlash) == -1);

            if (span.Length == JsonConstants.MaximumFormatGuidLength &&
                Utf8Parser.TryParse(span, out Guid tmp, out _, 'D'))
            {
                value = tmp;
                return(true);
            }

            value = default;
            return(false);
        }
コード例 #9
0
        /// <summary>
        /// Reads the next JSON token value from the source and parses it to a <see cref="Guid"/>.
        /// Returns <see langword="true"/> if the entire UTF-8 encoded token value can be successfully
        /// parsed to a <see cref="Guid"/> value. Only supports <see cref="Guid"/> values with hyphens
        /// and without any surrounding decorations.
        /// Returns <see langword="false"/> otherwise.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// Thrown if trying to get the value of a JSON token that is not a <see cref="JsonTokenType.String"/>.
        /// <seealso cref="TokenType" />
        /// </exception>
        public bool TryGetGuid(out Guid value)
        {
            if (TokenType != JsonTokenType.String)
            {
                throw ThrowHelper.GetInvalidOperationException_ExpectedString(TokenType);
            }

            ReadOnlySpan <byte> span = ValueSpan;
            Span <byte>         stackSpan;

            if (HasValueSequence)
            {
                long sequenceLength = ValueSequence.Length;
                if (sequenceLength > JsonConstants.MaximumEscapedGuidLength)
                {
                    value = default;
                    return(false);
                }

                // Cannot create a span directly since it gets passed to instance methods on a ref struct.
                unsafe
                {
                    byte *ptr = stackalloc byte[(int)sequenceLength];
                    stackSpan = new Span <byte>(ptr, (int)sequenceLength);
                }
                ValueSequence.CopyTo(stackSpan);
                span = stackSpan;
            }

            if (span.Length > JsonConstants.MaximumEscapedGuidLength)
            {
                value = default;
                return(false);
            }

            if (_stringHasEscaping)
            {
                return(JsonReaderHelper.TryGetEscapedGuid(span, out value));
            }

            Debug.Assert(span.IndexOf(JsonConstants.BackSlash) == -1);

            if (span.Length != JsonConstants.MaximumFormatGuidLength)
            {
                value = default;
                return(false);
            }

            return(Utf8Parser.TryParse(span, out value, out int bytesConsumed) && span.Length == bytesConsumed);
        }
コード例 #10
0
        /// <summary>
        /// Parses the current JSON token value from the source and decodes the Base64 encoded JSON string as bytes.
        /// Returns <see langword="true"/> if the entire token value is encoded as valid Base64 text and can be successfully
        /// decoded to bytes.
        /// Returns <see langword="false"/> otherwise.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// Thrown if trying to get the value of a JSON token that is not a <see cref="JsonTokenType.String"/>.
        /// <seealso cref="TokenType" />
        /// </exception>
        public bool TryGetBytesFromBase64(out byte[] value)
        {
            if (TokenType != JsonTokenType.String)
            {
                throw ThrowHelper.GetInvalidOperationException_ExpectedString(TokenType);
            }

            ReadOnlySpan <byte> span = HasValueSequence ? ValueSequence.ToArray() : ValueSpan;

            if (_stringHasEscaping)
            {
                int idx = span.IndexOf(JsonConstants.BackSlash);
                Debug.Assert(idx != -1);
                return(JsonReaderHelper.TryGetUnescapedBase64Bytes(span, idx, out value));
            }

            Debug.Assert(span.IndexOf(JsonConstants.BackSlash) == -1);
            return(JsonReaderHelper.TryDecodeBase64(span, out value));
        }
コード例 #11
0
        /// <summary>
        /// Parses the current JSON token value from the source, unescaped, and transcoded as a <see cref="string"/>.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// Thrown if trying to get the value of the JSON token that is not a string
        /// (i.e. other than <see cref="JsonTokenType.String"/> or <see cref="JsonTokenType.PropertyName"/>).
        /// <seealso cref="TokenType" />
        /// It will also throw when the JSON string contains invalid UTF-8 bytes, or invalid UTF-16 surrogates.
        /// </exception>
        public string GetString()
        {
            if (TokenType != JsonTokenType.String && TokenType != JsonTokenType.PropertyName)
            {
                throw ThrowHelper.GetInvalidOperationException_ExpectedString(TokenType);
            }

            ReadOnlySpan <byte> span = HasValueSequence ? ValueSequence.ToArray() : ValueSpan;

            if (_stringHasEscaping)
            {
                int idx = span.IndexOf(JsonConstants.BackSlash);
                Debug.Assert(idx != -1);
                return(JsonReaderHelper.GetUnescapedString(span, idx));
            }

            Debug.Assert(span.IndexOf(JsonConstants.BackSlash) == -1);
            return(JsonReaderHelper.TranscodeHelper(span));
        }