public Type GetActualType(
                BsonReader bsonReader,
                Type nominalType
                )
            {
                var bookmark = bsonReader.GetBookmark();

                bsonReader.ReadStartDocument();
                var actualType = nominalType;

                while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
                {
                    var name = bsonReader.ReadName();
                    if (name == "OnlyInB")
                    {
                        actualType = typeof(B);
                        break;
                    }
                    else if (name == "OnlyInC")
                    {
                        actualType = typeof(C);
                        break;
                    }
                    bsonReader.SkipValue();
                }
                bsonReader.ReturnToBookmark(bookmark);
                return(actualType);
            }
Example #2
0
        /// <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="actualType">The actual type of the object.</param>
        /// <param name="options">The serialization options.</param>
        /// <returns>An object.</returns>
        public object Deserialize(
            BsonReader bsonReader,
            Type nominalType,
            Type actualType,
            IBsonSerializationOptions options
            )
        {
            VerifyNominalType(nominalType);
            if (bsonReader.CurrentBsonType == Bson.BsonType.Null)
            {
                bsonReader.ReadNull();
                return(null);
            }
            else
            {
                if (actualType.IsValueType)
                {
                    var message = string.Format("Value class {0} cannot be deserialized.", actualType.FullName);
                    throw new BsonSerializationException(message);
                }

                var classMap = BsonClassMap.LookupClassMap(actualType);
                if (classMap.IsAnonymous)
                {
                    throw new InvalidOperationException("An anonymous class cannot be deserialized.");
                }
                var obj = classMap.CreateInstance();

                bsonReader.ReadStartDocument();
                var missingElementMemberMaps = new HashSet <BsonMemberMap>(classMap.MemberMaps); // make a copy!
                var discriminatorConvention  = BsonDefaultSerializer.LookupDiscriminatorConvention(nominalType);
                while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
                {
                    var elementName = bsonReader.ReadName();
                    if (elementName == discriminatorConvention.ElementName)
                    {
                        bsonReader.SkipValue(); // skip over discriminator
                        continue;
                    }

                    var memberMap = classMap.GetMemberMapForElement(elementName);
                    if (memberMap != null && memberMap != classMap.ExtraElementsMemberMap)
                    {
                        DeserializeMember(bsonReader, obj, memberMap);
                        missingElementMemberMaps.Remove(memberMap);
                    }
                    else
                    {
                        if (classMap.ExtraElementsMemberMap != null)
                        {
                            DeserializeExtraElement(bsonReader, obj, elementName, classMap.ExtraElementsMemberMap);
                        }
                        else if (classMap.IgnoreExtraElements)
                        {
                            bsonReader.SkipValue();
                        }
                        else
                        {
                            var message = string.Format("Element '{0}' does not match any field or property of class {1}.", elementName, classMap.ClassType.FullName);
                            throw new FileFormatException(message);
                        }
                    }
                }
                bsonReader.ReadEndDocument();

                foreach (var memberMap in missingElementMemberMaps)
                {
                    if (memberMap.IsRequired)
                    {
                        var fieldOrProperty = (memberMap.MemberInfo.MemberType == MemberTypes.Field) ? "field" : "property";
                        var message         = string.Format("Required element '{0}' for {1} '{2}' of class {3} is missing.", memberMap.ElementName, fieldOrProperty, memberMap.MemberName, classMap.ClassType.FullName);
                        throw new FileFormatException(message);
                    }

                    if (memberMap.HasDefaultValue)
                    {
                        memberMap.ApplyDefaultValue(obj);
                    }
                }

                return(obj);
            }
        }
