// constructors
 internal JsonReaderBookmark(BsonReaderState state, BsonType currentBsonType, string currentName, JsonReaderContext context, JsonToken currentToken, BsonValue currentValue, JsonToken pushedToken, int position)
     : base(state, currentBsonType, currentName)
 {
     _context = context.Clone();
     _currentToken = currentToken;
     _currentValue = currentValue;
     _pushedToken = pushedToken;
     _position = position;
 }
Пример #2
0
 private string FormatInvalidTokenMessage(
     JsonToken token
 ) {
     return string.Format("Invalid JSON token: '{0}'", token.Lexeme);
 }
Пример #3
0
 /// <summary>
 /// Returns the reader to previously bookmarked position and state.
 /// </summary>
 /// <param name="bookmark">The bookmark.</param>
 public override void ReturnToBookmark(
     BsonReaderBookmark bookmark
 ) {
     if (disposed) { ThrowObjectDisposedException(); }
     var jsonReaderBookmark = (JsonReaderBookmark) bookmark;
     state = jsonReaderBookmark.State;
     currentBsonType = jsonReaderBookmark.CurrentBsonType;
     currentName = jsonReaderBookmark.CurrentName;
     context = jsonReaderBookmark.CloneContext();
     currentToken = jsonReaderBookmark.CurrentToken;
     currentValue = jsonReaderBookmark.CurrentValue;
     pushedToken = jsonReaderBookmark.PushedToken;
     buffer.Position = jsonReaderBookmark.Position;
 }
Пример #4
0
 private void PushToken(
     JsonToken token
 ) {
     if (pushedToken == null) {
         pushedToken = token;
     } else {
         throw new BsonInternalException("There is already a pending token.");
     }
 }
Пример #5
0
 private JsonToken PopToken() {
     if (pushedToken != null) {
         var token = pushedToken;
         pushedToken = null;
         return token;
     } else {
         return JsonScanner.GetNextToken(buffer);
     }
 }
