System.Xml.Serialization.XmlSerializationReaderInterpreter.ReadMembers C# (CSharp) Method

ReadMembers() private method

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

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

				Reader.ReadStartElement();
			}

			// Reads elements

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

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

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

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

			if (map.FlatLists != null) 
			{
				indexes = new int[map.FlatLists.Count];
				flatLists = new object[map.FlatLists.Count];
				foreach (XmlTypeMapMemberExpandable mem in map.FlatLists) {
					if (IsReadOnly (mem, mem.TypeData, ob, isValueList))
						flatLists [mem.FlatArrayIndex] = mem.GetValue (ob);
					else if (mem.TypeData.Type.IsArray) {
						flatLists [mem.FlatArrayIndex] = InitializeList (mem.TypeData);
					}
					else {
						object list = mem.GetValue (ob);
						if (list == null) {
							list = InitializeList (mem.TypeData);
							SetMemberValue (mem, ob, list, isValueList);
						}
						flatLists [mem.FlatArrayIndex] = list;
					}
						
					if (mem.ChoiceMember != null) {
						if (flatListsChoices == null)
							flatListsChoices = new object [map.FlatLists.Count];
						flatListsChoices [mem.FlatArrayIndex] = InitializeList (mem.ChoiceTypeData);
					}
				}
			}
			
			if (_format == SerializationFormat.Encoded && map.ElementMembers != null)
			{
				FixupCallbackInfo info = new FixupCallbackInfo (this, map, isValueList);
				fixup = new Fixup(ob, new XmlSerializationFixupCallback(info.FixupMembers), map.ElementMembers.Count);
				AddFixup (fixup);
			}

			while (Reader.NodeType != System.Xml.XmlNodeType.EndElement && (ind < maxInd)) 
			{
				if (Reader.NodeType == System.Xml.XmlNodeType.Element) 
				{
					XmlTypeMapElementInfo info;
					
					if (readByOrder) {
						info = map.GetElement (ind++);
					}
					else if (hasAnyReturnMember) {
						info = (XmlTypeMapElementInfo) ((XmlTypeMapMemberElement)map.ReturnMember).ElementInfo[0];
						hasAnyReturnMember = false;
					}
					else
						info = map.GetElement (Reader.LocalName, Reader.NamespaceURI);
						
					if (info != null && !readFlag[info.Member.Index] )
					{
						if (info.Member.GetType() == typeof (XmlTypeMapMemberList))
						{
							if (_format == SerializationFormat.Encoded && info.MultiReferenceType)
							{
								object list = ReadReferencingElement (out fixup.Ids[info.Member.Index]);
								if (fixup.Ids[info.Member.Index] == null)	// Already read
								{
									if (IsReadOnly (info.Member, info.TypeData, ob, isValueList)) throw CreateReadOnlyCollectionException (info.TypeData.FullTypeName);
									else SetMemberValue (info.Member, ob, list, isValueList);
								}
								else if (!info.MappedType.TypeData.Type.IsArray)
								{
									if (IsReadOnly (info.Member, info.TypeData, ob, isValueList)) 
										list = GetMemberValue (info.Member, ob, isValueList);
									else { 
										list = CreateList (info.MappedType.TypeData.Type);
										SetMemberValue (info.Member, ob, list, isValueList);
									}
									AddFixup (new CollectionFixup (list, new XmlSerializationCollectionFixupCallback (FillList), fixup.Ids[info.Member.Index]));
									fixup.Ids[info.Member.Index] = null;	// The member already has the value, no further fix needed.
								}
							}
							else
							{
								if (IsReadOnly (info.Member, info.TypeData, ob, isValueList)) {
									ReadListElement (info.MappedType, info.IsNullable, GetMemberValue (info.Member, ob, isValueList), false);
								} else if (info.MappedType.TypeData.Type.IsArray) {
									object list = ReadListElement (info.MappedType, info.IsNullable, null, true);
									if (list != null || info.IsNullable)
										SetMemberValue (info.Member, ob, list, isValueList);
								} else {
									// If the member already has a list, reuse that list. No need to create a new one. 
									object list = GetMemberValue (info.Member, ob, isValueList);
									if (list == null) {
										list = CreateList (info.MappedType.TypeData.Type);
										SetMemberValue (info.Member, ob, list, isValueList);
									}
									ReadListElement (info.MappedType, info.IsNullable, list, true);
								}
							}
							readFlag[info.Member.Index] = true;
						}
						else if (info.Member.GetType() == typeof (XmlTypeMapMemberFlatList))
						{
							XmlTypeMapMemberFlatList mem = (XmlTypeMapMemberFlatList)info.Member;
							AddListValue (mem.TypeData, ref flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex]++, ReadObjectElement (info), !IsReadOnly (info.Member, info.TypeData, ob, isValueList));
							if (mem.ChoiceMember != null) {
								AddListValue (mem.ChoiceTypeData, ref flatListsChoices [mem.FlatArrayIndex], indexes[mem.FlatArrayIndex]-1, info.ChoiceValue, true);
							}
						}
						else if (info.Member.GetType() == typeof (XmlTypeMapMemberAnyElement))
						{
							XmlTypeMapMemberAnyElement mem = (XmlTypeMapMemberAnyElement)info.Member;
							if (mem.TypeData.IsListType) AddListValue (mem.TypeData, ref flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex]++, ReadXmlNode (mem.TypeData.ListItemTypeData, false), true);
							else SetMemberValue (mem, ob, ReadXmlNode (mem.TypeData, false), isValueList);
						}
						else if (info.Member.GetType() == typeof(XmlTypeMapMemberElement))
						{
							object val;
							readFlag[info.Member.Index] = true;
							if (_format == SerializationFormat.Encoded)
							{
								if (info.Member.TypeData.SchemaType != SchemaTypes.Primitive)
									val = ReadReferencingElement (out fixup.Ids[info.Member.Index]);
								else
									val = ReadReferencingElement (info.Member.TypeData.XmlType, System.Xml.Schema.XmlSchema.Namespace, out fixup.Ids[info.Member.Index]);
									
								if (info.MultiReferenceType) {
									if (fixup.Ids[info.Member.Index] == null)	// already read
										SetMemberValue (info.Member, ob, val, isValueList);
								}
								else if (val != null)
									SetMemberValue (info.Member, ob, val, isValueList);
							}
							else {
								SetMemberValue (info.Member, ob, ReadObjectElement (info), isValueList);
								if (info.ChoiceValue != null) {
									XmlTypeMapMemberElement imem = (XmlTypeMapMemberElement) info.Member;
									imem.SetChoice (ob, info.ChoiceValue);
								}
							}
						}
						else
							throw new InvalidOperationException ("Unknown member type");
					}
					else if (map.DefaultAnyElementMember != null)
					{
						XmlTypeMapMemberAnyElement mem = map.DefaultAnyElementMember;
						if (mem.TypeData.IsListType) AddListValue (mem.TypeData, ref flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex]++, ReadXmlNode (mem.TypeData.ListItemTypeData, false), true);
						else SetMemberValue (mem, ob, ReadXmlNode (mem.TypeData, false), isValueList);
					}
					else 
						ProcessUnknownElement(ob);
				}
				else if ((Reader.NodeType == System.Xml.XmlNodeType.Text || Reader.NodeType == System.Xml.XmlNodeType.CDATA) && map.XmlTextCollector != null)
				{
					if (map.XmlTextCollector is XmlTypeMapMemberExpandable)
					{
						XmlTypeMapMemberExpandable mem = (XmlTypeMapMemberExpandable)map.XmlTextCollector;
						XmlTypeMapMemberFlatList flatl = mem as XmlTypeMapMemberFlatList;
						TypeData itype = (flatl == null) ? mem.TypeData.ListItemTypeData : flatl.ListMap.FindTextElement().TypeData;

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

				Reader.MoveToContent();
			}

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

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