void WriteAttributeMembers(ClassMap map, object ob, bool isValueList)
        {
            // Write attributes

            XmlTypeMapMember anyAttrMember = map.DefaultAnyAttributeMember;

            if (anyAttrMember != null && MemberHasValue(anyAttrMember, ob, isValueList))
            {
                ICollection extraAtts = (ICollection)GetMemberValue(anyAttrMember, ob, isValueList);
                if (extraAtts != null)
                {
                    foreach (XmlAttribute attr in extraAtts)
                    {
                        if (attr.NamespaceURI != xmlNamespace)
                        {
                            WriteXmlAttribute(attr, ob);
                        }
                    }
                }
            }

            ICollection attributes = map.AttributeMembers;

            if (attributes != null)
            {
                foreach (XmlTypeMapMemberAttribute attr in attributes)
                {
                    if (MemberHasValue(attr, ob, isValueList))
                    {
                        WriteAttribute(attr.AttributeName, attr.Namespace, GetStringValue(attr.MappedType, attr.TypeData, GetMemberValue(attr, ob, isValueList)));
                    }
                }
            }
        }
        bool MemberHasValue(XmlTypeMapMember member, object ob, bool isValueList)
        {
            if (isValueList)
            {
                return(member.GlobalIndex < ((object[])ob).Length);
            }
            else if (member.DefaultValue != System.DBNull.Value)
            {
                object val = GetMemberValue(member, ob, isValueList);
                if (val == null && member.DefaultValue == null)
                {
                    return(false);
                }
                if (val != null && val.GetType().IsEnum)
                {
                    if (val.Equals(member.DefaultValue))
                    {
                        return(false);
                    }
                    Type t = Enum.GetUnderlyingType(val.GetType());
                    val = Convert.ChangeType(val, t);
                }
                if (val != null && val.Equals(member.DefaultValue))
                {
                    return(false);
                }
            }
            else if (member.IsOptionalValueType)
            {
                return(member.GetValueSpecified(ob));
            }

            return(true);
        }
示例#3
0
 public XmlTypeMapElementInfo(XmlTypeMapMember member, TypeData type)
 {
     _member = member;
     _type   = type;
     if (type.IsValueType && type.IsNullable)
     {
         _isNullable = true;
     }
 }
        void ReadAttributeMembers(ClassMap map, object ob, bool isValueList)
        {
            XmlTypeMapMember anyAttrMember = map.DefaultAnyAttributeMember;
            int    anyAttributeIndex       = 0;
            object anyAttributeArray       = null;

            while (Reader.MoveToNextAttribute())
            {
                XmlTypeMapMemberAttribute member = map.GetAttribute(Reader.LocalName, Reader.NamespaceURI);

                if (member != null)
                {
                    SetMemberValue(member, ob, GetValueFromXmlString(Reader.Value, member.TypeData, member.MappedType), isValueList);
                }
                else if (IsXmlnsAttribute(Reader.Name))
                {
                    // If the map has NamespaceDeclarations,
                    // then store this xmlns to the given member.
                    // If the instance doesn't exist, then create.
                    if (map.NamespaceDeclarations != null)
                    {
                        XmlSerializerNamespaces nss = this.GetMemberValue(map.NamespaceDeclarations, ob, isValueList) as XmlSerializerNamespaces;
                        if (nss == null)
                        {
                            nss = new XmlSerializerNamespaces();
                            SetMemberValue(map.NamespaceDeclarations, ob, nss, isValueList);
                        }
                        if (Reader.Prefix == "xmlns")
                        {
                            nss.Add(Reader.LocalName, Reader.Value);
                        }
                        else
                        {
                            nss.Add("", Reader.Value);
                        }
                    }
                }
                else if (anyAttrMember != null)
                {
                    XmlAttribute attr = (XmlAttribute)Document.ReadNode(Reader);
                    ParseWsdlArrayType(attr);
                    AddListValue(anyAttrMember.TypeData, ref anyAttributeArray, anyAttributeIndex++, attr, true);
                }
                else
                {
                    ProcessUnknownAttribute(ob);
                }
            }

            if (anyAttrMember != null)
            {
                anyAttributeArray = ShrinkArray((Array)anyAttributeArray, anyAttributeIndex, anyAttrMember.TypeData.Type.GetElementType(), true);
                SetMemberValue(anyAttrMember, ob, anyAttributeArray, isValueList);
            }
            Reader.MoveToElement();
        }
 object GetMemberValue(XmlTypeMapMember member, object ob, bool isValueList)
 {
     if (isValueList)
     {
         return(((object[])ob)[member.GlobalIndex]);
     }
     else
     {
         return(member.GetValue(ob));
     }
 }
 bool IsReadOnly(XmlTypeMapMember member, TypeData memType, object ob, bool isValueList)
 {
     if (isValueList)
     {
         return(!memType.HasPublicConstructor);
     }
     else
     {
         return(member.IsReadOnly(ob.GetType()) || !memType.HasPublicConstructor);
     }
 }
        void SetMemberValueFromAttr(XmlTypeMapMember member, object ob, object value, bool isValueList)
        {
            // Enumeration values specified in custom attributes are stored as integer
            // values if the custom attribute property is of type object. So, it is
            // necessary to convert to the enum type before asigning the value to the field.

            if (member.TypeData.Type.IsEnum)
            {
                value = Enum.ToObject(member.TypeData.Type, value);
            }
            SetMemberValue(member, ob, value, isValueList);
        }
 void SetMemberValue(XmlTypeMapMember member, object ob, object value, bool isValueList)
 {
     if (isValueList)
     {
         ((object[])ob)[member.GlobalIndex] = value;
     }
     else
     {
         member.SetValue(ob, value);
         if (member.IsOptionalValueType)
         {
             member.SetValueSpecified(ob, true);
         }
     }
 }
