Bläddra i källkod

2005-08-05 Lluis Sanchez Gual <[email protected]>

	* XmlTypeMapping.cs: Added ListMembers property that returns
	members which are collections.
	* SerializationCodeGenerator.cs:
	* XmlSerializationReaderInterpreter.cs: Initialize collection
	members to an empty collection by default. Fixes bug #75662.


svn path=/trunk/mcs/; revision=48037
Lluis Sanchez 20 år sedan
förälder
incheckning
2edbc72ff5

+ 8 - 0
mcs/class/System.XML/System.Xml.Serialization/ChangeLog

@@ -1,3 +1,11 @@
+2005-08-05  Lluis Sanchez Gual  <[email protected]>
+
+	* XmlTypeMapping.cs: Added ListMembers property that returns
+	members which are collections.
+	* SerializationCodeGenerator.cs:
+	* XmlSerializationReaderInterpreter.cs: Initialize collection
+	members to an empty collection by default. Fixes bug #75662.
+
 2005-08-01  Gert Driesen  <[email protected]>
 2005-08-01  Gert Driesen  <[email protected]>
 
 
 	* XmlMapping.cs: API compatibility fixes. Ctor is not protected
 	* XmlMapping.cs: API compatibility fixes. Ctor is not protected

+ 33 - 2
mcs/class/System.XML/System.Xml.Serialization/SerializationCodeGenerator.cs

@@ -1584,6 +1584,7 @@ namespace System.Xml.Serialization
 				WriteLine ("Reader.MoveToElement();");
 				WriteLine ("Reader.MoveToElement();");
 				WriteLineInd ("if (Reader.IsEmptyElement) {"); 
 				WriteLineInd ("if (Reader.IsEmptyElement) {"); 
 				WriteLine ("Reader.Skip ();");
 				WriteLine ("Reader.Skip ();");
+				GenerateSetListMembersDefaults (typeMap, map, ob, isValueList);
 				WriteLine ("return " + ob + ";");
 				WriteLine ("return " + ob + ";");
 				WriteLineUni ("}");
 				WriteLineUni ("}");
 				WriteLine ("");
 				WriteLine ("");
@@ -1629,8 +1630,11 @@ namespace System.Xml.Serialization
 						code += indexes[n] + "=0";
 						code += indexes[n] + "=0";
 						if (!MemberHasReadReplaceHook (xmlMapType, mem)) {
 						if (!MemberHasReadReplaceHook (xmlMapType, mem)) {
 							flatLists[n] = GetObTempVar ();
 							flatLists[n] = GetObTempVar ();
-							string rval = "null";
-							if (IsReadOnly (typeMap, mem, mem.TypeData, isValueList)) rval = ob + ".@" + mem.Name;
+							string rval;
+							if (IsReadOnly (typeMap, mem, mem.TypeData, isValueList))
+								rval = ob + ".@" + mem.Name;
+							else
+								rval = GenerateInitializeList (mem.TypeData);
 							WriteLine (mem.TypeData.FullTypeName + " " + flatLists[n] + " = " + rval + ";");
 							WriteLine (mem.TypeData.FullTypeName + " " + flatLists[n] + " = " + rval + ";");
 						}
 						}
 					}
 					}
@@ -1875,6 +1879,9 @@ namespace System.Xml.Serialization
 							GenerateSetMemberValue (mem, ob, list, isValueList);
 							GenerateSetMemberValue (mem, ob, list, isValueList);
 					}
 					}
 				}
 				}
+				
+				GenerateSetListMembersDefaults (typeMap, map, ob, isValueList);
+				
 				GenerateEndHook ();
 				GenerateEndHook ();
 			}			
 			}			
 
 
@@ -1885,6 +1892,22 @@ namespace System.Xml.Serialization
 			}
 			}
 		}
 		}
 		
 		
