Merge pull request #799 from kebby/master
[mono.git] / mcs / class / System.XML / System.Xml.Schema / XmlAtomicValue.cs
1 //
2 // XmlAtomicValue.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // (C)2004 Novell Inc.
8 //
9
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 #if NET_2_0
32
33 using System.Collections;
34 using System.Xml;
35 using System.Xml.XPath;
36
37 namespace System.Xml.Schema
38 {
39         [MonoTODO] // This class is unused and thus won't be finished.
40         public sealed class XmlAtomicValue : XPathItem, ICloneable
41         {
42                 bool booleanValue;
43                 DateTime dateTimeValue;
44                 decimal decimalValue;
45                 double doubleValue;
46                 int intValue;
47                 long longValue;
48                 ulong ulongValue;
49                 object objectValue;
50                 float floatValue;
51                 byte [] bytesValue;
52                 string stringValue;
53                 XmlSchemaType schemaType;
54                 XmlTypeCode xmlTypeCode;
55                 //ICollection valueAsList;
56
57                 #region Constructors
58
59                 internal XmlAtomicValue (bool value, XmlSchemaType xmlType)
60                 {
61                         Init (value, xmlType);
62                 }
63                 
64                 private void Init (bool value, XmlSchemaType xmlType)
65                 {
66                         if (xmlType == null)
67                                 throw new ArgumentNullException ("xmlType");
68                         xmlTypeCode = XmlTypeCode.Boolean;
69                         this.booleanValue = value;
70                         schemaType = xmlType;
71                 }
72
73                 internal XmlAtomicValue (byte [] value, XmlSchemaType xmlType)
74                 {
75                         Init (value, xmlType);
76                 }
77                 
78                 private void Init (byte [] value, XmlSchemaType xmlType)
79                 {
80                         if (xmlType == null)
81                                 throw new ArgumentNullException ("xmlType");
82                         xmlTypeCode = XmlTypeCode.Base64Binary;
83                         this.bytesValue = value;
84                         schemaType = xmlType;
85                 }
86
87                 internal XmlAtomicValue (DateTime value, XmlSchemaType xmlType)
88                 {
89                         Init (value, xmlType);
90                 }
91                 
92                 private void Init (DateTime value, XmlSchemaType xmlType)
93                 {
94                         if (xmlType == null)
95                                 throw new ArgumentNullException ("xmlType");
96                         xmlTypeCode = XmlTypeCode.DateTime;
97                         this.dateTimeValue = value;
98                         schemaType = xmlType;
99                 }
100
101                 internal XmlAtomicValue (decimal value, XmlSchemaType xmlType)
102                 {
103                         Init (value, xmlType);
104                 }
105                 
106                 private void Init (decimal value, XmlSchemaType xmlType)
107                 {
108                         if (xmlType == null)
109                                 throw new ArgumentNullException ("xmlType");
110                         xmlTypeCode = XmlTypeCode.Decimal;
111                         this.decimalValue = value;
112                         schemaType = xmlType;
113                 }
114
115                 internal XmlAtomicValue (double value, XmlSchemaType xmlType)
116                 {
117                         Init (value, xmlType);
118                 }
119                 
120                 private void Init (double value, XmlSchemaType xmlType)
121                 {
122                         if (xmlType == null)
123                                 throw new ArgumentNullException ("xmlType");
124                         xmlTypeCode = XmlTypeCode.Double;
125                         this.doubleValue = value;
126                         schemaType = xmlType;
127                 }
128
129                 internal XmlAtomicValue (int value, XmlSchemaType xmlType)
130                 {
131                         Init (value, xmlType);
132                 }
133                 
134                 private void Init (int value, XmlSchemaType xmlType)
135                 {
136                         if (xmlType == null)
137                                 throw new ArgumentNullException ("xmlType");
138                         xmlTypeCode = XmlTypeCode.Int;
139                         this.intValue = value;
140                         schemaType = xmlType;
141                 }
142
143                 internal XmlAtomicValue (long value, XmlSchemaType xmlType)
144                 {
145                         Init (value, xmlType);
146                 }
147                 
148                 private void Init (long value, XmlSchemaType xmlType)
149                 {
150                         if (xmlType == null)
151                                 throw new ArgumentNullException ("xmlType");
152                         xmlTypeCode = XmlTypeCode.Long;
153                         this.longValue = value;
154                         schemaType = xmlType;
155                 }
156
157                 internal XmlAtomicValue (ulong value, XmlSchemaType xmlType)
158                 {
159                         Init (value, xmlType);
160                 }
161                 
162                 private void Init (ulong value, XmlSchemaType xmlType)
163                 {
164                         if (xmlType == null)
165                                 throw new ArgumentNullException ("xmlType");
166                         xmlTypeCode = XmlTypeCode.UnsignedLong;
167                         this.ulongValue = value;
168                         schemaType = xmlType;
169                 }
170
171                 internal XmlAtomicValue (float value, XmlSchemaType xmlType)
172                 {
173                         Init (value, xmlType);
174                 }
175                 
176                 private void Init (float value, XmlSchemaType xmlType)
177                 {
178                         if (xmlType == null)
179                                 throw new ArgumentNullException ("xmlType");
180                         xmlTypeCode = XmlTypeCode.Float;
181                         this.floatValue = value;
182                         schemaType = xmlType;
183                 }
184
185                 internal XmlAtomicValue (string value, XmlSchemaType xmlType)
186                 {
187                         Init (value, xmlType);
188                 }
189                 
190                 private void Init (string value, XmlSchemaType xmlType)
191                 {
192                         if (value == null)
193                                 throw new ArgumentNullException ("value");
194                         if (xmlType == null)
195                                 throw new ArgumentNullException ("xmlType");
196                         xmlTypeCode = XmlTypeCode.String;
197                         this.stringValue = value;
198                         schemaType = xmlType;
199                 }
200
201                 internal XmlAtomicValue (object value, XmlSchemaType xmlType)
202                 {
203                         Init (value, xmlType);
204                 }
205
206                 private void Init (object value, XmlSchemaType xmlType)
207                 {
208                         // It accepts any kind of object, but will be rejected on each value properties.
209                         if (value == null)
210                                 throw new ArgumentNullException ("value");
211                         if (xmlType == null)
212                                 throw new ArgumentNullException ("xmlType");
213
214                         switch (Type.GetTypeCode (value.GetType ())) {
215                         case TypeCode.Byte:
216                                 Init ((byte) value, xmlType);
217                                 return;
218                         case TypeCode.SByte:
219                                 Init ((sbyte) value, xmlType);
220                                 return;
221                         case TypeCode.Int16:
222                                 Init ((short) value, xmlType);
223                                 return;
224                         case TypeCode.UInt16:
225                                 Init ((ushort) value, xmlType);
226                                 return;
227                         case TypeCode.Int32:
228                                 Init ((int) value, xmlType);
229                                 return;
230                         case TypeCode.Decimal:
231                                 Init ((decimal) value, xmlType);
232                                 return;
233                         case TypeCode.Double:
234                                 Init ((double) value, xmlType);
235                                 return;
236                         case TypeCode.Single:
237                                 Init ((float) value, xmlType);
238                                 return;
239                         case TypeCode.Int64:
240                                 Init ((long) value, xmlType);
241                                 return;
242                         case TypeCode.UInt32:
243                                 Init ((uint) value, xmlType);
244                                 return;
245                         case TypeCode.UInt64:
246                                 Init ((ulong) value, xmlType);
247                                 return;
248                         case TypeCode.String:
249                                 Init ((string) value, xmlType);
250                                 return;
251                         case TypeCode.DateTime:
252                                 Init ((DateTime) value, xmlType);
253                                 return;
254                         case TypeCode.Boolean:
255                                 Init ((bool) value, xmlType);
256                                 return;
257                         }
258                         if (value is byte []) {
259                                 Init ((byte []) value, xmlType);
260                                 return;
261                         }
262
263                         ICollection col = value as ICollection;
264                         if (col != null && col.Count == 1) {
265                                 if (col is IList)
266                                         Init (((IList) col) [0], xmlType);
267                                 else {
268                                         IEnumerator en = col.GetEnumerator ();
269                                         if (!en.MoveNext ())
270                                                 return;
271                                         if (en.Current is DictionaryEntry)
272                                                 Init (((DictionaryEntry) en.Current).Value, xmlType);
273                                         else
274                                                 Init (en.Current, xmlType);
275                                 }
276                                 return;
277                         }
278
279                         XmlAtomicValue another = value as XmlAtomicValue;
280                         if (another != null) {
281                                 switch (another.xmlTypeCode) {
282                                 case XmlTypeCode.Boolean:
283                                         Init (another.booleanValue, xmlType);
284                                         return;
285                                 case XmlTypeCode.DateTime:
286                                         Init (another.dateTimeValue, xmlType);
287                                         return;
288                                 case XmlTypeCode.Decimal:
289                                         Init (another.decimalValue, xmlType);
290                                         return;
291                                 case XmlTypeCode.Double:
292                                         Init (another.doubleValue, xmlType);
293                                         return;
294                                 case XmlTypeCode.Int:
295                                         Init (another.intValue, xmlType);
296                                         return;
297                                 case XmlTypeCode.Long:
298                                         Init (another.longValue, xmlType);
299                                         return;
300                                 case XmlTypeCode.UnsignedLong:
301                                         Init (another.ulongValue, xmlType);
302                                         return;
303                                 case XmlTypeCode.Float:
304                                         Init (another.floatValue, xmlType);
305                                         return;
306                                 case XmlTypeCode.String:
307                                         Init (another.stringValue, xmlType);
308                                         return;
309                                 default:
310                                         objectValue = another.objectValue;
311                                         break;
312                                 }
313                         }
314
315                         objectValue = value;
316                         schemaType = xmlType;
317                 }
318
319                 #endregion
320
321                 #region Methods
322
323                 object ICloneable.Clone ()
324                 {
325                         return this.Clone ();
326                 }
327
328                 public XmlAtomicValue Clone ()
329                 {
330                         return new XmlAtomicValue (this, schemaType);
331                 }
332
333                 public override object ValueAs (Type type, IXmlNamespaceResolver nsResolver)
334                 {
335                         switch (XmlTypeCodeFromRuntimeType (type, false)) {
336                         case XmlTypeCode.Int:
337                         case XmlTypeCode.Short:
338                         case XmlTypeCode.UnsignedShort:
339                                 return ValueAsInt;
340                         case XmlTypeCode.Decimal:
341                                 return ValueAsDecimal;
342                         case XmlTypeCode.Double:
343                         case XmlTypeCode.Float:
344                                 return ValueAsDouble;
345                         case XmlTypeCode.Long:
346                         case XmlTypeCode.UnsignedInt:
347                                 return ValueAsLong;
348                         case XmlTypeCode.String:
349                                 return Value;
350                         case XmlTypeCode.DateTime:
351                                 return ValueAsDateTime;
352                         case XmlTypeCode.Boolean:
353                                 return ValueAsBoolean;
354                         case XmlTypeCode.Item:
355                                 return TypedValue;
356                         case XmlTypeCode.QName:
357                                 return XmlQualifiedName.Parse (Value, nsResolver, true);
358                         case XmlTypeCode.Base64Binary:
359                         case XmlTypeCode.HexBinary:
360                                 if (bytesValue != null)
361                                         return bytesValue;
362                                 break;
363                         }
364                         throw new NotImplementedException ();
365                 }
366
367                 public override string ToString ()
368                 {
369                         return Value;
370                 }
371
372                 #endregion
373
374                 #region Properties
375
376                 // As long as I tried, neither of such XmlAtomicValue created
377                 // with XmlText that contains atomic value, XmlElement that
378                 // contains such XmlText, XmlDocument nor XPathNavigator 
379                 // created from such nodes returned false. So it won't be 
380                 // true on this class. Apparently this class needs more
381                 // documentation.
382                 public override bool IsNode {
383                         get { return false; }
384                 }
385
386                 internal XmlTypeCode ResolvedTypeCode {
387                         get {
388                                 if (schemaType != XmlSchemaComplexType.AnyType)
389                                         return schemaType.TypeCode;
390                                 else
391                                         return xmlTypeCode;
392                         }
393                 }
394
395                 public override object TypedValue {
396                         get {
397                                 switch (ResolvedTypeCode) {
398                                 case XmlTypeCode.Boolean:
399                                         return ValueAsBoolean;
400                                 case XmlTypeCode.DateTime:
401                                         return ValueAsDateTime;
402                                 case XmlTypeCode.Decimal:
403                                         return ValueAsDecimal;
404                                 case XmlTypeCode.Float:
405                                 case XmlTypeCode.Double:
406                                         return ValueAsDouble;
407                                 case XmlTypeCode.Long:
408                                         return ValueAsLong;
409                                 case XmlTypeCode.Int:
410                                         return ValueAsInt;
411                                 case XmlTypeCode.String:
412                                         return Value;
413                                 }
414                                 return objectValue;
415                         }
416                 }
417
418                 // This method works like ValueAsString.
419                 public override string Value {
420                         get {
421                                 switch (ResolvedTypeCode) {
422                                 case XmlTypeCode.Boolean:
423                                         stringValue = XQueryConvert.BooleanToString (ValueAsBoolean);
424                                         break;
425                                 case XmlTypeCode.Date:
426                                 case XmlTypeCode.Time:
427                                 case XmlTypeCode.DateTime:
428                                         stringValue = XQueryConvert.DateTimeToString (ValueAsDateTime);
429                                         break;
430                                 case XmlTypeCode.Duration:
431                                         stringValue = XQueryConvert.DayTimeDurationToString (TimeSpan.FromMilliseconds (doubleValue));
432                                         break;
433                                 case XmlTypeCode.GYear:
434                                         stringValue = XQueryConvert.GYearToString (ValueAsDateTime);
435                                         break;
436                                 case XmlTypeCode.GYearMonth:
437                                         stringValue = XQueryConvert.GYearMonthToString (ValueAsDateTime);
438                                         break;
439                                 case XmlTypeCode.GMonth:
440                                         stringValue = XQueryConvert.GMonthToString (ValueAsDateTime);
441                                         break;
442                                 case XmlTypeCode.GMonthDay:
443                                         stringValue = XQueryConvert.GMonthDayToString (ValueAsDateTime);
444                                         break;
445                                 case XmlTypeCode.GDay:
446                                         stringValue = XQueryConvert.GDayToString (ValueAsDateTime);
447                                         break;
448                                 case XmlTypeCode.Float:
449                                 case XmlTypeCode.Double:
450                                         stringValue = XQueryConvert.DoubleToString (ValueAsDouble);
451                                         break;
452                                 case XmlTypeCode.Integer:
453                                 case XmlTypeCode.UnsignedInt:
454                                 case XmlTypeCode.UnsignedLong:
455                                 case XmlTypeCode.Decimal:
456                                         stringValue = XQueryConvert.DecimalToString (ValueAsDecimal);
457                                         break;
458                                 case XmlTypeCode.NonPositiveInteger:
459                                 case XmlTypeCode.NonNegativeInteger:
460                                 case XmlTypeCode.NegativeInteger:
461                                 case XmlTypeCode.Long:
462                                 case XmlTypeCode.PositiveInteger:
463                                         stringValue = XQueryConvert.IntegerToString (ValueAsLong);
464                                         break;
465                                 case XmlTypeCode.Int:
466                                 case XmlTypeCode.Short:
467                                 case XmlTypeCode.Byte:
468                                 case XmlTypeCode.UnsignedShort:
469                                 case XmlTypeCode.UnsignedByte:
470                                         stringValue = XQueryConvert.IntToString (ValueAsInt);
471                                         break;
472                                 case XmlTypeCode.Base64Binary:
473                                         stringValue = XQueryConvert.Base64BinaryToString (bytesValue);
474                                         break;
475                                 case XmlTypeCode.HexBinary:
476                                         stringValue = XQueryConvert.HexBinaryToString (bytesValue);
477                                         break;
478                                 case XmlTypeCode.QName:
479                                 case XmlTypeCode.AnyUri:
480                                 case XmlTypeCode.String:
481                                         return stringValue;
482
483                                 case XmlTypeCode.None:
484                                 case XmlTypeCode.Item:
485                                 case XmlTypeCode.AnyAtomicType:
486                                         switch (XmlTypeCodeFromRuntimeType (objectValue.GetType (), false)) {
487                                         case XmlTypeCode.String:
488                                                 stringValue = (string) objectValue;
489                                                 break;
490                                         case XmlTypeCode.Date:
491                                                 stringValue = XQueryConvert.DateToString ((DateTime) objectValue);
492                                                 break;
493                                         case XmlTypeCode.Time:
494                                                 stringValue = XQueryConvert.TimeToString ((DateTime) objectValue);
495                                                 break;
496                                         case XmlTypeCode.DateTime:
497                                                 stringValue = XQueryConvert.DateTimeToString ((DateTime) objectValue);
498                                                 break;
499                                         case XmlTypeCode.Duration:
500                                                 stringValue = XQueryConvert.DayTimeDurationToString (TimeSpan.FromMilliseconds ((double) objectValue));
501                                                 break;
502                                         case XmlTypeCode.Boolean:
503                                                 stringValue = XQueryConvert.BooleanToString ((bool) objectValue);
504                                                 break;
505                                         case XmlTypeCode.Float:
506                                                 stringValue = XQueryConvert.FloatToString ((float) objectValue);
507                                                 break;
508                                         case XmlTypeCode.Double:
509                                                 stringValue = XQueryConvert.DoubleToString ((double) objectValue);
510                                                 break;
511                                         case XmlTypeCode.Integer:
512                                         case XmlTypeCode.Decimal:
513                                                 stringValue = XQueryConvert.DecimalToString ((decimal) objectValue);
514                                                 break;
515                                         case XmlTypeCode.Long:
516                                                 stringValue = XQueryConvert.IntegerToString ((long) objectValue);
517                                                 break;
518                                         case XmlTypeCode.Int:
519                                                 stringValue = XQueryConvert.IntToString ((int) objectValue);
520                                                 break;
521                                         case XmlTypeCode.Base64Binary:
522                                                 stringValue = XQueryConvert.Base64BinaryToString ((byte []) objectValue);
523                                                 break;
524                                         case XmlTypeCode.HexBinary:
525                                                 stringValue = XQueryConvert.HexBinaryToString ((byte []) objectValue);
526                                                 break;
527                                         }
528                                         break;
529                                 }
530                                 if (stringValue != null)
531                                         return stringValue;
532
533                                 if (objectValue != null)
534                                         throw new InvalidCastException (String.Format ("Conversion from runtime type {0}, resolved as type code {1}, to {2} is not supported", objectValue.GetType (), ResolvedTypeCode, XmlTypeCode.String));
535                                 else
536                                         throw new InvalidCastException (String.Format ("Conversion from schema type {0} (type code {1}, resolved type code {2}) to {3} is not supported.", schemaType.QualifiedName, xmlTypeCode, ResolvedTypeCode, XmlTypeCode.String));
537                         }
538                 }
539
540                 public override bool ValueAsBoolean {
541                         get {
542                                 switch (xmlTypeCode) {
543                                 case XmlTypeCode.Boolean:
544                                         return booleanValue;
545                                 case XmlTypeCode.Decimal:
546                                         return XQueryConvert.DecimalToBoolean (decimalValue);
547                                 case XmlTypeCode.Double:
548                                         return XQueryConvert.DoubleToBoolean (doubleValue);
549                                 case XmlTypeCode.Long:
550                                         return XQueryConvert.IntegerToBoolean (longValue);
551                                 case XmlTypeCode.Int:
552                                         return XQueryConvert.IntToBoolean (intValue);
553                                 case XmlTypeCode.Float:
554                                         return XQueryConvert.FloatToBoolean (floatValue);
555                                 case XmlTypeCode.String:
556                                         return XQueryConvert.StringToBoolean (stringValue);
557
558                                 case XmlTypeCode.None:
559                                 case XmlTypeCode.Item:
560                                 case XmlTypeCode.AnyAtomicType:
561                                         if (objectValue is bool)
562                                                 return (bool) objectValue;
563                                         break;
564
565                                 }
566
567                                 throw new InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsBoolean.QualifiedName));
568                         }
569                 }
570
571                 public override DateTime ValueAsDateTime {
572                         get {
573                                 switch (xmlTypeCode) {
574                                 case XmlTypeCode.DateTime:
575                                         return dateTimeValue;
576                                 case XmlTypeCode.String:
577                                         return XQueryConvert.StringToDateTime (stringValue);
578                                 case XmlTypeCode.GYear:
579                                         return XQueryConvert.StringToGYear (stringValue);
580                                 case XmlTypeCode.GYearMonth:
581                                         return XQueryConvert.StringToGYearMonth (stringValue);
582                                 case XmlTypeCode.GMonth:
583                                         return XQueryConvert.StringToGMonth (stringValue);
584                                 case XmlTypeCode.GMonthDay:
585                                         return XQueryConvert.StringToGMonthDay (stringValue);
586                                 case XmlTypeCode.GDay:
587                                         return XQueryConvert.StringToGDay (stringValue);
588                                 case XmlTypeCode.None:
589                                 case XmlTypeCode.Item:
590                                 case XmlTypeCode.AnyAtomicType:
591                                         if (objectValue is DateTime)
592                                                 return (DateTime) objectValue;
593                                         break;
594
595                                 }
596
597                                 throw new InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsDateTime.QualifiedName));
598                         }
599                 }
600
601                 // Unlike the other ValueAs...() functions, this is not part
602                 // of the XPathItem abstract class, so it's not an override
603                 public decimal ValueAsDecimal {
604                         get {
605                                 switch (xmlTypeCode) {
606                                 case XmlTypeCode.Boolean:
607                                         return XQueryConvert.BooleanToDecimal (booleanValue);
608                                 case XmlTypeCode.Decimal:
609                                         return decimalValue;
610                                 case XmlTypeCode.Double:
611                                         return XQueryConvert.DoubleToDecimal (doubleValue);
612                                 case XmlTypeCode.Long:
613                                         return XQueryConvert.IntegerToDecimal (longValue);
614                                 case XmlTypeCode.UnsignedLong:
615                                         return XQueryConvert.IntegerToDecimal (ulongValue);
616                                 case XmlTypeCode.Int:
617                                         return XQueryConvert.IntToDecimal (intValue);
618                                 case XmlTypeCode.Float:
619                                         return XQueryConvert.FloatToDecimal (floatValue);
620                                 case XmlTypeCode.String:
621                                         return XQueryConvert.StringToDecimal (stringValue);
622                                 case XmlTypeCode.None:
623                                 case XmlTypeCode.Item:
624                                 case XmlTypeCode.AnyAtomicType:
625                                         if (objectValue is decimal)
626                                                 return (decimal) objectValue;
627                                         break;
628                                 }
629
630                                 throw new InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsDecimal.QualifiedName));
631                         }
632                 }
633
634                 public override double ValueAsDouble {
635                         get {
636                                 switch (xmlTypeCode) {
637                                 case XmlTypeCode.Boolean:
638                                         return XQueryConvert.BooleanToDouble (booleanValue);
639                                 case XmlTypeCode.Decimal:
640                                         return XQueryConvert.DecimalToDouble (decimalValue);
641                                 case XmlTypeCode.Double:
642                                         return doubleValue;
643                                 case XmlTypeCode.Long:
644                                         return XQueryConvert.IntegerToDouble (longValue);
645                                 case XmlTypeCode.Int:
646                                         return XQueryConvert.IntToDouble (intValue);
647                                 case XmlTypeCode.Float:
648                                         return XQueryConvert.FloatToDouble (floatValue);
649                                 case XmlTypeCode.String:
650                                         return XQueryConvert.StringToDouble (stringValue);
651                                 case XmlTypeCode.None:
652                                 case XmlTypeCode.Item:
653                                 case XmlTypeCode.AnyAtomicType:
654                                         if (objectValue is double)
655                                                 return (double) objectValue;
656                                         break;
657
658                                 }
659
660                                 throw new InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsDouble.QualifiedName));
661                         }
662                 }
663
664                 public override int ValueAsInt {
665                         get {
666                                 switch (xmlTypeCode) {
667                                 case XmlTypeCode.Boolean:
668                                         return XQueryConvert.BooleanToInt (booleanValue);
669                                 case XmlTypeCode.Decimal:
670                                         return XQueryConvert.DecimalToInt (decimalValue);
671                                 case XmlTypeCode.Double:
672                                         return XQueryConvert.DoubleToInt (doubleValue);
673                                 case XmlTypeCode.Long:
674                                         return XQueryConvert.IntegerToInt (longValue);
675                                 case XmlTypeCode.Int:
676                                         return intValue;
677                                 case XmlTypeCode.Float:
678                                         return XQueryConvert.FloatToInt (floatValue);
679                                 case XmlTypeCode.String:
680                                         return XQueryConvert.StringToInt (stringValue);
681                                 case XmlTypeCode.None:
682                                 case XmlTypeCode.Item:
683                                 case XmlTypeCode.AnyAtomicType:
684                                         if (objectValue is int)
685                                                 return (int) objectValue;
686                                         break;
687
688                                 }
689
690                                 throw new InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsInt.QualifiedName));
691                         }
692                 }
693
694                 public override long ValueAsLong {
695                         get {
696                                 switch (xmlTypeCode) {
697                                 case XmlTypeCode.Boolean:
698                                         return XQueryConvert.BooleanToInteger (booleanValue);
699                                 case XmlTypeCode.Decimal:
700                                         return XQueryConvert.DecimalToInteger (decimalValue);
701                                 case XmlTypeCode.Double:
702                                         return XQueryConvert.DoubleToInteger (doubleValue);
703                                 case XmlTypeCode.Long:
704                                         return longValue;
705                                 case XmlTypeCode.Int:
706                                         return XQueryConvert.IntegerToInt (intValue);
707                                 case XmlTypeCode.Float:
708                                         return XQueryConvert.FloatToInteger (floatValue);
709                                 case XmlTypeCode.String:
710                                         return XQueryConvert.StringToInteger (stringValue);
711                                 case XmlTypeCode.None:
712                                 case XmlTypeCode.Item:
713                                 case XmlTypeCode.AnyAtomicType:
714                                         if (objectValue is long)
715                                                 return (long) objectValue;
716                                         break;
717
718                                 }
719
720                                 throw new InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsLong.QualifiedName));
721                         }
722                 }
723
724                 public override Type ValueType {
725                         get { return schemaType.Datatype.ValueType; }
726                 }
727
728                 public override XmlSchemaType XmlType {
729                         get { return schemaType; }
730                 }
731
732                 #endregion
733
734                 #region internal static members
735
736                 internal static Type RuntimeTypeFromXmlTypeCode (XmlTypeCode typeCode)
737                 {
738                         switch (typeCode) {
739                         case XmlTypeCode.Int:
740                                 return typeof (int);
741                         case XmlTypeCode.Decimal:
742                                 return typeof (decimal);
743                         case XmlTypeCode.Double:
744                                 return typeof (double);
745                         case XmlTypeCode.Float:
746                                 return typeof (float);
747                         case XmlTypeCode.Long:
748                                 return typeof (long);
749                         case XmlTypeCode.Short:
750                                 return typeof (short);
751                         case XmlTypeCode.UnsignedShort:
752                                 return typeof (ushort);
753                         case XmlTypeCode.UnsignedInt:
754                                 return typeof (uint);
755                         case XmlTypeCode.String:
756                                 return typeof (string);
757                         case XmlTypeCode.DateTime:
758                                 return typeof (DateTime);
759                         case XmlTypeCode.Boolean:
760                                 return typeof (bool);
761                         case XmlTypeCode.Base64Binary:
762                         case XmlTypeCode.HexBinary:
763                                 return typeof (byte []);
764                         case XmlTypeCode.Item:
765                                 return typeof (object);
766                         }
767                         throw new NotSupportedException (String.Format ("XQuery internal error: Cannot infer Runtime Type from XmlTypeCode {0}.", typeCode));
768                 }
769
770                 internal static XmlTypeCode XmlTypeCodeFromRuntimeType (Type cliType, bool raiseError)
771                 {
772                         switch (Type.GetTypeCode (cliType)) {
773                         case TypeCode.Int32:
774                                 return XmlTypeCode.Int;
775                         case TypeCode.Decimal:
776                                 return XmlTypeCode.Decimal;
777                         case TypeCode.Double:
778                                 return XmlTypeCode.Double;
779                         case TypeCode.Single:
780                                 return XmlTypeCode.Float;
781                         case TypeCode.Int64:
782                                 return XmlTypeCode.Long;
783                         case TypeCode.Int16:
784                                 return XmlTypeCode.Short;
785                         case TypeCode.UInt16:
786                                 return XmlTypeCode.UnsignedShort;
787                         case TypeCode.UInt32:
788                                 return XmlTypeCode.UnsignedInt;
789                         case TypeCode.String:
790                                 return XmlTypeCode.String;
791                         case TypeCode.DateTime:
792                                 return XmlTypeCode.DateTime;
793                         case TypeCode.Boolean:
794                                 return XmlTypeCode.Boolean;
795                         case TypeCode.Object:
796                                 if (cliType == typeof (byte []))
797                                         return XmlTypeCode.Base64Binary;
798                                 else
799                                         return XmlTypeCode.Item;
800                         }
801                         if (raiseError)
802                                 throw new NotSupportedException (String.Format ("XQuery internal error: Cannot infer XmlTypeCode from Runtime Type {0}", cliType));
803                         else
804                                 return XmlTypeCode.None;
805                 }
806                 #endregion
807         }
808 }
809
810 #endif