Browse Source

* XmlSerializationReaderInterpreter.cs, XmlSerializationWriterInterpreter.cs,
XmlTypeMapMember.cs, MapCodeGenerator.cs, SoapCodeExporter.cs, TypeData.cs,
XmlCodeExporter.cs, XmlReflectionImporter.cs, XmlSchemaExporter.cs,
XmlSchemaImporter.cs, XmlSerializationReaderInterpreter.cs,
XmlSerializationWriterInterpreter.cs, XmlTypeMapMember.cs:
Added support for value specifiers members. This fixes bug #53024.

svn path=/trunk/mcs/; revision=22308

Lluis Sanchez 22 years ago
parent
commit
648ca0b963

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

@@ -1,3 +1,12 @@
+2004-01-20  Lluis Sanchez Gual  <[email protected]>
+
+	* XmlSerializationReaderInterpreter.cs, XmlSerializationWriterInterpreter.cs,
+	  XmlTypeMapMember.cs, MapCodeGenerator.cs, SoapCodeExporter.cs, TypeData.cs,
+	  XmlCodeExporter.cs, XmlReflectionImporter.cs, XmlSchemaExporter.cs,
+	  XmlSchemaImporter.cs, XmlSerializationReaderInterpreter.cs,
+	  XmlSerializationWriterInterpreter.cs, XmlTypeMapMember.cs:
+	  Added support for value specifiers members. This fixes bug #53024.
+
 2004-01-20  Lluis Sanchez Gual  <[email protected]>
 
 	* XmlSchemaExporter.cs: Don't create referenced element if it has already

+ 13 - 1
mcs/class/System.XML/System.Xml.Serialization/MapCodeGenerator.cs

@@ -199,6 +199,14 @@ namespace System.Xml.Serialization {
 			}
 
 			GenerateElementMember (codeField, member);
+			
+			if (member.TypeData.IsValueType && member.IsOptionalValueType)
+			{
+				codeField = new CodeMemberField (typeof(bool), member.Name + "Specified");
+				codeField.Attributes = MemberAttributes.Public;
+				codeClass.Members.Add (codeField);
+				GenerateSpecifierMember (codeField);
+			}
 		}
 
 		void AddAnyElementFieldMember (CodeTypeDeclaration codeClass, XmlTypeMapMemberElement member, string defaultNamespace)
@@ -421,7 +429,11 @@ namespace System.Xml.Serialization {
 		
 		protected virtual void GenerateEnumItem (CodeMemberField codeField, EnumMap.EnumMapMember emem)
 		{
-		}		
+		}
+
+		protected virtual void GenerateSpecifierMember (CodeMemberField codeField)
+		{
+		}
 
 		#endregion
 	}

+ 5 - 0
mcs/class/System.XML/System.Xml.Serialization/SoapCodeExporter.cs

@@ -145,5 +145,10 @@ namespace System.Xml.Serialization {
 				AddCustomAttribute (codeField, xatt, true);
 			}
 		}		
+		
+		protected override void GenerateSpecifierMember (CodeMemberField codeField)
+		{
+			AddCustomAttribute (codeField, "System.Xml.Serialization.SoapIgnore");
+		}
 	}
 }

+ 9 - 0
mcs/class/System.XML/System.Xml.Serialization/TypeData.cs

@@ -111,6 +111,15 @@ namespace System.Xml.Serialization
 			}
 		}
 
+		public bool IsValueType
+		{
+			get
+			{
+				return  (type != null && type.IsValueType) ||
+						(sType == SchemaTypes.Primitive) ||
+					    (sType == SchemaTypes.Enum);
+			}
+		}
 
 		public TypeData ListItemTypeData
 		{

+ 7 - 1
mcs/class/System.XML/System.Xml.Serialization/XmlCodeExporter.cs

@@ -222,6 +222,12 @@ namespace System.Xml.Serialization {
 
 				AddCustomAttribute (codeField, xatt, true);
 			}
-		}		
+		}
+		
+		protected override void GenerateSpecifierMember (CodeMemberField codeField)
+		{
+			AddCustomAttribute (codeField, "System.Xml.Serialization.XmlIgnore");
+		}
+
 	}
 }

+ 3 - 1
mcs/class/System.XML/System.Xml.Serialization/XmlReflectionImporter.cs