Пример #6
0
        /// <summary>
        /// Reads a BsonType from the reader.
        /// </summary>
        /// <returns>A BsonType.</returns>
        public override BsonType ReadBsonType() {
            if (disposed) { ThrowObjectDisposedException(); }
            if (state == BsonReaderState.Initial || state == BsonReaderState.Done || state == BsonReaderState.ScopeDocument) {
                // in JSON the top level value can be of any type so fall through
                state = BsonReaderState.Type;
            }
            if (state != BsonReaderState.Type) {
                ThrowInvalidState("ReadBsonType", BsonReaderState.Type);
            }

            if (context.ContextType == ContextType.Document) {
                var nameToken = PopToken();
                switch (nameToken.Type) {
                    case JsonTokenType.String:
                    case JsonTokenType.UnquotedString:
                        currentName = nameToken.StringValue;
                        break;
                    case JsonTokenType.EndObject:
                        state = BsonReaderState.EndOfDocument;
                        return BsonType.EndOfDocument;
                    default:
                        var message = string.Format("JSON reader was expecting a name but found '{0}'.", nameToken.Lexeme);
                        throw new FileFormatException(message);
                }

                var colonToken = PopToken();
                if (colonToken.Type != JsonTokenType.Colon) {
                    var message = string.Format("JSON reader was expecting ':' but found '{0}'.", colonToken.Lexeme);
                    throw new FileFormatException(message);
                }
            }

            var valueToken = PopToken();
            if (context.ContextType == ContextType.Array && valueToken.Type == JsonTokenType.EndArray) {
                state = BsonReaderState.EndOfArray;
                return BsonType.EndOfDocument;
            }

            switch (valueToken.Type) {
                case JsonTokenType.BeginArray:
                    currentBsonType = BsonType.Array;
                    break;
                case JsonTokenType.BeginObject:
                    currentBsonType = ParseExtendedJson();
                    break;
                case JsonTokenType.DateTime:
                    currentBsonType = BsonType.DateTime;
                    currentValue = valueToken.DateTimeValue;
                    break;
                case JsonTokenType.Double:
                    currentBsonType = BsonType.Double;
                    currentValue = valueToken.DoubleValue;
                    break;
                case JsonTokenType.EndOfFile:
                    currentBsonType = BsonType.EndOfDocument;
                    break;
                case JsonTokenType.Int32:
                    currentBsonType = BsonType.Int32;
                    currentValue = valueToken.Int32Value;
                    break;
                case JsonTokenType.Int64:
                    currentBsonType = BsonType.Int64;
                    currentValue = valueToken.Int64Value;
                    break;
                case JsonTokenType.ObjectId:
                    currentBsonType = BsonType.ObjectId;
                    currentValue = valueToken.ObjectIdValue;
                    break;
                case JsonTokenType.RegularExpression:
                    currentBsonType = BsonType.RegularExpression;
                    currentValue = valueToken.RegularExpressionValue;
                    break;
                case JsonTokenType.String:
                    currentBsonType = BsonType.String;
                    currentValue = valueToken.StringValue;
                    break;
                case JsonTokenType.UnquotedString:
                    var isConstant = true;
                    switch (valueToken.Lexeme) {
                        case "false":
                        case "true":
                            currentBsonType = BsonType.Boolean;
                            currentValue = XmlConvert.ToBoolean(valueToken.Lexeme);
                            break;
                        case "Infinity":
                            currentBsonType = BsonType.Double;
                            currentValue = double.PositiveInfinity;
                            break;
                        case "NaN":
                            currentBsonType = BsonType.Double;
                            currentValue = double.NaN;
                            break;
                        case "null":
                            currentBsonType = BsonType.Null;
                            break;
                        case "undefined":
                            currentBsonType = BsonType.Undefined;
                            break;
                        case "BinData":
                            currentBsonType = BsonType.Binary;
                            currentValue = ParseBinDataConstructor();
                            break;
                        case "Date":
                            currentBsonType = BsonType.String;
                            currentValue = ParseDateTimeConstructor(false); // withNew = false
                            break;
                        case "HexData":
                            currentBsonType = BsonType.Binary;
                            currentValue = ParseHexDataConstructor();
                            break;
                        case "ISODate":
                            currentBsonType = BsonType.DateTime;
                            currentValue = ParseISODateTimeConstructor();
                            break;
                        case "NumberLong":
                            currentBsonType = BsonType.Int64;
                            currentValue = ParseNumberLongConstructor();
                            break;
                        case "ObjectId":
                            currentBsonType = BsonType.ObjectId;
                            currentValue = ParseObjectIdConstructor();
                            break;
                        case "RegExp":
                            currentBsonType = BsonType.RegularExpression;
                            currentValue = ParseRegularExpressionConstructor();
                            break;
                        case "UUID":
                        case "GUID":
                        case "CSUUID":
                        case "CSGUID":
                        case "JUUID":
                        case "JGUID":
                        case "PYUUID":
                        case "PYGUID":
                            currentBsonType = BsonType.Binary;
                            currentValue = ParseUUIDConstructor(valueToken.Lexeme);
                            break;
                        case "new":
                            currentBsonType = ParseNew(out currentValue);
                            break;
                        default:
                            isConstant = false;
                            break;
                    }
                    if (isConstant) {
                        break;
                    } else {
                        goto default;
                    }
                default:
                    var message = string.Format("JSON reader was expecting a value but found '{0}'.", valueToken.Lexeme);
                    throw new FileFormatException(message);
            }
            currentToken = valueToken;

            if (context.ContextType == ContextType.Array || context.ContextType == ContextType.Document) {
                var commaToken = PopToken();
                if (commaToken.Type != JsonTokenType.Comma) {
                    PushToken(commaToken);
                }
            }

            state = (context.ContextType == ContextType.Document) ? BsonReaderState.Name : BsonReaderState.Value;
            return currentBsonType;
        }
