(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / System.XML / System.Xml.XPath / XPathAtomicValue.cs
blobf582df37eca90b6edf1774c2b29d475e0c6f16f1
1 //
2 // XPathAtomicValue.cs
3 //
4 // Author:
5 // Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // (C)2004 Novell Inc.
8 //
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.
31 #if NET_2_0
33 using System.Collections;
34 using System.Xml;
35 using System.Xml.Schema;
37 namespace System.Xml.XPath
39 public sealed class XPathAtomicValue : XPathItem, ICloneable
41 bool booleanValue;
42 DateTime dateTimeValue;
43 decimal decimalValue;
44 double doubleValue;
45 int intValue;
46 long longValue;
47 object objectValue;
48 float floatValue;
49 string stringValue;
50 XmlSchemaType schemaType;
51 XmlTypeCode xmlTypeCode;
52 ICollection valueAsList;
54 #region Constructors
56 [MonoTODO]
57 public XPathAtomicValue (bool value, XmlSchemaType xmlType)
59 Init (value, xmlType);
62 private void Init (bool value, XmlSchemaType xmlType)
64 if (xmlType == null)
65 throw new ArgumentNullException ("xmlType");
66 xmlTypeCode = XmlTypeCode.Boolean;
67 this.booleanValue = value;
68 schemaType = xmlType;
71 [MonoTODO]
72 public XPathAtomicValue (DateTime value, XmlSchemaType xmlType)
74 Init (value, xmlType);
77 private void Init (DateTime value, XmlSchemaType xmlType)
79 if (xmlType == null)
80 throw new ArgumentNullException ("xmlType");
81 xmlTypeCode = XmlTypeCode.DateTime;
82 this.dateTimeValue = value;
83 schemaType = xmlType;
86 [MonoTODO]
87 public XPathAtomicValue (decimal value, XmlSchemaType xmlType)
89 Init (value, xmlType);
92 private void Init (decimal value, XmlSchemaType xmlType)
94 if (xmlType == null)
95 throw new ArgumentNullException ("xmlType");
96 xmlTypeCode = XmlTypeCode.Decimal;
97 this.decimalValue = value;
98 schemaType = xmlType;
101 [MonoTODO]
102 public XPathAtomicValue (double value, XmlSchemaType xmlType)
104 Init (value, xmlType);
107 private void Init (double value, XmlSchemaType xmlType)
109 if (xmlType == null)
110 throw new ArgumentNullException ("xmlType");
111 xmlTypeCode = XmlTypeCode.Double;
112 this.doubleValue = value;
113 schemaType = xmlType;
116 [MonoTODO]
117 public XPathAtomicValue (int value, XmlSchemaType xmlType)
119 Init (value, xmlType);
122 private void Init (int value, XmlSchemaType xmlType)
124 if (xmlType == null)
125 throw new ArgumentNullException ("xmlType");
126 xmlTypeCode = XmlTypeCode.Int;
127 this.intValue = value;
128 schemaType = xmlType;
131 [MonoTODO]
132 public XPathAtomicValue (long value, XmlSchemaType xmlType)
134 Init (value, xmlType);
137 private void Init (long value, XmlSchemaType xmlType)
139 if (xmlType == null)
140 throw new ArgumentNullException ("xmlType");
141 xmlTypeCode = XmlTypeCode.Long;
142 this.longValue = value;
143 schemaType = xmlType;
146 [MonoTODO]
147 public XPathAtomicValue (float value, XmlSchemaType xmlType)
149 Init (value, xmlType);
152 private void Init (float value, XmlSchemaType xmlType)
154 if (xmlType == null)
155 throw new ArgumentNullException ("xmlType");
156 xmlTypeCode = XmlTypeCode.Float;
157 this.floatValue = value;
158 schemaType = xmlType;
161 [MonoTODO]
162 public XPathAtomicValue (string value, XmlSchemaType xmlType)
164 Init (value, xmlType);
167 private void Init (string value, XmlSchemaType xmlType)
169 if (value == null)
170 throw new ArgumentNullException ("value");
171 if (xmlType == null)
172 throw new ArgumentNullException ("xmlType");
173 xmlTypeCode = XmlTypeCode.String;
174 this.stringValue = value;
175 schemaType = xmlType;
178 [MonoTODO]
179 public XPathAtomicValue (object value, XmlSchemaType xmlType)
181 Init (value, xmlType);
184 private void Init (object value, XmlSchemaType xmlType)
186 // It accepts any kind of object, but will be rejected on each value properties.
187 if (value == null)
188 throw new ArgumentNullException ("value");
189 if (xmlType == null)
190 throw new ArgumentNullException ("xmlType");
192 switch (Type.GetTypeCode (value.GetType ())) {
193 case TypeCode.Int16:
194 case TypeCode.UInt16:
195 case TypeCode.Int32:
196 Init ((int) value, xmlType);
197 return;
198 case TypeCode.Decimal:
199 Init ((decimal) value, xmlType);
200 return;
201 case TypeCode.Double:
202 Init ((double) value, xmlType);
203 return;
204 case TypeCode.Single:
205 Init ((float) value, xmlType);
206 return;
207 case TypeCode.Int64:
208 case TypeCode.UInt32:
209 Init ((long) value, xmlType);
210 return;
211 case TypeCode.String:
212 Init ((string) value, xmlType);
213 return;
214 case TypeCode.DateTime:
215 Init ((DateTime) value, xmlType);
216 return;
217 case TypeCode.Boolean:
218 Init ((bool) value, xmlType);
219 return;
222 ICollection col = value as ICollection;
223 if (col != null && col.Count == 1) {
224 if (col is IList)
225 Init (((IList) col) [0], xmlType);
226 else {
227 IEnumerator en = col.GetEnumerator ();
228 if (!en.MoveNext ())
229 return;
230 if (en.Current is DictionaryEntry)
231 Init (((DictionaryEntry) en.Current).Value, xmlType);
232 else
233 Init (en.Current, xmlType);
235 return;
238 XPathAtomicValue another = value as XPathAtomicValue;
239 if (another != null) {
240 switch (another.xmlTypeCode) {
241 case XmlTypeCode.Boolean:
242 Init (another.booleanValue, xmlType);
243 return;
244 case XmlTypeCode.DateTime:
245 Init (another.dateTimeValue, xmlType);
246 return;
247 case XmlTypeCode.Decimal:
248 Init (another.decimalValue, xmlType);
249 return;
250 case XmlTypeCode.Double:
251 Init (another.doubleValue, xmlType);
252 return;
253 case XmlTypeCode.Int:
254 Init (another.intValue, xmlType);
255 return;
256 case XmlTypeCode.Long:
257 Init (another.longValue, xmlType);
258 return;
259 case XmlTypeCode.Float:
260 Init (another.floatValue, xmlType);
261 return;
262 case XmlTypeCode.String:
263 Init (another.stringValue, xmlType);
264 return;
265 default:
266 objectValue = another.objectValue;
267 break;
271 objectValue = value;
272 schemaType = xmlType;
275 #endregion
277 #region Methods
279 object ICloneable.Clone ()
281 return this.Clone ();
284 [MonoTODO]
285 public XPathAtomicValue Clone ()
287 return new XPathAtomicValue (this, schemaType);
290 [MonoTODO]
291 public override object ValueAs (Type type, IXmlNamespaceResolver nsResolver)
293 switch (XmlTypeCodeFromRuntimeType (type, false)) {
294 case XmlTypeCode.Int:
295 case XmlTypeCode.Short:
296 case XmlTypeCode.UnsignedShort:
297 return ValueAsInt32;
298 case XmlTypeCode.Decimal:
299 return ValueAsDecimal;
300 case XmlTypeCode.Double:
301 return ValueAsDouble;
302 case XmlTypeCode.Float:
303 return ValueAsSingle;
304 case XmlTypeCode.Long:
305 case XmlTypeCode.UnsignedInt:
306 return ValueAsInt64;
307 case XmlTypeCode.String:
308 return Value;
309 case XmlTypeCode.DateTime:
310 return ValueAsDateTime;
311 case XmlTypeCode.Boolean:
312 return ValueAsBoolean;
313 case XmlTypeCode.Item:
314 return TypedValue;
315 case XmlTypeCode.QName:
316 return XmlQualifiedName.Parse (Value, nsResolver);
318 if (type.GetInterface ("System.Collections.ICollection") != null)
319 return ValueAsList;
320 throw new NotImplementedException ();
323 #endregion
325 #region Properties
327 // As long as I tried, neither of such XPathAtomicValue created
328 // with XmlText that contains atomic value, XmlElement that
329 // contains such XmlText, XmlDocument nor XPathNavigator
330 // created from such nodes returned false. So it won't be
331 // true on this class. Apparently this class needs more
332 // documentation.
333 public override bool IsNode {
334 get { return false; }
337 internal XmlTypeCode ResolvedTypeCode {
338 get {
339 if (schemaType != XmlSchemaComplexType.AnyType)
340 return schemaType.TypeCode;
341 else
342 return xmlTypeCode;
346 [MonoTODO]
347 public override object TypedValue {
348 get {
349 switch (ResolvedTypeCode) {
350 case XmlTypeCode.Boolean:
351 return ValueAsBoolean;
352 case XmlTypeCode.DateTime:
353 return ValueAsDateTime;
354 case XmlTypeCode.Decimal:
355 return ValueAsDecimal;
356 case XmlTypeCode.Double:
357 return ValueAsDouble;
358 case XmlTypeCode.Long:
359 return ValueAsInt64;
360 case XmlTypeCode.Int:
361 return ValueAsInt32;
362 case XmlTypeCode.Float:
363 return ValueAsSingle;
364 case XmlTypeCode.String:
365 return Value;
367 return objectValue;
371 [MonoTODO]
372 // This method works like ValueAsString.
373 public override string Value {
374 get {
375 switch (ResolvedTypeCode) {
376 case XmlTypeCode.Boolean:
377 stringValue = XQueryConvert.BooleanToString (ValueAsBoolean);
378 break;
379 case XmlTypeCode.DateTime:
380 stringValue = XQueryConvert.DateTimeToString (ValueAsDateTime);
381 break;
382 case XmlTypeCode.Decimal:
383 stringValue = XQueryConvert.DecimalToString (ValueAsDecimal);
384 break;
385 case XmlTypeCode.Double:
386 stringValue = XQueryConvert.DoubleToString (ValueAsDouble);
387 break;
388 case XmlTypeCode.Long:
389 stringValue = XQueryConvert.IntegerToString (ValueAsInt64);
390 break;
391 case XmlTypeCode.Int:
392 stringValue = XQueryConvert.IntToString (ValueAsInt32);
393 break;
394 case XmlTypeCode.Float:
395 stringValue = XQueryConvert.FloatToString (ValueAsSingle);
396 break;
397 case XmlTypeCode.String:
398 return stringValue;
400 case XmlTypeCode.None:
401 case XmlTypeCode.Item:
402 case XmlTypeCode.AnyAtomicType:
403 switch (XmlTypeCodeFromRuntimeType (objectValue.GetType (), false)) {
404 case XmlTypeCode.String:
405 stringValue = (string) objectValue;
406 break;
407 case XmlTypeCode.DateTime:
408 stringValue = XQueryConvert.DateTimeToString ((DateTime) objectValue);
409 break;
410 case XmlTypeCode.Boolean:
411 stringValue = XQueryConvert.BooleanToString ((bool) objectValue);
412 break;
413 case XmlTypeCode.Float:
414 stringValue = XQueryConvert.FloatToString ((float) objectValue);
415 break;
416 case XmlTypeCode.Double:
417 stringValue = XQueryConvert.DoubleToString ((double) objectValue);
418 break;
419 case XmlTypeCode.Decimal:
420 stringValue = XQueryConvert.DecimalToString ((decimal) objectValue);
421 break;
422 case XmlTypeCode.Long:
423 stringValue = XQueryConvert.IntegerToString ((long) objectValue);
424 break;
425 case XmlTypeCode.Int:
426 stringValue = XQueryConvert.IntToString ((int) objectValue);
427 break;
429 break;
431 if (stringValue != null)
432 return stringValue;
434 if (objectValue != null)
435 throw new InvalidCastException (String.Format ("Conversion from runtime type {0} to {1} is not supported", objectValue.GetType (), XmlTypeCode.String));
436 else
437 throw new InvalidCastException (String.Format ("Conversion from schema type {0} (type code {1}) to {2} is not supported", schemaType.QualifiedName, xmlTypeCode, XmlTypeCode.String));
441 [MonoTODO]
442 public override bool ValueAsBoolean {
443 get {
444 switch (xmlTypeCode) {
445 case XmlTypeCode.Boolean:
446 return booleanValue;
447 case XmlTypeCode.Decimal:
448 return XQueryConvert.DecimalToBoolean (decimalValue);
449 case XmlTypeCode.Double:
450 return XQueryConvert.DoubleToBoolean (doubleValue);
451 case XmlTypeCode.Long:
452 return XQueryConvert.IntegerToBoolean (longValue);
453 case XmlTypeCode.Int:
454 return XQueryConvert.IntToBoolean (intValue);
455 case XmlTypeCode.Float:
456 return XQueryConvert.FloatToBoolean (floatValue);
457 case XmlTypeCode.String:
458 return XQueryConvert.StringToBoolean (stringValue);
460 case XmlTypeCode.None:
461 case XmlTypeCode.Item:
462 case XmlTypeCode.AnyAtomicType:
463 if (objectValue is bool)
464 return (bool) objectValue;
465 break;
469 throw new InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsBoolean.QualifiedName));
473 [MonoTODO]
474 public override DateTime ValueAsDateTime {
475 get {
476 switch (xmlTypeCode) {
477 case XmlTypeCode.DateTime:
478 return dateTimeValue;
479 case XmlTypeCode.String:
480 return XQueryConvert.StringToDateTime (stringValue);
481 case XmlTypeCode.None:
482 case XmlTypeCode.Item:
483 case XmlTypeCode.AnyAtomicType:
484 if (objectValue is DateTime)
485 return (DateTime) objectValue;
486 break;
490 throw new InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsDateTime.QualifiedName));
494 [MonoTODO]
495 public override decimal ValueAsDecimal {
496 get {
497 switch (xmlTypeCode) {
498 case XmlTypeCode.Boolean:
499 return XQueryConvert.BooleanToDecimal (booleanValue);
500 case XmlTypeCode.Decimal:
501 return decimalValue;
502 case XmlTypeCode.Double:
503 return XQueryConvert.DoubleToDecimal (doubleValue);
504 case XmlTypeCode.Long:
505 return XQueryConvert.IntegerToDecimal (longValue);
506 case XmlTypeCode.Int:
507 return XQueryConvert.IntToDecimal (intValue);
508 case XmlTypeCode.Float:
509 return XQueryConvert.FloatToDecimal (floatValue);
510 case XmlTypeCode.String:
511 return XQueryConvert.StringToDecimal (stringValue);
512 case XmlTypeCode.None:
513 case XmlTypeCode.Item:
514 case XmlTypeCode.AnyAtomicType:
515 if (objectValue is decimal)
516 return (decimal) objectValue;
517 break;
521 throw new InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsDecimal.QualifiedName));
525 [MonoTODO]
526 public override double ValueAsDouble {
527 get {
528 switch (xmlTypeCode) {
529 case XmlTypeCode.Boolean:
530 return XQueryConvert.BooleanToDouble (booleanValue);
531 case XmlTypeCode.Decimal:
532 return XQueryConvert.DecimalToDouble (decimalValue);
533 case XmlTypeCode.Double:
534 return doubleValue;
535 case XmlTypeCode.Long:
536 return XQueryConvert.IntegerToDouble (longValue);
537 case XmlTypeCode.Int:
538 return XQueryConvert.IntToDouble (intValue);
539 case XmlTypeCode.Float:
540 return XQueryConvert.FloatToDouble (floatValue);
541 case XmlTypeCode.String:
542 return XQueryConvert.StringToDouble (stringValue);
543 case XmlTypeCode.None:
544 case XmlTypeCode.Item:
545 case XmlTypeCode.AnyAtomicType:
546 if (objectValue is double)
547 return (double) objectValue;
548 break;
552 throw new InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsDouble.QualifiedName));
556 [MonoTODO]
557 public override int ValueAsInt32 {
558 get {
559 switch (xmlTypeCode) {
560 case XmlTypeCode.Boolean:
561 return XQueryConvert.BooleanToInt (booleanValue);
562 case XmlTypeCode.Decimal:
563 return XQueryConvert.DecimalToInt (decimalValue);
564 case XmlTypeCode.Double:
565 return XQueryConvert.DoubleToInt (doubleValue);
566 case XmlTypeCode.Long:
567 return XQueryConvert.IntegerToInt (longValue);
568 case XmlTypeCode.Int:
569 return intValue;
570 case XmlTypeCode.Float:
571 return XQueryConvert.FloatToInt (floatValue);
572 case XmlTypeCode.String:
573 return XQueryConvert.StringToInt (stringValue);
574 case XmlTypeCode.None:
575 case XmlTypeCode.Item:
576 case XmlTypeCode.AnyAtomicType:
577 if (objectValue is int)
578 return (int) objectValue;
579 break;
583 throw new InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsInt.QualifiedName));
587 [MonoTODO]
588 public override long ValueAsInt64 {
589 get {
590 switch (xmlTypeCode) {
591 case XmlTypeCode.Boolean:
592 return XQueryConvert.BooleanToInteger (booleanValue);
593 case XmlTypeCode.Decimal:
594 return XQueryConvert.DecimalToInteger (decimalValue);
595 case XmlTypeCode.Double:
596 return XQueryConvert.DoubleToInteger (doubleValue);
597 case XmlTypeCode.Long:
598 return longValue;
599 case XmlTypeCode.Int:
600 return XQueryConvert.IntegerToInt (intValue);
601 case XmlTypeCode.Float:
602 return XQueryConvert.FloatToInteger (floatValue);
603 case XmlTypeCode.String:
604 return XQueryConvert.StringToInteger (stringValue);
605 case XmlTypeCode.None:
606 case XmlTypeCode.Item:
607 case XmlTypeCode.AnyAtomicType:
608 if (objectValue is long)
609 return (long) objectValue;
610 break;
614 throw new InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsLong.QualifiedName));
618 [MonoTODO]
619 public override float ValueAsSingle {
620 get {
621 switch (xmlTypeCode) {
622 case XmlTypeCode.Boolean:
623 return XQueryConvert.BooleanToFloat (booleanValue);
624 case XmlTypeCode.Decimal:
625 return XQueryConvert.DecimalToFloat (decimalValue);
626 case XmlTypeCode.Double:
627 return XQueryConvert.DoubleToFloat (doubleValue);
628 case XmlTypeCode.Float:
629 return floatValue;
630 case XmlTypeCode.Int:
631 return XQueryConvert.FloatToInt (intValue);
632 case XmlTypeCode.Long:
633 return XQueryConvert.IntegerToFloat (longValue);
634 case XmlTypeCode.String:
635 return XQueryConvert.StringToFloat (stringValue);
636 case XmlTypeCode.None:
637 case XmlTypeCode.Item:
638 case XmlTypeCode.AnyAtomicType:
639 if (objectValue is float)
640 return (float) objectValue;
641 break;
645 throw new InvalidCastException (String.Format ("Conversion from {0} to {1} is not supported", schemaType.QualifiedName, XmlSchemaSimpleType.XsFloat.QualifiedName));
649 [MonoTODO]
650 public override ICollection ValueAsList {
651 get {
652 if (valueAsList != null)
653 return valueAsList;
654 if (objectValue is ICollection)
655 valueAsList = objectValue as ICollection;
656 else if (objectValue is Array)
657 valueAsList = new ArrayList ((Array) objectValue);
658 else if (xmlTypeCode != XmlTypeCode.None) {
659 ArrayList al = new ArrayList ();
660 al.Add (TypedValue);
661 valueAsList = al;
663 else
664 throw new NotImplementedException ();
665 return valueAsList;
669 [MonoTODO]
670 public override Type ValueType {
671 get { return schemaType.Datatype.ValueType; }
674 [MonoTODO]
675 public override XmlSchemaType XmlType {
676 get { return schemaType; }
679 #endregion
681 #region internal static members
683 internal static Type RuntimeTypeFromXmlTypeCode (XmlTypeCode typeCode)
685 switch (typeCode) {
686 case XmlTypeCode.Int:
687 return typeof (int);
688 case XmlTypeCode.Decimal:
689 return typeof (decimal);
690 case XmlTypeCode.Double:
691 return typeof (double);
692 case XmlTypeCode.Float:
693 return typeof (float);
694 case XmlTypeCode.Long:
695 return typeof (long);
696 case XmlTypeCode.Short:
697 return typeof (short);
698 case XmlTypeCode.UnsignedShort:
699 return typeof (ushort);
700 case XmlTypeCode.UnsignedInt:
701 return typeof (uint);
702 case XmlTypeCode.String:
703 return typeof (string);
704 case XmlTypeCode.DateTime:
705 return typeof (DateTime);
706 case XmlTypeCode.Boolean:
707 return typeof (bool);
708 case XmlTypeCode.Item:
709 return typeof (object);
711 throw new NotSupportedException (String.Format ("XQuery internal error: Cannot infer Runtime Type from XmlTypeCode {0}.", typeCode));
714 internal static XmlTypeCode XmlTypeCodeFromRuntimeType (Type cliType, bool raiseError)
716 switch (Type.GetTypeCode (cliType)) {
717 case TypeCode.Int32:
718 return XmlTypeCode.Int;
719 case TypeCode.Decimal:
720 return XmlTypeCode.Decimal;
721 case TypeCode.Double:
722 return XmlTypeCode.Double;
723 case TypeCode.Single:
724 return XmlTypeCode.Float;
725 case TypeCode.Int64:
726 return XmlTypeCode.Long;
727 case TypeCode.Int16:
728 return XmlTypeCode.Short;
729 case TypeCode.UInt16:
730 return XmlTypeCode.UnsignedShort;
731 case TypeCode.UInt32:
732 return XmlTypeCode.UnsignedInt;
733 case TypeCode.String:
734 return XmlTypeCode.String;
735 case TypeCode.DateTime:
736 return XmlTypeCode.DateTime;
737 case TypeCode.Boolean:
738 return XmlTypeCode.Boolean;
739 case TypeCode.Object:
740 return XmlTypeCode.Item;
742 if (raiseError)
743 throw new NotSupportedException (String.Format ("XQuery internal error: Cannot infer XmlTypeCode from Runtime Type {0}", cliType));
744 else
745 return XmlTypeCode.None;
747 #endregion
751 #endif