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);
     }
 }
        void SetMemberValue(XmlTypeMapMember member, object ob, object value, bool isValueList)
        {
            var memberType = member.TypeData.Type;

            if (value != null && !value.GetType().IsAssignableFrom(memberType))
            {
                value = XmlSerializationWriterInterpreter.ImplicitConvert(value, memberType);
            }

            if (isValueList)
            {
                ((object[])ob)[member.GlobalIndex] = value;
            }
            else
            {
                member.SetValue(ob, value);
            }
            if (member.IsOptionalValueType)
            {
                member.SetValueSpecified(ob, true);
            }
        }
		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); 
			}
		}
        void ReadMembers(ClassMap map, object ob, bool isValueList, bool readBySoapOrder)
        {
            // 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 = -1;
            int      maxInd;

            if (readBySoapOrder)
            {
                if (map.ElementMembers != null)
                {
                    maxInd = map.ElementMembers.Count;
                }
                else
                {
                    maxInd = -1;
                }
            }
            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);
            }

            XmlTypeMapMember previousMember = null;

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

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

                    if (info != null && !readFlag[info.Member.Index])
                    {
                        if (info.Member != previousMember)
                        {
                            ind = info.ExplicitOrder + 1;
                            // If the member is a flat list don't increase the index, since the next element may
                            // be another item of the list. This is a fix for Xamarin bug #9193.
                            if (info.Member is XmlTypeMapMemberFlatList)
                            {
                                ind--;
                            }
                            previousMember = info.Member;
                        }

                        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);
        }
