Esempio n. 1
0
		private XmlTypeMapMember CreateMapMember (Type declaringType, XmlReflectionMember rmember, string defaultNamespace)
		{
			XmlTypeMapMember mapMember;
			XmlAttributes atts = rmember.XmlAttributes;
			TypeData typeData = TypeTranslator.GetTypeData (rmember.MemberType);

			if (atts.XmlArray != null) {
				if (atts.XmlArray.Namespace != null && atts.XmlArray.Form == XmlSchemaForm.Unqualified)
					throw new InvalidOperationException ("XmlArrayAttribute.Form must not be Unqualified when it has an explicit Namespace value.");
				if (typeData.SchemaType != SchemaTypes.Array &&
				    !(typeData.SchemaType == SchemaTypes.Primitive && typeData.Type == typeof (byte [])))
					throw new InvalidOperationException ("XmlArrayAttribute can be applied to members of array or collection type.");
			}

#if !MOONLIGHT
			if (atts.XmlAnyAttribute != null)
			{
				if ( (rmember.MemberType.FullName == "System.Xml.XmlAttribute[]") ||
					 (rmember.MemberType.FullName == "System.Xml.XmlNode[]") )
				{
					mapMember = new XmlTypeMapMemberAnyAttribute();
				}
				else
					throw new InvalidOperationException ("XmlAnyAttributeAttribute can only be applied to members of type XmlAttribute[] or XmlNode[]");
			}
			else
#endif
			if (atts.XmlAnyElements != null && atts.XmlAnyElements.Count > 0)
			{
				// no XmlNode type check is done here (seealso: bug #553032).
				XmlTypeMapMemberAnyElement member = new XmlTypeMapMemberAnyElement();
				member.ElementInfo = ImportAnyElementInfo (defaultNamespace, rmember, member, atts);
				mapMember = member;
			}
			else if (atts.Xmlns)
			{
				XmlTypeMapMemberNamespaces mapNamespaces = new XmlTypeMapMemberNamespaces ();
				mapMember = mapNamespaces;
			}
			else if (atts.XmlAttribute != null)
			{
				// An attribute

				if (atts.XmlElements != null && atts.XmlElements.Count > 0)
					throw new Exception ("XmlAttributeAttribute and XmlElementAttribute cannot be applied to the same member");

				XmlTypeMapMemberAttribute mapAttribute = new XmlTypeMapMemberAttribute ();
				if (atts.XmlAttribute.AttributeName.Length == 0) 
					mapAttribute.AttributeName = rmember.MemberName;
				else 
					mapAttribute.AttributeName = atts.XmlAttribute.AttributeName;

				mapAttribute.AttributeName = XmlConvert.EncodeLocalName (mapAttribute.AttributeName);

				if (typeData.IsComplexType)
					mapAttribute.MappedType = ImportTypeMapping (typeData.Type, null, defaultNamespace);

				if (atts.XmlAttribute.Namespace != null && atts.XmlAttribute.Namespace != defaultNamespace)
				{
					if (atts.XmlAttribute.Form == XmlSchemaForm.Unqualified)
						throw new InvalidOperationException ("The Form property may not be 'Unqualified' when an explicit Namespace property is present");
					mapAttribute.Form = XmlSchemaForm.Qualified;
					mapAttribute.Namespace = atts.XmlAttribute.Namespace;
				}
				else
				{
					mapAttribute.Form = atts.XmlAttribute.Form;
					if (atts.XmlAttribute.Form == XmlSchemaForm.Qualified)
						mapAttribute.Namespace = defaultNamespace;
					else
						mapAttribute.Namespace = "";
				}
				
				typeData = TypeTranslator.GetTypeData(rmember.MemberType, atts.XmlAttribute.DataType);
				mapMember = mapAttribute;
			}
			else if (typeData.SchemaType == SchemaTypes.Array)
			{
				// If the member has a single XmlElementAttribute and the type is the type of the member,
				// then it is not a flat list
				
				if (atts.XmlElements.Count > 1 ||
				   (atts.XmlElements.Count == 1 && atts.XmlElements[0].Type != typeData.Type) ||
				   (atts.XmlText != null))
				{
					// A flat list

					// check that it does not have XmlArrayAttribute
					if (atts.XmlArray != null)
						throw new InvalidOperationException ("XmlArrayAttribute cannot be used with members which also attributed with XmlElementAttribute or XmlTextAttribute.");

					XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList ();
					member.ListMap = new ListMap ();
					member.ListMap.ItemInfo = ImportElementInfo (declaringType, XmlConvert.EncodeLocalName (rmember.MemberName), defaultNamespace, typeData.ListItemType, member, atts);
					member.ElementInfo = member.ListMap.ItemInfo;
					member.ListMap.ChoiceMember = member.ChoiceMember;
					mapMember = member;
				}
				else
				{
					// A list

					XmlTypeMapMemberList member = new XmlTypeMapMemberList ();

					// Creates an ElementInfo that identifies the array instance. 
					member.ElementInfo = new XmlTypeMapElementInfoList();
					XmlTypeMapElementInfo elem = new XmlTypeMapElementInfo (member, typeData);
					elem.ElementName = XmlConvert.EncodeLocalName((atts.XmlArray != null && atts.XmlArray.ElementName.Length != 0) ? atts.XmlArray.ElementName : rmember.MemberName);
					// note that it could be changed below (when Form is Unqualified)
					elem.Namespace = (atts.XmlArray != null && atts.XmlArray.Namespace != null) ? atts.XmlArray.Namespace : defaultNamespace;
					elem.MappedType = ImportListMapping (rmember.MemberType, null, elem.Namespace, atts, 0);
					elem.IsNullable = (atts.XmlArray != null) ? atts.XmlArray.IsNullable : false;
					elem.Form = (atts.XmlArray != null) ? atts.XmlArray.Form : XmlSchemaForm.Qualified;
					// This is a bit tricky, but is done
					// after filling descendant members, so
					// that array items could be serialized
					// with proper namespace.
					if (atts.XmlArray != null && atts.XmlArray.Form == XmlSchemaForm.Unqualified)
						elem.Namespace = String.Empty;

					member.ElementInfo.Add (elem);
					mapMember = member;
				}
			}
			else
			{
				// An element

				XmlTypeMapMemberElement member = new XmlTypeMapMemberElement ();
 				member.ElementInfo = ImportElementInfo (declaringType, XmlConvert.EncodeLocalName(rmember.MemberName), defaultNamespace, rmember.MemberType, member, atts);
				mapMember = member;
			}

			mapMember.DefaultValue = GetDefaultValue (typeData, atts.XmlDefaultValue);
			mapMember.TypeData = typeData;
			mapMember.Name = rmember.MemberName;
			mapMember.IsReturnValue = rmember.IsReturnValue;
			return mapMember;
		}