Example #3
0
        /// <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="actualType">The actual type of the object.</param>
        /// <param name="options">The serialization options.</param>
        /// <returns>An object.</returns>
        public object Deserialize(
            BsonReader bsonReader,
            Type nominalType,
            Type actualType,
            IBsonSerializationOptions options
            )
        {
            VerifyNominalType(nominalType);
            if (bsonReader.CurrentBsonType == Bson.BsonType.Null)
            {
                bsonReader.ReadNull();
                return(null);
            }
            else
            {
                var classMap = BsonClassMap.LookupClassMap(actualType);
                if (classMap.IsAnonymous)
                {
                    throw new InvalidOperationException("Anonymous classes cannot be deserialized");
                }
                var obj = classMap.CreateInstance();

                bsonReader.ReadStartDocument();
                var missingElementMemberMaps = new HashSet <BsonMemberMap>(classMap.MemberMaps); // make a copy!
                var discriminatorConvention  = BsonDefaultSerializer.LookupDiscriminatorConvention(nominalType);
                while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
                {
                    var elementName = bsonReader.ReadName();
                    if (elementName == discriminatorConvention.ElementName)
                    {
                        bsonReader.SkipValue(); // skip over discriminator
                        continue;
                    }

                    var memberMap = classMap.GetMemberMapForElement(elementName);
                    if (memberMap != null && memberMap != classMap.ExtraElementsMemberMap)
                    {
                        DeserializeMember(bsonReader, obj, memberMap);
                        missingElementMemberMaps.Remove(memberMap);
                    }
                    else
                    {
                        if (classMap.ExtraElementsMemberMap != null)
                        {
                            DeserializeExtraElement(bsonReader, obj, elementName, classMap.ExtraElementsMemberMap);
                        }
                        else if (classMap.IgnoreExtraElements)
                        {
                            bsonReader.SkipValue();
                        }
                        else
                        {
                            string message = string.Format("Unexpected element: {0}", elementName);
                            throw new FileFormatException(message);
                        }
                    }
                }
                bsonReader.ReadEndDocument();

                foreach (var memberMap in missingElementMemberMaps)
                {
                    if (memberMap.IsRequired)
                    {
                        var message = string.Format("Required element is missing: {0}", memberMap.ElementName);
                        throw new FileFormatException(message);
                    }

                    if (memberMap.HasDefaultValue)
                    {
                        memberMap.ApplyDefaultValue(obj);
                    }
                }

                return(obj);
            }
        }