示例#9
0
 bool DefinedInBaseMap(XmlTypeMapping map, XmlTypeMapMember member)
 {
     if (((ClassMap)map.ObjectMap).FindMember(member.Name) != null)
     {
         return(true);
     }
     else if (map.BaseMap != null)
     {
         return(DefinedInBaseMap(map.BaseMap, member));
     }
     else
     {
         return(false);
     }
 }
示例#10
0
        XmlMembersMapping ImportMembersMapping(string elementName, string ns, XmlReflectionMember[] members, bool hasWrapperElement, bool writeAccessors, bool validate, XmlMappingAccess access)
        {
            elementName = XmlConvert.EncodeLocalName(elementName);
            XmlMemberMapping[] mapping = new XmlMemberMapping[members.Length];
            for (int n = 0; n < members.Length; n++)
            {
                XmlTypeMapMember mapMem = CreateMapMember(members[n], ns);
                mapping[n] = new XmlMemberMapping(XmlConvert.EncodeLocalName(members[n].MemberName), ns, mapMem, true);
            }
            XmlMembersMapping mps = new XmlMembersMapping(elementName, ns, hasWrapperElement, writeAccessors, mapping);

            mps.RelatedMaps = relatedMaps;
            mps.Format      = SerializationFormat.Encoded;
            Type[] extraTypes = includedTypes != null ? (Type[])includedTypes.ToArray(typeof(Type)) : null;
            mps.Source = new MembersSerializationSource(elementName, hasWrapperElement, members, writeAccessors, false, null, extraTypes);
            return(mps);
        }
 void SetListMembersDefaults(ClassMap map, object ob, bool isValueList)
 {
     if (map.ListMembers != null)
     {
         ArrayList members = map.ListMembers;
         for (int n = 0; n < members.Count; n++)
         {
             XmlTypeMapMember mem = (XmlTypeMapMember)members[n];
             if (IsReadOnly(mem, mem.TypeData, ob, isValueList))
             {
                 continue;
             }
             if (GetMemberValue(mem, ob, isValueList) == null)
             {
                 SetMemberValue(mem, ob, InitializeList(mem.TypeData), isValueList);
             }
         }
     }
 }
