GetElement() public method

public GetElement ( int index ) : System.Xml.Serialization.XmlTypeMapElementInfo
index int
return System.Xml.Serialization.XmlTypeMapElementInfo
Esempio n. 1
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 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);
		}
		void GenerateReadMembers (XmlMapping xmlMap, ClassMap map, string ob, bool isValueList, bool readBySoapOrder)
		{
			XmlTypeMapping typeMap = xmlMap as XmlTypeMapping;
			Type xmlMapType = (typeMap != null) ? typeMap.TypeData.Type : typeof(object[]);
			
			bool first = false;
			// Read attributes
			GenerateReadAttributeMembers (xmlMap, map, ob, isValueList, ref first);

			if (!isValueList)
			{
				WriteLine ("Reader.MoveToElement();");
				WriteLineInd ("if (Reader.IsEmptyElement) {"); 
				WriteLine ("Reader.Skip ();");
				GenerateSetListMembersDefaults (typeMap, map, ob, isValueList);
				WriteLine ("return " + ob + ";");
				WriteLineUni ("}");
				WriteLine ("");
	
				WriteLine ("Reader.ReadStartElement();");
			}
			
			// Reads elements

			WriteLine("Reader.MoveToContent();");
			WriteLine ("");

			if (!GenerateReadHook (HookType.elements, xmlMapType))
			{
				string[] readFlag = null;
				if (map.ElementMembers != null && !readBySoapOrder)
				{
					string readFlagsVars = string.Empty;
					readFlag = new string[map.ElementMembers.Count];
					int n=0;
					foreach (XmlTypeMapMember mem in map.ElementMembers) {
						// The text collector doesn't need a flag
						if (!((mem is XmlTypeMapMemberElement) && ((XmlTypeMapMemberElement)mem).IsXmlTextCollector)) {
							readFlag[n] = GetBoolTempVar ();
							if (readFlagsVars.Length > 0) readFlagsVars += ", ";
							readFlagsVars += readFlag[n] + "=false";
						}
						n++;
					}
					if (readFlagsVars.Length > 0) {
						readFlagsVars = "bool " + readFlagsVars;
						WriteLine (readFlagsVars + ";");
					}
					foreach (XmlTypeMapElementInfo info in map.AllElementInfos)
						if (info.ExplicitOrder >= 0) {
							WriteLine ("int idx = -1;");
							break;
						}
					WriteLine ("");
				}
				
				string[] indexes = null;
				string[] flatLists = null;
				string[] flatListsChoices = null;
	
				if (map.FlatLists != null) 
				{
					indexes = new string[map.FlatLists.Count];
					flatLists = new string[map.FlatLists.Count];
					
					string code = "int ";
					for (int n=0; n<map.FlatLists.Count; n++) 
					{
						XmlTypeMapMemberElement mem = (XmlTypeMapMemberElement)map.FlatLists[n];
						indexes[n] = GetNumTempVar ();
						if (n > 0) code += ", ";
						code += indexes[n] + "=0";
						if (!MemberHasReadReplaceHook (xmlMapType, mem)) {
							flatLists[n] = GetObTempVar ();
							string rval;
							WriteLine (mem.TypeData.CSharpFullName + " " + flatLists[n] + ";");
							if (IsReadOnly (typeMap, mem, mem.TypeData, isValueList)) {
								rval = GenerateGetMemberValue (mem, ob, isValueList);
								WriteLine (flatLists[n] + " = " + rval + ";");
							} else if (mem.TypeData.Type.IsArray) {
								rval = GenerateInitializeList (mem.TypeData);
								WriteLine (flatLists[n] + " = " + rval + ";");
							} else {
								WriteLine (flatLists[n] + " = " + GenerateGetMemberValue (mem, ob, isValueList) + ";");
								WriteLineInd ("if (((object)" + flatLists[n] + ") == null) {");
								WriteLine (flatLists[n] + " = " + GenerateInitializeList (mem.TypeData) + ";");
								GenerateSetMemberValue (mem, ob, flatLists[n], isValueList);
								WriteLineUni ("}");
							}
						}
						
						if (mem.ChoiceMember != null) {
							if (flatListsChoices == null)
								flatListsChoices = new string [map.FlatLists.Count];
							flatListsChoices[n] = GetObTempVar ();
							string rval = GenerateInitializeList (mem.ChoiceTypeData);
							WriteLine (mem.ChoiceTypeData.CSharpFullName + " " + flatListsChoices[n] + " = " + rval + ";");
						}
					}
					WriteLine (code + ";");
					WriteLine ("");
				}
				
				if (_format == SerializationFormat.Encoded && map.ElementMembers != null)
				{
					_fixupCallbacks.Add (xmlMap);
					WriteLine ("Fixup fixup = new Fixup(" + ob + ", new XmlSerializationFixupCallback(" + GetFixupCallbackName (xmlMap) + "), " + map.ElementMembers.Count + ");");
					WriteLine ("AddFixup (fixup);");
					WriteLine ("");
				}
	
				ArrayList infos = null;
				
				int maxInd;
				if (readBySoapOrder) {
					if (map.ElementMembers != null) maxInd = map.ElementMembers.Count;
					else maxInd = 0;
				}
				else
				{
					infos = new ArrayList ();
					infos.AddRange (map.AllElementInfos);
					maxInd = infos.Count;
					
					WriteLine ("while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) ");
					WriteLineInd ("{");
					WriteLine ("if (Reader.NodeType == System.Xml.XmlNodeType.Element) ");
					WriteLineInd ("{");
				}
				
				first = true;
				for (int ind = 0; ind < maxInd; ind++)
				{
					XmlTypeMapElementInfo info = readBySoapOrder ? map.GetElement (ind) : (XmlTypeMapElementInfo) infos [ind];
					
					if (!readBySoapOrder)
					{
						if (info.IsTextElement || info.IsUnnamedAnyElement) continue;
						string elemCond = first ? "" : "else ";
						elemCond += "if (";
						if (info.ExplicitOrder >= 0)
							elemCond += "idx < " + info.ExplicitOrder + "&& ";
						if (!(info.Member.IsReturnValue && _format == SerializationFormat.Encoded)) {
							elemCond += "Reader.LocalName == " + GetLiteral (info.ElementName);
							if (!map.IgnoreMemberNamespace) elemCond += " && Reader.NamespaceURI == " + GetLiteral (info.Namespace);
							elemCond += " && ";
						}
						if (readFlag[info.Member.Index] != null)
							elemCond += "!" + readFlag[info.Member.Index] + ") {";
						else
							elemCond += "true) {";
						WriteLineInd (elemCond);
					}
	
					if (info.Member.GetType() == typeof (XmlTypeMapMemberList))
					{
						if (_format == SerializationFormat.Encoded && info.MultiReferenceType)
						{
							string list = GetObTempVar ();
							WriteLine ("object " + list + " = ReadReferencingElement (out fixup.Ids[" + info.Member.Index + "]);");
							RegisterReferencingMap (info.MappedType);

							WriteLineInd ("if (fixup.Ids[" + info.Member.Index + "] == null) {");	// Already read
							if (IsReadOnly (typeMap, info.Member, info.TypeData, isValueList)) 
								WriteLine ("throw CreateReadOnlyCollectionException (" + GetLiteral(info.TypeData.CSharpFullName) + ");");
							else 
								GenerateSetMemberValue (info.Member, ob, GetCast (info.Member.TypeData,list), isValueList);
							WriteLineUni ("}");
	
							if (!info.MappedType.TypeData.Type.IsArray)
							{
								WriteLineInd ("else {");
								if (IsReadOnly (typeMap, info.Member, info.TypeData, isValueList)) 
									WriteLine (list + " = " + GenerateGetMemberValue (info.Member, ob, isValueList) + ";");
								else { 
									WriteLine (list + " = " + GenerateCreateList (info.MappedType.TypeData.Type) + ";");
									GenerateSetMemberValue (info.Member, ob, GetCast (info.Member.TypeData,list), isValueList);
								}
								WriteLine ("AddFixup (new CollectionFixup (" + list + ", new XmlSerializationCollectionFixupCallback (" + GetFillListName(info.Member.TypeData) + "), fixup.Ids[" + info.Member.Index + "]));");
								WriteLine ("fixup.Ids[" + info.Member.Index + "] = null;");		// The member already has the value, no further fix needed.
								WriteLineUni ("}");
							}
						}
						else
						{
							if (!GenerateReadMemberHook (xmlMapType, info.Member)) {
								if (IsReadOnly (typeMap, info.Member, info.TypeData, isValueList)) {
									GenerateReadListElement (info.MappedType, GenerateGetMemberValue (info.Member, ob, isValueList), GetLiteral(info.IsNullable), false);
								} else if (info.MappedType.TypeData.Type.IsArray) {
									if (info.IsNullable)
										GenerateSetMemberValue (info.Member, ob, GenerateReadListElement (info.MappedType, null, GetLiteral(info.IsNullable), true), isValueList);
									else {
										string list = GetObTempVar ();
										WriteLine (info.MappedType.TypeData.CSharpFullName + " " + list + " = " + GenerateReadListElement (info.MappedType, null, GetLiteral(info.IsNullable), true) + ";");
										WriteLineInd ("if (((object)" + list + ") != null) {");
										GenerateSetMemberValue (info.Member, ob, list, isValueList);
										WriteLineUni ("}");
									}
								} else {
									string list = GetObTempVar ();
									WriteLine (info.MappedType.TypeData.CSharpFullName + " " + list + " = " + GenerateGetMemberValue (info.Member, ob, isValueList) + ";");
									WriteLineInd ("if (((object)" + list + ") == null) {");
									WriteLine (list + " = " + GenerateCreateList (info.MappedType.TypeData.Type) + ";");
									GenerateSetMemberValue (info.Member, ob, list, isValueList);
									WriteLineUni ("}");
									GenerateReadListElement (info.MappedType, list, GetLiteral(info.IsNullable), true);
								}
								GenerateEndHook ();
							}
						}
						if (!readBySoapOrder)
							WriteLine (readFlag[info.Member.Index] + " = true;");
					}
					else if (info.Member.GetType() == typeof (XmlTypeMapMemberFlatList))
					{
						XmlTypeMapMemberFlatList mem = (XmlTypeMapMemberFlatList)info.Member;
						if (!GenerateReadArrayMemberHook (xmlMapType, info.Member, indexes[mem.FlatArrayIndex])) {
							GenerateAddListValue (mem.TypeData, flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], GenerateReadObjectElement (info), !IsReadOnly (typeMap, info.Member, info.TypeData, isValueList));
							if (mem.ChoiceMember != null) {
								GenerateAddListValue (mem.ChoiceTypeData, flatListsChoices[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], GetLiteral (info.ChoiceValue), true);
							}
							GenerateEndHook ();
						}
						WriteLine (indexes[mem.FlatArrayIndex] + "++;");
					}
					else if (info.Member.GetType() == typeof (XmlTypeMapMemberAnyElement))
					{
						XmlTypeMapMemberAnyElement mem = (XmlTypeMapMemberAnyElement)info.Member;
						if (mem.TypeData.IsListType) { 
							if (!GenerateReadArrayMemberHook (xmlMapType, info.Member, indexes[mem.FlatArrayIndex])) {
								GenerateAddListValue (mem.TypeData, flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], GetReadXmlNode (mem.TypeData.ListItemTypeData, false), true);
								GenerateEndHook ();
							}
							WriteLine (indexes[mem.FlatArrayIndex] + "++;");
						}
						else {
							if (!GenerateReadMemberHook (xmlMapType, info.Member)) {
								GenerateSetMemberValue (mem, ob, GetReadXmlNode(mem.TypeData, false), isValueList);
								GenerateEndHook ();
							}
						}
					}
					else if (info.Member.GetType() == typeof(XmlTypeMapMemberElement))
					{
						if (!readBySoapOrder)
							WriteLine (readFlag[info.Member.Index] + " = true;");
						if (info.ExplicitOrder >= 0)
							WriteLine ("idx = " + info.ExplicitOrder + ";");
						if (_format == SerializationFormat.Encoded)
						{
							string val = GetObTempVar ();
							RegisterReferencingMap (info.MappedType);
							
							if (info.Member.TypeData.SchemaType != SchemaTypes.Primitive)
								WriteLine ("object " + val + " = ReadReferencingElement (out fixup.Ids[" + info.Member.Index + "]);");
							else
								WriteLine ("object " + val + " = ReadReferencingElement (" + GetLiteral(info.Member.TypeData.XmlType) + ", " + GetLiteral(System.Xml.Schema.XmlSchema.Namespace) + ", out fixup.Ids[" + info.Member.Index + "]);");
							
							if (info.MultiReferenceType)
								WriteLineInd ("if (fixup.Ids[" + info.Member.Index + "] == null) {");	// already read
							else
								WriteLineInd ("if (" + val + " != null) {");	// null value
								
							GenerateSetMemberValue (info.Member, ob, GetCast (info.Member.TypeData,val), isValueList);
							WriteLineUni ("}");
						}
						else if (!GenerateReadMemberHook (xmlMapType, info.Member)) {
							if (info.ChoiceValue != null) {
								XmlTypeMapMemberElement imem = (XmlTypeMapMemberElement) info.Member;
								WriteLine (ob + ".@" + imem.ChoiceMember + " = " + GetLiteral(info.ChoiceValue) + ";");
							}
							GenerateSetMemberValue (info.Member, ob, GenerateReadObjectElement (info), isValueList);
							GenerateEndHook ();
						}
					}
					else
						throw new InvalidOperationException ("Unknown member type");
	
					if (!readBySoapOrder)
						WriteLineUni ("}");
					else
						WriteLine ("Reader.MoveToContent();");
					first = false;
				}
				
				if (!readBySoapOrder)
				{
					if (!first) WriteLineInd ("else {");
					
					if (map.DefaultAnyElementMember != null)
					{
						XmlTypeMapMemberAnyElement mem = map.DefaultAnyElementMember;
						if (mem.TypeData.IsListType) {
							if (!GenerateReadArrayMemberHook (xmlMapType, mem, indexes[mem.FlatArrayIndex])) {
								GenerateAddListValue (mem.TypeData, flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], GetReadXmlNode(mem.TypeData.ListItemTypeData, false), true);
								GenerateEndHook ();
							}
							WriteLine (indexes[mem.FlatArrayIndex] + "++;");
						}
						else if (! GenerateReadMemberHook (xmlMapType, mem)) {
							GenerateSetMemberValue (mem, ob, GetReadXmlNode(mem.TypeData, false), isValueList);
							GenerateEndHook ();
						}
					}
					else {
						if (!GenerateReadHook (HookType.unknownElement, xmlMapType)) {
							WriteLine ("UnknownNode (" + ob + ");");
							GenerateEndHook ();
						}
					}
					
					if (!first) WriteLineUni ("}");
		
					WriteLineUni ("}");
					
					if (map.XmlTextCollector != null)
					{
						WriteLine ("else if (Reader.NodeType == System.Xml.XmlNodeType.Text || Reader.NodeType == System.Xml.XmlNodeType.CDATA)");
						WriteLineInd ("{");
		
						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;
							
							if (!GenerateReadArrayMemberHook (xmlMapType, map.XmlTextCollector, indexes[mem.FlatArrayIndex])) {
								string val = (itype.Type == typeof (string)) ? "Reader.ReadString()" : GetReadXmlNode (itype, false);
								GenerateAddListValue (mem.TypeData, flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], val, true);
								GenerateEndHook ();
							}
							WriteLine (indexes[mem.FlatArrayIndex] + "++;");
						}
						else if (!GenerateReadMemberHook (xmlMapType, map.XmlTextCollector))
						{
							XmlTypeMapMemberElement mem = (XmlTypeMapMemberElement) map.XmlTextCollector;
							XmlTypeMapElementInfo info = (XmlTypeMapElementInfo) mem.ElementInfo [0];
							if (info.TypeData.Type == typeof (string))
								GenerateSetMemberValue (mem, ob, "ReadString (" + GenerateGetMemberValue (mem, ob, isValueList) + ")", isValueList);
							else {
								WriteLineInd ("{");
								string str = GetStrTempVar ();
								WriteLine ("string " + str + " = Reader.ReadString();");
								GenerateSetMemberValue (mem, ob, GenerateGetValueFromXmlString (str, info.TypeData, info.MappedType, info.IsNullable), isValueList);
								WriteLineUni ("}");
							}
							GenerateEndHook ();
						}
						WriteLineUni ("}");
					}
						
					WriteLine ("else");
					WriteLine ("\tUnknownNode(" + ob + ");");
					WriteLine ("");
					WriteLine ("Reader.MoveToContent();");
					WriteLineUni ("}");
				}
				else
					WriteLine ("Reader.MoveToContent();");
	
				if (flatLists != null)
				{
					WriteLine ("");
					foreach (XmlTypeMapMemberExpandable mem in map.FlatLists)
					{
						if (MemberHasReadReplaceHook (xmlMapType, mem)) continue;
						
						string list = flatLists[mem.FlatArrayIndex];
						if (mem.TypeData.Type.IsArray)
							WriteLine (list + " = (" + mem.TypeData.CSharpFullName + ") ShrinkArray (" + list + ", " + indexes[mem.FlatArrayIndex] + ", " + GetTypeOf(mem.TypeData.Type.GetElementType()) + ", true);");
						if (!IsReadOnly (typeMap, mem, mem.TypeData, isValueList) && mem.TypeData.Type.IsArray)
							GenerateSetMemberValue (mem, ob, list, isValueList);
					}
				}
				
				if (flatListsChoices != null)
				{
					WriteLine ("");
					foreach (XmlTypeMapMemberExpandable mem in map.FlatLists)
					{
						if (MemberHasReadReplaceHook (xmlMapType, mem)) continue;
						if (mem.ChoiceMember == null) continue;
						
						string list = flatListsChoices[mem.FlatArrayIndex];
						WriteLine (list + " = (" + mem.ChoiceTypeData.CSharpFullName + ") ShrinkArray (" + list + ", " + indexes[mem.FlatArrayIndex] + ", " + GetTypeOf(mem.ChoiceTypeData.Type.GetElementType()) + ", true);");
						WriteLine (ob + ".@" + mem.ChoiceMember + " = " + list + ";");
					}
				}
				
				GenerateSetListMembersDefaults (typeMap, map, ob, isValueList);
				
				GenerateEndHook ();
			}			

			if (!isValueList)
			{
				WriteLine ("");
				WriteLine ("ReadEndElement();");
			}
		}
        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);
        }