Example #4
0
        /// <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="actualType">The actual type of the object.</param>
        /// <param name="options">The serialization options.</param>
        /// <returns>An object.</returns>
        public object Deserialize(
            BsonReader bsonReader,
            Type nominalType,
            Type actualType,
            IBsonSerializationOptions options)
        {
            VerifyNominalType(nominalType);
            var bsonType = bsonReader.GetCurrentBsonType();

            if (bsonType == Bson.BsonType.Null)
            {
                bsonReader.ReadNull();
                return(null);
            }
            else
            {
                if (actualType != _classMap.ClassType)
                {
                    var message = string.Format("BsonClassMapSerializer.Deserialize for type {0} was called with actualType {1}.",
                                                BsonUtils.GetFriendlyTypeName(_classMap.ClassType), BsonUtils.GetFriendlyTypeName(actualType));
                    throw new BsonSerializationException(message);
                }

                if (actualType.IsValueType)
                {
                    var message = string.Format("Value class {0} cannot be deserialized.", actualType.FullName);
                    throw new BsonSerializationException(message);
                }

                if (_classMap.IsAnonymous)
                {
                    throw new InvalidOperationException("An anonymous class cannot be deserialized.");
                }

                if (bsonType != BsonType.Document)
                {
                    var message = string.Format(
                        "Expected a nested document representing the serialized form of a {0} value, but found a value of type {1} instead.",
                        actualType.FullName, bsonType);
                    throw new FileFormatException(message);
                }

                Dictionary <string, object> values        = null;
                object             obj                    = null;
                ISupportInitialize supportsInitialization = null;
                if (_classMap.HasCreatorMaps)
                {
                    // for creator-based deserialization we first gather the values in a dictionary and then call a matching creator
                    values = new Dictionary <string, object>();
                }
                else
                {
                    // for mutable classes we deserialize the values directly into the result object
                    obj = _classMap.CreateInstance();

                    supportsInitialization = obj as ISupportInitialize;
                    if (supportsInitialization != null)
                    {
                        supportsInitialization.BeginInit();
                    }
                }

                var discriminatorConvention     = _classMap.GetDiscriminatorConvention();
                var allMemberMaps               = _classMap.AllMemberMaps;
                var extraElementsMemberMapIndex = _classMap.ExtraElementsMemberMapIndex;
                var memberMapBitArray           = FastMemberMapHelper.GetBitArray(allMemberMaps.Count);

                bsonReader.ReadStartDocument();
                var  elementTrie = _classMap.ElementTrie;
                bool memberMapFound;
                int  memberMapIndex;
                while (bsonReader.ReadBsonType(elementTrie, out memberMapFound, out memberMapIndex) != BsonType.EndOfDocument)
                {
                    var elementName = bsonReader.ReadName();
                    if (memberMapFound)
                    {
                        var memberMap = allMemberMaps[memberMapIndex];
                        if (memberMapIndex != extraElementsMemberMapIndex)
                        {
                            if (obj != null)
                            {
                                if (memberMap.IsReadOnly)
                                {
                                    bsonReader.SkipValue();
                                }
                                else
                                {
                                    var value = DeserializeMemberValue(bsonReader, memberMap);
                                    memberMap.Setter(obj, value);
                                }
                            }
                            else
                            {
                                var value = DeserializeMemberValue(bsonReader, memberMap);
                                values[elementName] = value;
                            }
                        }
                        else
                        {
                            DeserializeExtraElement(bsonReader, obj, elementName, memberMap);
                        }
                        memberMapBitArray[memberMapIndex >> 5] |= 1U << (memberMapIndex & 31);
                    }
                    else
                    {
                        if (elementName == discriminatorConvention.ElementName)
                        {
                            bsonReader.SkipValue(); // skip over discriminator
                            continue;
                        }

                        if (extraElementsMemberMapIndex >= 0)
                        {
                            DeserializeExtraElement(bsonReader, obj, elementName, _classMap.ExtraElementsMemberMap);
                            memberMapBitArray[extraElementsMemberMapIndex >> 5] |= 1U << (extraElementsMemberMapIndex & 31);
                        }
                        else if (_classMap.IgnoreExtraElements)
                        {
                            bsonReader.SkipValue();
                        }
                        else
                        {
                            var message = string.Format(
                                "Element '{0}' does not match any field or property of class {1}.",
                                elementName, _classMap.ClassType.FullName);
                            throw new FileFormatException(message);
                        }
                    }
                }
                bsonReader.ReadEndDocument();

                // check any members left over that we didn't have elements for (in blocks of 32 elements at a time)
                for (var bitArrayIndex = 0; bitArrayIndex < memberMapBitArray.Length; ++bitArrayIndex)
                {
                    memberMapIndex = bitArrayIndex << 5;
                    var memberMapBlock = ~memberMapBitArray[bitArrayIndex]; // notice that bits are flipped so 1's are now the missing elements

                    // work through this memberMapBlock of 32 elements
                    while (true)
                    {
                        // examine missing elements (memberMapBlock is shifted right as we work through the block)
                        for (; (memberMapBlock & 1) != 0; ++memberMapIndex, memberMapBlock >>= 1)
                        {
                            var memberMap = allMemberMaps[memberMapIndex];
                            if (memberMap.IsReadOnly)
                            {
                                continue;
                            }

                            if (memberMap.IsRequired)
                            {
                                var fieldOrProperty = (memberMap.MemberInfo.MemberType == MemberTypes.Field) ? "field" : "property";
                                var message         = string.Format(
                                    "Required element '{0}' for {1} '{2}' of class {3} is missing.",
                                    memberMap.ElementName, fieldOrProperty, memberMap.MemberName, _classMap.ClassType.FullName);
                                throw new FileFormatException(message);
                            }

                            if (obj != null)
                            {
                                memberMap.ApplyDefaultValue(obj);
                            }
                            else if (memberMap.IsDefaultValueSpecified && !memberMap.IsReadOnly)
                            {
                                values[memberMap.ElementName] = memberMap.DefaultValue;
                            }
                        }

                        if (memberMapBlock == 0)
                        {
                            break;
                        }

                        // skip ahead to the next missing element
                        var leastSignificantBit = FastMemberMapHelper.GetLeastSignificantBit(memberMapBlock);
                        memberMapIndex  += leastSignificantBit;
                        memberMapBlock >>= leastSignificantBit;
                    }
                }

                if (obj != null)
                {
                    if (supportsInitialization != null)
                    {
                        supportsInitialization.EndInit();
                    }

                    return(obj);
                }
                else
                {
                    return(CreateInstanceUsingCreator(values));
                }
            }
        }