示例#12
0
 public XmlTypeMapElementInfo FindElement(object ob, int index, object memberValue)
 {
     if (_itemInfo.Count == 1)
     {
         return((XmlTypeMapElementInfo)_itemInfo[0]);
     }
     else if (_choiceMember != null && index != -1)
     {
         Array values = (Array)XmlTypeMapMember.GetValue(ob, _choiceMember);
         if (values == null || index >= values.Length)
         {
             throw new InvalidOperationException("Invalid or missing choice enum value in member '" + _choiceMember + "'.");
         }
         object val = values.GetValue(index);
         foreach (XmlTypeMapElementInfo elem in _itemInfo)
         {
             if (elem.ChoiceValue != null && elem.ChoiceValue.Equals(val))
             {
                 return(elem);
             }
         }
     }
     else
     {
         if (memberValue == null)
         {
             return(null);
         }
         Type type = memberValue.GetType();
         foreach (XmlTypeMapElementInfo elem in _itemInfo)
         {
             if (elem.TypeData.Type == type)
             {
                 return(elem);
             }
         }
     }
     return(null);
 }
示例#13
0
        internal XmlMemberMapping(string memberName, string defaultNamespace, XmlTypeMapMember mapMem, bool encodedFormat)
        {
            _mapMember  = mapMem;
            _memberName = memberName;

            if (mapMem is XmlTypeMapMemberAnyElement)
            {
                XmlTypeMapMemberAnyElement anyelem = (XmlTypeMapMemberAnyElement)mapMem;
                XmlTypeMapElementInfo      info    = (XmlTypeMapElementInfo)anyelem.ElementInfo[anyelem.ElementInfo.Count - 1];
                _elementName = info.ElementName;
                _namespace   = info.Namespace;
                if (info.MappedType != null)
                {
                    _typeNamespace = info.MappedType.Namespace;
                }
                else
                {
                    _typeNamespace = "";
                }
            }
            else if (mapMem is XmlTypeMapMemberElement)
            {
                XmlTypeMapElementInfo info = (XmlTypeMapElementInfo)((XmlTypeMapMemberElement)mapMem).ElementInfo[0];
                _elementName = info.ElementName;
                if (encodedFormat)
                {
                    _namespace = defaultNamespace;
                    if (info.MappedType != null)
                    {
                        _typeNamespace = "";
                    }
                    else
                    {
                        _typeNamespace = info.DataTypeNamespace;
                    }
                }
                else
                {
                    _namespace = info.Namespace;
                    if (info.MappedType != null)
                    {
                        _typeNamespace = info.MappedType.Namespace;
                    }
                    else
                    {
                        _typeNamespace = "";
                    }
                    _form = info.Form;
                }
            }
            else
            {
                _elementName = _memberName;
                _namespace   = "";
            }

            if (_form == XmlSchemaForm.None)
            {
                _form = XmlSchemaForm.Qualified;
            }
        }
示例#14
0
        void ExportMembersMapCode(CodeTypeDeclaration codeClass, ClassMap map, string defaultNamespace, XmlTypeMapping baseMap)
        {
            ICollection attributes = map.AttributeMembers;
            ICollection members    = map.ElementMembers;

            // collect names
            if (attributes != null)
            {
                foreach (XmlTypeMapMemberAttribute attr in attributes)
                {
                    identifiers.AddUnique(attr.Name, attr);
                }
            }
            if (members != null)
            {
                foreach (XmlTypeMapMemberElement member in members)
                {
                    identifiers.AddUnique(member.Name, member);
                }
            }

            // Write attributes

            if (attributes != null)
            {
                foreach (XmlTypeMapMemberAttribute attr in attributes)
                {
                    if (baseMap != null && DefinedInBaseMap(baseMap, attr))
                    {
                        continue;
                    }
                    AddAttributeFieldMember(codeClass, attr, defaultNamespace);
                }
            }

            members = map.ElementMembers;

            if (members != null)
            {
                foreach (XmlTypeMapMemberElement member in members)
                {
                    if (baseMap != null && DefinedInBaseMap(baseMap, member))
                    {
                        continue;
                    }

                    Type memType = member.GetType();
                    if (memType == typeof(XmlTypeMapMemberList))
                    {
                        AddArrayElementFieldMember(codeClass, (XmlTypeMapMemberList)member, defaultNamespace);
                    }
                    else if (memType == typeof(XmlTypeMapMemberFlatList))
                    {
                        AddElementFieldMember(codeClass, member, defaultNamespace);
                    }
                    else if (memType == typeof(XmlTypeMapMemberAnyElement))
                    {
                        AddAnyElementFieldMember(codeClass, member, defaultNamespace);
                    }
                    else if (memType == typeof(XmlTypeMapMemberElement))
                    {
                        AddElementFieldMember(codeClass, member, defaultNamespace);
                    }
                    else
                    {
                        throw new InvalidOperationException("Member type " + memType + " not supported");
                    }
                }
            }

            XmlTypeMapMember anyAttrMember = map.DefaultAnyAttributeMember;

            if (anyAttrMember != null)
            {
                CodeTypeMember codeField = CreateFieldMember(codeClass, anyAttrMember.TypeData, anyAttrMember.Name);
                AddComments(codeField, anyAttrMember.Documentation);
                codeField.Attributes = MemberAttributes.Public;
                GenerateAnyAttribute(codeField);
            }
        }
