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; }
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; }
/// <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; } }
/// <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; } }
// 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; } }
/// <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; } }
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; } }
/// <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; } }