Esempio n. 2
0
		void AddTextMember (XmlQualifiedName typeQName, ClassMap cmap, CodeIdentifiers classIds)
		{
			if (cmap.XmlTextCollector == null)
			{
				XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList ();
				member.Name = classIds.AddUnique ("Text", member);
				member.TypeData = TypeTranslator.GetTypeData (typeof(string[]));
				member.ElementInfo.Add (CreateTextElementInfo (typeQName.Namespace, member, member.TypeData.ListItemTypeData));
				member.IsXmlTextCollector = true;
				member.ListMap = new ListMap ();
				member.ListMap.ItemInfo = member.ElementInfo;
				cmap.AddMember (member);
			}
		}
Esempio n. 3
0
		void ImportSequenceContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaObjectCollection items, CodeIdentifiers classIds, bool multiValue, ref bool isMixed)
		{
			foreach (XmlSchemaObject item in items)
			{
				if (item is XmlSchemaElement)
				{
					string ns;
					XmlSchemaElement elem = (XmlSchemaElement) item;
					XmlTypeMapping emap;
					TypeData typeData = GetElementTypeData (typeQName, elem, null, out emap);
					XmlSchemaElement refElem = GetRefElement (typeQName, elem, out ns);

					if (elem.MaxOccurs == 1 && !multiValue)
					{
						XmlTypeMapMemberElement member = null;
						if (typeData.SchemaType != SchemaTypes.Array)
						{
							member = new XmlTypeMapMemberElement ();
							if (refElem.DefaultValue != null) member.DefaultValue = ImportDefaultValue (typeData, refElem.DefaultValue);
						}
						else if (GetTypeMapping (typeData).IsSimpleType)
						{
							// It is a simple list (space separated list).
							// Since this is not supported, map as a single item value
							member = new XmlTypeMapMemberElement ();
#if NET_2_0
							// In MS.NET those types are mapped to a string
							typeData = TypeTranslator.GetTypeData(typeof(string));
#else
							typeData = typeData.ListItemTypeData;
#endif
						}
						else
							member = new XmlTypeMapMemberList ();

						if (elem.MinOccurs == 0 && typeData.IsValueType)
							member.IsOptionalValueType = true;

						member.Name = classIds.AddUnique(CodeIdentifier.MakeValid(refElem.Name), member);
						member.Documentation = GetDocumentation (elem);
						member.TypeData = typeData;
						member.ElementInfo.Add (CreateElementInfo (ns, member, refElem.Name, typeData, refElem.IsNillable, refElem.Form, emap, items.IndexOf (item)));
						cmap.AddMember (member);
					}
					else
					{
						XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList ();
						member.ListMap = new ListMap ();
						member.Name = classIds.AddUnique(CodeIdentifier.MakeValid(refElem.Name), member);
						member.Documentation = GetDocumentation (elem);
						member.TypeData = typeData.ListTypeData;
						member.ElementInfo.Add (CreateElementInfo (ns, member, refElem.Name, typeData, refElem.IsNillable, refElem.Form, emap, items.IndexOf (item)));
						member.ListMap.ItemInfo = member.ElementInfo;
						cmap.AddMember (member);
					}
				}
				else if (item is XmlSchemaAny)
				{
					XmlSchemaAny elem = (XmlSchemaAny) item;
					XmlTypeMapMemberAnyElement member = new XmlTypeMapMemberAnyElement ();
					member.Name = classIds.AddUnique ("Any", member);
					member.Documentation = GetDocumentation (elem);
					
					Type ctype;
					if (elem.MaxOccurs != 1 || multiValue)
						ctype = isMixed ? typeof(XmlNode[]) : typeof(XmlElement[]);
					else
						ctype = isMixed ? typeof(XmlNode) : typeof(XmlElement);

					member.TypeData = TypeTranslator.GetTypeData (ctype);
					XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, member.TypeData);
					einfo.IsUnnamedAnyElement = true;
					member.ElementInfo.Add (einfo);

					if (isMixed)
					{
						einfo = CreateTextElementInfo (typeQName.Namespace, member, member.TypeData);
						member.ElementInfo.Add (einfo);
						member.IsXmlTextCollector = true;
						isMixed = false;	//Allow only one XmlTextAttribute
					}
					
					cmap.AddMember (member);
				}
				else if (item is XmlSchemaParticle) {
					ImportParticleContent (typeQName, cmap, (XmlSchemaParticle)item, classIds, multiValue, ref isMixed);
				}
			}
		}
