Example #1
0
        public Type GetActualType(BsonReader bsonReader, System.Type nominalType)
        {
            var currentBsonType = bsonReader.GetCurrentBsonType();

            if (bsonReader.State == BsonReaderState.Value)
            {
                if (currentBsonType == BsonType.Document)
                {
                    var bookmark = bsonReader.GetBookmark();
                    bsonReader.ReadStartDocument();
                    var type = nominalType;
                    if (bsonReader.FindElement(ElementName))
                    {
                        var discriminator = BsonValue.ReadFrom(bsonReader).AsString;
                        try
                        {
                            if (discriminator == "Typed")
                            {
                                type = typeof(TypedSettings <>);

                                bsonReader.ReturnToBookmark(bookmark);
                                bsonReader.ReadStartDocument();
                                bsonReader.FindElement("Name");
                                var stringType = BsonValue.ReadFrom(bsonReader).AsString;
                                type = type.MakeGenericType(Type.GetType(stringType));
                            }
                            else if (discriminator == "Setting")
                            {
                                type = typeof(Setting);
                            }
                        }
                        catch (Exception ex)
                        {
                            type = typeof(Setting);
                        }
                    }
                    bsonReader.ReturnToBookmark(bookmark);
                    return(type);
                }
            }
            return(nominalType);
        }
Example #2
0
        public Type GetActualType(BsonReader bsonReader, Type nominalType)
        {
            BsonReaderBookmark bookmark = bsonReader.GetBookmark();

            bsonReader.ReadStartDocument();
            Type actualType = nominalType;

            if (bsonReader.FindElement("Type"))
            {
                BsonValue discriminator = BsonSerializer.Deserialize <BsonValue>(bsonReader);
                actualType = BsonSerializer.LookupActualType(nominalType, discriminator);
            }
            bsonReader.ReturnToBookmark(bookmark);
            return(actualType);
        }
Example #3
0
    public Type GetActualType(BsonReader bsonReader, Type nominalType)
    {
        var bookmark = bsonReader.GetBookmark();

        bsonReader.ReadStartDocument();
        var actualType = nominalType;

        if (bsonReader.FindElement(ElementName))
        {
            var discriminator = (BsonValue)BsonValueSerializer.Instance.Deserialize(bsonReader, typeof(BsonValue), null);
            actualType = BsonSerializer.LookupActualType(nominalType, discriminator);
        }
        bsonReader.ReturnToBookmark(bookmark);
        return(actualType);
    }
        /// <summary>
        /// Deserializes an object from a BsonReader.
        /// </summary>
        /// <param name="bsonReader">The BsonReader.</param>
        /// <param name="nominalType">The nominal type of the object.</param>
        /// <param name="options">The serialization options.</param>
        /// <returns>An object.</returns>
        public object Deserialize(
            BsonReader bsonReader,
            Type nominalType,
            IBsonSerializationOptions options
            )
        {
            if (nominalType != typeof(object))
            {
                var message = string.Format("ObjectSerializer can only be used with nominal type System.Object, not type {1}.", nominalType.FullName);
                throw new InvalidOperationException(message);
            }

            var bsonType = bsonReader.CurrentBsonType;

            if (bsonType == BsonType.Null)
            {
                bsonReader.ReadNull();
                return(null);
            }
            else if (bsonType == BsonType.Document)
            {
                var bookmark = bsonReader.GetBookmark();
                bsonReader.ReadStartDocument();
                if (bsonReader.ReadBsonType() == BsonType.EndOfDocument)
                {
                    bsonReader.ReadEndDocument();
                    return(new object());
                }
                else
                {
                    bsonReader.ReturnToBookmark(bookmark);
                }
            }

            var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(object));
            var actualType = discriminatorConvention.GetActualType(bsonReader, typeof(object));

            if (actualType == typeof(object))
            {
                var message = string.Format("Unable to determine actual type of object to deserialize. NominalType is System.Object and BsonType is {0}.", bsonType);
                throw new FileFormatException(message);
            }

            var serializer = BsonSerializer.LookupSerializer(actualType);

            return(serializer.Deserialize(bsonReader, nominalType, actualType, options));
        }
        // public methods
        /// <summary>
        /// Deserializes an object from a BsonReader.
        /// </summary>
        /// <param name="bsonReader">The BsonReader.</param>
        /// <param name="nominalType">The nominal type of the object.</param>
        /// <param name="options">The serialization options.</param>
        /// <returns>An object.</returns>
        public object Deserialize(BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options)
        {
            if (nominalType != typeof(object))
            {
                var message = string.Format("ObjectSerializer can only be used with nominal type System.Object, not type {0}.", nominalType.FullName);
                throw new InvalidOperationException(message);
            }

            var bsonType = bsonReader.GetCurrentBsonType();
            if (bsonType == BsonType.Null)
            {
                bsonReader.ReadNull();
                return null;
            }
            else if (bsonType == BsonType.Document)
            {
                var bookmark = bsonReader.GetBookmark();
                bsonReader.ReadStartDocument();
                if (bsonReader.ReadBsonType() == BsonType.EndOfDocument)
                {
                    bsonReader.ReadEndDocument();
                    return new object();
                }
                else
                {
                    bsonReader.ReturnToBookmark(bookmark);
                }
            }

            var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object));
            var actualType = discriminatorConvention.GetActualType(bsonReader, typeof(object));
            if (actualType == typeof(object))
            {
                var message = string.Format("Unable to determine actual type of object to deserialize. NominalType is System.Object and BsonType is {0}.", bsonType);
                throw new FileFormatException(message);
            }

            var serializer = BsonSerializer.LookupSerializer(actualType);
            return serializer.Deserialize(bsonReader, nominalType, actualType, options);
        }