Пример #7
0
 private BsonValue ParseTimestampExtendedJsonOldRepresentation(JsonToken valueToken)
 {
     long value;
     if (valueToken.Type == JsonTokenType.Int32 || valueToken.Type == JsonTokenType.Int64)
     {
         value = valueToken.Int64Value;
     }
     else if (valueToken.Type == JsonTokenType.UnquotedString && valueToken.Lexeme == "NumberLong")
     {
         value = ParseNumberLongConstructor().AsInt64;
     }
     else
     {
         var message = string.Format("JSON reader expected an integer but found '{0}'.", valueToken.Lexeme);
         throw new FileFormatException(message);
     }
     VerifyToken("}");
     return new BsonTimestamp(value);
 }
Пример #8
0
        /// <summary>
        /// Reads a BsonType from the reader.
        /// </summary>
        /// <returns>A BsonType.</returns>
        public override BsonType ReadBsonType()
        {
            if (Disposed) { ThrowObjectDisposedException(); }
            if (State == BsonReaderState.Initial || State == BsonReaderState.Done || State == BsonReaderState.ScopeDocument)
            {
                if (State == BsonReaderState.Initial || State == BsonReaderState.Done)
                {
                    _buffer.ResetBuffer();
                }

                // in JSON the top level value can be of any type so fall through
                State = BsonReaderState.Type;
            }
            if (State != BsonReaderState.Type)
            {
                ThrowInvalidState("ReadBsonType", BsonReaderState.Type);
            }

            if (_context.ContextType == ContextType.Document)
            {
                var nameToken = PopToken();
                switch (nameToken.Type)
                {
                    case JsonTokenType.String:
                    case JsonTokenType.UnquotedString:
                        CurrentName = nameToken.StringValue;
                        break;
                    case JsonTokenType.EndObject:
                        State = BsonReaderState.EndOfDocument;
                        return BsonType.EndOfDocument;
                    default:
                        var message = string.Format("JSON reader was expecting a name but found '{0}'.", nameToken.Lexeme);
                        throw new FileFormatException(message);
                }

                var colonToken = PopToken();
                if (colonToken.Type != JsonTokenType.Colon)
                {
                    var message = string.Format("JSON reader was expecting ':' but found '{0}'.", colonToken.Lexeme);
                    throw new FileFormatException(message);
                }
            }

            var valueToken = PopToken();
            if (_context.ContextType == ContextType.Array && valueToken.Type == JsonTokenType.EndArray)
            {
                State = BsonReaderState.EndOfArray;
                return BsonType.EndOfDocument;
            }

            var noValueFound = false;
            switch (valueToken.Type)
            {
                case JsonTokenType.BeginArray:
                    CurrentBsonType = BsonType.Array;
                    break;
                case JsonTokenType.BeginObject:
                    CurrentBsonType = ParseExtendedJson();
                    break;
                case JsonTokenType.DateTime:
                    CurrentBsonType = BsonType.DateTime;
                    _currentValue = valueToken.DateTimeValue;
                    break;
                case JsonTokenType.Double:
                    CurrentBsonType = BsonType.Double;
                    _currentValue = valueToken.DoubleValue;
                    break;
                case JsonTokenType.EndOfFile:
                    CurrentBsonType = BsonType.EndOfDocument;
                    break;
                case JsonTokenType.Int32:
                    CurrentBsonType = BsonType.Int32;
                    _currentValue = valueToken.Int32Value;
                    break;
                case JsonTokenType.Int64:
                    CurrentBsonType = BsonType.Int64;
                    _currentValue = valueToken.Int64Value;
                    break;
                case JsonTokenType.ObjectId:
                    CurrentBsonType = BsonType.ObjectId;
                    _currentValue = valueToken.ObjectIdValue;
                    break;
                case JsonTokenType.RegularExpression:
                    CurrentBsonType = BsonType.RegularExpression;
                    _currentValue = valueToken.RegularExpressionValue;
                    break;
                case JsonTokenType.String:
                    CurrentBsonType = BsonType.String;
                    _currentValue = valueToken.StringValue;
                    break;
                case JsonTokenType.UnquotedString:
                    switch (valueToken.Lexeme)
                    {
                        case "false":
                        case "true":
                            CurrentBsonType = BsonType.Boolean;
                            _currentValue = XmlConvert.ToBoolean(valueToken.Lexeme);
                            break;
                        case "Infinity":
                            CurrentBsonType = BsonType.Double;
                            _currentValue = double.PositiveInfinity;
                            break;
                        case "NaN":
                            CurrentBsonType = BsonType.Double;
                            _currentValue = double.NaN;
                            break;
                        case "null":
                            CurrentBsonType = BsonType.Null;
                            break;
                        case "undefined":
                            CurrentBsonType = BsonType.Undefined;
                            break;
                        case "BinData":
                            CurrentBsonType = BsonType.Binary;
                            _currentValue = ParseBinDataConstructor();
                            break;
                        case "Date":
                            CurrentBsonType = BsonType.String;
                            _currentValue = ParseDateTimeConstructor(false); // withNew = false
                            break;
                        case "HexData":
                            CurrentBsonType = BsonType.Binary;
                            _currentValue = ParseHexDataConstructor();
                            break;
                        case "ISODate":
                            CurrentBsonType = BsonType.DateTime;
                            _currentValue = ParseISODateTimeConstructor();
                            break;
                        case "MaxKey":
                            CurrentBsonType = BsonType.MaxKey;
                            _currentValue = BsonMaxKey.Value;
                            break;
                        case "MinKey":
                            CurrentBsonType = BsonType.MinKey;
                            _currentValue = BsonMinKey.Value;
                            break;
                        case "Number":
                        case "NumberInt":
                            CurrentBsonType = BsonType.Int32;
                            _currentValue = ParseNumberConstructor();
                            break;
                        case "NumberLong":
                            CurrentBsonType = BsonType.Int64;
                            _currentValue = ParseNumberLongConstructor();
                            break;
                        case "ObjectId":
                            CurrentBsonType = BsonType.ObjectId;
                            _currentValue = ParseObjectIdConstructor();
                            break;
                        case "RegExp":
                            CurrentBsonType = BsonType.RegularExpression;
                            _currentValue = ParseRegularExpressionConstructor();
                            break;
                        case "Timestamp":
                            CurrentBsonType = BsonType.Timestamp;
                            _currentValue = ParseTimestampConstructor();
                            break;
                        case "UUID":
                        case "GUID":
                        case "CSUUID":
                        case "CSGUID":
                        case "JUUID":
                        case "JGUID":
                        case "PYUUID":
                        case "PYGUID":
                            CurrentBsonType = BsonType.Binary;
                            _currentValue = ParseUUIDConstructor(valueToken.Lexeme);
                            break;
                        case "new":
                            CurrentBsonType = ParseNew(out _currentValue);
                            break;
                        default:
                            noValueFound = true;
                            break;
                    }
                    break;
                default:
                    noValueFound = true;
                    break;
            }
            if (noValueFound)
            {
                var message = string.Format("JSON reader was expecting a value but found '{0}'.", valueToken.Lexeme);
                throw new FileFormatException(message);
            }
            _currentToken = valueToken;

            if (_context.ContextType == ContextType.Array || _context.ContextType == ContextType.Document)
            {
                var commaToken = PopToken();
                if (commaToken.Type != JsonTokenType.Comma)
                {
                    PushToken(commaToken);
                }
            }

            switch (_context.ContextType)
            {
                case ContextType.Document:
                case ContextType.ScopeDocument:
                default:
                    State = BsonReaderState.Name;
                    break;
                case ContextType.Array:
                case ContextType.JavaScriptWithScope:
                case ContextType.TopLevel:
                    State = BsonReaderState.Value;
                    break;
            }
            return CurrentBsonType;
        }