示例#15
0
        void ExportMembersMapSchema(XmlSchema schema, ClassMap map, XmlTypeMapping baseMap, XmlSchemaObjectCollection outAttributes, out XmlSchemaSequence particle, out XmlSchemaAnyAttribute anyAttribute)
        {
            particle = null;
            XmlSchemaSequence seq = new XmlSchemaSequence();

            ICollection members = map.ElementMembers;

            if (members != null && !map.HasSimpleContent)
            {
                foreach (XmlTypeMapMemberElement member in members)
                {
                    if (baseMap != null && DefinedInBaseMap(baseMap, member))
                    {
                        continue;
                    }

                    Type memType = member.GetType();
                    if (memType == typeof(XmlTypeMapMemberFlatList))
                    {
                        XmlSchemaParticle part = GetSchemaArrayElement(schema, member.ElementInfo);
                        if (part != null)
                        {
                            seq.Items.Add(part);
                        }
                    }
                    else if (memType == typeof(XmlTypeMapMemberAnyElement))
                    {
                        seq.Items.Add(GetSchemaArrayElement(schema, member.ElementInfo));
                    }
                    else if (memType == typeof(XmlTypeMapMemberElement))
                    {
                        GetSchemaElement(schema, (XmlTypeMapElementInfo)member.ElementInfo [0],
                                         member.DefaultValue, true, new XmlSchemaObjectContainer(seq));
                    }
                    else
                    {
                        GetSchemaElement(schema, (XmlTypeMapElementInfo)member.ElementInfo[0],
                                         true, new XmlSchemaObjectContainer(seq));
                    }
                }
            }

            if (seq.Items.Count > 0)
            {
                particle = seq;
            }

            // Write attributes

            ICollection attributes = map.AttributeMembers;

            if (attributes != null)
            {
                foreach (XmlTypeMapMemberAttribute attr in attributes)
                {
                    if (baseMap != null && DefinedInBaseMap(baseMap, attr))
                    {
                        continue;
                    }
                    outAttributes.Add(GetSchemaAttribute(schema, attr, true));
                }
            }

            XmlTypeMapMember anyAttrMember = map.DefaultAnyAttributeMember;

            if (anyAttrMember != null)
            {
                anyAttribute = new XmlSchemaAnyAttribute();
            }
            else
            {
                anyAttribute = null;
            }
        }
示例#16
0
 CodeTypeMember CreateFieldMember(CodeTypeDeclaration codeClass, XmlTypeMapMember member)
 {
     return(CreateFieldMember(codeClass, GetDomType(member.TypeData, member.RequiresNullable), member.Name, member.DefaultValue, member.TypeData, member.Documentation));
 }