Example #6
0
        private Type GetActualType(BsonReader bsonReader)
        {
            var bookmark = bsonReader.GetBookmark();

            bsonReader.ReadStartDocument();
            if (bsonReader.FindElement("type"))
            {
                var type = bsonReader.ReadString();
                bsonReader.ReturnToBookmark(bookmark);

                switch (type)
                {
                case "Feature": return(typeof(GeoJsonFeature <TCoordinates>));

                case "FeatureCollection": return(typeof(GeoJsonFeatureCollection <TCoordinates>));

                case "GeometryCollection": return(typeof(GeoJsonGeometryCollection <TCoordinates>));

                case "LineString": return(typeof(GeoJsonLineString <TCoordinates>));

                case "MultiLineString": return(typeof(GeoJsonMultiLineString <TCoordinates>));

                case "MultiPoint": return(typeof(GeoJsonMultiPoint <TCoordinates>));

                case "MultiPolygon": return(typeof(GeoJsonMultiPolygon <TCoordinates>));

                case "Point": return(typeof(GeoJsonPoint <TCoordinates>));

                case "Polygon": return(typeof(GeoJsonPolygon <TCoordinates>));

                default:
                    var message = string.Format("The type field of the GeoJosnGeometry is not valid: '{0}'.", type);
                    throw new FormatException(message);
                }
            }
            else
            {
                throw new FormatException("GeoJson object is missing the type field.");
            }
        }
        public void TestBookmark()
        {
            var json = "{ \"x\" : 1, \"y\" : 2 }";

            using (_bsonReader = BsonReader.Create(json))
            {
                // do everything twice returning to bookmark in between
                var bookmark = _bsonReader.GetBookmark();
                Assert.AreEqual(BsonType.Document, _bsonReader.ReadBsonType());
                _bsonReader.ReturnToBookmark(bookmark);
                Assert.AreEqual(BsonType.Document, _bsonReader.ReadBsonType());

                bookmark = _bsonReader.GetBookmark();
                _bsonReader.ReadStartDocument();
                _bsonReader.ReturnToBookmark(bookmark);
                _bsonReader.ReadStartDocument();

                bookmark = _bsonReader.GetBookmark();
                Assert.AreEqual(BsonType.Int32, _bsonReader.ReadBsonType());
                _bsonReader.ReturnToBookmark(bookmark);
                Assert.AreEqual(BsonType.Int32, _bsonReader.ReadBsonType());

                bookmark = _bsonReader.GetBookmark();
                Assert.AreEqual("x", _bsonReader.ReadName());
                _bsonReader.ReturnToBookmark(bookmark);
                Assert.AreEqual("x", _bsonReader.ReadName());

                bookmark = _bsonReader.GetBookmark();
                Assert.AreEqual(1, _bsonReader.ReadInt32());
                _bsonReader.ReturnToBookmark(bookmark);
                Assert.AreEqual(1, _bsonReader.ReadInt32());

                bookmark = _bsonReader.GetBookmark();
                Assert.AreEqual(BsonType.Int32, _bsonReader.ReadBsonType());
                _bsonReader.ReturnToBookmark(bookmark);
                Assert.AreEqual(BsonType.Int32, _bsonReader.ReadBsonType());

                bookmark = _bsonReader.GetBookmark();
                Assert.AreEqual("y", _bsonReader.ReadName());
                _bsonReader.ReturnToBookmark(bookmark);
                Assert.AreEqual("y", _bsonReader.ReadName());

                bookmark = _bsonReader.GetBookmark();
                Assert.AreEqual(2, _bsonReader.ReadInt32());
                _bsonReader.ReturnToBookmark(bookmark);
                Assert.AreEqual(2, _bsonReader.ReadInt32());

                bookmark = _bsonReader.GetBookmark();
                Assert.AreEqual(BsonType.EndOfDocument, _bsonReader.ReadBsonType());
                _bsonReader.ReturnToBookmark(bookmark);
                Assert.AreEqual(BsonType.EndOfDocument, _bsonReader.ReadBsonType());

                bookmark = _bsonReader.GetBookmark();
                _bsonReader.ReadEndDocument();
                _bsonReader.ReturnToBookmark(bookmark);
                _bsonReader.ReadEndDocument();

                Assert.AreEqual(BsonReaderState.Done, _bsonReader.State);
            }
            Assert.AreEqual(json, BsonSerializer.Deserialize <BsonDocument>(new StringReader(json)).ToJson());
        }
        // public methods
        /// <summary>
        /// Gets the actual type of an object by reading the discriminator from a BsonReader.
        /// </summary>
        /// <param name="bsonReader">The reader.</param>
        /// <param name="nominalType">The nominal type.</param>
        /// <returns>The actual type.</returns>
        public Type GetActualType(BsonReader bsonReader, Type nominalType)
        {
            // the BsonReader is sitting at the value whose actual type needs to be found
            var bsonType = bsonReader.GetCurrentBsonType();

            if (bsonReader.State == BsonReaderState.Value)
            {
                Type primitiveType = null;
                switch (bsonType)
                {
                case BsonType.Boolean: primitiveType = typeof(bool); break;

                case BsonType.Binary:
                    var bookmark   = bsonReader.GetBookmark();
                    var binaryData = bsonReader.ReadBinaryData();
                    var subType    = binaryData.SubType;
                    if (subType == BsonBinarySubType.UuidStandard || subType == BsonBinarySubType.UuidLegacy)
                    {
                        primitiveType = typeof(Guid);
                    }
                    bsonReader.ReturnToBookmark(bookmark);
                    break;

                case BsonType.DateTime: primitiveType = typeof(DateTime); break;

                case BsonType.Double: primitiveType = typeof(double); break;

                case BsonType.Int32: primitiveType = typeof(int); break;

                case BsonType.Int64: primitiveType = typeof(long); break;

                case BsonType.ObjectId: primitiveType = typeof(ObjectId); break;

                case BsonType.String: primitiveType = typeof(string); break;
                }

                // Type.IsAssignableFrom is extremely expensive, always perform a direct type check before calling Type.IsAssignableFrom
                if (primitiveType != null && (primitiveType == nominalType || nominalType.IsAssignableFrom(primitiveType)))
                {
                    return(primitiveType);
                }
            }

            if (bsonType == BsonType.Document)
            {
                // ensure KnownTypes of nominalType are registered (so IsTypeDiscriminated returns correct answer)
                BsonSerializer.EnsureKnownTypesAreRegistered(nominalType);

                // we can skip looking for a discriminator if nominalType has no discriminated sub types
                if (BsonSerializer.IsTypeDiscriminated(nominalType))
                {
                    var bookmark = bsonReader.GetBookmark();
                    bsonReader.ReadStartDocument();
                    var actualType = nominalType;
                    if (bsonReader.FindElement(_elementName))
                    {
                        var discriminator = (BsonValue)BsonValueSerializer.Instance.Deserialize(bsonReader, typeof(BsonValue), null);
                        if (discriminator.IsBsonArray)
                        {
                            discriminator = discriminator.AsBsonArray.Last(); // last item is leaf class discriminator
                        }
                        actualType = BsonSerializer.LookupActualType(nominalType, discriminator);
                    }
                    bsonReader.ReturnToBookmark(bookmark);
                    return(actualType);
                }
            }

            return(nominalType);
        }
        /// <summary>
        /// Gets the actual type of an object by reading the discriminator from a BsonReader.
        /// </summary>
        /// <param name="bsonReader">The reader.</param>
        /// <param name="nominalType">The nominal type.</param>
        /// <returns>The actual type.</returns>
        public Type GetActualType(
            BsonReader bsonReader,
            Type nominalType
            )
        {
            // the BsonReader is sitting at the value whose actual type needs to be found
            var bsonType = bsonReader.CurrentBsonType;

            if (bsonReader.State == BsonReaderState.Value)
            {
                Type primitiveType = null;
                switch (bsonType)
                {
                case BsonType.Boolean: primitiveType = typeof(bool); break;

                case BsonType.Binary:
                    var               bookmark = bsonReader.GetBookmark();
                    byte[]            bytes;
                    BsonBinarySubType subType;
                    bsonReader.ReadBinaryData(out bytes, out subType);
                    if (subType == BsonBinarySubType.Uuid && bytes.Length == 16)
                    {
                        primitiveType = typeof(Guid);
                    }
                    bsonReader.ReturnToBookmark(bookmark);
                    break;

                case BsonType.DateTime: primitiveType = typeof(DateTime); break;

                case BsonType.Double: primitiveType = typeof(double); break;

                case BsonType.Int32: primitiveType = typeof(int); break;

                case BsonType.Int64: primitiveType = typeof(long); break;

                case BsonType.ObjectId: primitiveType = typeof(ObjectId); break;

                case BsonType.String: primitiveType = typeof(string); break;
                }

                if (primitiveType != null && nominalType.IsAssignableFrom(primitiveType))
                {
                    return(primitiveType);
                }
            }

            if (bsonType == BsonType.Document)
            {
                var bookmark = bsonReader.GetBookmark();
                bsonReader.ReadStartDocument();
                var actualType = nominalType;
                if (bsonReader.FindElement(elementName))
                {
                    var discriminator = BsonValue.ReadFrom(bsonReader);
                    if (discriminator.IsBsonArray)
                    {
                        discriminator = discriminator.AsBsonArray.Last(); // last item is leaf class discriminator
                    }
                    actualType = BsonDefaultSerializer.LookupActualType(nominalType, discriminator);
                }
                bsonReader.ReturnToBookmark(bookmark);
                return(actualType);
            }

            return(nominalType);
        }
        // private methods
        private bool IsCSharpNullRepresentation(BsonReader bsonReader)
        {
            var bookmark = bsonReader.GetBookmark();
            bsonReader.ReadStartDocument();
            var bsonType = bsonReader.ReadBsonType();
            if (bsonType == BsonType.Boolean)
            {
                var name = bsonReader.ReadName();
                if (name == "_csharpnull" || name == "$csharpnull")
                {
                    var value = bsonReader.ReadBoolean();
                    if (value)
                    {
                        bsonType = bsonReader.ReadBsonType();
                        if (bsonType == BsonType.EndOfDocument)
                        {
                            bsonReader.ReadEndDocument();
                            return true;
                        }
                    }
                }
            }

            bsonReader.ReturnToBookmark(bookmark);
            return false;
        }