+		void GenerateSetListMembersDefaults (XmlTypeMapping typeMap, ClassMap map, string ob, bool isValueList)
+		{
+			if (map.ListMembers != null)
+			{
+				ArrayList members = map.ListMembers;
+				for (int n=0; n<members.Count; n++) {
+					XmlTypeMapMember mem = (XmlTypeMapMember) members[n];
+					if (IsReadOnly (typeMap, mem, mem.TypeData, isValueList))
+						continue;
+					WriteLineInd ("if (" + GenerateGetMemberValue (mem, ob, isValueList) + " == null) {");
+					GenerateSetMemberValue (mem, ob, GenerateInitializeList (mem.TypeData), isValueList);
+					WriteLineUni ("}");
+				}
+			}
+		}
+		
 		bool IsReadOnly (XmlTypeMapping map, XmlTypeMapMember member, TypeData memType, bool isValueList)
 		bool IsReadOnly (XmlTypeMapping map, XmlTypeMapMember member, TypeData memType, bool isValueList)
 		{
 		{
 			if (isValueList) return !memType.HasPublicConstructor;
 			if (isValueList) return !memType.HasPublicConstructor;
@@ -2098,6 +2121,14 @@ namespace System.Xml.Serialization
 				return "new " + listType.FullName + "()";
 				return "new " + listType.FullName + "()";
 		}
 		}
 		
 		
+		string GenerateInitializeList (TypeData listType)
+		{
+			if (listType.Type.IsArray)
+				return "null";
+			else
+				return "new " + listType.Type.FullName + "()";
+		}
+		
 		void GenerateFillerCallbacks ()
 		void GenerateFillerCallbacks ()
 		{
 		{
 			foreach (TypeData td in _listsToFill)
 			foreach (TypeData td in _listsToFill)

+ 32 - 3
mcs/class/System.XML/System.Xml.Serialization/XmlSerializationReaderInterpreter.cs

@@ -284,8 +284,10 @@ namespace System.Xml.Serialization
 			if (!isValueList)
 			if (!isValueList)
 			{
 			{
 				Reader.MoveToElement();
 				Reader.MoveToElement();
-				if (Reader.IsEmptyElement) 
+				if (Reader.IsEmptyElement) { 
+					SetListMembersDefaults (map, ob, isValueList);
 					return;
 					return;
+				}
 
 
 				Reader.ReadStartElement();
 				Reader.ReadStartElement();
 			}
 			}
@@ -316,7 +318,10 @@ namespace System.Xml.Serialization
 				indexes = new int[map.FlatLists.Count];
 				indexes = new int[map.FlatLists.Count];
 				flatLists = new object[map.FlatLists.Count];
 				flatLists = new object[map.FlatLists.Count];
 				foreach (XmlTypeMapMemberExpandable mem in map.FlatLists)
 				foreach (XmlTypeMapMemberExpandable mem in map.FlatLists)
-					if (IsReadOnly (mem, mem.TypeData, ob, isValueList)) flatLists[mem.FlatArrayIndex] = mem.GetValue (ob);
+					if (IsReadOnly (mem, mem.TypeData, ob, isValueList))
+						flatLists [mem.FlatArrayIndex] = mem.GetValue (ob);
+					else
+						flatLists [mem.FlatArrayIndex] = InitializeList (mem.TypeData);
 			}
 			}
 			
 			
 			if (_format == SerializationFormat.Encoded && map.ElementMembers != null)
 			if (_format == SerializationFormat.Encoded && map.ElementMembers != null)
@@ -459,7 +464,23 @@ namespace System.Xml.Serialization
 					if (!IsReadOnly (mem, mem.TypeData, ob, isValueList))
 					if (!IsReadOnly (mem, mem.TypeData, ob, isValueList))
 						SetMemberValue (mem, ob, list, isValueList);
 						SetMemberValue (mem, ob, list, isValueList);
 				}
 				}
