Ver código fonte

2004-08-25 Atsushi Enomoto <[email protected]>

	* XPathAtomicValue.cs : Handle .ctor() with object parameter more
	  precisely (still not enough, for list argument).
	  Removed commended blocks.

svn path=/trunk/mcs/; revision=32811
Atsushi Eno 21 anos atrás
pai
commit
dd03aab9d5

+ 6 - 0
mcs/class/System.XML/System.Xml.XPath/ChangeLog

@@ -1,3 +1,9 @@
+2004-08-25  Atsushi Enomoto  <[email protected]>
+
+	* XPathAtomicValue.cs : Handle .ctor() with object parameter more
+	  precisely (still not enough, for list argument).
+	  Removed commended blocks.
+
 2004-08-24  Atsushi Enomoto  <[email protected]>
 
 	* XPathAtomicValue.cs : DateTime should be convertible to string.

+ 170 - 36
mcs/class/System.XML/System.Xml.XPath/XPathAtomicValue.cs

@@ -49,7 +49,7 @@ namespace System.Xml.XPath
 		string stringValue;
 		XmlSchemaType schemaType;
 		XmlTypeCode xmlTypeCode;
-		ArrayList valueAsList;
+		ICollection valueAsList;
 
 		#region Constructors
 
@@ -116,16 +116,16 @@ namespace System.Xml.XPath
 		[MonoTODO]
 		public XPathAtomicValue (object value, XmlSchemaType xmlType)
 		{
-			// (known) acceptable types:
-			//	* ArrayList
-			//	* XPathAtomicValue (including Clone() support)
-
+			// It accepts any kind of object, but will be rejected on each value properties.
 			if (value == null)
 				throw new ArgumentNullException ("value");
 			if (xmlType == null)
 				throw new ArgumentNullException ("xmlType");
-			xmlTypeCode = xmlType.TypeCode;
-			objectValue = value;
+
+			if (value is XPathAtomicValue)
+				objectValue = ((XPathAtomicValue) value).TypedValue;
+			else
+				objectValue = value;
 			schemaType = xmlType;
 		}
 
@@ -169,6 +169,33 @@ namespace System.Xml.XPath
 		[MonoTODO]
 		public override object ValueAs (Type type, IXmlNamespaceResolver nsResolver)
 		{
+			switch (XmlTypeCodeFromRuntimeType (type, false)) {
+			case XmlTypeCode.Int:
+			case XmlTypeCode.Short:
+			case XmlTypeCode.UnsignedShort:
+				return ValueAsInt32;
+			case XmlTypeCode.Decimal:
+				return ValueAsDecimal;
+			case XmlTypeCode.Double:
+				return ValueAsDouble;
+			case XmlTypeCode.Float:
+				return ValueAsSingle;
+			case XmlTypeCode.Long:
+			case XmlTypeCode.UnsignedInt:
+				return ValueAsInt64;
+			case XmlTypeCode.String:
+				return Value;
+			case XmlTypeCode.DateTime:
+				return ValueAsDateTime;
+			case XmlTypeCode.Boolean:
+				return ValueAsBoolean;
+			case XmlTypeCode.Item:
+				return TypedValue;
+			case XmlTypeCode.QName:
+				return XmlQualifiedName.Parse (Value, nsResolver);
+			}
+			if (type.GetInterface ("System.Collections.ICollection") != null)
+				return ValueAsList;
 			throw new NotImplementedException ();
 		}
 
@@ -233,12 +260,22 @@ namespace System.Xml.XPath
 				case XmlTypeCode.String:
 					return stringValue;
 
-				// FIXME: more check
+				case XmlTypeCode.None:
+				case XmlTypeCode.Item:
 				case XmlTypeCode.AnyAtomicType:
-					return objectValue.ToString ();
+					if (objectValue is string)
+						return (string) objectValue;
+					break;
+
+//				// FIXME: more check
+//				case XmlTypeCode.AnyAtomicType:
+//					return objectValue.ToString ();
 				}
 