Esempio n. 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 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) 
					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 
										&& map.ReturnMember.TypeData.Type == typeof(object));
			
			Reader.MoveToContent();

			int[] indexes = null;
			object[] flatLists = 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, ob, isValueList)) flatLists[mem.FlatArrayIndex] = mem.GetValue (ob);
			}
			
			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, 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, 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, ob, isValueList)) ReadListElement (info.MappedType, info.IsNullable, GetMemberValue (info.Member, ob, isValueList), false);
								else SetMemberValue (info.Member, ob, ReadListElement (info.MappedType, info.IsNullable, null, true), isValueList);
							}
							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, ob, isValueList));
						}
						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)
							{
								val = ReadReferencingElement (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);
						}
						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 && 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.Read();
				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, ob, isValueList))
						SetMemberValue (mem, ob, list, isValueList);
				}
			}		
		}
		void GenerateReadMembers (XmlMapping xmlMap, ClassMap map, string ob, bool isValueList, bool readByOrder)
		{
			XmlTypeMapping typeMap = xmlMap as XmlTypeMapping;
			Type xmlMapType = (typeMap != null) ? typeMap.TypeData.Type : typeof(object[]);
			
			// Load the default value of members
			if (map.MembersWithDefault != null)
			{
				ArrayList members = map.MembersWithDefault;
				for (int n=0; n<members.Count; n++) {
					XmlTypeMapMember mem = (XmlTypeMapMember) members[n];
					GenerateSetMemberValueFromAttr (mem, ob, GetLiteral (mem.DefaultValue), isValueList);
				}
			}
			
			// A value list cannot have attributes

			bool first;
			if (!isValueList && !GenerateReadHook (HookType.attributes, xmlMapType))
			{
				// Reads attributes
				
				XmlTypeMapMember anyAttrMember = map.DefaultAnyAttributeMember;
				
				if (anyAttrMember != null)
				{
					WriteLine ("int anyAttributeIndex = 0;");
					WriteLine (anyAttrMember.TypeData.FullTypeName + " anyAttributeArray = null;");
				}
				
				WriteLine ("while (Reader.MoveToNextAttribute())");
				WriteLineInd ("{");
				first = true;
				if (map.AttributeMembers != null) {
					foreach (XmlTypeMapMemberAttribute at in map.AttributeMembers)
					{
						WriteLineInd ((first?"":"else ") + "if (Reader.LocalName == " + GetLiteral (at.AttributeName) + " && Reader.NamespaceURI == " + GetLiteral (at.Namespace) + ") {");
						if (!GenerateReadMemberHook (xmlMapType, at)) {
							GenerateSetMemberValue (at, ob, GenerateGetValueFromXmlString ("Reader.Value", at.TypeData, at.MappedType), isValueList);
							GenerateEndHook ();
						}
						WriteLineUni ("}");
						first = false;
					}
				}
				WriteLineInd ((first?"":"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) {
					if (!GenerateReadMemberHook (xmlMapType, map.NamespaceDeclarations)) {
						string nss = ob + ".@" + map.NamespaceDeclarations.Name;
						WriteLine ("if (" + nss + " == null) " + nss + " = new XmlSerializerNamespaces ();");
						WriteLineInd ("if (Reader.Prefix == \"xmlns\")");
						WriteLine (nss + ".Add (Reader.LocalName, Reader.Value);");
						Unindent ();
						WriteLineInd ("else");
						WriteLine (nss + ".Add (\"\", Reader.Value);");
						Unindent ();
						GenerateEndHook ();
					}
				}
				
				WriteLineUni ("}");
				WriteLineInd ("else {");

				if (anyAttrMember != null) 
				{
					if (!GenerateReadArrayMemberHook (xmlMapType, anyAttrMember, "anyAttributeIndex")) {
						WriteLine ("System.Xml.XmlAttribute attr = (System.Xml.XmlAttribute) Document.ReadNode(Reader);");
						if (typeof(System.Xml.Schema.XmlSchemaAnnotated).IsAssignableFrom (xmlMapType)) 
							WriteLine ("ParseWsdlArrayType (attr);");
						GenerateAddListValue (anyAttrMember.TypeData, "anyAttributeArray", "anyAttributeIndex", GetCast (anyAttrMember.TypeData.ListItemTypeData, "attr"), true);
						GenerateEndHook ();
					}
					WriteLine ("anyAttributeIndex++;");
				}
				else {
					if (!GenerateReadHook (HookType.unknownAttribute, xmlMapType)) {
						WriteLine ("UnknownNode (" + ob + ");");
						GenerateEndHook ();
					}
				}

				WriteLineUni ("}");
				WriteLineUni ("}");

				if (anyAttrMember != null && !MemberHasReadReplaceHook (xmlMapType, anyAttrMember))
				{
					WriteLine ("");
					WriteLine("anyAttributeArray = (" + anyAttrMember.TypeData.FullTypeName + ") ShrinkArray (anyAttributeArray, anyAttributeIndex, " + GetTypeOf(anyAttrMember.TypeData.Type.GetElementType()) + ", true);");
					GenerateSetMemberValue (anyAttrMember, ob, "anyAttributeArray", isValueList);
				}
				WriteLine ("");
	
				GenerateEndHook ();
			}

			if (!isValueList)
			{
				WriteLine ("Reader.MoveToElement();");
				WriteLineInd ("if (Reader.IsEmptyElement) {"); 
				WriteLine ("Reader.Skip ();");
				WriteLine ("return " + ob + ";");
				WriteLineUni ("}");
				WriteLine ("");
	
				WriteLine ("Reader.ReadStartElement();");
			}
			
			// Reads elements

			WriteLine("Reader.MoveToContent();");
			WriteLine ("");

			if (!GenerateReadHook (HookType.elements, xmlMapType))
			{
				string[] readFlag = null;
				if (map.ElementMembers != null && !readByOrder)
				{
					string readFlagsVars = "bool ";
					readFlag = new string[map.ElementMembers.Count];
					for (int n=0; n<map.ElementMembers.Count; n++) {
						readFlag[n] = GetBoolTempVar ();
						if (n > 0) readFlagsVars += ", ";
						readFlagsVars += readFlag[n] + "=false";
					}
					if (map.ElementMembers.Count > 0) WriteLine (readFlagsVars + ";");
					WriteLine ("");
				}
				
				string[] indexes = null;
				string[] flatLists = null;
	
				if (map.FlatLists != null) 
				{
					indexes = new string[map.FlatLists.Count];
					flatLists = new string[map.FlatLists.Count];
					
					string code = "int ";
					for (int n=0; n<map.FlatLists.Count; n++) 
					{
						XmlTypeMapMember mem = (XmlTypeMapMember)map.FlatLists[n];
						indexes[n] = GetNumTempVar ();
						if (n > 0) code += ", ";
						code += indexes[n] + "=0";
						if (!MemberHasReadReplaceHook (xmlMapType, mem)) {
							flatLists[n] = GetObTempVar ();
							string rval = "null";
							if (IsReadOnly (typeMap, mem, isValueList)) rval = ob + ".@" + mem.Name;
							WriteLine (mem.TypeData.FullTypeName + " " + flatLists[n] + " = " + rval + ";");
						}
					}
					WriteLine (code + ";");
					WriteLine ("");
				}
				
				if (_format == SerializationFormat.Encoded && map.ElementMembers != null)
				{
					_fixupCallbacks.Add (xmlMap);
					WriteLine ("Fixup fixup = new Fixup(" + ob + ", new XmlSerializationFixupCallback(" + GetFixupCallbackName (xmlMap) + "), " + map.ElementMembers.Count + ");");
					WriteLine ("AddFixup (fixup);");
					WriteLine ("");
				}
	
				ArrayList infos = null;
				
				int maxInd;
				if (readByOrder) {
					if (map.ElementMembers != null) maxInd = map.ElementMembers.Count;
					else maxInd = 0;
				}
				else
				{
					infos = new ArrayList ();
					infos.AddRange (map.AllElementInfos);
					maxInd = infos.Count;
					
					WriteLine ("while (Reader.NodeType != System.Xml.XmlNodeType.EndElement) ");
					WriteLineInd ("{");
					WriteLine ("if (Reader.NodeType == System.Xml.XmlNodeType.Element) ");
					WriteLineInd ("{");
				}
				
				first = true;
				for (int ind = 0; ind < maxInd; ind++)
				{
					XmlTypeMapElementInfo info = readByOrder ? map.GetElement (ind) : (XmlTypeMapElementInfo) infos [ind];
					
					if (!readByOrder)
					{
						if (info.IsTextElement || info.IsUnnamedAnyElement) continue;
						string elemCond = first ? "" : "else ";
						elemCond += "if (";
						if (!(info.Member.IsReturnValue && info.TypeData.Type == typeof(object) && _format == SerializationFormat.Encoded)) {
							elemCond += "Reader.LocalName == " + GetLiteral (info.ElementName);
							if (!map.IgnoreMemberNamespace) elemCond += " && Reader.NamespaceURI == " + GetLiteral (info.Namespace);
							elemCond += " && ";
						}
						elemCond += "!" + readFlag[info.Member.Index] + ") {";
						WriteLineInd (elemCond);
					}
	
					if (info.Member.GetType() == typeof (XmlTypeMapMemberList))
					{
						if (_format == SerializationFormat.Encoded && info.MultiReferenceType)
						{
							string list = GetObTempVar ();
							WriteLine ("object " + list + " = ReadReferencingElement (out fixup.Ids[" + info.Member.Index + "]);");
							RegisterReferencingMap (info.MappedType);

							WriteLineInd ("if (fixup.Ids[" + info.Member.Index + "] == null) {");	// Already read
							if (IsReadOnly (typeMap, info.Member, isValueList)) 
								WriteLine ("throw CreateReadOnlyCollectionException (" + GetLiteral(info.TypeData.FullTypeName) + ");");
							else 
								GenerateSetMemberValue (info.Member, ob, GetCast (info.Member.TypeData,list), isValueList);
							WriteLineUni ("}");
	
							if (!info.MappedType.TypeData.Type.IsArray)
							{
								WriteLineInd ("else {");
								if (IsReadOnly (typeMap, info.Member, isValueList)) 
									WriteLine (list + " = " + GenerateGetMemberValue (info.Member, ob, isValueList) + ";");
								else { 
									WriteLine (list + " = " + GenerateCreateList (info.MappedType.TypeData.Type) + ";");
									GenerateSetMemberValue (info.Member, ob, GetCast (info.Member.TypeData,list), isValueList);
								}
								WriteLine ("AddFixup (new CollectionFixup (" + list + ", new XmlSerializationCollectionFixupCallback (" + GetFillListName(info.Member.TypeData) + "), fixup.Ids[" + info.Member.Index + "]));");
								WriteLine ("fixup.Ids[" + info.Member.Index + "] = null;");		// The member already has the value, no further fix needed.
								WriteLineUni ("}");
							}
						}
						else
						{
							if (!GenerateReadMemberHook (xmlMapType, info.Member)) {
								if (IsReadOnly (typeMap, info.Member, isValueList)) GenerateReadListElement (info.MappedType, GenerateGetMemberValue (info.Member, ob, isValueList), GetLiteral(info.IsNullable), false);
								else GenerateSetMemberValue (info.Member, ob, GenerateReadListElement (info.MappedType, null, GetLiteral(info.IsNullable), true), isValueList);
								GenerateEndHook ();
							}
						}
						if (!readByOrder)
							WriteLine (readFlag[info.Member.Index] + " = true;");
					}
					else if (info.Member.GetType() == typeof (XmlTypeMapMemberFlatList))
					{
						XmlTypeMapMemberFlatList mem = (XmlTypeMapMemberFlatList)info.Member;
						if (!GenerateReadArrayMemberHook (xmlMapType, info.Member, indexes[mem.FlatArrayIndex])) {
							GenerateAddListValue (mem.TypeData, flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], GenerateReadObjectElement (info), !IsReadOnly (typeMap, info.Member, isValueList));
							GenerateEndHook ();
						}
						WriteLine (indexes[mem.FlatArrayIndex] + "++;");
					}
					else if (info.Member.GetType() == typeof (XmlTypeMapMemberAnyElement))
					{
						XmlTypeMapMemberAnyElement mem = (XmlTypeMapMemberAnyElement)info.Member;
						if (mem.TypeData.IsListType) { 
							if (!GenerateReadArrayMemberHook (xmlMapType, info.Member, indexes[mem.FlatArrayIndex])) {
								GenerateAddListValue (mem.TypeData, flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], GetReadXmlNode (mem.TypeData.ListItemTypeData, false), true);
								GenerateEndHook ();
							}
							WriteLine (indexes[mem.FlatArrayIndex] + "++;");
						}
						else {
							if (!GenerateReadMemberHook (xmlMapType, info.Member)) {
								GenerateSetMemberValue (mem, ob, GetReadXmlNode(mem.TypeData, false), isValueList);
								GenerateEndHook ();
							}
						}
					}
					else if (info.Member.GetType() == typeof(XmlTypeMapMemberElement))
					{
						if (!readByOrder)
							WriteLine (readFlag[info.Member.Index] + " = true;");
						if (_format == SerializationFormat.Encoded) 
						{
							string val = GetObTempVar ();
							RegisterReferencingMap (info.MappedType);
							WriteLine ("object " + val + " = ReadReferencingElement (out fixup.Ids[" + info.Member.Index + "]);");
							
							if (info.MultiReferenceType)
								WriteLineInd ("if (fixup.Ids[" + info.Member.Index + "] == null) {");	// already read
							else
								WriteLineInd ("if (" + val + " != null) {");	// null value
								
							GenerateSetMemberValue (info.Member, ob, GetCast (info.Member.TypeData,val), isValueList);
							WriteLineUni ("}");
						}
						else if (!GenerateReadMemberHook (xmlMapType, info.Member)) {
							GenerateSetMemberValue (info.Member, ob, GenerateReadObjectElement (info), isValueList);
							GenerateEndHook ();
						}
					}
					else
						throw new InvalidOperationException ("Unknown member type");
	
					if (!readByOrder)
						WriteLineUni ("}");
					first = false;
				}
				
				if (!readByOrder)
				{
					if (!first) WriteLineInd ("else {");
					
					if (map.DefaultAnyElementMember != null)
					{
						XmlTypeMapMemberAnyElement mem = map.DefaultAnyElementMember;
						if (mem.TypeData.IsListType) {
							if (!GenerateReadArrayMemberHook (xmlMapType, mem, indexes[mem.FlatArrayIndex])) {
								GenerateAddListValue (mem.TypeData, flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], GetReadXmlNode(mem.TypeData.ListItemTypeData, false), true);
								GenerateEndHook ();
							}
							WriteLine (indexes[mem.FlatArrayIndex] + "++;");
						}
						else if (! GenerateReadMemberHook (xmlMapType, mem)) {
							GenerateSetMemberValue (mem, ob, GetReadXmlNode(mem.TypeData, false), isValueList);
							GenerateEndHook ();
						}
					}
					else {
						if (!GenerateReadHook (HookType.unknownElement, xmlMapType)) {
							WriteLine ("UnknownNode (" + ob + ");");
							GenerateEndHook ();
						}
					}
					
					if (!first) WriteLineUni ("}");
		
					WriteLineUni ("}");
					
					if (map.XmlTextCollector != null)
					{
						WriteLine ("else if (Reader.NodeType == System.Xml.XmlNodeType.Text)");
						WriteLineInd ("{");
		
						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;
							
							if (!GenerateReadArrayMemberHook (xmlMapType, map.XmlTextCollector, indexes[mem.FlatArrayIndex])) {
								string val = (itype.Type == typeof (string)) ? "Reader.ReadString()" : GetReadXmlNode (itype, false);
								GenerateAddListValue (mem.TypeData, flatLists[mem.FlatArrayIndex], indexes[mem.FlatArrayIndex], val, true);
								GenerateEndHook ();
							}
							WriteLine (indexes[mem.FlatArrayIndex] + "++;");
						}
						else if (!GenerateReadMemberHook (xmlMapType, map.XmlTextCollector))
						{
							XmlTypeMapMemberElement mem = (XmlTypeMapMemberElement) map.XmlTextCollector;
							XmlTypeMapElementInfo info = (XmlTypeMapElementInfo) mem.ElementInfo [0];
							if (info.TypeData.Type == typeof (string))
								GenerateSetMemberValue (mem, ob, "ReadString (" + GenerateGetMemberValue (mem, ob, isValueList) + ")", isValueList);
							else
								GenerateSetMemberValue (mem, ob, GenerateGetValueFromXmlString ("Reader.ReadString()", info.TypeData, info.MappedType), isValueList);
							GenerateEndHook ();
						}
						WriteLineUni ("}");
					}
						
					WriteLine ("else");
					WriteLine ("\tUnknownNode(" + ob + ");");
					WriteLine ("");
					WriteLine ("Reader.MoveToContent();");
					WriteLineUni ("}");
				}
				else
					WriteLine ("Reader.MoveToContent();");
	
				if (flatLists != null)
				{
					WriteLine ("");
					foreach (XmlTypeMapMemberExpandable mem in map.FlatLists)
					{
						if (MemberHasReadReplaceHook (xmlMapType, mem)) continue;
						
						string list = flatLists[mem.FlatArrayIndex];
						if (mem.TypeData.Type.IsArray)
							WriteLine (list + " = (" + mem.TypeData.FullTypeName + ") ShrinkArray (" + list + ", " + indexes[mem.FlatArrayIndex] + ", " + GetTypeOf(mem.TypeData.Type.GetElementType()) + ", true);");
						if (!IsReadOnly (typeMap, mem, isValueList))
							GenerateSetMemberValue (mem, ob, list, isValueList);
					}
				}
				GenerateEndHook ();
			}			

			if (!isValueList)
			{
				WriteLine ("");
				WriteLine ("ReadEndElement();");
			}
		}
Esempio n. 8
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);
        }