-			}		
+			}
+			SetListMembersDefaults (map, ob, isValueList);
+		}
+		
+		void SetListMembersDefaults (ClassMap map, object ob, bool isValueList)
+		{
+			if (map.ListMembers != null)
+			{
+				ArrayList members = map.ListMembers;
+				for (int n=0; n<members.Count; n++) {
+					XmlTypeMapMember mem = (XmlTypeMapMember) members[n];
+					if (IsReadOnly (mem, mem.TypeData, ob, isValueList))
+						continue;
+					if (GetMemberValue (mem, ob, isValueList) == null)
+						SetMemberValue (mem, ob, InitializeList (mem.TypeData), isValueList);
+				}
+			}
 		}
 		}
 
 
 		internal void FixupMembers (ClassMap map, object obfixup, bool isValueList)
 		internal void FixupMembers (ClassMap map, object obfixup, bool isValueList)
@@ -662,6 +683,14 @@ namespace System.Xml.Serialization
 			else
 			else
 				return Activator.CreateInstance (listType);
 				return Activator.CreateInstance (listType);
 		}
 		}
+		
+		object InitializeList (TypeData listType)
+		{
+			if (listType.Type.IsArray)
+				return null;
+			else
+				return Activator.CreateInstance (listType.Type);
+		}
 
 
 		void FillList (object list, object items)
 		void FillList (object list, object items)
 		{
 		{

+ 13 - 2
mcs/class/System.XML/System.Xml.Serialization/XmlTypeMapping.cs

@@ -207,6 +207,7 @@ namespace System.Xml.Serialization
 		ArrayList _flatLists;
 		ArrayList _flatLists;
 		ArrayList _allMembers = new ArrayList ();
 		ArrayList _allMembers = new ArrayList ();
 		ArrayList _membersWithDefault;
 		ArrayList _membersWithDefault;
+		ArrayList _listMembers;
 		XmlTypeMapMemberAnyElement _defaultAnyElement;
 		XmlTypeMapMemberAnyElement _defaultAnyElement;
 		XmlTypeMapMemberAnyAttribute _defaultAnyAttribute;
 		XmlTypeMapMemberAnyAttribute _defaultAnyAttribute;
 		XmlTypeMapMemberNamespaces _namespaceDeclarations;
 		XmlTypeMapMemberNamespaces _namespaceDeclarations;
@@ -219,7 +220,7 @@ namespace System.Xml.Serialization
 		{
 		{
 			_allMembers.Add (member);
 			_allMembers.Add (member);
 			
 			
-			if (!(member.DefaultValue is System.DBNull)) {
+			if (!(member.DefaultValue is System.DBNull) && member.DefaultValue != null) {
 				if (_membersWithDefault == null) _membersWithDefault = new ArrayList ();
 				if (_membersWithDefault == null) _membersWithDefault = new ArrayList ();
 				_membersWithDefault.Add (member);
 				_membersWithDefault.Add (member);
 			}
 			}
@@ -280,6 +281,11 @@ namespace System.Xml.Serialization
 				if (_elements.ContainsKey (key)) 
 				if (_elements.ContainsKey (key)) 
 					throw new InvalidOperationException ("The XML element named '" + elem.ElementName + "' from namespace '" + elem.Namespace + "' already present in the current scope. Use XML attributes to specify another XML name or namespace for the element.");
 					throw new InvalidOperationException ("The XML element named '" + elem.ElementName + "' from namespace '" + elem.Namespace + "' already present in the current scope. Use XML attributes to specify another XML name or namespace for the element.");
 				_elements.Add (key, elem);
 				_elements.Add (key, elem);
+			}
+			
+			if (member.TypeData.IsListType && !member.TypeData.Type.IsArray) {
+				if (_listMembers == null) _listMembers = new ArrayList ();
+				_listMembers.Add (member);
 			}
 			}
 		}
 		}
 
 
@@ -393,7 +399,12 @@ namespace System.Xml.Serialization
 		public ArrayList MembersWithDefault
 		public ArrayList MembersWithDefault
 		{
 		{
 			get { return _membersWithDefault; }
 			get { return _membersWithDefault; }
-		}
+		}
+		
+		public ArrayList ListMembers
+		{
+			get { return _listMembers; }
+		}
 
 
 		public XmlTypeMapMember XmlTextCollector
 		public XmlTypeMapMember XmlTextCollector
 		{
 		{