-				throw new InvalidOperationException (String.Format ("Conversion from {0} ({1}) to {2} is not supported", schemaType.QualifiedName, xmlTypeCode, XmlTypeCode.String));
+				if (objectValue != null)
+					throw new InvalidOperationException (String.Format ("Conversion from {0} to {1} is not supported", objectValue.GetType (), XmlTypeCode.String));
+				else
+					throw new InvalidOperationException (String.Format ("Conversion from {0} ({1}) to {2} is not supported", schemaType.QualifiedName, xmlTypeCode, XmlTypeCode.String));
 			}
 		}
 
@@ -262,6 +299,14 @@ namespace System.Xml.XPath
 					return XQueryConvert.FloatToBoolean (floatValue);
 				case XmlTypeCode.String:
 					return XQueryConvert.StringToBoolean (stringValue);
+
+				case XmlTypeCode.None:
+				case XmlTypeCode.Item:
+				case XmlTypeCode.AnyAtomicType:
+					if (objectValue is bool)
+						return (bool) objectValue;
+					break;
+
 				}
 
 				throw new InvalidOperationException (String.Format ("Conversion from {0} to {1} is not supported", schemaType, XmlTypeCode.Boolean));
@@ -272,22 +317,17 @@ namespace System.Xml.XPath
 		public override DateTime ValueAsDateTime {
 			get {
 				switch (xmlTypeCode) {
-//				case XmlTypeCode.Boolean:
-//					return XQueryConvert.BooleanToDateTime (booleanValue);
 				case XmlTypeCode.DateTime:
 					return dateTimeValue;
-//				case XmlTypeCode.Decimal:
-//					return XQueryConvert.DecimalToDateTime (decimalValue);
-//				case XmlTypeCode.Double:
-//					return XQueryConvert.DoubleToDateTime (doubleValue);
-//				case XmlTypeCode.Long:
-//					return XQueryConvert.IntegerToDateTime (longValue);
-//				case XmlTypeCode.Int:
-//					return XQueryConvert.IntToDateTime (intValue);
-//				case XmlTypeCode.Float:
-//					return XQueryConvert.FloatToDateTime (floatValue);
 				case XmlTypeCode.String:
 					return XQueryConvert.StringToDateTime (stringValue);
+				case XmlTypeCode.None:
+				case XmlTypeCode.Item:
+				case XmlTypeCode.AnyAtomicType:
+					if (objectValue is DateTime)
+						return (DateTime) objectValue;
+					break;
+
 				}
 
 				throw new InvalidOperationException (String.Format ("Conversion from {0} to {1} is not supported", schemaType, XmlTypeCode.DateTime));
@@ -300,8 +340,6 @@ namespace System.Xml.XPath
 				switch (xmlTypeCode) {
 				case XmlTypeCode.Boolean:
 					return XQueryConvert.BooleanToDecimal (booleanValue);
-//				case XmlTypeCode.DateTime:
-//					return XQueryConvert.DateTimeToDecimal (decimalValue);
 				case XmlTypeCode.Decimal:
 					return decimalValue;
 				case XmlTypeCode.Double:
@@ -314,6 +352,13 @@ namespace System.Xml.XPath
 					return XQueryConvert.FloatToDecimal (floatValue);
 				case XmlTypeCode.String:
 					return XQueryConvert.StringToDecimal (stringValue);
+				case XmlTypeCode.None:
+				case XmlTypeCode.Item:
+				case XmlTypeCode.AnyAtomicType:
+					if (objectValue is decimal)
+						return (decimal) objectValue;
+					break;
+
 				}
 
 				throw new InvalidOperationException (String.Format ("Conversion from {0} to {1} is not supported", schemaType, XmlTypeCode.Decimal));
@@ -326,8 +371,6 @@ namespace System.Xml.XPath
 				switch (xmlTypeCode) {
 				case XmlTypeCode.Boolean:
 					return XQueryConvert.BooleanToDouble (booleanValue);
-//				case XmlTypeCode.DateTime:
-//					return XQueryConvert.DateTimeToDouble (dateTimeValue);
 				case XmlTypeCode.Decimal:
 					return XQueryConvert.DecimalToDouble (decimalValue);
 				case XmlTypeCode.Double:
@@ -340,6 +383,13 @@ namespace System.Xml.XPath
 					return XQueryConvert.FloatToDouble (floatValue);
 				case XmlTypeCode.String:
 					return XQueryConvert.StringToDouble (stringValue);
+				case XmlTypeCode.None:
+				case XmlTypeCode.Item:
+				case XmlTypeCode.AnyAtomicType:
+					if (objectValue is double)
+						return (double) objectValue;
+					break;
+
 				}
 
 				throw new InvalidOperationException (String.Format ("Conversion from {0} to {1} is not supported", schemaType, XmlTypeCode.Double));
@@ -352,8 +402,6 @@ namespace System.Xml.XPath
 				switch (xmlTypeCode) {
 				case XmlTypeCode.Boolean:
 					return XQueryConvert.BooleanToInt (booleanValue);
-//				case XmlTypeCode.DateTime:
-//					return XQueryConvert.DateTimeToInt (dateTimeValue);
 				case XmlTypeCode.Decimal:
 					return XQueryConvert.DecimalToInt (decimalValue);
 				case XmlTypeCode.Double:
@@ -366,6 +414,13 @@ namespace System.Xml.XPath
 					return XQueryConvert.FloatToInt (floatValue);
 				case XmlTypeCode.String:
 					return XQueryConvert.StringToInt (stringValue);
+				case XmlTypeCode.None:
+				case XmlTypeCode.Item:
+				case XmlTypeCode.AnyAtomicType:
+					if (objectValue is int)
+						return (int) objectValue;
+					break;
+
 				}
 
 				throw new InvalidOperationException (String.Format ("Conversion from {0} to {1} is not supported", schemaType, XmlTypeCode.Int));
@@ -378,8 +433,6 @@ namespace System.Xml.XPath
 				switch (xmlTypeCode) {
 				case XmlTypeCode.Boolean:
 					return XQueryConvert.BooleanToInteger (booleanValue);
-//				case XmlTypeCode.DateTime:
-//					return XQueryConvert.DateTimeToInteger (dateTimeValue);
 				case XmlTypeCode.Decimal:
 					return XQueryConvert.DecimalToInteger (decimalValue);
 				case XmlTypeCode.Double:
@@ -392,6 +445,13 @@ namespace System.Xml.XPath
 					return XQueryConvert.FloatToInteger (floatValue);
 				case XmlTypeCode.String:
 					return XQueryConvert.StringToInteger (stringValue);
+				case XmlTypeCode.None:
+				case XmlTypeCode.Item:
+				case XmlTypeCode.AnyAtomicType:
+					if (objectValue is long)
+						return (long) objectValue;
+					break;
+
 				}
 
 				throw new InvalidOperationException (String.Format ("Conversion from {0} to {1} is not supported", schemaType, XmlTypeCode.Long));
@@ -404,8 +464,6 @@ namespace System.Xml.XPath
 				switch (xmlTypeCode) {
 				case XmlTypeCode.Boolean:
 					return XQueryConvert.BooleanToFloat (booleanValue);
-//				case XmlTypeCode.DateTime:
-//					return XQueryConvert.DateTimeToFloat (dateTimeValue);
 				case XmlTypeCode.Decimal:
 					return XQueryConvert.DecimalToFloat (decimalValue);
 				case XmlTypeCode.Double:
@@ -418,6 +476,13 @@ namespace System.Xml.XPath
 					return XQueryConvert.IntegerToFloat (longValue);
 				case XmlTypeCode.String:
 					return XQueryConvert.StringToFloat (stringValue);
+				case XmlTypeCode.None:
+				case XmlTypeCode.Item:
+				case XmlTypeCode.AnyAtomicType:
+					if (objectValue is float)
+						return (float) objectValue;
+					break;
+
 				}
 
 				throw new InvalidOperationException (String.Format ("Conversion from {0} to {1} is not supported", schemaType, XmlTypeCode.Float));
@@ -429,13 +494,14 @@ namespace System.Xml.XPath
 			get {
 				if (valueAsList != null)
 					return valueAsList;
-				if (objectValue is ArrayList)
-					valueAsList = objectValue as ArrayList;
+				if (objectValue is ICollection)
+					valueAsList = objectValue as ICollection;
 				else if (objectValue is Array)
 					valueAsList = new ArrayList ((Array) objectValue);
 				else if (xmlTypeCode != XmlTypeCode.None) {
-					valueAsList = new ArrayList ();
-					valueAsList.Add (TypedValue);
+					ArrayList al = new ArrayList ();
+					al.Add (TypedValue);
+					valueAsList = al;
 				}
 				else
 					throw new NotImplementedException ();
@@ -454,6 +520,74 @@ namespace System.Xml.XPath
 		}
 
 		#endregion
+
+		#region internal static members
+
+		internal static Type RuntimeTypeFromXmlTypeCode (XmlTypeCode typeCode)
+		{
+			switch (typeCode) {
+			case XmlTypeCode.Int:
+				return typeof (int);
+			case XmlTypeCode.Decimal:
+				return typeof (decimal);
+			case XmlTypeCode.Double:
+				return typeof (double);
+			case XmlTypeCode.Float:
+				return typeof (float);
+			case XmlTypeCode.Long:
+				return typeof (long);
+			case XmlTypeCode.Short:
+				return typeof (short);
+			case XmlTypeCode.UnsignedShort:
+				return typeof (ushort);
+			case XmlTypeCode.UnsignedInt:
+				return typeof (uint);
+			case XmlTypeCode.String:
+				return typeof (string);
+			case XmlTypeCode.DateTime:
+				return typeof (DateTime);
+			case XmlTypeCode.Boolean:
+				return typeof (bool);
+			case XmlTypeCode.Item:
+				return typeof (object);
+			}
+			throw new NotSupportedException (String.Format ("XQuery internal error: Cannot infer Runtime Type from XmlTypeCode {0}.", typeCode));
+		}
+
+		internal static XmlTypeCode XmlTypeCodeFromRuntimeType (Type cliType, bool raiseError)
+		{
+			switch (Type.GetTypeCode (cliType)) {
+			case TypeCode.Int32:
+				return XmlTypeCode.Int;
+			case TypeCode.Decimal:
+				return XmlTypeCode.Decimal;
+			case TypeCode.Double:
+				return XmlTypeCode.Double;
+			case TypeCode.Single:
+				return XmlTypeCode.Float;
+			case TypeCode.Int64:
+				return XmlTypeCode.Long;
+			case TypeCode.Int16:
+				return XmlTypeCode.Short;
+			case TypeCode.UInt16:
+				return XmlTypeCode.UnsignedShort;
+			case TypeCode.UInt32:
+				return XmlTypeCode.UnsignedInt;
+			case TypeCode.String:
+				return XmlTypeCode.String;
+			case TypeCode.DateTime:
+				return XmlTypeCode.DateTime;
+			case TypeCode.Boolean:
+				return XmlTypeCode.Boolean;
+			case TypeCode.Object:
+				return XmlTypeCode.Item;
+			}
+			if (raiseError)
+				throw new NotSupportedException (String.Format ("XQuery internal error: Cannot infer XmlTypeCode from Runtime Type {0}", cliType));
+			else
+				return XmlTypeCode.None;
+		}
+		#endregion
 	}
 }