Пример #9
0
        public override BsonType ReadBsonType()
        {
            if (disposed) { ThrowObjectDisposedException(); }
            if (state == BsonReaderState.Initial || state == BsonReaderState.ScopeDocument) {
                // in JSON the top level value can be of any type so fall through
                state = BsonReaderState.Type;
            }
            if (state != BsonReaderState.Type) {
                var message = string.Format("ReadBsonType cannot be called when State is: {0}", state);
                throw new InvalidOperationException(message);
            }

            if (context.ContextType == ContextType.Document) {
                var nameToken = PopToken();
                switch (nameToken.Type) {
                    case JsonTokenType.String:
                    case JsonTokenType.UnquotedString:
                        currentName = nameToken.StringValue;
                        break;
                    case JsonTokenType.EndObject:
                        state = BsonReaderState.EndOfDocument;
                        return BsonType.EndOfDocument;
                    default:
                        var message = string.Format("JSON reader was expecting a name but found: '{0}'", nameToken.Lexeme);
                        throw new FileFormatException(message);
                }

                var colonToken = PopToken();
                if (colonToken.Type != JsonTokenType.Colon) {
                    var message = string.Format("JSON reader was expecting ':' but found: '{0}'", colonToken.Lexeme);
                    throw new FileFormatException(message);
                }
            }

            var valueToken = PopToken();
            if (context.ContextType == ContextType.Array && valueToken.Type == JsonTokenType.EndArray) {
                state = BsonReaderState.EndOfArray;
                return BsonType.EndOfDocument;
            }

            switch (valueToken.Type) {
                case JsonTokenType.BeginArray:
                    currentBsonType = BsonType.Array;
                    break;
                case JsonTokenType.BeginObject:
                    currentBsonType = ParseExtendedJson();
                    break;
                case JsonTokenType.DateTime:
                    currentBsonType = BsonType.DateTime;
                    currentValue = valueToken.DateTimeValue;
                    break;
                case JsonTokenType.Double:
                    currentBsonType = BsonType.Double;
                    currentValue = valueToken.DoubleValue;
                    break;
                case JsonTokenType.Int32:
                    currentBsonType = BsonType.Int32;
                    currentValue = valueToken.Int32Value;
                    break;
                case JsonTokenType.Int64:
                    currentBsonType = BsonType.Int64;
                    currentValue = valueToken.Int64Value;
                    break;
                case JsonTokenType.ObjectId:
                    currentBsonType = BsonType.ObjectId;
                    currentValue = valueToken.ObjectIdValue;
                    break;
                case JsonTokenType.RegularExpression:
                    currentBsonType = BsonType.RegularExpression;
                    currentValue = valueToken.RegularExpressionValue;
                    break;
                case JsonTokenType.String:
                    currentBsonType = BsonType.String;
                    currentValue = valueToken.StringValue;
                    break;
                case JsonTokenType.UnquotedString:
                    var validConstant = true;
                    switch (valueToken.Lexeme) {
                        case "true":
                        case "false":
                            currentBsonType = BsonType.Boolean;
                            currentValue = XmlConvert.ToBoolean(valueToken.Lexeme);
                            break;
                        case "null":
                            currentBsonType = BsonType.Null;
                            break;
                        default:
                            validConstant = false;
                            break;
                    }
                    if (validConstant) {
                        break;
                    } else {
                        goto default;
                    }
                default:
                    var message = string.Format("JSON reader was expecting a value but found: '{0}'", valueToken.Lexeme);
                    throw new FileFormatException(message);
            }
            currentToken = valueToken;

            if (context.ContextType == ContextType.Array || context.ContextType == ContextType.Document) {
                var commaToken = PopToken();
                if (commaToken.Type != JsonTokenType.Comma) {
                    PushToken(commaToken);
                }
            }

            state = (context.ContextType == ContextType.Document) ? BsonReaderState.Name : BsonReaderState.Value;
            return currentBsonType;
        }
Пример #10
0
 public override void ReturnToBookmark(
     BsonReaderBookmark bookmark
 )
 {
     var jsonReaderBookmark = (JsonReaderBookmark) bookmark;
     state = jsonReaderBookmark.State;
     currentBsonType = jsonReaderBookmark.CurrentBsonType;
     currentName = jsonReaderBookmark.CurrentName;
     context = jsonReaderBookmark.Context;
     currentToken = jsonReaderBookmark.CurrentToken;
     currentValue = jsonReaderBookmark.CurrentValue;
     pushedToken = jsonReaderBookmark.PushedToken;
     buffer.Position = jsonReaderBookmark.Position;
 }