예제 #5
0
        private void ReadMembers(ClassMap map, object ob, bool isValueList, bool readByOrder)
        {
            this.ReadAttributeMembers(map, ob, isValueList);
            if (!isValueList)
            {
                base.Reader.MoveToElement();
                if (base.Reader.IsEmptyElement)
                {
                    this.SetListMembersDefaults(map, ob, isValueList);
                    return;
                }
                base.Reader.ReadStartElement();
            }
            bool[] array = new bool[(map.ElementMembers == null) ? 0 : map.ElementMembers.Count];
            bool   flag  = isValueList && this._format == SerializationFormat.Encoded && map.ReturnMember != null;

            base.Reader.MoveToContent();
            int[]    array2 = null;
            object[] array3 = null;
            object[] array4 = null;
            XmlSerializationReader.Fixup fixup = null;
            int num = 0;
            int num2;

            if (readByOrder)
            {
                if (map.ElementMembers != null)
                {
                    num2 = map.ElementMembers.Count;
                }
                else
                {
                    num2 = 0;
                }
            }
            else
            {
                num2 = int.MaxValue;
            }
            if (map.FlatLists != null)
            {
                array2 = new int[map.FlatLists.Count];
                array3 = new object[map.FlatLists.Count];
                foreach (object obj in map.FlatLists)
                {
                    XmlTypeMapMemberExpandable xmlTypeMapMemberExpandable = (XmlTypeMapMemberExpandable)obj;
                    if (this.IsReadOnly(xmlTypeMapMemberExpandable, xmlTypeMapMemberExpandable.TypeData, ob, isValueList))
                    {
                        array3[xmlTypeMapMemberExpandable.FlatArrayIndex] = xmlTypeMapMemberExpandable.GetValue(ob);
                    }
                    else if (xmlTypeMapMemberExpandable.TypeData.Type.IsArray)
                    {
                        array3[xmlTypeMapMemberExpandable.FlatArrayIndex] = this.InitializeList(xmlTypeMapMemberExpandable.TypeData);
                    }
                    else
                    {
                        object obj2 = xmlTypeMapMemberExpandable.GetValue(ob);
                        if (obj2 == null)
                        {
                            obj2 = this.InitializeList(xmlTypeMapMemberExpandable.TypeData);
                            this.SetMemberValue(xmlTypeMapMemberExpandable, ob, obj2, isValueList);
                        }
                        array3[xmlTypeMapMemberExpandable.FlatArrayIndex] = obj2;
                    }
                    if (xmlTypeMapMemberExpandable.ChoiceMember != null)
                    {
                        if (array4 == null)
                        {
                            array4 = new object[map.FlatLists.Count];
                        }
                        array4[xmlTypeMapMemberExpandable.FlatArrayIndex] = this.InitializeList(xmlTypeMapMemberExpandable.ChoiceTypeData);
                    }
                }
            }
            if (this._format == SerializationFormat.Encoded && map.ElementMembers != null)
            {
                XmlSerializationReaderInterpreter.FixupCallbackInfo @object = new XmlSerializationReaderInterpreter.FixupCallbackInfo(this, map, isValueList);
                fixup = new XmlSerializationReader.Fixup(ob, new XmlSerializationFixupCallback(@object.FixupMembers), map.ElementMembers.Count);
                base.AddFixup(fixup);
            }
            while (base.Reader.NodeType != XmlNodeType.EndElement && num < num2)
            {
                if (base.Reader.NodeType == XmlNodeType.Element)
                {
                    XmlTypeMapElementInfo xmlTypeMapElementInfo;
                    if (readByOrder)
                    {
                        xmlTypeMapElementInfo = map.GetElement(num++);
                    }
                    else if (flag)
                    {
                        xmlTypeMapElementInfo = (XmlTypeMapElementInfo)((XmlTypeMapMemberElement)map.ReturnMember).ElementInfo[0];
                        flag = false;
                    }
                    else
                    {
                        xmlTypeMapElementInfo = map.GetElement(base.Reader.LocalName, base.Reader.NamespaceURI);
                    }
                    if (xmlTypeMapElementInfo != null && !array[xmlTypeMapElementInfo.Member.Index])
                    {
                        if (xmlTypeMapElementInfo.Member.GetType() == typeof(XmlTypeMapMemberList))
                        {
                            if (this._format == SerializationFormat.Encoded && xmlTypeMapElementInfo.MultiReferenceType)
                            {
                                object obj3 = base.ReadReferencingElement(out fixup.Ids[xmlTypeMapElementInfo.Member.Index]);
                                if (fixup.Ids[xmlTypeMapElementInfo.Member.Index] == null)
                                {
                                    if (this.IsReadOnly(xmlTypeMapElementInfo.Member, xmlTypeMapElementInfo.TypeData, ob, isValueList))
                                    {
                                        throw base.CreateReadOnlyCollectionException(xmlTypeMapElementInfo.TypeData.FullTypeName);
                                    }
                                    this.SetMemberValue(xmlTypeMapElementInfo.Member, ob, obj3, isValueList);
                                }
                                else if (!xmlTypeMapElementInfo.MappedType.TypeData.Type.IsArray)
                                {
                                    if (this.IsReadOnly(xmlTypeMapElementInfo.Member, xmlTypeMapElementInfo.TypeData, ob, isValueList))
                                    {
                                        obj3 = this.GetMemberValue(xmlTypeMapElementInfo.Member, ob, isValueList);
                                    }
                                    else
                                    {
                                        obj3 = this.CreateList(xmlTypeMapElementInfo.MappedType.TypeData.Type);
                                        this.SetMemberValue(xmlTypeMapElementInfo.Member, ob, obj3, isValueList);
                                    }
                                    base.AddFixup(new XmlSerializationReader.CollectionFixup(obj3, new XmlSerializationCollectionFixupCallback(this.FillList), fixup.Ids[xmlTypeMapElementInfo.Member.Index]));
                                    fixup.Ids[xmlTypeMapElementInfo.Member.Index] = null;
                                }
                            }
                            else if (this.IsReadOnly(xmlTypeMapElementInfo.Member, xmlTypeMapElementInfo.TypeData, ob, isValueList))
                            {
                                this.ReadListElement(xmlTypeMapElementInfo.MappedType, xmlTypeMapElementInfo.IsNullable, this.GetMemberValue(xmlTypeMapElementInfo.Member, ob, isValueList), false);
                            }
                            else if (xmlTypeMapElementInfo.MappedType.TypeData.Type.IsArray)
                            {
                                object obj4 = this.ReadListElement(xmlTypeMapElementInfo.MappedType, xmlTypeMapElementInfo.IsNullable, null, true);
                                if (obj4 != null || xmlTypeMapElementInfo.IsNullable)
                                {
                                    this.SetMemberValue(xmlTypeMapElementInfo.Member, ob, obj4, isValueList);
                                }
                            }
                            else
                            {
                                object obj5 = this.GetMemberValue(xmlTypeMapElementInfo.Member, ob, isValueList);
                                if (obj5 == null)
                                {
                                    obj5 = this.CreateList(xmlTypeMapElementInfo.MappedType.TypeData.Type);
                                    this.SetMemberValue(xmlTypeMapElementInfo.Member, ob, obj5, isValueList);
                                }
                                this.ReadListElement(xmlTypeMapElementInfo.MappedType, xmlTypeMapElementInfo.IsNullable, obj5, true);
                            }
                            array[xmlTypeMapElementInfo.Member.Index] = true;
                        }
                        else if (xmlTypeMapElementInfo.Member.GetType() == typeof(XmlTypeMapMemberFlatList))
                        {
                            XmlTypeMapMemberFlatList xmlTypeMapMemberFlatList = (XmlTypeMapMemberFlatList)xmlTypeMapElementInfo.Member;
                            this.AddListValue(xmlTypeMapMemberFlatList.TypeData, ref array3[xmlTypeMapMemberFlatList.FlatArrayIndex], array2[xmlTypeMapMemberFlatList.FlatArrayIndex]++, this.ReadObjectElement(xmlTypeMapElementInfo), !this.IsReadOnly(xmlTypeMapElementInfo.Member, xmlTypeMapElementInfo.TypeData, ob, isValueList));
                            if (xmlTypeMapMemberFlatList.ChoiceMember != null)
                            {
                                this.AddListValue(xmlTypeMapMemberFlatList.ChoiceTypeData, ref array4[xmlTypeMapMemberFlatList.FlatArrayIndex], array2[xmlTypeMapMemberFlatList.FlatArrayIndex] - 1, xmlTypeMapElementInfo.ChoiceValue, true);
                            }
                        }
                        else if (xmlTypeMapElementInfo.Member.GetType() == typeof(XmlTypeMapMemberAnyElement))
                        {
                            XmlTypeMapMemberAnyElement xmlTypeMapMemberAnyElement = (XmlTypeMapMemberAnyElement)xmlTypeMapElementInfo.Member;
                            if (xmlTypeMapMemberAnyElement.TypeData.IsListType)
                            {
                                this.AddListValue(xmlTypeMapMemberAnyElement.TypeData, ref array3[xmlTypeMapMemberAnyElement.FlatArrayIndex], array2[xmlTypeMapMemberAnyElement.FlatArrayIndex]++, this.ReadXmlNode(xmlTypeMapMemberAnyElement.TypeData.ListItemTypeData, false), true);
                            }
                            else
                            {
                                this.SetMemberValue(xmlTypeMapMemberAnyElement, ob, this.ReadXmlNode(xmlTypeMapMemberAnyElement.TypeData, false), isValueList);
                            }
                        }
                        else
                        {
                            if (xmlTypeMapElementInfo.Member.GetType() != typeof(XmlTypeMapMemberElement))
                            {
                                throw new InvalidOperationException("Unknown member type");
                            }
                            array[xmlTypeMapElementInfo.Member.Index] = true;
                            if (this._format == SerializationFormat.Encoded)
                            {
                                object obj6;
                                if (xmlTypeMapElementInfo.Member.TypeData.SchemaType != SchemaTypes.Primitive)
                                {
                                    obj6 = base.ReadReferencingElement(out fixup.Ids[xmlTypeMapElementInfo.Member.Index]);
                                }
                                else
                                {
                                    obj6 = base.ReadReferencingElement(xmlTypeMapElementInfo.Member.TypeData.XmlType, "http://www.w3.org/2001/XMLSchema", out fixup.Ids[xmlTypeMapElementInfo.Member.Index]);
                                }
                                if (xmlTypeMapElementInfo.MultiReferenceType)
                                {
                                    if (fixup.Ids[xmlTypeMapElementInfo.Member.Index] == null)
                                    {
                                        this.SetMemberValue(xmlTypeMapElementInfo.Member, ob, obj6, isValueList);
                                    }
                                }
                                else if (obj6 != null)
                                {
                                    this.SetMemberValue(xmlTypeMapElementInfo.Member, ob, obj6, isValueList);
                                }
                            }
                            else
                            {
                                this.SetMemberValue(xmlTypeMapElementInfo.Member, ob, this.ReadObjectElement(xmlTypeMapElementInfo), isValueList);
                                if (xmlTypeMapElementInfo.ChoiceValue != null)
                                {
                                    XmlTypeMapMemberElement xmlTypeMapMemberElement = (XmlTypeMapMemberElement)xmlTypeMapElementInfo.Member;
                                    xmlTypeMapMemberElement.SetChoice(ob, xmlTypeMapElementInfo.ChoiceValue);
                                }
                            }
                        }
                    }
                    else if (map.DefaultAnyElementMember != null)
                    {
                        XmlTypeMapMemberAnyElement defaultAnyElementMember = map.DefaultAnyElementMember;
                        if (defaultAnyElementMember.TypeData.IsListType)
                        {
                            this.AddListValue(defaultAnyElementMember.TypeData, ref array3[defaultAnyElementMember.FlatArrayIndex], array2[defaultAnyElementMember.FlatArrayIndex]++, this.ReadXmlNode(defaultAnyElementMember.TypeData.ListItemTypeData, false), true);
                        }
                        else
                        {
                            this.SetMemberValue(defaultAnyElementMember, ob, this.ReadXmlNode(defaultAnyElementMember.TypeData, false), isValueList);
                        }
                    }
                    else
                    {
                        this.ProcessUnknownElement(ob);
                    }
                }
                else if ((base.Reader.NodeType == XmlNodeType.Text || base.Reader.NodeType == XmlNodeType.CDATA) && map.XmlTextCollector != null)
                {
                    if (map.XmlTextCollector is XmlTypeMapMemberExpandable)
                    {
                        XmlTypeMapMemberExpandable xmlTypeMapMemberExpandable2 = (XmlTypeMapMemberExpandable)map.XmlTextCollector;
                        XmlTypeMapMemberFlatList   xmlTypeMapMemberFlatList2   = xmlTypeMapMemberExpandable2 as XmlTypeMapMemberFlatList;
                        TypeData typeData = (xmlTypeMapMemberFlatList2 != null) ? xmlTypeMapMemberFlatList2.ListMap.FindTextElement().TypeData : xmlTypeMapMemberExpandable2.TypeData.ListItemTypeData;
                        object   value    = (typeData.Type != typeof(string)) ? this.ReadXmlNode(typeData, false) : base.Reader.ReadString();
                        this.AddListValue(xmlTypeMapMemberExpandable2.TypeData, ref array3[xmlTypeMapMemberExpandable2.FlatArrayIndex], array2[xmlTypeMapMemberExpandable2.FlatArrayIndex]++, value, true);
                    }
                    else
                    {
                        XmlTypeMapMemberElement xmlTypeMapMemberElement2 = (XmlTypeMapMemberElement)map.XmlTextCollector;
                        XmlTypeMapElementInfo   xmlTypeMapElementInfo2   = (XmlTypeMapElementInfo)xmlTypeMapMemberElement2.ElementInfo[0];
                        if (xmlTypeMapElementInfo2.TypeData.Type == typeof(string))
                        {
                            this.SetMemberValue(xmlTypeMapMemberElement2, ob, base.ReadString((string)this.GetMemberValue(xmlTypeMapMemberElement2, ob, isValueList)), isValueList);
                        }
                        else
                        {
                            this.SetMemberValue(xmlTypeMapMemberElement2, ob, this.GetValueFromXmlString(base.Reader.ReadString(), xmlTypeMapElementInfo2.TypeData, xmlTypeMapElementInfo2.MappedType), isValueList);
                        }
                    }
                }
                else
                {
                    base.UnknownNode(ob);
                }
                base.Reader.MoveToContent();
            }
            if (array3 != null)
            {
                foreach (object obj7 in map.FlatLists)
                {
                    XmlTypeMapMemberExpandable xmlTypeMapMemberExpandable3 = (XmlTypeMapMemberExpandable)obj7;
                    object obj8 = array3[xmlTypeMapMemberExpandable3.FlatArrayIndex];
                    if (xmlTypeMapMemberExpandable3.TypeData.Type.IsArray)
                    {
                        obj8 = base.ShrinkArray((Array)obj8, array2[xmlTypeMapMemberExpandable3.FlatArrayIndex], xmlTypeMapMemberExpandable3.TypeData.Type.GetElementType(), true);
                    }
                    if (!this.IsReadOnly(xmlTypeMapMemberExpandable3, xmlTypeMapMemberExpandable3.TypeData, ob, isValueList) && xmlTypeMapMemberExpandable3.TypeData.Type.IsArray)
                    {
                        this.SetMemberValue(xmlTypeMapMemberExpandable3, ob, obj8, isValueList);
                    }
                }
            }
            if (array4 != null)
            {
                foreach (object obj9 in map.FlatLists)
                {
                    XmlTypeMapMemberExpandable xmlTypeMapMemberExpandable4 = (XmlTypeMapMemberExpandable)obj9;
                    object obj10 = array4[xmlTypeMapMemberExpandable4.FlatArrayIndex];
                    if (obj10 != null)
                    {
                        obj10 = base.ShrinkArray((Array)obj10, array2[xmlTypeMapMemberExpandable4.FlatArrayIndex], xmlTypeMapMemberExpandable4.ChoiceTypeData.Type.GetElementType(), true);
                        XmlTypeMapMember.SetValue(ob, xmlTypeMapMemberExpandable4.ChoiceMember, obj10);
                    }
                }
            }
            this.SetListMembersDefaults(map, ob, isValueList);
        }
		void SetMemberValue (XmlTypeMapMember member, object ob, object value, bool isValueList)
		{
			var memberType = member.TypeData.Type;
			if (value != null && !value.GetType().IsAssignableFrom (memberType))
				value = XmlSerializationWriterInterpreter.ImplicitConvert (value, memberType);

			if (isValueList)
				((object[])ob)[member.GlobalIndex] = value;
			else
				member.SetValue (ob, value);
			if (member.IsOptionalValueType)
				member.SetValueSpecified (ob, true); 
		}
예제 #7
0
 public void SetChoice(object ob, object choice)
 {
     XmlTypeMapMember.SetValue(ob, this._choiceMember, choice);
 }
예제 #8
0
파일: Class1.cs 프로젝트: lanicon/Cinchoo
        void ReadMembers(ClassMap map, object ob, bool isValueList, bool readByOrder)
        {
            // Set the default values of the members
            if (map.MembersWithDefault != null)
            {
                ArrayList members = map.MembersWithDefault;
                for (int n = 0; n < members.Count; n++)
                {
                    XmlTypeMapMember mem = (XmlTypeMapMember)members[n];
                    SetMemberValueFromAttr(mem, ob, mem.DefaultValue, isValueList);
                }
            }

            // Reads attributes

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

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