コード例 #1
0
 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;
 }
コード例 #2
0
        public override object Deserialize(BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options)
        {
            dynamic item = new ebayItemDataForSeller();
            IDictionary<String, Object> dict = new Dictionary<String, Object>();
            bsonReader.ReadStartDocument();
            while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
            {
                var elementName = bsonReader.ReadName();

                var pi = nominalType.GetProperty(elementName);
                if (pi != null)
                {
                    dynamic data = null;
                    if (bsonReader.CurrentBsonType.Equals(BsonType.Null))
                    {
                        bsonReader.ReadNull();
                    }
                    else
                    {
                        data = BsonDefaultSerializer.Instance.GetSerializer(pi.PropertyType).Deserialize(bsonReader, pi.PropertyType, options);
                        this.GetType().GetProperty(pi.Name).SetValue(item, data, null);
                    }
                }
                else
                {
                    if (bsonReader.CurrentBsonType.Equals(BsonType.Null))
                    {
                        bsonReader.SkipValue();
                    }
                    else dict[elementName] = bsonReader.ReadString();
                }
            }
            bsonReader.ReadEndDocument();

            item.SetDynamics(dict);
            return this;
        }
コード例 #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
            {
                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();

                if (bsonReader.CurrentBsonType != 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, bsonReader.CurrentBsonType);
                    throw new FileFormatException(message);
                }

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

                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);
                            missingElementMemberMaps.Remove(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);
                    }

                    memberMap.ApplyDefaultValue(obj);
                }

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

                return obj;
            }
        }
コード例 #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.");
                }
                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 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 (memberMap.IsReadOnly)
                            {
                                bsonReader.SkipValue();
                            }
                            else
                            {
                                DeserializeMember(bsonReader, obj, memberMap);
                            }
                        }
                        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
                    for (;;)
                    {
                        // 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);
                            }
                            memberMap.ApplyDefaultValue(obj);
                        }

                        if (memberMapBlock == 0)
                        {
                            break;
                        }

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

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

                return obj;
            }
        }
コード例 #5
0
ファイル: SystemProfileInfo.cs プロジェクト: abel/sinan
        // 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="actualType">The actual type of the object.</param>
        /// <param name="options">The serialization options.</param>
        /// <returns>An object.</returns>
        public override object Deserialize(
            BsonReader bsonReader,
            Type nominalType,
            Type actualType,
            IBsonSerializationOptions options)
        {
            VerifyTypes(nominalType, actualType, typeof(SystemProfileInfo));

            if (bsonReader.GetCurrentBsonType() == Bson.BsonType.Null)
            {
                bsonReader.ReadNull();
                return null;
            }
            else
            {
                var profileInfo = new SystemProfileInfo();

                bsonReader.ReadStartDocument();
                BsonType bsonType;
                while ((bsonType = bsonReader.ReadBsonType()) != BsonType.EndOfDocument)
                {
                    var name = bsonReader.ReadName();
                    switch (name)
                    {
                        case "abbreviated":
                            profileInfo.Abbreviated = bsonReader.ReadString();
                            break;
                        case "client":
                            profileInfo.Client = bsonReader.ReadString();
                            break;
                        case "command":
                            profileInfo.Command = BsonDocument.ReadFrom(bsonReader);
                            break;
                        case "cursorid":
                            profileInfo.CursorId = BsonValue.ReadFrom(bsonReader).ToInt64();
                            break;
                        case "err":
                            profileInfo.Error = bsonReader.ReadString();
                            break;
                        case "exception":
                            profileInfo.Exception = bsonReader.ReadString();
                            break;
                        case "exceptionCode":
                            profileInfo.ExceptionCode = BsonValue.ReadFrom(bsonReader).ToInt32();
                            break;
                        case "exhaust":
                            profileInfo.Exhaust = BsonValue.ReadFrom(bsonReader).ToBoolean();
                            break;
                        case "fastmod":
                            profileInfo.FastMod = BsonValue.ReadFrom(bsonReader).ToBoolean();
                            break;
                        case "fastmodinsert":
                            profileInfo.FastModInsert = BsonValue.ReadFrom(bsonReader).ToBoolean();
                            break;
                        case "idhack":
                            profileInfo.IdHack = BsonValue.ReadFrom(bsonReader).ToBoolean();
                            break;
                        case "info":
                            profileInfo.Info = bsonReader.ReadString();
                            break;
                        case "keyUpdates":
                            profileInfo.KeyUpdates = BsonValue.ReadFrom(bsonReader).ToInt32();
                            break;
                        case "millis":
                            profileInfo.Duration = TimeSpan.FromMilliseconds(BsonValue.ReadFrom(bsonReader).ToDouble());
                            break;
                        case "moved":
                            profileInfo.Moved = BsonValue.ReadFrom(bsonReader).ToBoolean();
                            break;
                        case "nreturned":
                            profileInfo.NumberReturned = BsonValue.ReadFrom(bsonReader).ToInt32();
                            break;
                        case "ns":
                            profileInfo.Namespace = bsonReader.ReadString();
                            break;
                        case "nscanned":
                            profileInfo.NumberScanned = BsonValue.ReadFrom(bsonReader).ToInt32();
                            break;
                        case "ntoreturn":
                            profileInfo.NumberToReturn = BsonValue.ReadFrom(bsonReader).ToInt32();
                            break;
                        case "ntoskip":
                            profileInfo.NumberToSkip = BsonValue.ReadFrom(bsonReader).ToInt32();
                            break;
                        case "op":
                            profileInfo.Op = bsonReader.ReadString();
                            break;
                        case "query":
                            profileInfo.Query = BsonDocument.ReadFrom(bsonReader);
                            break;
                        case "responseLength":
                            profileInfo.ResponseLength = BsonValue.ReadFrom(bsonReader).ToInt32();
                            break;
                        case "scanAndOrder":
                            profileInfo.ScanAndOrder = BsonValue.ReadFrom(bsonReader).ToBoolean();
                            break;
                        case "ts":
                            profileInfo.Timestamp = BsonUtils.ToDateTimeFromMillisecondsSinceEpoch(bsonReader.ReadDateTime());
                            break;
                        case "updateobj":
                            profileInfo.UpdateObject = BsonDocument.ReadFrom(bsonReader);
                            break;
                        case "upsert":
                            profileInfo.Upsert = BsonValue.ReadFrom(bsonReader).ToBoolean();
                            break;
                        case "user":
                            profileInfo.User = bsonReader.ReadString();
                            break;
                        default:
                            bsonReader.SkipValue(); // ignore unknown elements
                            break;
                    }
                }
                bsonReader.ReadEndDocument();

                return profileInfo;
            }
        }
コード例 #6
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("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 {
                            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 '{0}' is missing.", memberMap.ElementName);
                        throw new FileFormatException(message);
                    }

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

                return obj;
            }
        }
コード例 #7
0
		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;
			}
		}
コード例 #8
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;
            }
        }