private bool ReadReference() { switch (CurrentState) { case State.ObjectStart: { SetToken(JsonToken.PropertyName, "$ref"); _bsonReaderState = BsonReaderState.ReferenceRef; return(true); } case State.Property: { if (_bsonReaderState == BsonReaderState.ReferenceRef) { SetToken(JsonToken.String, ReadLengthString()); return(true); } else if (_bsonReaderState == BsonReaderState.ReferenceId) { SetToken(JsonToken.Bytes, ReadBytes(12)); return(true); } else { throw ExceptionUtils.CreateJsonReaderException(this, "Unexpected state when reading BSON reference: " + _bsonReaderState); } } case State.PostValue: { if (_bsonReaderState == BsonReaderState.ReferenceRef) { SetToken(JsonToken.PropertyName, "$id"); _bsonReaderState = BsonReaderState.ReferenceId; return(true); } else if (_bsonReaderState == BsonReaderState.ReferenceId) { SetToken(JsonToken.EndObject); _bsonReaderState = BsonReaderState.Normal; return(true); } else { throw ExceptionUtils.CreateJsonReaderException(this, "Unexpected state when reading BSON reference: " + _bsonReaderState); } } default: throw ExceptionUtils.CreateJsonReaderException(this, "Unexpected state when reading BSON reference: " + CurrentState); } }
/// <summary> /// Reads the next JSON token from the underlying <see cref="Stream"/>. /// </summary> /// <returns> /// <c>true</c> if the next token was read successfully; <c>false</c> if there are no more tokens to read. /// </returns> public override bool Read() { try { bool success; switch (_bsonReaderState) { case BsonReaderState.Normal: success = ReadNormal(); break; case BsonReaderState.ReferenceStart: case BsonReaderState.ReferenceRef: case BsonReaderState.ReferenceId: success = ReadReference(); break; case BsonReaderState.CodeWScopeStart: case BsonReaderState.CodeWScopeCode: case BsonReaderState.CodeWScopeScope: case BsonReaderState.CodeWScopeScopeObject: case BsonReaderState.CodeWScopeScopeEnd: success = ReadCodeWScope(); break; default: throw ExceptionUtils.CreateJsonReaderException(this, "Unexpected state: {0}".FormatWith(CultureInfo.InvariantCulture, _bsonReaderState)); } if (!success) { SetToken(JsonToken.None); return(false); } return(true); } catch (EndOfStreamException) { SetToken(JsonToken.None); return(false); } }
private bool ReadNormal() { switch (CurrentState) { case State.Start: { JsonToken token = (!_readRootValueAsArray) ? JsonToken.StartObject : JsonToken.StartArray; BsonType type = (!_readRootValueAsArray) ? BsonType.Object : BsonType.Array; SetToken(token); ContainerContext newContext = new ContainerContext(type); PushContext(newContext); newContext.Length = ReadInt32(); return(true); } case State.Complete: case State.Closed: return(false); case State.Property: { ReadType(_currentElementType); return(true); } case State.ObjectStart: case State.ArrayStart: case State.PostValue: ContainerContext context = _currentContext; if (context == null) { return(false); } int lengthMinusEnd = context.Length - 1; if (context.Position < lengthMinusEnd) { if (context.Type == BsonType.Array) { ReadElement(); ReadType(_currentElementType); return(true); } else { SetToken(JsonToken.PropertyName, ReadElement()); return(true); } } else if (context.Position == lengthMinusEnd) { if (ReadByte() != 0) { throw ExceptionUtils.CreateJsonReaderException(this, "Unexpected end of object byte value."); } PopContext(); if (_currentContext != null) { MovePosition(context.Length); } JsonToken endToken = (context.Type == BsonType.Object) ? JsonToken.EndObject : JsonToken.EndArray; SetToken(endToken); return(true); } else { throw ExceptionUtils.CreateJsonReaderException(this, "Read past end of current container context."); } case State.ConstructorStart: break; case State.Constructor: break; case State.Error: break; case State.Finished: break; default: throw new ArgumentOutOfRangeException(); } return(false); }