Esempio n. 4
0
        private XmlTypeMapMember CreateMapMember(XmlReflectionMember rmember, string defaultNamespace)
        {
            XmlTypeMapMember mapMember;
            XmlAttributes    atts     = rmember.XmlAttributes;
            TypeData         typeData = TypeTranslator.GetTypeData(rmember.MemberType);

            if (atts.XmlAnyAttribute != null)
            {
                if ((rmember.MemberType.FullName == "System.Xml.XmlAttribute[]") ||
                    (rmember.MemberType.FullName == "System.Xml.XmlNode[]"))
                {
                    mapMember = new XmlTypeMapMemberAnyAttribute();
                }
                else
                {
                    throw new InvalidOperationException("XmlAnyAttributeAttribute can only be applied to members of type XmlAttribute[] or XmlNode[]");
                }
            }
            else if (atts.XmlAnyElements != null && atts.XmlAnyElements.Count > 0)
            {
                if ((rmember.MemberType.FullName == "System.Xml.XmlElement[]") ||
                    (rmember.MemberType.FullName == "System.Xml.XmlNode[]") ||
                    (rmember.MemberType.FullName == "System.Xml.XmlElement"))
                {
                    XmlTypeMapMemberAnyElement member = new XmlTypeMapMemberAnyElement();
                    member.ElementInfo = ImportAnyElementInfo(defaultNamespace, rmember, member, atts);
                    mapMember          = member;
                }
                else
                {
                    throw new InvalidOperationException("XmlAnyElementAttribute can only be applied to members of type XmlElement, XmlElement[] or XmlNode[]");
                }
            }
            else if (atts.Xmlns)
            {
                XmlTypeMapMemberNamespaces mapNamespaces = new XmlTypeMapMemberNamespaces();
                mapMember = mapNamespaces;
            }
            else if (atts.XmlAttribute != null)
            {
                // An attribute

                if (atts.XmlElements != null && atts.XmlElements.Count > 0)
                {
                    throw new Exception("XmlAttributeAttribute and XmlElementAttribute cannot be applied to the same member");
                }

                XmlTypeMapMemberAttribute mapAttribute = new XmlTypeMapMemberAttribute();
                if (atts.XmlAttribute.AttributeName == null)
                {
                    mapAttribute.AttributeName = rmember.MemberName;
                }
                else
                {
                    mapAttribute.AttributeName = atts.XmlAttribute.AttributeName;
                }

                if (typeData.IsComplexType)
                {
                    mapAttribute.MappedType = ImportTypeMapping(typeData.Type, null, mapAttribute.Namespace);
                }

                if (atts.XmlAttribute.Namespace != null && atts.XmlAttribute.Namespace != defaultNamespace)
                {
                    if (atts.XmlAttribute.Form == XmlSchemaForm.Unqualified)
                    {
                        throw new InvalidOperationException("The Form property may not be 'Unqualified' when an explicit Namespace property is present");
                    }
                    mapAttribute.Form      = XmlSchemaForm.Qualified;
                    mapAttribute.Namespace = atts.XmlAttribute.Namespace;
                }
                else
                {
                    mapAttribute.Form = atts.XmlAttribute.Form;
                    if (atts.XmlAttribute.Form == XmlSchemaForm.Qualified)
                    {
                        mapAttribute.Namespace = defaultNamespace;
                    }
                    else
                    {
                        mapAttribute.Namespace = "";
                    }
                }

                typeData  = TypeTranslator.GetTypeData(rmember.MemberType, atts.XmlAttribute.DataType);
                mapMember = mapAttribute;
            }
            else if (typeData.SchemaType == SchemaTypes.Array)
            {
                // If the member has a single XmlElementAttribute and the type is the type of the member,
                // then it is not a flat list

                if (atts.XmlElements.Count > 1 ||
                    (atts.XmlElements.Count == 1 && atts.XmlElements[0].Type != typeData.Type) ||
                    (atts.XmlText != null))
                {
                    // A flat list

                    // TODO: check that it does not have XmlArrayAttribute
                    XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList();
                    member.ListMap          = new ListMap();
                    member.ListMap.ItemInfo = ImportElementInfo(rmember.MemberName, defaultNamespace, typeData.ListItemType, member, atts);
                    member.ElementInfo      = member.ListMap.ItemInfo;
                    mapMember = member;
                }
                else
                {
                    // A list

                    XmlTypeMapMemberList member = new XmlTypeMapMemberList();

                    // Creates an ElementInfo that identifies the array instance.
                    member.ElementInfo = new XmlTypeMapElementInfoList();
                    XmlTypeMapElementInfo elem = new XmlTypeMapElementInfo(member, typeData);
                    elem.ElementName = (atts.XmlArray != null && atts.XmlArray.ElementName != null) ? atts.XmlArray.ElementName : rmember.MemberName;
                    elem.Namespace   = (atts.XmlArray != null && atts.XmlArray.Namespace != null) ? atts.XmlArray.Namespace : defaultNamespace;
                    elem.MappedType  = ImportListMapping(rmember.MemberType, null, elem.Namespace, atts, 0);
                    elem.IsNullable  = (atts.XmlArray != null) ? atts.XmlArray.IsNullable : false;
                    elem.Form        = (atts.XmlArray != null) ? atts.XmlArray.Form : XmlSchemaForm.Qualified;

                    member.ElementInfo.Add(elem);
                    mapMember = member;
                }
            }
            else
            {
                // An element

                XmlTypeMapMemberElement member = new XmlTypeMapMemberElement();
                member.ElementInfo = ImportElementInfo(rmember.MemberName, defaultNamespace, rmember.MemberType, member, atts);
                mapMember          = member;
            }

            mapMember.DefaultValue  = atts.XmlDefaultValue;
            mapMember.TypeData      = typeData;
            mapMember.Name          = rmember.MemberName;
            mapMember.IsReturnValue = rmember.IsReturnValue;
            return(mapMember);
        }