Example #5
0
        /// <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="actualType">The actual type of the object.</param>
        /// <param name="options">The serialization options.</param>
        /// <returns>An object.</returns>
        public object Deserialize(
            BsonReader bsonReader,
            Type nominalType,
            Type actualType,
            IBsonSerializationOptions options)
        {
            VerifyNominalType(nominalType);
            var bsonType = bsonReader.GetCurrentBsonType();

            if (bsonType == Bson.BsonType.Null)
            {
                bsonReader.ReadNull();
                return(null);
            }
            else
            {
                if (actualType != _classMap.ClassType)
                {
                    var message = string.Format("BsonClassMapSerializer.Deserialize for type {0} was called with actualType {1}.",
                                                BsonUtils.GetFriendlyTypeName(_classMap.ClassType), BsonUtils.GetFriendlyTypeName(actualType));
                    throw new BsonSerializationException(message);
                }

                if (actualType.IsValueType)
                {
                    var message = string.Format("Value class {0} cannot be deserialized.", actualType.FullName);
                    throw new BsonSerializationException(message);
                }

                if (_classMap.IsAnonymous)
                {
                    throw new InvalidOperationException("An anonymous class cannot be deserialized.");
                }
                var obj = _classMap.CreateInstance();

                if (bsonType != BsonType.Document)
                {
                    var message = string.Format(
                        "Expected a nested document representing the serialized form of a {0} value, but found a value of type {1} instead.",
                        actualType.FullName, bsonType);
                    throw new FileFormatException(message);
                }

                var supportsInitialization = obj as ISupportInitialize;
                if (supportsInitialization != null)
                {
                    supportsInitialization.BeginInit();
                }

                var discriminatorConvention = _classMap.GetDiscriminatorConvention();
                var fastMemberMapFinder     = new FastMemberMapFinder(_classMap);

                bsonReader.ReadStartDocument();
                while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
                {
                    var elementName = bsonReader.ReadName();
                    if (elementName == discriminatorConvention.ElementName)
                    {
                        bsonReader.SkipValue(); // skip over discriminator
                        continue;
                    }

                    var memberMap = fastMemberMapFinder.GetMemberMapForElement(elementName);
                    if (memberMap != null)
                    {
                        if (memberMap.IsReadOnly)
                        {
                            bsonReader.SkipValue();
                        }
                        else
                        {
                            DeserializeMember(bsonReader, obj, memberMap);
                        }
                    }
                    else
                    {
                        if (_classMap.ExtraElementsMemberMap != null)
                        {
                            DeserializeExtraElement(bsonReader, obj, elementName, _classMap.ExtraElementsMemberMap);
                        }
                        else if (_classMap.IgnoreExtraElements)
                        {
                            bsonReader.SkipValue();
                        }
                        else
                        {
                            var message = string.Format(
                                "Element '{0}' does not match any field or property of class {1}.",
                                elementName, _classMap.ClassType.FullName);
                            throw new FileFormatException(message);
                        }
                    }
                }
                bsonReader.ReadEndDocument();

                // check any members left over that we didn't have elements for
                if (fastMemberMapFinder.HasLeftOverMemberMaps())
                {
                    foreach (var memberMap in fastMemberMapFinder.GetLeftOverMemberMaps())
                    {
                        if (memberMap.IsReadOnly)
                        {
                            continue;
                        }

                        if (memberMap.IsRequired)
                        {
                            var fieldOrProperty = (memberMap.MemberInfo.MemberType == MemberTypes.Field) ? "field" : "property";
                            var message         = string.Format(
                                "Required element '{0}' for {1} '{2}' of class {3} is missing.",
                                memberMap.ElementName, fieldOrProperty, memberMap.MemberName, _classMap.ClassType.FullName);
                            throw new FileFormatException(message);
                        }

                        memberMap.ApplyDefaultValue(obj);
                    }
                }

                if (supportsInitialization != null)
                {
                    supportsInitialization.EndInit();
                }

                return(obj);
            }
        }
        /// <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="actualType">The actual type of the object.</param>
        /// <param name="options">The serialization options.</param>
        /// <returns>An object.</returns>
        public object Deserialize(
            BsonReader bsonReader,
            Type nominalType,
            Type actualType,
            IBsonSerializationOptions options)
        {
            VerifyNominalType(nominalType);
            var bsonType = bsonReader.GetCurrentBsonType();
            if (bsonType == Bson.BsonType.Null)
            {
                bsonReader.ReadNull();
                return null;
            }
            else
            {
                if (actualType != _classMap.ClassType)
                {
                    var message = string.Format("BsonClassMapSerializer.Deserialize for type {0} was called with actualType {1}.",
                        BsonUtils.GetFriendlyTypeName(_classMap.ClassType), BsonUtils.GetFriendlyTypeName(actualType));
                    throw new BsonSerializationException(message);
                }

                if (actualType.IsValueType)
                {
                    var message = string.Format("Value class {0} cannot be deserialized.", actualType.FullName);
                    throw new BsonSerializationException(message);
                }

                if (_classMap.IsAnonymous)
                {
                    throw new InvalidOperationException("An anonymous class cannot be deserialized.");
                }

                if (bsonType != BsonType.Document)
                {
                    var message = string.Format(
                        "Expected a nested document representing the serialized form of a {0} value, but found a value of type {1} instead.",
                        actualType.FullName, bsonType);
                    throw new FileFormatException(message);
                }

                Dictionary<string, object> values = null;
                object obj = null;
                ISupportInitialize supportsInitialization = null;
                if (_classMap.HasCreatorMaps)
                {
                    // for creator-based deserialization we first gather the values in a dictionary and then call a matching creator
                    values = new Dictionary<string, object>();
                }
                else
                {
                    // for mutable classes we deserialize the values directly into the result object
                    obj = _classMap.CreateInstance();

                    supportsInitialization = obj as ISupportInitialize;
                    if (supportsInitialization != null)
                    {
                        supportsInitialization.BeginInit();
                    }
                }

                var discriminatorConvention = _classMap.GetDiscriminatorConvention();
                var allMemberMaps = _classMap.AllMemberMaps;
                var extraElementsMemberMapIndex = _classMap.ExtraElementsMemberMapIndex;
                var memberMapBitArray = FastMemberMapHelper.GetBitArray(allMemberMaps.Count);

                bsonReader.ReadStartDocument();
                var elementTrie = _classMap.ElementTrie;
                bool memberMapFound;
                int memberMapIndex;
                while (bsonReader.ReadBsonType(elementTrie, out memberMapFound, out memberMapIndex) != BsonType.EndOfDocument)
                {
                    var elementName = bsonReader.ReadName();
                    if (memberMapFound)
                    {
                        var memberMap = allMemberMaps[memberMapIndex];
                        if (memberMapIndex != extraElementsMemberMapIndex)
                        {
                            if (obj != null)
                            {
                                if (memberMap.IsReadOnly)
                                {
                                    bsonReader.SkipValue();
                                }
                                else
                                {
                                    var value = DeserializeMemberValue(bsonReader, memberMap);
                                    memberMap.Setter(obj, value);
                                }
                            }
                            else
                            {
                                var value = DeserializeMemberValue(bsonReader, memberMap);
                                values[elementName] = value;
                            }
                        }
                        else
                        {
                            DeserializeExtraElement(bsonReader, obj, elementName, memberMap);
                        }
                        memberMapBitArray[memberMapIndex >> 5] |= 1U << (memberMapIndex & 31);
                    }
                    else
                    {
                        if (elementName == discriminatorConvention.ElementName)
                        {
                            bsonReader.SkipValue(); // skip over discriminator
                            continue;
                        }

                        if (extraElementsMemberMapIndex >= 0)
                        {
                            DeserializeExtraElement(bsonReader, obj, elementName, _classMap.ExtraElementsMemberMap);
                            memberMapBitArray[extraElementsMemberMapIndex >> 5] |= 1U << (extraElementsMemberMapIndex & 31);
                        }
                        else if (_classMap.IgnoreExtraElements)
                        {
                            bsonReader.SkipValue();
                        }
                        else
                        {
                            //james.wei 针对/_id属性没有扩展映射的提示。
                            var message = string.Format("Element '{0}' does not match any field or property of class {1}.",elementName, _classMap.ClassType.FullName);
                            throw new FileFormatException(message);
                        }
                    }
                }
                bsonReader.ReadEndDocument();

                // check any members left over that we didn't have elements for (in blocks of 32 elements at a time)
                for (var bitArrayIndex = 0; bitArrayIndex < memberMapBitArray.Length; ++bitArrayIndex)
                {
                    memberMapIndex = bitArrayIndex << 5;
                    var memberMapBlock = ~memberMapBitArray[bitArrayIndex]; // notice that bits are flipped so 1's are now the missing elements

                    // work through this memberMapBlock of 32 elements
                    while (true)
                    {
                        // examine missing elements (memberMapBlock is shifted right as we work through the block)
                        for (; (memberMapBlock & 1) != 0; ++memberMapIndex, memberMapBlock >>= 1)
                        {
                            var memberMap = allMemberMaps[memberMapIndex];
                            if (memberMap.IsReadOnly)
                            {
                                continue;
                            }

                            if (memberMap.IsRequired)
                            {
                                var fieldOrProperty = (memberMap.MemberInfo.MemberType == MemberTypes.Field) ? "field" : "property";
                                var message = string.Format(
                                    "Required element '{0}' for {1} '{2}' of class {3} is missing.",
                                    memberMap.ElementName, fieldOrProperty, memberMap.MemberName, _classMap.ClassType.FullName);
                                throw new FileFormatException(message);
                            }

                            if (obj != null)
                            {
                                memberMap.ApplyDefaultValue(obj);
                            }
                            else if (memberMap.IsDefaultValueSpecified && !memberMap.IsReadOnly)
                            {
                                values[memberMap.ElementName] = memberMap.DefaultValue;
                            }
                        }

                        if (memberMapBlock == 0)
                        {
                            break;
                        }

                        // skip ahead to the next missing element
                        var leastSignificantBit = FastMemberMapHelper.GetLeastSignificantBit(memberMapBlock);
                        memberMapIndex += leastSignificantBit;
                        memberMapBlock >>= leastSignificantBit;
                    }
                }

                if (obj != null)
                {
                    if (supportsInitialization != null)
                    {
                        supportsInitialization.EndInit();
                    }

                    return obj;
                }
                else
                {
                    return CreateInstanceUsingCreator(values);
                }

            }
        }
 public object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
 {
     this.VerifyNominalType(nominalType);
     if (bsonReader.CurrentBsonType == BsonType.Null)
     {
         bsonReader.ReadNull();
         return((object)null);
     }
     else
     {
         if (actualType.IsValueType)
         {
             throw new BsonSerializationException(string.Format("Value class {0} cannot be deserialized.", (object)actualType.FullName));
         }
         BsonClassMap bsonClassMap = BsonClassMap.LookupClassMap(actualType);
         if (bsonClassMap.IsAnonymous)
         {
             throw new InvalidOperationException("An anonymous class cannot be deserialized.");
         }
         // Added
         object instance = CreateInstance(bsonClassMap);
         // Added
         if (bsonReader.CurrentBsonType != BsonType.Document)
         {
             throw new FileFormatException(string.Format("Expected a nested document representing the serialized form of a {0} value, but found a value of type {1} instead.", (object)actualType.FullName, (object)bsonReader.CurrentBsonType));
         }
         bsonReader.ReadStartDocument();
         HashSet <BsonMemberMap>  hashSet = new HashSet <BsonMemberMap>(bsonClassMap.MemberMaps);
         IDiscriminatorConvention discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(nominalType);
         while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
         {
             string elementName = bsonReader.ReadName();
             if (elementName == discriminatorConvention.ElementName)
             {
                 bsonReader.SkipValue();
             }
             else
             {
                 BsonMemberMap memberMapForElement = bsonClassMap.GetMemberMapForElement(elementName);
                 if (memberMapForElement != null && memberMapForElement != bsonClassMap.ExtraElementsMemberMap)
                 {
                     this.DeserializeMember(bsonReader, instance, memberMapForElement);
                     hashSet.Remove(memberMapForElement);
                 }
                 else if (bsonClassMap.ExtraElementsMemberMap != null)
                 {
                     this.DeserializeExtraElement(bsonReader, instance, elementName, bsonClassMap.ExtraElementsMemberMap);
                 }
                 else
                 {
                     if (!bsonClassMap.IgnoreExtraElements)
                     {
                         throw new FileFormatException(string.Format("Element '{0}' does not match any field or property of class {1}.", (object)elementName, (object)bsonClassMap.ClassType.FullName));
                     }
                     bsonReader.SkipValue();
                 }
             }
         }
         bsonReader.ReadEndDocument();
         foreach (BsonMemberMap bsonMemberMap in hashSet)
         {
             if (bsonMemberMap.IsRequired)
             {
                 string str = bsonMemberMap.MemberInfo.MemberType == MemberTypes.Field ? "field" : "property";
                 throw new FileFormatException(string.Format("Required element '{0}' for {1} '{2}' of class {3} is missing.", (object)bsonMemberMap.ElementName, (object)str, (object)bsonMemberMap.MemberName, (object)bsonClassMap.ClassType.FullName));
             }
             else if (bsonMemberMap.HasDefaultValue)
             {
                 bsonMemberMap.ApplyDefaultValue(instance);
             }
         }
         return(instance);
     }
 }