| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656 |
- //
- // XmlAtomicValue.cs
- //
- // Author:
- // Atsushi Enomoto <[email protected]>
- //
- // (C)2004 Novell Inc.
- //
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- #if NET_2_0
- using System.Collections;
- using System.Xml;
- using System.Xml.XPath;
- namespace System.Xml.Schema
- {
- public sealed class XmlAtomicValue : XPathItem, ICloneable
- {
- bool booleanValue;
- DateTime dateTimeValue;
- decimal decimalValue;
- double doubleValue;
- int intValue;
- long longValue;
- object objectValue;
- float floatValue;
- string stringValue;
- XmlSchemaType schemaType;
- XmlTypeCode xmlTypeCode;
- ICollection valueAsList;
- #region Constructors
- [MonoTODO]
- internal XmlAtomicValue (bool value, XmlSchemaType xmlType)
- {
- Init (value, xmlType);
- }
-
- private void Init (bool value, XmlSchemaType xmlType)
- {
- if (xmlType == null)
- throw new ArgumentNullException ("xmlType");
- xmlTypeCode = XmlTypeCode.Boolean;
- this.booleanValue = value;
- schemaType = xmlType;
- }
- [MonoTODO]
- internal XmlAtomicValue (DateTime value, XmlSchemaType xmlType)
- {
- Init (value, xmlType);
- }
-
- private void Init (DateTime value, XmlSchemaType xmlType)
- {
- if (xmlType == null)
- throw new ArgumentNullException ("xmlType");
- xmlTypeCode = XmlTypeCode.DateTime;
- this.dateTimeValue = value;
- schemaType = xmlType;
- }
- [MonoTODO]
- internal XmlAtomicValue (decimal value, XmlSchemaType xmlType)
- {
- Init (value, xmlType);
- }
-
- private void Init (decimal value, XmlSchemaType xmlType)
- {
- if (xmlType == null)
- throw new ArgumentNullException ("xmlType");
- xmlTypeCode = XmlTypeCode.Decimal;
- this.decimalValue = value;
- schemaType = xmlType;
- }
- [MonoTODO]
- internal XmlAtomicValue (double value, XmlSchemaType xmlType)
- {
- Init (value, xmlType);
- }
-
- private void Init (double value, XmlSchemaType xmlType)
- {
- if (xmlType == null)
- throw new ArgumentNullException ("xmlType");
- xmlTypeCode = XmlTypeCode.Double;
- this.doubleValue = value;
- schemaType = xmlType;
- }
- [MonoTODO]
- internal XmlAtomicValue (int value, XmlSchemaType xmlType)
- {
- Init (value, xmlType);
- }
-
- private void Init (int value, XmlSchemaType xmlType)
- {
- if (xmlType == null)
- throw new ArgumentNullException ("xmlType");
- xmlTypeCode = XmlTypeCode.Int;
- this.intValue = value;
- schemaType = xmlType;
- }
- [MonoTODO]
- internal XmlAtomicValue (long value, XmlSchemaType xmlType)
- {
- Init (value, xmlType);
- }
-
- private void Init (long value, XmlSchemaType xmlType)
- {
- if (xmlType == null)
- throw new ArgumentNullException ("xmlType");
- xmlTypeCode = XmlTypeCode.Long;
- this.longValue = value;
- schemaType = xmlType;
- }
- [MonoTODO]
- internal XmlAtomicValue (float value, XmlSchemaType xmlType)
- {
- Init (value, xmlType);
- }
-
- private void Init (float value, XmlSchemaType xmlType)
- {
- if (xmlType == null)
- throw new ArgumentNullException ("xmlType");
- xmlTypeCode = XmlTypeCode.Float;
- this.floatValue = value;
- schemaType = xmlType;
- }
- [MonoTODO]
- internal XmlAtomicValue (string value, XmlSchemaType xmlType)
- {
- Init (value, xmlType);
- }
-
- private void Init (string value, XmlSchemaType xmlType)
- {
- if (value == null)
- throw new ArgumentNullException ("value");
- if (xmlType == null)
- throw new ArgumentNullException ("xmlType");
- xmlTypeCode = XmlTypeCode.String;
- this.stringValue = value;
- schemaType = xmlType;
- }
- [MonoTODO]
- internal XmlAtomicValue (object value, XmlSchemaType xmlType)
- {
- Init (value, xmlType);
- }
- private void Init (object value, XmlSchemaType xmlType)
- {
- // 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");
- switch (Type.GetTypeCode (value.GetType ())) {
- case TypeCode.Int16:
- case TypeCode.UInt16:
- case TypeCode.Int32:
- Init ((int) value, xmlType);
- return;
- case TypeCode.Decimal:
- Init ((decimal) value, xmlType);
- return;
- case TypeCode.Double:
- Init ((double) value, xmlType);
- return;
- case TypeCode.Single:
- Init ((float) value, xmlType);
- return;
- case TypeCode.Int64:
- case TypeCode.UInt32:
- Init ((long) value, xmlType);
- return;
- case TypeCode.String:
- Init ((string) value, xmlType);
- return;
- case TypeCode.DateTime:
- Init ((DateTime) value, xmlType);
- return;
- case TypeCode.Boolean:
- Init ((bool) value, xmlType);
- return;
- }
- ICollection col = value as ICollection;
- if (col != null && col.Count == 1) {
- if (col is IList)
- Init (((IList) col) [0], xmlType);
- else {
- IEnumerator en = col.GetEnumerator ();
- if (!en.MoveNext ())
- return;
- if (en.Current is DictionaryEntry)
- Init (((DictionaryEntry) en.Current).Value, xmlType);
- else
- Init (en.Current, xmlType);
- }
- return;
- }
- XmlAtomicValue another = value as XmlAtomicValue;
- if (another != null) {
- switch (another.xmlTypeCode) {
- case XmlTypeCode.Boolean:
- Init (another.booleanValue, xmlType);
- return;
- case XmlTypeCode.DateTime:
- Init (another.dateTimeValue, xmlType);
- return;
- case XmlTypeCode.Decimal:
- Init (another.decimalValue, xmlType);
- return;
- case XmlTypeCode.Double:
- Init (another.doubleValue, xmlType);
- return;
- case XmlTypeCode.Int:
- Init (another.intValue, xmlType);
- return;
- case XmlTypeCode.Long:
- Init (another.longValue, xmlType);
- return;
- case XmlTypeCode.Float:
- Init (another.floatValue, xmlType);
- return;
- case XmlTypeCode.String:
- Init (another.stringValue, xmlType);
- return;
- default:
- objectValue = another.objectValue;
- break;
- }
- }
- objectValue = value;
- schemaType = xmlType;
- }
- #endregion
- #region Methods
- object ICloneable.Clone ()
- {
- return this.Clone ();
- }
- [MonoTODO]
- public XmlAtomicValue Clone ()
- {
- return new XmlAtomicValue (this, schemaType);
- }
- [MonoTODO]
- public override object ValueAs (Type type, IXmlNamespaceResolver nsResolver)
- {
- switch (XmlTypeCodeFromRuntimeType (type, false)) {
- case XmlTypeCode.Int:
- case XmlTypeCode.Short:
- case XmlTypeCode.UnsignedShort:
- return ValueAsInt;
- case XmlTypeCode.Double:
- case XmlTypeCode.Float:
- return ValueAsDouble;
- case XmlTypeCode.Long:
- case XmlTypeCode.UnsignedInt:
- return ValueAsLong;
- 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);
- }
- throw new NotImplementedException ();
- }
- #endregion
- #region Properties
- // As long as I tried, neither of such XmlAtomicValue created
- // with XmlText that contains atomic value, XmlElement that
- // contains such XmlText, XmlDocument nor XPathNavigator
- // created from such nodes returned false. So it won't be
- // true on this class. Apparently this class needs more
- // documentation.
- public override bool IsNode {
- get { return false; }
- }
- internal XmlTypeCode ResolvedTypeCode {
- get {
- if (schemaType != XmlSchemaComplexType.AnyType)
- return schemaType.TypeCode;
- else
- return xmlTypeCode;
- }
- }
- [MonoTODO]
- public override object TypedValue {
- get {
- switch (ResolvedTypeCode) {
- case XmlTypeCode.Boolean:
- return ValueAsBoolean;
- case XmlTypeCode.DateTime:
- return ValueAsDateTime;
- case XmlTypeCode.Float:
- case XmlTypeCode.Double:
- return ValueAsDouble;
- case XmlTypeCode.Long:
- return ValueAsLong;
- case XmlTypeCode.Int:
- return ValueAsInt;
- case XmlTypeCode.String:
- return Value;
- }
- return objectValue;
- }
- }
- [MonoTODO]
- // This method works like ValueAsString.
- public override string Value {
- get {
- switch (ResolvedTypeCode) {
- case XmlTypeCode.Boolean:
- stringValue = XQueryConvert.BooleanToString (ValueAsBoolean);
- break;
- case XmlTypeCode.DateTime:
- stringValue = XQueryConvert.DateTimeToString (ValueAsDateTime);
- break;
- case XmlTypeCode.Float:
- case XmlTypeCode.Double:
- stringValue = XQueryConvert.DoubleToString (ValueAsDouble);
- break;
- case XmlTypeCode.Long:
- stringValue = XQueryConvert.IntegerToString (ValueAsLong);
- break;
- case XmlTypeCode.Int:
- stringValue = XQueryConvert.IntToString (ValueAsInt);
- break;
- case XmlTypeCode.String:
- return stringValue;
- case XmlTypeCode.None:
- case XmlTypeCode.Item:
- case XmlTypeCode.AnyAtomicType:
- switch (XmlTypeCodeFromRuntimeType (objectValue.GetType (), false)) {
- case XmlTypeCode.String:
- stringValue = (string) objectValue;
- break;
- case XmlTypeCode.DateTime:
- stringValue = XQueryConvert.DateTimeToString ((DateTime) objectValue);
- break;
- case XmlTypeCode.Boolean:
- stringValue = XQueryConvert.BooleanToString ((bool) objectValue);
- break;
- case XmlTypeCode.Float:
- stringValue = XQueryConvert.FloatToString ((float) objectValue);
- break;
- case XmlTypeCode.Double:
- stringValue = XQueryConvert.DoubleToString ((double) objectValue);
- break;
- case XmlTypeCode.Decimal:
- stringValue = XQueryConvert.DecimalToString ((decimal) objectValue);
- break;
- case XmlTypeCode.Long:
- stringValue = XQueryConvert.IntegerToString ((long) objectValue);
- break;
- case XmlTypeCode.Int:
- stringValue = XQueryConvert.IntToString ((int) objectValue);
- break;
- }
- break;
- }
- if (stringValue != null)
- return stringValue;
- if (objectValue != null)
- throw new InvalidCastException (String.Format ("Conversion from runtime type {0} to {1} is not supported", objectValue.GetType (), XmlTypeCode.String));
- else
- throw new InvalidCastException (String.Format ("Conversion from schema type {0} (type code {1}) to {2} is not supported", schemaType.QualifiedName, xmlTypeCode, XmlTypeCode.String));
- }
- }
- [MonoTODO]
- public override bool ValueAsBoolean {
- get {
- switch (xmlTypeCode) {
- case XmlTypeCode.Boolean:
- return booleanValue;
- case XmlTypeCode.Decimal:
- return XQueryConvert.DecimalToBoolean (decimalValue);
- case XmlTypeCode.Double:
- return XQueryConvert.DoubleToBoolean (doubleValue);
- case XmlTypeCode.Long:
- return XQueryConvert.IntegerToBoolean (longValue);
- case XmlTypeCode.Int:
- return XQueryConvert.IntToBoolean (intValue);
- case XmlTypeCode.Float:
- 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 InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsBoolean.QualifiedName));
- }
- }
- [MonoTODO]
- public override DateTime ValueAsDateTime {
- get {
- switch (xmlTypeCode) {
- case XmlTypeCode.DateTime:
- return dateTimeValue;
- 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 InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsDateTime.QualifiedName));
- }
- }
- [MonoTODO]
- public override double ValueAsDouble {
- get {
- switch (xmlTypeCode) {
- case XmlTypeCode.Boolean:
- return XQueryConvert.BooleanToDouble (booleanValue);
- case XmlTypeCode.Decimal:
- return XQueryConvert.DecimalToDouble (decimalValue);
- case XmlTypeCode.Double:
- return doubleValue;
- case XmlTypeCode.Long:
- return XQueryConvert.IntegerToDouble (longValue);
- case XmlTypeCode.Int:
- return XQueryConvert.IntToDouble (intValue);
- case XmlTypeCode.Float:
- 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 InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsDouble.QualifiedName));
- }
- }
- [MonoTODO]
- public override int ValueAsInt {
- get {
- switch (xmlTypeCode) {
- case XmlTypeCode.Boolean:
- return XQueryConvert.BooleanToInt (booleanValue);
- case XmlTypeCode.Decimal:
- return XQueryConvert.DecimalToInt (decimalValue);
- case XmlTypeCode.Double:
- return XQueryConvert.DoubleToInt (doubleValue);
- case XmlTypeCode.Long:
- return XQueryConvert.IntegerToInt (longValue);
- case XmlTypeCode.Int:
- return intValue;
- case XmlTypeCode.Float:
- 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 InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsInt.QualifiedName));
- }
- }
- [MonoTODO]
- public override long ValueAsLong {
- get {
- switch (xmlTypeCode) {
- case XmlTypeCode.Boolean:
- return XQueryConvert.BooleanToInteger (booleanValue);
- case XmlTypeCode.Decimal:
- return XQueryConvert.DecimalToInteger (decimalValue);
- case XmlTypeCode.Double:
- return XQueryConvert.DoubleToInteger (doubleValue);
- case XmlTypeCode.Long:
- return longValue;
- case XmlTypeCode.Int:
- return XQueryConvert.IntegerToInt (intValue);
- case XmlTypeCode.Float:
- 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 InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsLong.QualifiedName));
- }
- }
- [MonoTODO]
- public override Type ValueType {
- get { return schemaType.Datatype.ValueType; }
- }
- [MonoTODO]
- public override XmlSchemaType XmlType {
- get { return schemaType; }
- }
- #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
- }
- }
- #endif
|