@@ -216,7 +216,9 @@ namespace System.Xml.Serialization {
 				foreach (XmlReflectionMember rmember in members)
 				{
 					if (rmember.XmlAttributes.XmlIgnore) continue;
-					classMap.AddMember (CreateMapMember (rmember, map.XmlTypeNamespace));
+					XmlTypeMapMember mem = CreateMapMember (rmember, map.XmlTypeNamespace);
+					mem.CheckOptionalValueType (type);
+					classMap.AddMember (mem);
 				}
 //			}
 //			catch (Exception ex) {

+ 1 - 2
mcs/class/System.XML/System.Xml.Serialization/XmlSchemaExporter.cs

@@ -342,8 +342,7 @@ namespace System.Xml.Serialization {
 				selem.MaxOccurs = 1;
 				selem.MinOccurs = einfo.IsNullable ? 1 : 0;
 				
-				if ((einfo.IsPrimitive && einfo.TypeData.Type != typeof(string)) ||
-					einfo.TypeData.Type.IsEnum || encodedFormat) 
+				if ((einfo.TypeData.IsValueType && einfo.Member != null && !einfo.Member.IsOptionalValueType) || encodedFormat) 
 					selem.MinOccurs = 1;
 			}
 

+ 5 - 1
mcs/class/System.XML/System.Xml.Serialization/XmlSchemaImporter.cs

@@ -433,7 +433,8 @@ namespace System.Xml.Serialization {
 					member.Namespace = ns;
 					member.Form = refAttr.Form;
 					member.TypeData = GetAttributeTypeData (typeQName, attr);
-					if (refAttr.DefaultValue != null) member.DefaultValue = XmlCustomFormatter.FromXmlString (member.TypeData, refAttr.DefaultValue);
+					if (refAttr.DefaultValue != null) 
+						member.DefaultValue = XmlCustomFormatter.FromXmlString (member.TypeData, refAttr.DefaultValue);
 					if (member.TypeData.IsComplexType)
 						member.MappedType = GetTypeMapping (member.TypeData);
 					cmap.AddMember (member);
@@ -627,6 +628,9 @@ namespace System.Xml.Serialization {
 						else
 							member = new XmlTypeMapMemberList ();
 
+						if (elem.MinOccurs == 0 && typeData.IsValueType)
+							member.IsOptionalValueType = true;
+
 						member.Name = classIds.AddUnique(CodeIdentifier.MakeValid(refElem.Name), member);
 						member.Documentation = GetDocumentation (elem);
 						member.TypeData = typeData;

+ 5 - 1
mcs/class/System.XML/System.Xml.Serialization/XmlSerializationReaderInterpreter.cs

@@ -429,7 +429,11 @@ namespace System.Xml.Serialization
 		void SetMemberValue (XmlTypeMapMember member, object ob, object value, bool isValueList)
 		{
 			if (isValueList) ((object[])ob)[member.Index] = value;
-			else member.SetValue (ob, value);
+			else {
+				member.SetValue (ob, value);
+				if (member.IsOptionalValueType)
+					member.SetValueSpecified (ob, true); 
+			}
 		}
 
 		object GetMemberValue (XmlTypeMapMember member, object ob, bool isValueList)

+ 3 - 0
mcs/class/System.XML/System.Xml.Serialization/XmlSerializationWriterInterpreter.cs

@@ -266,6 +266,9 @@ namespace System.Xml.Serialization
 				}
 				if (val != null && val.Equals (member.DefaultValue)) return false;
 			}
+			else if (member.IsOptionalValueType)
+				return member.GetValueSpecified (ob);
+
 			return true;
 		}
 

+ 29 - 0
mcs/class/System.XML/System.Xml.Serialization/XmlTypeMapMember.cs

@@ -22,8 +22,10 @@ namespace System.Xml.Serialization
 		int _index;
 		TypeData _typeData;
 		MemberInfo _member;
+		MemberInfo _specifiedMember;
 		object _defaultValue = System.DBNull.Value;
 		string documentation;
+		bool _isOptional;
 
 		public XmlTypeMapMember()
 		{
@@ -78,6 +80,9 @@ namespace System.Xml.Serialization
 		{
 			MemberInfo[] mems = type.GetMember (_name, BindingFlags.Instance|BindingFlags.Public);
 			_member = mems[0];
+			
+			mems = type.GetMember (_name + "Specified", BindingFlags.Instance|BindingFlags.Public);
+			if (mems.Length > 0) _specifiedMember = mems[0];
 		}
 
 		public TypeData TypeData
@@ -91,5 +96,29 @@ namespace System.Xml.Serialization
 			get { return _index; }
 			set { _index = value; }
 		}
+		
+		public bool IsOptionalValueType
+		{
+			get { return _isOptional; }
+			set { _isOptional = value; }
+		}
+		
+		public void CheckOptionalValueType (Type type)
+		{
+			if (_member == null) InitMember (type);
+			_isOptional = (_specifiedMember != null);
+		}
+		
+		public bool GetValueSpecified (object ob)
+		{
+			if (_specifiedMember is PropertyInfo) return (bool) ((PropertyInfo)_specifiedMember).GetValue (ob, null);
+			else return (bool) ((FieldInfo)_specifiedMember).GetValue (ob);
+		}
+
+		public void SetValueSpecified (object ob, bool value)
+		{
+			if (_specifiedMember is PropertyInfo) ((PropertyInfo)_specifiedMember).SetValue (ob, value, null);
+			else ((FieldInfo)_specifiedMember).SetValue (ob, value);
+		}
 	}
 }