예제 #1
0
            public BsonMemberMap GetMemberMapForElement(string elementName)
            {
                // linear search should be fast because elements will normally be in the same order as the member maps
                for (int i = _from; i <= _to; i++)
                {
                    var memberMap = _memberMaps[i];
                    if (memberMap == null)
                    {
                        if (i == _from)
                        {
                            _from++; // shrink the range from the left
                        }
                        continue;
                    }

                    if (memberMap.ElementName == elementName)
                    {
                        if (i == _from)
                        {
                            _from++; // shrink the range from the left
                        }
                        else if (i == _to)
                        {
                            _to--; // shrink the range from the right
                        }
                        else
                        {
                            _memberMaps[i] = null; // set to null so we don't think it's missing
                        }
                        return(memberMap);
                    }
                }

                // fall back to the class map in case it's a duplicate element name that we've already null'ed out
                // but make sure not to return the extraElementsMemberMap
                if (_extraElementsMemberMap == null || elementName != _extraElementsMemberMap.ElementName)
                {
                    return(_classMap.GetMemberMapForElement(elementName));
                }
                else
                {
                    return(null);
                }
            }
 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);
     }
 }