Example #11
0
        public override object Deserialize(BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options)
        {
            var bsonType = bsonReader.CurrentBsonType;

            if (bsonType == BsonType.Null)
            {
                bsonReader.ReadNull();
                return(null);
            }
            else if (bsonType == BsonType.Document)
            {
                var          os = new ObjectSerializer();
                MongoDynamic md = new MongoDynamic();
                bsonReader.ReadStartDocument();

                Dictionary <string, Type> typeMap = null;

                // scan document first to find interfaces
                {
                    var bookMark = bsonReader.GetBookmark();
                    if (bsonReader.FindElement(MongoDynamic.InterfacesField))
                    {
                        md[MongoDynamic.InterfacesField] = BsonSerializer.Deserialize <BsonValue>(bsonReader).AsBsonArray.Select(x => x.AsString);
                        typeMap = md.GetTypeMap();
                    }
                    else
                    {
                        throw new FormatException("No interfaces defined for this dynamic object - can't deserialize it");
                    }
                    bsonReader.ReturnToBookmark(bookMark);
                }

                while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
                {
                    var name = bsonReader.ReadName();

                    if (name == "_id")
                    {
                        //md[name] = BsonValue.ReadFrom(bsonReader).AsObjectId;
                        md[name] = BsonSerializer.Deserialize <ObjectId>(bsonReader);
                    }
                    else if (name == MongoDynamic.InterfacesField)
                    {
                        // Read it and ignore it, we already have it
                        //BsonValue.ReadFrom(bsonReader);
                        BsonSerializer.Deserialize <ObjectId>(bsonReader);
                    }
                    else
                    {
                        if (typeMap == null)
                        {
                            throw new FormatException("No interfaces define for this dynamic object - can't deserialize");
                        }
                        // lookup the type for this element according to the interfaces
                        Type elementType;
                        if (typeMap.TryGetValue(name, out elementType))
                        {
                            var value = BsonSerializer.Deserialize(bsonReader, elementType);
                            md[name] = value;
                        }
                        else
                        {
                            // This is a value that is no longer in the interface, maybe a column you removed
                            // not really much we can do with it ... but we need to read it and move on
                            var value = BsonSerializer.Deserialize(bsonReader, typeof(object));
                            md[name] = value;

                            // As with all databases, removing elements from the schema is always going to cause problems ...
                        }
                    }
                }
                bsonReader.ReadEndDocument();
                return(md);
            }
            else
            {
                var message = string.Format("Can't deserialize a {0} from BsonType {1}.", nominalType.FullName, bsonType);
                throw new FormatException(message);
            }
        }
        // public methods
        /// <summary>
        /// Gets the actual type of an object by reading the discriminator from a BsonReader.
        /// </summary>
        /// <param name="bsonReader">The reader.</param>
        /// <param name="nominalType">The nominal type.</param>
        /// <returns>The actual type.</returns>
        public Type GetActualType(BsonReader bsonReader, Type nominalType)
        {
            // the BsonReader is sitting at the value whose actual type needs to be found
            var bsonType = bsonReader.GetCurrentBsonType();
            if (bsonReader.State == BsonReaderState.Value)
            {
                Type primitiveType = null;
                switch (bsonType)
                {
                    case BsonType.Boolean: primitiveType = typeof(bool); break;
                    case BsonType.Binary:
                        var bookmark = bsonReader.GetBookmark();
                        byte[] bytes;
                        BsonBinarySubType subType;
                        bsonReader.ReadBinaryData(out bytes, out subType);
                        if (subType == BsonBinarySubType.UuidStandard || subType == BsonBinarySubType.UuidLegacy)
                        {
                            primitiveType = typeof(Guid);
                        }
                        bsonReader.ReturnToBookmark(bookmark);
                        break;
                    case BsonType.DateTime: primitiveType = typeof(DateTime); break;
                    case BsonType.Double: primitiveType = typeof(double); break;
                    case BsonType.Int32: primitiveType = typeof(int); break;
                    case BsonType.Int64: primitiveType = typeof(long); break;
                    case BsonType.ObjectId: primitiveType = typeof(ObjectId); break;
                    case BsonType.String: primitiveType = typeof(string); break;
                }

                // Type.IsAssignableFrom is extremely expensive, always perform a direct type check before calling Type.IsAssignableFrom
                if (primitiveType != null && (primitiveType == nominalType || nominalType.IsAssignableFrom(primitiveType)))
                {
                    return primitiveType;
                }
            }

            if (bsonType == BsonType.Document)
            {
                // ensure KnownTypes of nominalType are registered (so IsTypeDiscriminated returns correct answer)
                BsonSerializer.EnsureKnownTypesAreRegistered(nominalType);

                // we can skip looking for a discriminator if nominalType has no discriminated sub types
                if (BsonSerializer.IsTypeDiscriminated(nominalType))
                {
                    var bookmark = bsonReader.GetBookmark();
                    bsonReader.ReadStartDocument();
                    var actualType = nominalType;
                    if (bsonReader.FindElement(_elementName))
                    {
                        var discriminator = BsonValue.ReadFrom(bsonReader);
                        if (discriminator.IsBsonArray)
                        {
                            discriminator = discriminator.AsBsonArray.Last(); // last item is leaf class discriminator
                        }
                        actualType = BsonSerializer.LookupActualType(nominalType, discriminator);
                    }
                    bsonReader.ReturnToBookmark(bookmark);
                    return actualType;
                }
            }

            return nominalType;
        }