Esempio n. 5
0
		void ImportChoiceContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaChoice choice, CodeIdentifiers classIds, bool multiValue)
		{
			XmlTypeMapElementInfoList choices = new XmlTypeMapElementInfoList ();
			multiValue = ImportChoices (typeQName, null, choices, choice.Items) || multiValue;
			if (choices.Count == 0) return;

			if (choice.MaxOccurs > 1) multiValue = true;

			XmlTypeMapMemberElement member;
			if (multiValue)
			{
				member = new XmlTypeMapMemberFlatList ();
				member.Name = classIds.AddUnique ("Items", member);
				ListMap listMap = new ListMap ();
				listMap.ItemInfo = choices;
				((XmlTypeMapMemberFlatList)member).ListMap = listMap;
			}
			else
			{
				member = new XmlTypeMapMemberElement ();
				member.Name = classIds.AddUnique ("Item", member);
			}
			
			// If all choices have the same type, use that type for the member.
			// If not use System.Object.
			// If there are at least two choices with the same type, use a choice
			// identifier attribute

			TypeData typeData = null;
			bool twoEqual = false;
			bool allEqual = true;
			Hashtable types = new Hashtable ();

			for (int n = choices.Count - 1; n >= 0; n--)
			{
				XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) choices [n];
				
				// In some complex schemas, we may end up with several options
				// with the same name. It is better to ignore the extra options
				// than to crash. It's the best we can do, and btw it works
				// better than in MS.NET.
				
				if (cmap.GetElement (einfo.ElementName, einfo.Namespace, einfo.ExplicitOrder) != null ||
					choices.IndexOfElement (einfo.ElementName, einfo.Namespace) != n)
				{
					choices.RemoveAt (n);
					continue;
				}
					
				if (types.ContainsKey (einfo.TypeData)) twoEqual = true;
				else types.Add (einfo.TypeData, einfo);

				TypeData choiceType = einfo.TypeData;
				if (choiceType.SchemaType == SchemaTypes.Class)
				{
					// When comparing class types, use the most generic class in the
					// inheritance hierarchy

					XmlTypeMapping choiceMap = GetTypeMapping (choiceType);
					BuildPendingMap (choiceMap);
					while (choiceMap.BaseMap != null) {
						choiceMap = choiceMap.BaseMap;
						BuildPendingMap (choiceMap);
						choiceType = choiceMap.TypeData;
					}
				}
				
				if (typeData == null) typeData = choiceType;
				else if (typeData != choiceType) allEqual = false;
			}

			if (!allEqual)
				typeData = TypeTranslator.GetTypeData (typeof(object));

			if (twoEqual)
			{
				// Create the choice member
				XmlTypeMapMemberElement choiceMember = new XmlTypeMapMemberElement ();
				choiceMember.Ignore = true;
				choiceMember.Name = classIds.AddUnique (member.Name + "ElementName", choiceMember);
				member.ChoiceMember = choiceMember.Name;

				// Create the choice enum
				XmlTypeMapping enumMap = CreateTypeMapping (new XmlQualifiedName (member.Name + "ChoiceType", typeQName.Namespace), SchemaTypes.Enum, null);
				enumMap.IncludeInSchema = false;

				CodeIdentifiers codeIdents = new CodeIdentifiers ();
				EnumMap.EnumMapMember[] members = new EnumMap.EnumMapMember [choices.Count];
				for (int n=0; n<choices.Count; n++)
				{
					XmlTypeMapElementInfo it =(XmlTypeMapElementInfo) choices[n];
					bool extraNs = (it.Namespace != null && it.Namespace != "" && it.Namespace != typeQName.Namespace);
					string xmlName = extraNs ? it.Namespace + ":" + it.ElementName : it.ElementName;
					string enumName = codeIdents.AddUnique (CodeIdentifier.MakeValid (it.ElementName), it);
					members [n] = new EnumMap.EnumMapMember (xmlName, enumName);
				}
				enumMap.ObjectMap = new EnumMap (members, false);

				choiceMember.TypeData = multiValue ? enumMap.TypeData.ListTypeData : enumMap.TypeData;
				choiceMember.ElementInfo.Add (CreateElementInfo (typeQName.Namespace, choiceMember, choiceMember.Name, choiceMember.TypeData, false, XmlSchemaForm.None, -1));
				cmap.AddMember (choiceMember);
			}
			
			if (typeData == null)
				return;
	
			if (multiValue)
				typeData = typeData.ListTypeData;

			member.ElementInfo = choices;
			member.Documentation = GetDocumentation (choice);
			member.TypeData = typeData;
			cmap.AddMember (member);
		}
        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);
        }
		void ImportParticleComplexContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaParticle particle, CodeIdentifiers classIds, bool isMixed)
		{
			ImportParticleContent (typeQName, cmap, particle, classIds, false, ref isMixed);
			if (isMixed && cmap.XmlTextCollector == null)
			{
				XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList ();
				member.Name = classIds.AddUnique ("Text", member);
				member.TypeData = TypeTranslator.GetTypeData (typeof(string[]));
				member.ElementInfo.Add (CreateTextElementInfo (typeQName.Namespace, member, member.TypeData.ListItemTypeData));
				member.IsXmlTextCollector = true;
				member.ListMap = new ListMap ();
				member.ListMap.ItemInfo = member.ElementInfo;
				cmap.AddMember (member);
			}
		}
