Example #1
0
            /// <summary>
            /// Gets next JSON token from the JsonReader as a raw series of bytes that is buffered.
            /// </summary>
            /// <returns>The next JSON token from the JsonReader as a raw series of bytes that is buffered.</returns>
            public override ReadOnlyMemory <byte> GetBufferedRawJsonToken()
            {
                if (!JsonBinaryEncoding.TryGetValueLength(
                        this.jsonBinaryBuffer.GetBufferedRawJsonToken(this.currentTokenPosition).Span,
                        out int length))
                {
                    throw new InvalidOperationException();
                }

                return(this.jsonBinaryBuffer.GetBufferedRawJsonToken(this.currentTokenPosition, this.currentTokenPosition + length));
            }
            /// <inheritdoc />
            public override bool TryGetBufferedRawJsonToken(out ReadOnlyMemory<byte> bufferedRawJsonToken)
            {
                if (!JsonBinaryEncoding.TryGetValueLength(
                    this.jsonBinaryBuffer.GetBufferedRawJsonToken(this.currentTokenPosition).Span,
                    out int length))
                {
                    throw new InvalidOperationException();
                }

                ReadOnlyMemory<byte> candidate = this.jsonBinaryBuffer.GetBufferedRawJsonToken(
                    this.currentTokenPosition,
                    this.currentTokenPosition + length);

                if ((this.jsonStringDictionary != null) && JsonBinaryReader.IsStringOrNested(this.CurrentTokenType))
                {
                    // If there is dictionary encoding, then we need to force a rewrite.
                    bufferedRawJsonToken = default;
                    return false;
                }

                bufferedRawJsonToken = candidate;
                return true;
            }
            /// <inheritdoc />
            public override bool Read()
            {
                JsonTokenType jsonTokenType;
                int nextTokenOffset;
                // First check if we just finished an array or object context
                if (!this.arrayAndObjectEndStack.Empty() && (this.arrayAndObjectEndStack.Peek() == this.jsonBinaryBuffer.Position))
                {
                    if (this.JsonObjectState.InArrayContext)
                    {
                        jsonTokenType = JsonTokenType.EndArray;
                    }
                    else if (this.JsonObjectState.InObjectContext)
                    {
                        jsonTokenType = JsonTokenType.EndObject;
                    }
                    else
                    {
                        throw new JsonInvalidTokenException();
                    }

                    nextTokenOffset = 0;
                    this.arrayAndObjectEndStack.Pop();
                }
                else
                {
                    // We are not at the end of a context.
                    if (this.jsonBinaryBuffer.IsEof)
                    {
                        // Need to check if we are still inside of an object or array
                        if (this.JsonObjectState.CurrentDepth != 0)
                        {
                            if (this.JsonObjectState.InObjectContext)
                            {
                                throw new JsonMissingEndObjectException();
                            }
                            else if (this.JsonObjectState.InArrayContext)
                            {
                                throw new JsonMissingEndArrayException();
                            }
                            else
                            {
                                throw new InvalidOperationException("Expected to be in either array or object context");
                            }
                        }

                        return false;
                    }

                    if ((this.JsonObjectState.CurrentDepth == 0) && (this.CurrentTokenType != JsonTokenType.NotStarted))
                    {
                        // There are trailing characters outside of the outter most object or array
                        throw new JsonUnexpectedTokenException();
                    }

                    byte firstByte = this.jsonBinaryBuffer.Peek();
                    jsonTokenType = JsonBinaryReader.GetJsonTokenType(firstByte);
                    if ((jsonTokenType == JsonTokenType.String) && this.JsonObjectState.IsPropertyExpected)
                    {
                        jsonTokenType = JsonTokenType.FieldName;
                    }

                    // If this is begin array/object token then we need to identify where array/object end token is.
                    // Also the next token offset is just the array type marker + length prefix + count prefix
                    if ((jsonTokenType == JsonTokenType.BeginArray) || (jsonTokenType == JsonTokenType.BeginObject))
                    {
                        if (!JsonBinaryEncoding.TryGetValueLength(
                            this.jsonBinaryBuffer.GetBufferedRawJsonToken().Span,
                            out int arrayOrObjectLength))
                        {
                            throw new JsonUnexpectedTokenException();
                        }

                        this.arrayAndObjectEndStack.Push(this.jsonBinaryBuffer.Position + arrayOrObjectLength);
                        nextTokenOffset = JsonBinaryReader.GetArrayOrObjectPrefixLength(firstByte);
                    }
                    else
                    {
                        if (!JsonBinaryEncoding.TryGetValueLength(
                            this.jsonBinaryBuffer.GetBufferedRawJsonToken().Span,
                            out nextTokenOffset))
                        {
                            throw new JsonUnexpectedTokenException();
                        }
                    }
                }

                this.JsonObjectState.RegisterToken(jsonTokenType);
                this.currentTokenPosition = this.jsonBinaryBuffer.Position;
                this.jsonBinaryBuffer.SkipBytes(nextTokenOffset);
                return true;
            }