示例#17
0
        public void AddMember(XmlTypeMapMember member)
        {
            member.GlobalIndex = _allMembers.Count;
            _allMembers.Add(member);

            if (!(member.DefaultValue is System.DBNull) && member.DefaultValue != null)
            {
                if (_membersWithDefault == null)
                {
                    _membersWithDefault = new ArrayList();
                }
                _membersWithDefault.Add(member);
            }

            if (member.IsReturnValue)
            {
                _returnMember = member;
            }

            if (member is XmlTypeMapMemberAttribute)
            {
                XmlTypeMapMemberAttribute atm = (XmlTypeMapMemberAttribute)member;
                if (_attributeMembers == null)
                {
                    _attributeMembers = new Hashtable();
                }
                string key = BuildKey(atm.AttributeName, atm.Namespace);
                if (_attributeMembers.ContainsKey(key))
                {
                    throw new InvalidOperationException("The XML attribute named '" + atm.AttributeName + "' from namespace '" + atm.Namespace + "' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the attribute.");
                }
                member.Index = _attributeMembers.Count;
                _attributeMembers.Add(key, member);
                return;
            }
            else if (member is XmlTypeMapMemberFlatList)
            {
                RegisterFlatList((XmlTypeMapMemberFlatList)member);
            }
            else if (member is XmlTypeMapMemberAnyElement)
            {
                XmlTypeMapMemberAnyElement mem = (XmlTypeMapMemberAnyElement)member;
                if (mem.IsDefaultAny)
                {
                    _defaultAnyElement = mem;
                }
                if (mem.TypeData.IsListType)
                {
                    RegisterFlatList(mem);
                }
            }
            else if (member is XmlTypeMapMemberAnyAttribute)
            {
                _defaultAnyAttribute = (XmlTypeMapMemberAnyAttribute)member;
                return;
            }
            else if (member is XmlTypeMapMemberNamespaces)
            {
                _namespaceDeclarations = (XmlTypeMapMemberNamespaces)member;
                return;
            }

            if (member is XmlTypeMapMemberElement && ((XmlTypeMapMemberElement)member).IsXmlTextCollector)
            {
                if (_xmlTextCollector != null)
                {
                    throw new InvalidOperationException("XmlTextAttribute can only be applied once in a class");
                }
                _xmlTextCollector = member;
            }

            if (_elementMembers == null)
            {
                _elementMembers = new ArrayList();
                _elements       = new Hashtable();
            }

            member.Index = _elementMembers.Count;
            _elementMembers.Add(member);

            ICollection elemsInfo = ((XmlTypeMapMemberElement)member).ElementInfo;

            foreach (XmlTypeMapElementInfo elem in elemsInfo)
            {
                string key = BuildKey(elem.ElementName, elem.Namespace);
                if (_elements.ContainsKey(key))
                {
                    throw new InvalidOperationException("The XML element named '" + elem.ElementName + "' from namespace '" + elem.Namespace + "' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the element.");
                }
                _elements.Add(key, elem);
            }

            if (member.TypeData.IsListType && member.TypeData.Type != null && !member.TypeData.Type.IsArray)
            {
                if (_listMembers == null)
                {
                    _listMembers = new ArrayList();
                }
                _listMembers.Add(member);
            }
        }
        protected virtual object ReadMessage(XmlMembersMapping typeMap)
        {
            object[] parameters = new object[typeMap.Count];

            if (typeMap.HasWrapperElement)
            {
                // bug #79988: out parameters need to be initialized if they
                // are value types
                ArrayList members = ((ClassMap)typeMap.ObjectMap).AllMembers;
                for (int n = 0; n < members.Count; n++)
                {
                    XmlTypeMapMember mem = (XmlTypeMapMember)members [n];
                    if (!mem.IsReturnValue && mem.TypeData.IsValueType)
                    {
                        SetMemberValueFromAttr(mem, parameters, CreateInstance(
                                                   mem.TypeData.Type), true);
                    }
                }

                if (_format == SerializationFormat.Encoded)
                {
                    while (Reader.NodeType == System.Xml.XmlNodeType.Element)
                    {
                        string root = Reader.GetAttribute("root", XmlSerializer.EncodingNamespace);
                        if (root == null || System.Xml.XmlConvert.ToBoolean(root))
                        {
                            break;
                        }
                        ReadReferencedElement();
                        Reader.MoveToContent();
                    }
                }

                while (Reader.NodeType != System.Xml.XmlNodeType.EndElement &&
                       // it could be an empty root element
                       Reader.ReadState == ReadState.Interactive)
                {
                    if (Reader.IsStartElement(typeMap.ElementName, typeMap.Namespace) ||
                        _format == SerializationFormat.Encoded)
                    {
                        ReadAttributeMembers((ClassMap)typeMap.ObjectMap, parameters, true);
                        if (Reader.IsEmptyElement)
                        {
                            Reader.Skip();
                            Reader.MoveToContent();
                            continue;
                        }
                        Reader.ReadStartElement();
                        ReadMembers((ClassMap)typeMap.ObjectMap, parameters, true, false);
                        ReadEndElement();
                        break;
                    }
                    else
                    {
                        UnknownNode(null);
                    }

                    Reader.MoveToContent();
                }
            }
            else
            {
                ReadMembers((ClassMap)typeMap.ObjectMap, parameters, true, _format == SerializationFormat.Encoded);
            }

            if (_format == SerializationFormat.Encoded)
            {
                ReadReferencedElements();
            }

            return(parameters);
        }
        void ReadMembers(ClassMap map, object ob, bool isValueList, bool readByOrder)
        {
            // Reads attributes
            ReadAttributeMembers(map, ob, isValueList);

            if (!isValueList)
            {
                Reader.MoveToElement();
                if (Reader.IsEmptyElement)
                {
                    SetListMembersDefaults(map, ob, isValueList);
                    return;
                }

                Reader.ReadStartElement();
            }

            // Reads elements

            bool[] readFlag = new bool[(map.ElementMembers != null) ? map.ElementMembers.Count : 0];

            bool hasAnyReturnMember = (isValueList && _format == SerializationFormat.Encoded && map.ReturnMember != null);

            Reader.MoveToContent();

            int[]    indexes          = null;
            object[] flatLists        = null;
            object[] flatListsChoices = null;
            Fixup    fixup            = null;
            int      ind = 0;
            int      maxInd;

            if (readByOrder)
            {
                if (map.ElementMembers != null)
                {
                    maxInd = map.ElementMembers.Count;
                }
                else
                {
                    maxInd = 0;
                }
            }
            else
            {
                maxInd = int.MaxValue;
            }

            if (map.FlatLists != null)
            {
                indexes   = new int[map.FlatLists.Count];
                flatLists = new object[map.FlatLists.Count];
                foreach (XmlTypeMapMemberExpandable mem in map.FlatLists)
                {
                    if (IsReadOnly(mem, mem.TypeData, ob, isValueList))
                    {
                        flatLists [mem.FlatArrayIndex] = mem.GetValue(ob);
                    }
                    else if (mem.TypeData.Type.IsArray)
                    {
                        flatLists [mem.FlatArrayIndex] = InitializeList(mem.TypeData);
                    }
                    else
                    {
                        object list = mem.GetValue(ob);
                        if (list == null)
                        {
                            list = InitializeList(mem.TypeData);
                            SetMemberValue(mem, ob, list, isValueList);
                        }
                        flatLists [mem.FlatArrayIndex] = list;
                    }

                    if (mem.ChoiceMember != null)
                    {
                        if (flatListsChoices == null)
                        {
                            flatListsChoices = new object [map.FlatLists.Count];
                        }
                        flatListsChoices [mem.FlatArrayIndex] = InitializeList(mem.ChoiceTypeData);
                    }
                }
            }

            if (_format == SerializationFormat.Encoded && map.ElementMembers != null)
            {
                FixupCallbackInfo info = new FixupCallbackInfo(this, map, isValueList);
                fixup = new Fixup(ob, new XmlSerializationFixupCallback(info.FixupMembers), map.ElementMembers.Count);
                AddFixup(fixup);
            }

            while (Reader.NodeType != System.Xml.XmlNodeType.EndElement && (ind < maxInd))
            {
                if (Reader.NodeType == System.Xml.XmlNodeType.Element)
                {
                    XmlTypeMapElementInfo info;

                    if (readByOrder)
                    {
                        info = map.GetElement(ind++);
                    }
                    else if (hasAnyReturnMember)
                    {
                        info = (XmlTypeMapElementInfo)((XmlTypeMapMemberElement)map.ReturnMember).ElementInfo[0];
                        hasAnyReturnMember = false;
                    }
                    else
                    {
                        info = map.GetElement(Reader.LocalName, Reader.NamespaceURI);
                    }

                    if (info != null && !readFlag[info.Member.Index])
                    {
                        if (info.Member.GetType() == typeof(XmlTypeMapMemberList))
                        {
                            if (_format == SerializationFormat.Encoded && info.MultiReferenceType)
                            {
                                object list = ReadReferencingElement(out fixup.Ids[info.Member.Index]);
                                if (fixup.Ids[info.Member.Index] == null)                                       // Already read
                                {
                                    if (IsReadOnly(info.Member, info.TypeData, ob, isValueList))
                                    {
                                        throw CreateReadOnlyCollectionException(info.TypeData.FullTypeName);
                                    }
                                    else
                                    {
                                        SetMemberValue(info.Member, ob, list, isValueList);
                                    }
                                }
                                else if (!info.MappedType.TypeData.Type.IsArray)
                                {
                                    if (IsReadOnly(info.Member, info.TypeData, ob, isValueList))
                                    {
                                        list = GetMemberValue(info.Member, ob, isValueList);
                                    }
                                    else
                                    {
                                        list = CreateList(info.MappedType.TypeData.Type);
                                        SetMemberValue(info.Member, ob, list, isValueList);
                                    }
                                    AddFixup(new CollectionFixup(list, new XmlSerializationCollectionFixupCallback(FillList), fixup.Ids[info.Member.Index]));
                                    fixup.Ids[info.Member.Index] = null;                                        // The member already has the value, no further fix needed.
                                }
                            }
                            else
                            {
                                if (IsReadOnly(info.Member, info.TypeData, ob, isValueList))
                                {
                                    ReadListElement(info.MappedType, info.IsNullable, GetMemberValue(info.Member, ob, isValueList), false);
                                }
                                else if (info.MappedType.TypeData.Type.IsArray)
                                {
                                    object list = ReadListElement(info.MappedType, info.IsNullable, null, true);
                                    if (list != null || info.IsNullable)
                                    {
                                        SetMemberValue(info.Member, ob, list, isValueList);
                                    }
                                }
                                else
                                {
                                    // If the member already has a list, reuse that list. No need to create a new one.
                                    object list = GetMemberValue(info.Member, ob, isValueList);
                                    if (list == null)
                                    {
                                        list = CreateList(info.MappedType.TypeData.Type);
                                        SetMemberValue(info.Member, ob, list, isValueList);
                                    }
                                    ReadListElement(info.MappedType, info.IsNullable, list, true);
                                }
                            }
                            readFlag[info.Member.Index] = true;
                        }
                        else if (info.Member.GetType() == typeof(XmlTypeMapMemberFlatList))
                        {
                            XmlTypeMapMemberFlatList mem = (XmlTypeMapMemberFlatList)info.Member;
                            AddListValue(mem.TypeData, ref flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex]++, ReadObjectElement(info), !IsReadOnly(info.Member, info.TypeData, ob, isValueList));
                            if (mem.ChoiceMember != null)
                            {
                                AddListValue(mem.ChoiceTypeData, ref flatListsChoices [mem.FlatArrayIndex], indexes[mem.FlatArrayIndex] - 1, info.ChoiceValue, true);
                            }
                        }
                        else if (info.Member.GetType() == typeof(XmlTypeMapMemberAnyElement))
                        {
                            XmlTypeMapMemberAnyElement mem = (XmlTypeMapMemberAnyElement)info.Member;
                            if (mem.TypeData.IsListType)
                            {
                                AddListValue(mem.TypeData, ref flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex]++, ReadXmlNode(mem.TypeData.ListItemTypeData, false), true);
                            }
                            else
                            {
                                SetMemberValue(mem, ob, ReadXmlNode(mem.TypeData, false), isValueList);
                            }
                        }
                        else if (info.Member.GetType() == typeof(XmlTypeMapMemberElement))
                        {
                            object val;
                            readFlag[info.Member.Index] = true;
                            if (_format == SerializationFormat.Encoded)
                            {
                                if (info.Member.TypeData.SchemaType != SchemaTypes.Primitive)
                                {
                                    val = ReadReferencingElement(out fixup.Ids[info.Member.Index]);
                                }
                                else
                                {
                                    val = ReadReferencingElement(info.Member.TypeData.XmlType, System.Xml.Schema.XmlSchema.Namespace, out fixup.Ids[info.Member.Index]);
                                }

                                if (info.MultiReferenceType)
                                {
                                    if (fixup.Ids[info.Member.Index] == null)                                           // already read
                                    {
                                        SetMemberValue(info.Member, ob, val, isValueList);
                                    }
                                }
                                else if (val != null)
                                {
                                    SetMemberValue(info.Member, ob, val, isValueList);
                                }
                            }
                            else
                            {
                                SetMemberValue(info.Member, ob, ReadObjectElement(info), isValueList);
                                if (info.ChoiceValue != null)
                                {
                                    XmlTypeMapMemberElement imem = (XmlTypeMapMemberElement)info.Member;
                                    imem.SetChoice(ob, info.ChoiceValue);
                                }
                            }
                        }
                        else
                        {
                            throw new InvalidOperationException("Unknown member type");
                        }
                    }
                    else if (map.DefaultAnyElementMember != null)
                    {
                        XmlTypeMapMemberAnyElement mem = map.DefaultAnyElementMember;
                        if (mem.TypeData.IsListType)
                        {
                            AddListValue(mem.TypeData, ref flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex]++, ReadXmlNode(mem.TypeData.ListItemTypeData, false), true);
                        }
                        else
                        {
                            SetMemberValue(mem, ob, ReadXmlNode(mem.TypeData, false), isValueList);
                        }
                    }
                    else
                    {
                        ProcessUnknownElement(ob);
                    }
                }
                else if ((Reader.NodeType == System.Xml.XmlNodeType.Text || Reader.NodeType == System.Xml.XmlNodeType.CDATA) && map.XmlTextCollector != null)
                {
                    if (map.XmlTextCollector is XmlTypeMapMemberExpandable)
                    {
                        XmlTypeMapMemberExpandable mem   = (XmlTypeMapMemberExpandable)map.XmlTextCollector;
                        XmlTypeMapMemberFlatList   flatl = mem as XmlTypeMapMemberFlatList;
                        TypeData itype = (flatl == null) ? mem.TypeData.ListItemTypeData : flatl.ListMap.FindTextElement().TypeData;

                        object val = (itype.Type == typeof(string)) ? (object)Reader.ReadString() : (object)ReadXmlNode(itype, false);
                        AddListValue(mem.TypeData, ref flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex]++, val, true);
                    }
                    else
                    {
                        XmlTypeMapMemberElement mem  = (XmlTypeMapMemberElement)map.XmlTextCollector;
                        XmlTypeMapElementInfo   info = (XmlTypeMapElementInfo)mem.ElementInfo [0];
                        if (info.TypeData.Type == typeof(string))
                        {
                            SetMemberValue(mem, ob, ReadString((string)GetMemberValue(mem, ob, isValueList)), isValueList);
                        }
                        else
                        {
                            SetMemberValue(mem, ob, GetValueFromXmlString(Reader.ReadString(), info.TypeData, info.MappedType), isValueList);
                        }
                    }
                }
                else
                {
                    UnknownNode(ob);
                }

                Reader.MoveToContent();
            }

            if (flatLists != null)
            {
                foreach (XmlTypeMapMemberExpandable mem in map.FlatLists)
                {
                    Object list = flatLists[mem.FlatArrayIndex];
                    if (mem.TypeData.Type.IsArray)
                    {
                        list = ShrinkArray((Array)list, indexes[mem.FlatArrayIndex], mem.TypeData.Type.GetElementType(), true);
                    }
                    if (!IsReadOnly(mem, mem.TypeData, ob, isValueList) && mem.TypeData.Type.IsArray)
                    {
                        SetMemberValue(mem, ob, list, isValueList);
                    }
                }
            }

            if (flatListsChoices != null)
            {
                foreach (XmlTypeMapMemberExpandable mem in map.FlatLists)
                {
                    Object list = flatListsChoices[mem.FlatArrayIndex];
                    if (list == null)
                    {
                        continue;
                    }
                    list = ShrinkArray((Array)list, indexes[mem.FlatArrayIndex], mem.ChoiceTypeData.Type.GetElementType(), true);
                    XmlTypeMapMember.SetValue(ob, mem.ChoiceMember, list);
                }
            }
            SetListMembersDefaults(map, ob, isValueList);
        }