Esempio n. 8
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);
        }
		private XmlTypeMapMember CreateMapMember (XmlReflectionMember rmember, string defaultNamespace)
		{
			XmlTypeMapMember mapMember;
			XmlAttributes atts = rmember.XmlAttributes;
			TypeData typeData = TypeTranslator.GetTypeData (rmember.MemberType);

			if (atts.XmlAnyAttribute != null)
			{
				if ( (rmember.MemberType.FullName == "System.Xml.XmlAttribute[]") ||
					 (rmember.MemberType.FullName == "System.Xml.XmlNode[]") )
				{
					mapMember = new XmlTypeMapMemberAnyAttribute();
				}
				else
					throw new InvalidOperationException ("XmlAnyAttributeAttribute can only be applied to members of type XmlAttribute[] or XmlNode[]");
			}
			else if (atts.XmlAnyElements != null && atts.XmlAnyElements.Count > 0)
			{
				if ( (rmember.MemberType.FullName == "System.Xml.XmlElement[]") ||
					 (rmember.MemberType.FullName == "System.Xml.XmlNode[]") ||
					 (rmember.MemberType.FullName == "System.Xml.XmlElement"))
				{
					XmlTypeMapMemberAnyElement member = new XmlTypeMapMemberAnyElement();
					member.ElementInfo = ImportAnyElementInfo (defaultNamespace, rmember, member, atts);
					mapMember = member;
				}
				else
					throw new InvalidOperationException ("XmlAnyElementAttribute can only be applied to members of type XmlElement, XmlElement[] or XmlNode[]");
			}
			else if (atts.Xmlns)
			{
				XmlTypeMapMemberNamespaces mapNamespaces = new XmlTypeMapMemberNamespaces ();
				mapMember = mapNamespaces;
			}
			else if (atts.XmlAttribute != null)
			{
				// An attribute

				if (atts.XmlElements != null && atts.XmlElements.Count > 0)
					throw new Exception ("XmlAttributeAttribute and XmlElementAttribute cannot be applied to the same member");

				XmlTypeMapMemberAttribute mapAttribute = new XmlTypeMapMemberAttribute ();
				if (atts.XmlAttribute.AttributeName == null) 
					mapAttribute.AttributeName = rmember.MemberName;
				else 
					mapAttribute.AttributeName = atts.XmlAttribute.AttributeName;

				if (typeData.IsComplexType)
					mapAttribute.MappedType = ImportTypeMapping (typeData.Type, null, mapAttribute.Namespace);
				
				if (atts.XmlAttribute.Namespace != null && atts.XmlAttribute.Namespace != defaultNamespace)
				{
					if (atts.XmlAttribute.Form == XmlSchemaForm.Unqualified)
						throw new InvalidOperationException ("The Form property may not be 'Unqualified' when an explicit Namespace property is present");
					mapAttribute.Form = XmlSchemaForm.Qualified;
					mapAttribute.Namespace = atts.XmlAttribute.Namespace;
				}
				else
				{
					mapAttribute.Form = atts.XmlAttribute.Form;
					if (atts.XmlAttribute.Form == XmlSchemaForm.Qualified)
						mapAttribute.Namespace = defaultNamespace;
					else
						mapAttribute.Namespace = "";
				}
				
				typeData = TypeTranslator.GetTypeData(rmember.MemberType, atts.XmlAttribute.DataType);
				mapMember = mapAttribute;
			}
			else if (typeData.SchemaType == SchemaTypes.Array)
			{
				// If the member has a single XmlElementAttribute and the type is the type of the member,
				// then it is not a flat list
				
				if (atts.XmlElements.Count > 1 ||
				   (atts.XmlElements.Count == 1 && atts.XmlElements[0].Type != typeData.Type) ||
				   (atts.XmlText != null))
				{
					// A flat list

					// TODO: check that it does not have XmlArrayAttribute
					XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList ();
					member.ListMap = new ListMap ();
					member.ListMap.ItemInfo = ImportElementInfo (rmember.MemberName, defaultNamespace, typeData.ListItemType, member, atts);
					member.ElementInfo = member.ListMap.ItemInfo;
					mapMember = member;
				}
				else
				{
					// A list

					XmlTypeMapMemberList member = new XmlTypeMapMemberList ();

					// Creates an ElementInfo that identifies the array instance. 
					member.ElementInfo = new XmlTypeMapElementInfoList();
					XmlTypeMapElementInfo elem = new XmlTypeMapElementInfo (member, typeData);
					elem.ElementName = (atts.XmlArray != null && atts.XmlArray.ElementName != null) ? atts.XmlArray.ElementName : rmember.MemberName;
					elem.Namespace = (atts.XmlArray != null && atts.XmlArray.Namespace != null) ? atts.XmlArray.Namespace : defaultNamespace;
					elem.MappedType = ImportListMapping (rmember.MemberType, null, elem.Namespace, atts, 0);
					elem.IsNullable = (atts.XmlArray != null) ? atts.XmlArray.IsNullable : false;
					elem.Form = (atts.XmlArray != null) ? atts.XmlArray.Form : XmlSchemaForm.Qualified;

					member.ElementInfo.Add (elem);
					mapMember = member;
				}
			}
			else
			{
				// An element

				XmlTypeMapMemberElement member = new XmlTypeMapMemberElement ();
				member.ElementInfo = ImportElementInfo (rmember.MemberName, defaultNamespace, rmember.MemberType, member, atts);
				mapMember = member;
			}

			mapMember.DefaultValue = atts.XmlDefaultValue;
			mapMember.TypeData = typeData;
			mapMember.Name = rmember.MemberName;
			mapMember.IsReturnValue = rmember.IsReturnValue;
			return mapMember;
		}
Esempio n. 10
0
        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);
        }