2004-05-05 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.XML / System.Xml.Schema / BuiltInDatatype.cs
1 //\r
2 // System.Xml.Schema.XmlSchemaDatatype.cs\r
3 //\r
4 // Author:\r
5 //      Atsushi Enomoto\r
6 //\r
7 // (C)2003 Atsushi Enomoto\r
8 //\r
9 using System;\r
10 using System.Collections;\r
11 using System.Text;\r
12 using System.Xml;\r
13 using System.Xml.Schema;\r
14 using System.Globalization;\r
15 using System.Security.Cryptography;\r
16 \r
17 namespace Mono.Xml.Schema\r
18 {\r
19         public enum XsdWhitespaceFacet\r
20         {\r
21                 Preserve,\r
22                 Replace,\r
23                 Collapse\r
24         }\r
25 \r
26         public enum XsdOrderedFacet\r
27         {\r
28                 False,\r
29                 Partial,\r
30                 Total\r
31         }\r
32 \r
33         public enum XsdOrdering \r
34         {\r
35                 LessThan = -1,\r
36                 Equal = 0,\r
37                 GreaterThan = 1,\r
38                 Indeterminate = 2\r
39         }\r
40         \r
41         public class XsdAnySimpleType : XmlSchemaDatatype\r
42         {\r
43                 static XsdAnySimpleType instance;\r
44                 static XsdAnySimpleType ()\r
45                 {\r
46                         instance = new XsdAnySimpleType ();\r
47                 }\r
48 \r
49                 public static XsdAnySimpleType Instance {\r
50                         get { return instance; }\r
51                 }\r
52 \r
53                 readonly char [] whitespaceArray = new char [] {' '};\r
54 \r
55                 // Fundamental Facets\r
56                 public virtual bool Bounded {\r
57                         get { return false; }\r
58                 }\r
59 \r
60                 public virtual bool Finite {\r
61                         get { return false; }\r
62                 }\r
63 \r
64                 public virtual bool Numeric { \r
65                         get { return false; }\r
66                 }\r
67 \r
68                 public virtual XsdOrderedFacet Ordered { \r
69                         get { return XsdOrderedFacet.False; }\r
70                 }\r
71 \r
72                 public override Type ValueType {\r
73 #if BUGGY_MS_COMPLIANT\r
74                         get { return typeof (string); }\r
75 #else\r
76                         get { return typeof (object); }\r
77 #endif\r
78                 }\r
79 \r
80                 public override XmlTokenizedType TokenizedType {\r
81                         get {\r
82                                 return XmlTokenizedType.None;\r
83                         }\r
84                 }\r
85 \r
86                 public override object ParseValue (string s,\r
87                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
88                 {\r
89                         return Normalize (s);\r
90                 }\r
91 \r
92                 internal override ValueType ParseValueType (string s,\r
93                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
94                 {\r
95                         return new StringValueType (Normalize (s));\r
96                 }\r
97 \r
98                 internal string [] ParseListValue (string s, XmlNameTable nameTable)\r
99                 {\r
100                         return this.Normalize (s, XsdWhitespaceFacet.Collapse).Split (whitespaceArray);\r
101                 }\r
102                 \r
103         \r
104 \r
105                         // Can you even use XsdAnySimpleType in a schema?\r
106                         // -> Yes. See E1-22 of http://www.w3.org/2001/05/xmlschema-errata#Errata1 (somewhat paranoid ;-)\r
107                 \r
108                 internal bool AllowsFacet(XmlSchemaFacet xsf) {\r
109                         return (AllowedFacets & xsf.ThisFacet)!=0;\r
110                 }\r
111 \r
112 \r
113 \r
114                 internal virtual XsdOrdering Compare(object x, object y) {\r
115                         return XsdOrdering.Indeterminate;\r
116                         }\r
117         \r
118                 internal virtual int Length(string s) {\r
119                         return s.Length;\r
120                 }\r
121 \r
122                 \r
123                 // anySimpleType allows any facet\r
124                 internal virtual XmlSchemaFacet.Facet AllowedFacets {\r
125                         get { return XmlSchemaFacet.AllFacets ;}\r
126                 }\r
127 \r
128                 /* Matches facets allowed on boolean type\r
129                  */\r
130                 internal const XmlSchemaFacet.Facet booleanAllowedFacets = \r
131                                          XmlSchemaFacet.Facet.pattern | XmlSchemaFacet.Facet.whiteSpace;\r
132 \r
133                 /* Matches facets allowed on decimal type. \r
134                  */\r
135                 internal const XmlSchemaFacet.Facet decimalAllowedFacets = \r
136                                                         XmlSchemaFacet.Facet.pattern | XmlSchemaFacet.Facet.enumeration | \r
137                                                         XmlSchemaFacet.Facet.whiteSpace | XmlSchemaFacet.Facet.maxInclusive | \r
138                                                         XmlSchemaFacet.Facet.minInclusive | XmlSchemaFacet.Facet.maxExclusive | \r
139                                                         XmlSchemaFacet.Facet.minExclusive | XmlSchemaFacet.Facet.fractionDigits | \r
140                                                         XmlSchemaFacet.Facet.totalDigits ;\r
141 \r
142                 /* Matches facets allowed on float, double, duration, dateTime, time, date,\r
143                  * gYearMonth, gYear, gMonthDay, gMonth, and gDay types\r
144                  */\r
145 \r
146                 internal const XmlSchemaFacet.Facet durationAllowedFacets = \r
147                                                         XmlSchemaFacet.Facet.pattern | XmlSchemaFacet.Facet.enumeration | \r
148                                                         XmlSchemaFacet.Facet.whiteSpace | XmlSchemaFacet.Facet.maxInclusive |\r
149                                                         XmlSchemaFacet.Facet.minInclusive | XmlSchemaFacet.Facet.maxExclusive |\r
150                                                         XmlSchemaFacet.Facet.minExclusive ;\r
151 \r
152                 /* Matches facet allowed on string, hexBinary, base64Binary,\r
153                  * anyURI, QName and NOTATION types \r
154                  *\r
155                  * Also used on list types\r
156                  */\r
157 \r
158                 internal const XmlSchemaFacet.Facet stringAllowedFacets = \r
159                                                  XmlSchemaFacet.Facet.length | XmlSchemaFacet.Facet.minLength |\r
160                                                  XmlSchemaFacet.Facet.maxLength | XmlSchemaFacet.Facet.pattern | \r
161                                                  XmlSchemaFacet.Facet.enumeration | XmlSchemaFacet.Facet.whiteSpace; \r
162         }\r
163 \r
164         // xs:string\r
165         public class XsdString : XsdAnySimpleType\r
166         {\r
167                 internal XsdString ()\r
168                 {\r
169                 }\r
170 \r
171                 internal override XmlSchemaFacet.Facet AllowedFacets {\r
172                         get { return stringAllowedFacets; } \r
173                 }\r
174 \r
175                 public override XmlTokenizedType TokenizedType {\r
176                         get { return XmlTokenizedType.CDATA; }\r
177                 }\r
178 \r
179                 public override Type ValueType {\r
180                         get { return typeof (string); }\r
181                 }\r
182 \r
183                 // Fundamental Facets\r
184                 public override bool Bounded {\r
185                         get { return false; }\r
186                 }\r
187                 public override bool Finite {\r
188                         get { return false; }\r
189                 }\r
190                 public override bool Numeric {\r
191                         get { return false; }\r
192                 }\r
193                 public override XsdOrderedFacet Ordered {\r
194                         get { return XsdOrderedFacet.False; }\r
195                 }\r
196 \r
197         }\r
198 \r
199         // xs:normalizedString\r
200         public class XsdNormalizedString : XsdString\r
201         {\r
202                 internal XsdNormalizedString ()\r
203                 {\r
204                         this.WhitespaceValue = XsdWhitespaceFacet.Replace;\r
205                 }\r
206 \r
207                 public override XmlTokenizedType TokenizedType {\r
208 \r
209                         get { return XmlTokenizedType.CDATA; }\r
210                 }\r
211 \r
212                 public override Type ValueType {\r
213                         get { return typeof (string); }\r
214                 }\r
215 \r
216                 // ParseValue () method is as same as that of xs:string\r
217         }\r
218 \r
219         // xs:token\r
220         public class XsdToken : XsdNormalizedString\r
221         {\r
222                 internal XsdToken ()\r
223                 {\r
224                         this.WhitespaceValue = XsdWhitespaceFacet.Collapse;\r
225                 }\r
226 \r
227                 public override XmlTokenizedType TokenizedType {\r
228                         get { return XmlTokenizedType.CDATA; }\r
229                 }\r
230 \r
231                 public override Type ValueType {\r
232                         get { return typeof (string); }\r
233                 }\r
234 \r
235                 // ParseValue () method is as same as that of xs:string\r
236         }\r
237 \r
238         // xs:language\r
239         public class XsdLanguage : XsdToken\r
240         {\r
241                 internal XsdLanguage ()\r
242                 {\r
243                 }\r
244 \r
245                 public override XmlTokenizedType TokenizedType {\r
246                         get { return XmlTokenizedType.CDATA; }\r
247                 }\r
248 \r
249                 public override Type ValueType {\r
250                         get { return typeof (string); }\r
251                 }\r
252 \r
253                 // ParseValue () method is as same as that of xs:string\r
254         }\r
255 \r
256         // xs;NMTOKEN\r
257         public class XsdNMToken : XsdToken\r
258         {\r
259                 internal XsdNMToken ()\r
260                 {\r
261                 }\r
262 \r
263                 public override XmlTokenizedType TokenizedType {\r
264                         get { return XmlTokenizedType.NMTOKEN; }\r
265                 }\r
266 \r
267                 public override Type ValueType {\r
268                         get { return typeof (string); }\r
269                 }\r
270 \r
271                 public override object ParseValue (string s,\r
272                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
273                 {\r
274                         if (!XmlChar.IsNmToken (s))\r
275                                 throw new ArgumentException ("'" + s + "' is an invalid NMTOKEN.");\r
276                         return s;\r
277                 }\r
278 \r
279                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
280                 {\r
281                         return new StringValueType (ParseValue (s, nameTable, nsmgr) as string);\r
282                 }\r
283         }\r
284 \r
285         // xs:NMTOKENS\r
286         public class XsdNMTokens : XsdNMToken\r
287         {\r
288                 internal XsdNMTokens ()\r
289                 {\r
290                 }\r
291 \r
292                 public override XmlTokenizedType TokenizedType {\r
293                         get { return XmlTokenizedType.NMTOKENS; }\r
294                 }\r
295 \r
296                 public override Type ValueType {\r
297                         get { return typeof (string []); }\r
298                 }\r
299 \r
300                 public override object ParseValue (string value, XmlNameTable nt, XmlNamespaceManager nsmgr)\r
301                 {\r
302                         return GetValidatedArray (value, nt);\r
303                 }\r
304 \r
305                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
306                 {\r
307                         return new StringArrayValueType (GetValidatedArray (s, nameTable));\r
308                 }\r
309 \r
310                 private string [] GetValidatedArray (string value, XmlNameTable nt)\r
311                 {\r
312                         string [] nmtokens = ParseListValue (value, nt);\r
313                         for (int i = 0; i < nmtokens.Length; i++)\r
314                                 if (!XmlChar.IsNmToken (nmtokens [i]))\r
315                                         throw new ArgumentException ("Invalid name token.");\r
316                         return nmtokens;\r
317                 }\r
318         }\r
319 \r
320         // xs:Name\r
321         public class XsdName : XsdToken\r
322         {\r
323                 internal XsdName ()\r
324                 {\r
325                 }\r
326 \r
327                 public override XmlTokenizedType TokenizedType {\r
328                         get { return XmlTokenizedType.CDATA; }\r
329                 }\r
330 \r
331                 public override Type ValueType {\r
332                         get { return typeof (string); }\r
333                 }\r
334 \r
335                 public override object ParseValue (string s,\r
336                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
337                 {\r
338                         if (!XmlChar.IsName (s))\r
339                                 throw new ArgumentException ("'" + s + "' is an invalid name.");\r
340                         return s;\r
341                 }\r
342 \r
343                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
344                 {\r
345                         return new StringValueType (ParseValue (s, nameTable, nsmgr) as string);\r
346                 }\r
347         }\r
348 \r
349         // xs:NCName\r
350         public class XsdNCName : XsdName\r
351         {\r
352                 internal XsdNCName ()\r
353                 {\r
354                 }\r
355 \r
356                 public override XmlTokenizedType TokenizedType {\r
357                         get { return XmlTokenizedType.NCName; }\r
358                 }\r
359 \r
360                 public override Type ValueType {\r
361                         get { return typeof (string); }\r
362                 }\r
363 \r
364                 public override object ParseValue (string s,\r
365                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
366                 {\r
367                         if (!XmlChar.IsNCName (s))\r
368                                 throw new ArgumentException ("'" + s + "' is an invalid NCName.");\r
369                         return s;\r
370                 }\r
371 \r
372                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
373                 {\r
374                         return new StringValueType (ParseValue (s, nameTable, nsmgr) as string);\r
375                 }\r
376         }\r
377 \r
378         // xs:ID\r
379         public class XsdID : XsdName\r
380         {\r
381                 internal XsdID ()\r
382                 {\r
383                 }\r
384 \r
385                 public override XmlTokenizedType TokenizedType {\r
386                         get { return XmlTokenizedType.ID; }\r
387                 }\r
388 \r
389                 public override Type ValueType {\r
390                         get { return typeof (string); }\r
391                 }\r
392 \r
393                 public override object ParseValue (string s, XmlNameTable nt, XmlNamespaceManager nsmgr)\r
394                 {\r
395                         if (!XmlChar.IsNCName (s))\r
396                                 throw new ArgumentException ("'" + s + "' is an invalid NCName.");\r
397                         return s;\r
398                 }\r
399         }\r
400 \r
401         // xs:IDREF\r
402         public class XsdIDRef : XsdName\r
403         {\r
404                 internal XsdIDRef ()\r
405                 {\r
406                 }\r
407 \r
408                 public override XmlTokenizedType TokenizedType {\r
409                         get { return XmlTokenizedType.IDREF; }\r
410                 }\r
411 \r
412                 public override Type ValueType {\r
413                         get { return typeof (string); }\r
414                 }\r
415 \r
416                 public override object ParseValue (string s, XmlNameTable nt, XmlNamespaceManager nsmgr)\r
417                 {\r
418                         if (!XmlChar.IsNCName (s))\r
419                                 throw new ArgumentException ("'" + s + "' is an invalid NCName.");\r
420                         return s;\r
421                 }\r
422         }\r
423 \r
424         // xs:IDREFS\r
425         public class XsdIDRefs : XsdName\r
426         {\r
427                 internal XsdIDRefs ()\r
428                 {\r
429                 }\r
430 \r
431                 public override XmlTokenizedType TokenizedType {\r
432                         get { return XmlTokenizedType.IDREFS; }\r
433                 }\r
434 \r
435                 public override Type ValueType {\r
436                         get { return typeof (string []); }\r
437                 }\r
438 \r
439                 public override object ParseValue (string value, XmlNameTable nt, XmlNamespaceManager nsmgr)\r
440                 {\r
441                         return GetValidatedArray (value, nt);\r
442                 }\r
443 \r
444                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
445                 {\r
446                         return new StringArrayValueType (GetValidatedArray (s, nameTable));\r
447                 }\r
448 \r
449                 private string [] GetValidatedArray (string value, XmlNameTable nt)\r
450                 {\r
451                         string [] idrefs = ParseListValue (value, nt);\r
452                         for (int i = 0; i < idrefs.Length; i++)\r
453                                 XmlConvert.VerifyNCName (idrefs [i]);\r
454                         return idrefs;\r
455                 }\r
456         }\r
457 \r
458         // xs:ENTITY\r
459         public class XsdEntity : XsdName\r
460         {\r
461                 internal XsdEntity ()\r
462                 {\r
463                 }\r
464 \r
465                 public override XmlTokenizedType TokenizedType {\r
466                         get { return XmlTokenizedType.ENTITY; }\r
467                 }\r
468 \r
469                 public override Type ValueType {\r
470                         get { return typeof (string); }\r
471                 }\r
472 \r
473 \r
474         }\r
475 \r
476 \r
477         // xs:ENTITIES\r
478         public class XsdEntities : XsdName\r
479         {\r
480                 internal XsdEntities ()\r
481                 {\r
482                 }\r
483 \r
484                 public override XmlTokenizedType TokenizedType {\r
485                         get { return XmlTokenizedType.ENTITIES; }\r
486                 }\r
487 \r
488                 public override Type ValueType {\r
489                         get { return typeof (string []); }\r
490                 }\r
491 \r
492                 public override object ParseValue (string value, XmlNameTable nt, XmlNamespaceManager nsmgr)\r
493                 {\r
494                         return GetValidatedArray (value, nt);\r
495                 }\r
496 \r
497                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
498                 {\r
499                         return new StringArrayValueType (GetValidatedArray (s, nameTable));\r
500                 }\r
501 \r
502                 private string [] GetValidatedArray (string value, XmlNameTable nt)\r
503                 {\r
504                         string [] entities = ParseListValue (value, nt);\r
505                         for (int i = 0; i < entities.Length; i++)\r
506                                 if (!XmlChar.IsName (entities [i]))\r
507                                         throw new ArgumentException ("Invalid entitiy name.");\r
508                         return entities;\r
509                 }\r
510         }\r
511 \r
512         // xs:NOTATION\r
513         public class XsdNotation : XsdAnySimpleType\r
514         {\r
515                 internal XsdNotation ()\r
516                 {\r
517                 }\r
518 \r
519                 internal override XmlSchemaFacet.Facet AllowedFacets {\r
520                         get { return stringAllowedFacets; } \r
521                 }\r
522 \r
523                 public override XmlTokenizedType TokenizedType {\r
524                         get { return XmlTokenizedType.NOTATION; }\r
525                 }\r
526 \r
527                 public override Type ValueType {\r
528                         get { return typeof (string); }\r
529                 }\r
530 \r
531                 public override object ParseValue (string s,\r
532                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
533                 {\r
534                         return Normalize (s);\r
535                 }\r
536 \r
537                 // Fundamental Facets\r
538                 public override bool Bounded {\r
539                         get { return false; }\r
540                 }\r
541                 public override bool Finite {\r
542                         get { return false; }\r
543                 }\r
544                 public override bool Numeric {\r
545                         get { return false; }\r
546                 }\r
547                 public override XsdOrderedFacet Ordered {\r
548                         get { return XsdOrderedFacet.False; }\r
549                 }\r
550 \r
551         }\r
552 \r
553         // xs:decimal\r
554         public class XsdDecimal : XsdAnySimpleType\r
555         {\r
556                 internal XsdDecimal ()\r
557                 {\r
558                         this.WhitespaceValue = XsdWhitespaceFacet.Collapse;\r
559                 }\r
560 \r
561                 internal override XmlSchemaFacet.Facet AllowedFacets {\r
562                         get { return decimalAllowedFacets; } \r
563                 }\r
564 \r
565                 public override XmlTokenizedType TokenizedType {\r
566                         get { return XmlTokenizedType.None; }\r
567                 }\r
568 \r
569                 public override Type ValueType {\r
570                         get { return typeof (decimal); }\r
571                 }\r
572 \r
573                 public override object ParseValue (string s,\r
574                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
575                 {\r
576                         return ParseValueType (s, nameTable, nsmgr);\r
577                 }\r
578 \r
579                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
580                 {\r
581                         return XmlConvert.ToDecimal (this.Normalize (s));\r
582                 }\r
583          \r
584                 internal override XsdOrdering Compare(object x, object y) {\r
585                         if ((x is Decimal) && (y is Decimal)) {\r
586                                 int ret = Decimal.Compare((Decimal)x, (Decimal)y);\r
587                                 if (ret < 0) { \r
588                                         return XsdOrdering.LessThan;\r
589                                 }\r
590                                 else if (ret > 0) {\r
591                                         return XsdOrdering.GreaterThan;\r
592                                 }\r
593                                 else {\r
594                                         return XsdOrdering.Equal;\r
595                                 }\r
596                         }\r
597                         return XsdOrdering.Indeterminate;\r
598                 }\r
599                 \r
600                 // Fundamental Facets\r
601                 public override bool Bounded {\r
602                         get { return false; }\r
603                 }\r
604                 public override bool Finite {\r
605                         get { return false; }\r
606                 }\r
607                 public override bool Numeric {\r
608                         get { return true; }\r
609                 }\r
610                 public override XsdOrderedFacet Ordered {\r
611                         get { return XsdOrderedFacet.Total; }\r
612                 }\r
613 \r
614         }\r
615 \r
616         // xs:integer\r
617         public class XsdInteger : XsdDecimal\r
618         {\r
619                 public XsdInteger ()\r
620                 {\r
621                 }\r
622 \r
623                 // Here it may be bigger than int's (or long's) MaxValue.\r
624                 public override Type ValueType {\r
625                         get { return typeof (decimal); }\r
626                 }\r
627 \r
628                 public override object ParseValue (string s,\r
629                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
630                 {\r
631                         return ParseValueType (s, nameTable, nsmgr);\r
632                 }\r
633 \r
634                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
635                 {\r
636                         decimal d = XmlConvert.ToDecimal (Normalize (s));\r
637                         if (Decimal.Floor (d) != d)\r
638                                 throw new FormatException ("Integer contains point number.");\r
639                         return d;\r
640                 }\r
641          \r
642                 \r
643         \r
644         }\r
645 \r
646         // xs:Long\r
647         public class XsdLong : XsdInteger\r
648         {\r
649                 public override Type ValueType {\r
650                         get { return typeof (long); }\r
651                 }\r
652 \r
653                 public override object ParseValue (string s,\r
654                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
655                 {\r
656                         return ParseValueType (s, nameTable, nsmgr);\r
657                 }\r
658 \r
659                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
660                 {\r
661                         return XmlConvert.ToInt64 (Normalize (s));\r
662                 }\r
663                 \r
664                 internal override XsdOrdering Compare(object x, object y) {\r
665                         if ((x is long) && (y is long)) {\r
666                                 if ((long)x==(long)y) {\r
667                                         return XsdOrdering.Equal;\r
668                                 }\r
669                                 else if ((long)x<(long)y) {\r
670                                         return XsdOrdering.LessThan;\r
671                                 }\r
672                                 else {\r
673                                         return XsdOrdering.GreaterThan;\r
674                                 }\r
675                         }\r
676                         return XsdOrdering.Indeterminate;\r
677                 }\r
678         }\r
679 \r
680         // xs:Int\r
681         public class XsdInt : XsdLong\r
682         {\r
683                 public override Type ValueType {\r
684                         get { return typeof (int); }\r
685                 }\r
686 \r
687                 public override object ParseValue (string s,\r
688                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
689                 {\r
690                         return ParseValueType (s, nameTable, nsmgr);\r
691                 }\r
692 \r
693                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
694                 {\r
695                         return XmlConvert.ToInt32 (Normalize (s));\r
696                 }\r
697 \r
698                 internal override XsdOrdering Compare(object x, object y) {\r
699                         if ((x is int) && (y is int)) {\r
700                                 if ((int)x==(int)y) {\r
701                                         return XsdOrdering.Equal;\r
702                                 }\r
703                                 else if ((int)x<(int)y) {\r
704                                         return XsdOrdering.LessThan;\r
705                                 }\r
706                                 else {\r
707                                         return XsdOrdering.GreaterThan;\r
708                                 }\r
709                         }\r
710                         return XsdOrdering.Indeterminate;\r
711                 }\r
712         }\r
713 \r
714 \r
715         // xs:Short\r
716         public class XsdShort : XsdInt\r
717         {\r
718                 public override Type ValueType {\r
719                         get { return typeof (short); }\r
720                 }\r
721 \r
722                 public override object ParseValue (string s,\r
723                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
724                 {\r
725                         return ParseValueType (s, nameTable, nsmgr);\r
726                 }\r
727 \r
728                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
729                 {\r
730                         return XmlConvert.ToInt16 (Normalize (s));\r
731                 }\r
732 \r
733                 internal override XsdOrdering Compare(object x, object y) {\r
734                         if ((x is short) && (y is short)) {\r
735                                 if ((short)x==(short)y) {\r
736                                         return XsdOrdering.Equal;\r
737                                 }\r
738                                 else if ((short)x<(short)y) {\r
739                                         return XsdOrdering.LessThan;\r
740                                 }\r
741                                 else {\r
742                                         return XsdOrdering.GreaterThan;\r
743                                 }\r
744                         }\r
745                         return XsdOrdering.Indeterminate;\r
746                 }\r
747         }\r
748 \r
749         // xs:Byte\r
750         public class XsdByte : XsdShort\r
751         {\r
752                 public override Type ValueType {\r
753                         get { return typeof (sbyte); }\r
754                 }\r
755 \r
756                 public override object ParseValue (string s,\r
757                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
758                 {\r
759                         return ParseValueType (s, nameTable, nsmgr);\r
760                 }\r
761 \r
762                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
763                 {\r
764                         return XmlConvert.ToSByte (Normalize (s));\r
765                 }\r
766 \r
767                 internal override XsdOrdering Compare(object x, object y) {\r
768                         if ((x is sbyte) && (y is sbyte)) {\r
769                                 if ((sbyte)x==(sbyte)y) {\r
770                                         return XsdOrdering.Equal;\r
771                                 }\r
772                                 else if ((sbyte)x<(sbyte)y) {\r
773                                         return XsdOrdering.LessThan;\r
774                                 }\r
775                                 else {\r
776                                         return XsdOrdering.GreaterThan;\r
777                                 }\r
778                         }\r
779                         return XsdOrdering.Indeterminate;\r
780                 }\r
781         }\r
782 \r
783         // xs:nonNegativeInteger\r
784         [CLSCompliant (false)]\r
785         public class XsdNonNegativeInteger : XsdInteger\r
786         {\r
787                 public override Type ValueType {\r
788                         get { return typeof (decimal); }\r
789                 }\r
790 \r
791                 [CLSCompliant (false)]\r
792                 public override object ParseValue (string s,\r
793                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
794                 {\r
795                         return ParseValueType (s, nameTable, nsmgr);\r
796                 }\r
797 \r
798                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
799                 {\r
800                         return XmlConvert.ToDecimal (Normalize (s));\r
801                 }\r
802         }\r
803 \r
804         // xs:unsignedLong\r
805         [CLSCompliant (false)]\r
806         public class XsdUnsignedLong : XsdNonNegativeInteger\r
807         {\r
808                 public override Type ValueType {\r
809                         get { return typeof (ulong); }\r
810                 }\r
811 \r
812                 public override object ParseValue (string s,\r
813                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
814                 {\r
815                         return ParseValueType (s, nameTable, nsmgr);\r
816                 }\r
817 \r
818                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
819                 {\r
820                         return XmlConvert.ToUInt64 (Normalize (s));\r
821                 }\r
822 \r
823                 internal override XsdOrdering Compare(object x, object y) {\r
824                         if ((x is ulong) && (y is ulong)) {\r
825                                 if ((ulong)x==(ulong)y) {\r
826                                         return XsdOrdering.Equal;\r
827                                 }\r
828                                 else if ((ulong)x<(ulong)y) {\r
829                                         return XsdOrdering.LessThan;\r
830                                 }\r
831                                 else {\r
832                                         return XsdOrdering.GreaterThan;\r
833                                 }\r
834                         }\r
835                         return XsdOrdering.Indeterminate;\r
836                 }\r
837         }\r
838 \r
839         // xs:unsignedInt\r
840         [CLSCompliant (false)]\r
841         public class XsdUnsignedInt : XsdUnsignedLong\r
842         {\r
843                 public override Type ValueType {\r
844                         get { return typeof (uint); }\r
845                 }\r
846 \r
847                 public override object ParseValue (string s,\r
848                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
849                 {\r
850                         return ParseValueType (s, nameTable, nsmgr);\r
851                 }\r
852 \r
853                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
854                 {\r
855                         return XmlConvert.ToUInt32 (Normalize (s));\r
856                 }\r
857 \r
858                 internal override XsdOrdering Compare(object x, object y) {\r
859                         if ((x is uint) && (y is uint)) {\r
860                                 if ((uint)x==(uint)y) {\r
861                                         return XsdOrdering.Equal;\r
862                                 }\r
863                                 else if ((uint)x<(uint)y) {\r
864                                         return XsdOrdering.LessThan;\r
865                                 }\r
866                                 else {\r
867                                         return XsdOrdering.GreaterThan;\r
868                                 }\r
869                         }\r
870                         return XsdOrdering.Indeterminate;\r
871                 }\r
872         }\r
873 \r
874 \r
875         // xs:unsignedShort\r
876         [CLSCompliant (false)]\r
877         public class XsdUnsignedShort : XsdUnsignedInt\r
878         {\r
879                 public override Type ValueType {\r
880                         get { return typeof (ushort); }\r
881                 }\r
882 \r
883                 public override object ParseValue (string s,\r
884                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
885                 {\r
886                         return ParseValueType (s, nameTable, nsmgr);\r
887                 }\r
888 \r
889                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
890                 {\r
891                         return XmlConvert.ToUInt16 (Normalize (s));\r
892                 }\r
893 \r
894                 internal override XsdOrdering Compare(object x, object y) {\r
895                         if ((x is ushort) && (y is ushort)) {\r
896                                 if ((ushort)x==(ushort)y) {\r
897                                         return XsdOrdering.Equal;\r
898                                 }\r
899                                 else if ((ushort)x<(ushort)y) {\r
900                                         return XsdOrdering.LessThan;\r
901                                 }\r
902                                 else {\r
903                                         return XsdOrdering.GreaterThan;\r
904                                 }\r
905                         }\r
906                         return XsdOrdering.Indeterminate;\r
907                 }\r
908         }\r
909 \r
910         // xs:unsignedByte\r
911         [CLSCompliant (false)]\r
912         public class XsdUnsignedByte : XsdUnsignedShort\r
913         {\r
914                 public override Type ValueType {\r
915                         get { return typeof (byte); }\r
916                 }\r
917 \r
918                 public override object ParseValue (string s,\r
919                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
920                 {\r
921                         return ParseValueType (s, nameTable, nsmgr);\r
922                 }\r
923 \r
924                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
925                 {\r
926                         return XmlConvert.ToByte(Normalize (s));\r
927                 }\r
928 \r
929                 internal override XsdOrdering Compare(object x, object y) {\r
930                         if ((x is byte) && (y is byte)) {\r
931                                 if ((byte)x==(byte)y) {\r
932                                         return XsdOrdering.Equal;\r
933                                 }\r
934                                 else if ((byte)x<(byte)y) {\r
935                                         return XsdOrdering.LessThan;\r
936                                 }\r
937                                 else {\r
938                                         return XsdOrdering.GreaterThan;\r
939                                 }\r
940                         }\r
941                         return XsdOrdering.Indeterminate;\r
942                 }\r
943         }\r
944 \r
945 \r
946         // xs:positiveInteger\r
947         [CLSCompliant (false)]\r
948         public class XsdPositiveInteger : XsdNonNegativeInteger\r
949         {\r
950                 // It returns decimal, instead of int or long.\r
951                 // Maybe MS developers thought about big integer...\r
952                 public override Type ValueType {\r
953                         get { return typeof (decimal); }\r
954                 }\r
955 \r
956                 public override object ParseValue (string s,\r
957                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
958                 {\r
959                         return ParseValueType (s, nameTable, nsmgr);\r
960                 }\r
961 \r
962                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
963                 {\r
964                         return XmlConvert.ToDecimal (Normalize (s));\r
965                 }\r
966         }\r
967 \r
968         // xs:nonPositiveInteger\r
969         public class XsdNonPositiveInteger : XsdInteger\r
970         {\r
971                 public override Type ValueType {\r
972                         get { return typeof (decimal); }\r
973                 }\r
974 \r
975                 public override object ParseValue (string s,\r
976                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
977                 {\r
978                         return ParseValueType (s, nameTable, nsmgr);\r
979                 }\r
980 \r
981                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
982                 {\r
983                         return XmlConvert.ToDecimal (Normalize (s));\r
984                 }\r
985         }\r
986 \r
987         // xs:negativeInteger\r
988         public class XsdNegativeInteger : XsdNonPositiveInteger\r
989         {\r
990                 public override Type ValueType {\r
991 \r
992                         get { return typeof (decimal); }\r
993                 }\r
994 \r
995                 public override object ParseValue (string s,\r
996                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
997                 {\r
998                         return ParseValueType (s, nameTable, nsmgr);\r
999                 }\r
1000 \r
1001                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
1002                 {\r
1003                         return XmlConvert.ToDecimal (Normalize (s));\r
1004                 }\r
1005         }\r
1006 \r
1007         // xs:float\r
1008         public class XsdFloat : XsdAnySimpleType\r
1009         {\r
1010                 internal XsdFloat ()\r
1011                 {\r
1012                         this.WhitespaceValue = XsdWhitespaceFacet.Collapse;\r
1013                 }\r
1014     \r
1015                 internal override XmlSchemaFacet.Facet AllowedFacets {\r
1016                         get { return durationAllowedFacets; } \r
1017                 }\r
1018                 \r
1019                 // Fundamental Facets\r
1020                 public override bool Bounded {\r
1021                         get { return true; }\r
1022                 }\r
1023                 public override bool Finite {\r
1024                         get { return true; }\r
1025                 }\r
1026                 public override bool Numeric {\r
1027                         get { return true; }\r
1028                 }\r
1029                 public override XsdOrderedFacet Ordered {\r
1030                         get { return XsdOrderedFacet.Total; }\r
1031                 }\r
1032 \r
1033                 public override Type ValueType {\r
1034                         get { return typeof (float); }\r
1035                 }\r
1036 \r
1037                 public override object ParseValue (string s,\r
1038                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
1039                 {\r
1040                         return ParseValueType (s, nameTable, nsmgr);\r
1041                 }\r
1042 \r
1043                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
1044                 {\r
1045                         return XmlConvert.ToSingle (Normalize (s));\r
1046                 }\r
1047 \r
1048                 internal override XsdOrdering Compare(object x, object y) {\r
1049                         if ((x is float) && (y is float)) {\r
1050                                 if ((float)x==(float)y) {\r
1051                                         return XsdOrdering.Equal;\r
1052                                 }\r
1053                                 else if ((float)x<(float)y) {\r
1054                                         return XsdOrdering.LessThan;\r
1055                                 }\r
1056                                 else {\r
1057                                         return XsdOrdering.GreaterThan;\r
1058                                 }\r
1059                 }\r
1060                         return XsdOrdering.Indeterminate;\r
1061                 }\r
1062                 \r
1063         }\r
1064 \r
1065         // xs:double\r
1066         public class XsdDouble : XsdAnySimpleType\r
1067         {\r
1068                 internal XsdDouble ()\r
1069                 {\r
1070                         this.WhitespaceValue = XsdWhitespaceFacet.Collapse;\r
1071                 }\r
1072     \r
1073                 internal override XmlSchemaFacet.Facet AllowedFacets {\r
1074                         get { return durationAllowedFacets; } \r
1075                 }\r
1076                 \r
1077                 // Fundamental Facets\r
1078                 public override bool Bounded {\r
1079                         get { return true; }\r
1080                 }\r
1081                 public override bool Finite {\r
1082                         get { return true; }\r
1083                 }\r
1084                 public override bool Numeric {\r
1085                         get { return true; }\r
1086                 }\r
1087                 public override XsdOrderedFacet Ordered {\r
1088                         get { return XsdOrderedFacet.Total; }\r
1089                 }\r
1090 \r
1091                 public override Type ValueType {\r
1092                         get { return typeof (double); }\r
1093                 }\r
1094 \r
1095                 public override object ParseValue (string s,\r
1096                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
1097                 {\r
1098                         return ParseValueType (s, nameTable, nsmgr);\r
1099                 }\r
1100 \r
1101                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
1102                 {\r
1103                         return XmlConvert.ToDouble (Normalize (s));\r
1104                 }\r
1105 \r
1106                 internal override XsdOrdering Compare(object x, object y) {\r
1107                         if ((x is double) && (y is double)) {\r
1108                                 if ((double)x==(double)y) {\r
1109                                         return XsdOrdering.Equal;\r
1110                                 }\r
1111                                 else if ((double)x<(double)y) {\r
1112                                         return XsdOrdering.LessThan;\r
1113                 }\r
1114                                 else {\r
1115                                         return XsdOrdering.GreaterThan;\r
1116                                 }\r
1117                         }\r
1118                         return XsdOrdering.Indeterminate;\r
1119                 }\r
1120                 \r
1121         }\r
1122 \r
1123         // xs:base64Binary\r
1124         public class XsdBase64Binary : XsdString\r
1125         {\r
1126                 internal XsdBase64Binary ()\r
1127                 {\r
1128                 }\r
1129 \r
1130                 public override Type ValueType {\r
1131                         get { return typeof (byte[]); }\r
1132                 }\r
1133 \r
1134                 public override object ParseValue (string s,\r
1135                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
1136                 {\r
1137                         // If it isnt ASCII it isnt valid base64 data\r
1138                         byte[] inArr = new System.Text.ASCIIEncoding().GetBytes(s);\r
1139                         FromBase64Transform t = new FromBase64Transform();\r
1140                         return t.TransformFinalBlock(inArr, 0, inArr.Length);\r
1141                 }\r
1142 \r
1143 \r
1144                 internal override int Length(string s) {\r
1145                         int length = 0;\r
1146                         int pad = 0;\r
1147                         int end = s.Length;\r
1148                         for (int i = 0; i < end; i++) {\r
1149                           char c = s[i];\r
1150                                 if (!Char.IsWhiteSpace(c)) {\r
1151                                         if (isData(c))\r
1152                                                 length ++;\r
1153                                         else if (isPad(c)) \r
1154                                                 pad++;                                  \r
1155                                         else \r
1156                                           return -1;   // Invalid characters\r
1157                                 }       \r
1158                         }\r
1159                         if (pad > 2) \r
1160                           return -1; // Max 2 padding at the end.\r
1161                         if (pad > 0) \r
1162                           pad = 3-pad;                          \r
1163                         \r
1164                   return ((length/4)*3)+pad;\r
1165                 }       \r
1166 \r
1167 /* TODO: Use the Base64Table and similar code when it makes it \r
1168  * out of System.Security.Cryptography (currently internal so I \r
1169  * don't think we can use it).\r
1170  * \r
1171  */\r
1172                         private static string ALPHABET =\r
1173                                 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";\r
1174 \r
1175                         private static byte[] decodeTable;\r
1176                         static XsdBase64Binary ()\r
1177                         {\r
1178                                 int len = ALPHABET.Length;\r
1179 \r
1180                                 decodeTable = new byte [1 + (int)'z'];\r
1181 \r
1182                                 for (int i=0; i < decodeTable.Length; i++) {\r
1183                                         decodeTable [i] = Byte.MaxValue;\r
1184                                 }\r
1185 \r
1186                                 for (int i=0; i < len; i++) {\r
1187                                         char ch = ALPHABET [i];\r
1188                                         decodeTable [(int)ch] = (byte) i;\r
1189                                 }\r
1190                         }\r
1191         \r
1192                 protected static bool isPad(char octect) {\r
1193                         return (octect == '=');\r
1194                 }\r
1195                                                                                         \r
1196                 protected static bool isData(char octect) {\r
1197                         return ((octect <= 'z') && (decodeTable[octect] != Byte.MaxValue));\r
1198                 }\r
1199 \r
1200 \r
1201                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
1202                 {\r
1203                         return new StringValueType (ParseValue (s, nameTable, nsmgr) as string);\r
1204                 }\r
1205         }\r
1206 \r
1207         \r
1208         // xs:hexBinary\r
1209         public class XsdHexBinary : XsdAnySimpleType\r
1210         {\r
1211                 internal XsdHexBinary ()\r
1212                 {\r
1213                         this.WhitespaceValue = XsdWhitespaceFacet.Collapse;\r
1214                 }\r
1215 \r
1216                 internal override XmlSchemaFacet.Facet AllowedFacets {\r
1217                         get { return stringAllowedFacets; } \r
1218                 }\r
1219 \r
1220                 public override XmlTokenizedType TokenizedType {\r
1221                         get { return XmlTokenizedType.None; }\r
1222                 }\r
1223 \r
1224                 public override Type ValueType {\r
1225                         get { return typeof (byte []); }\r
1226                 }\r
1227 \r
1228                 public override object ParseValue (string s,\r
1229                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
1230                 {\r
1231                         return XmlConvert.FromBinHexString (Normalize (s));\r
1232                 }\r
1233                 \r
1234                 internal override int Length(string s) {\r
1235                   return s.Length / 2 + s.Length % 2 ;   // Not sure if odd lengths are even allowed\r
1236     }\r
1237 \r
1238                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
1239                 {\r
1240                         return new StringValueType (ParseValue (s, nameTable, nsmgr) as string);\r
1241                 }\r
1242 \r
1243                 // Fundamental Facets ... no need to override\r
1244         }\r
1245 \r
1246         // xs:QName\r
1247         public class XsdQName : XsdName\r
1248         {\r
1249                 internal XsdQName ()\r
1250                 {\r
1251                 }\r
1252 \r
1253                 // Fundamental facets are the same as anySimpleType.\r
1254 \r
1255                 public override XmlTokenizedType TokenizedType {\r
1256                         get { return XmlTokenizedType.QName; }\r
1257                 }\r
1258 \r
1259                 public override Type ValueType {\r
1260                         get { return typeof (XmlQualifiedName); }\r
1261                 }\r
1262 \r
1263                 // ParseValue () method is as same as that of xs:string\r
1264                 public override object ParseValue (string s,\r
1265                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
1266                 {\r
1267                         if (nameTable == null)\r
1268                                 throw new ArgumentNullException ("name table");\r
1269                         if (nsmgr == null)\r
1270                                 throw new ArgumentNullException ("namespace manager");\r
1271                         int colonAt = s.IndexOf (':');\r
1272                         string localName = colonAt < 0 ? s : s.Substring (colonAt + 1);\r
1273 //                      string localName = nameTable.Add (colonAt < 0 ? s : s.Substring (colonAt + 1));\r
1274                         return new XmlQualifiedName (localName, nsmgr.LookupNamespace (\r
1275                                 colonAt < 0 ? "" : s.Substring (0, colonAt - 1)));\r
1276                 }\r
1277 \r
1278                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
1279                 {\r
1280                         return new QNameValueType (ParseValue (s, nameTable, nsmgr) as XmlQualifiedName);\r
1281                 }\r
1282         }\r
1283 \r
1284         // xs:boolean\r
1285         public class XsdBoolean : XsdAnySimpleType\r
1286         {\r
1287                 internal XsdBoolean ()\r
1288                 {\r
1289                         this.WhitespaceValue = XsdWhitespaceFacet.Collapse;\r
1290                 }\r
1291 \r
1292                 internal override XmlSchemaFacet.Facet AllowedFacets {\r
1293                         get { return booleanAllowedFacets; } \r
1294                 }\r
1295 \r
1296                 public override XmlTokenizedType TokenizedType {\r
1297 #if BUGGY_MS_COMPLIANT\r
1298                         get { return XmlTokenizedType.None; }\r
1299 #else\r
1300                         get { return XmlTokenizedType.CDATA; }\r
1301 #endif\r
1302                 }\r
1303 \r
1304                 public override Type ValueType {\r
1305                         get { return typeof (bool); }\r
1306                 }\r
1307 \r
1308                 public override object ParseValue (string s,\r
1309                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
1310                 {\r
1311                         return ParseValueType (s, nameTable, nsmgr);\r
1312                 }\r
1313 \r
1314                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
1315                 {\r
1316                         return XmlConvert.ToBoolean (this.Normalize (s));\r
1317                 }\r
1318 \r
1319                 // Fundamental Facets\r
1320                 public override bool Bounded {\r
1321                         get { return false; }\r
1322                 }\r
1323                 public override bool Finite {\r
1324                         get { return true; }\r
1325                 }\r
1326                 public override bool Numeric {\r
1327                         get { return false; }\r
1328                 }\r
1329                 public override XsdOrderedFacet Ordered {\r
1330                         get { return XsdOrderedFacet.Total; }\r
1331                 }\r
1332                 \r
1333                 \r
1334         }\r
1335 \r
1336         // xs:anyURI\r
1337         public class XsdAnyURI : XsdString\r
1338         {\r
1339                 public override XmlTokenizedType TokenizedType {\r
1340 \r
1341                         get { return XmlTokenizedType.CDATA; }\r
1342                 }\r
1343 \r
1344                 public override Type ValueType {\r
1345                         get { return typeof (Uri); }\r
1346                 }\r
1347 \r
1348                 public override object ParseValue (string s,\r
1349                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
1350                 {\r
1351                         return ParseValueType (s, nameTable, nsmgr);\r
1352                 }\r
1353 \r
1354                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
1355                 {\r
1356                         return new UriValueType (Normalize (s));\r
1357                 }\r
1358         }\r
1359         \r
1360         // xs:duration\r
1361         public class XsdDuration : XsdAnySimpleType\r
1362         {\r
1363                 internal XsdDuration ()\r
1364                 {\r
1365       this.WhitespaceValue = XsdWhitespaceFacet.Collapse;\r
1366                 }\r
1367 \r
1368                 internal override XmlSchemaFacet.Facet AllowedFacets {\r
1369                         get { return durationAllowedFacets; } \r
1370                 }\r
1371 \r
1372                 public override XmlTokenizedType TokenizedType {\r
1373                         get { return XmlTokenizedType.CDATA; }\r
1374                 }\r
1375 \r
1376                 public override Type ValueType {\r
1377                         get { return typeof (TimeSpan); }\r
1378                 }\r
1379 \r
1380                 public override object ParseValue (string s,\r
1381                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
1382                 {\r
1383                         return ParseValueType (s, nameTable, nsmgr);\r
1384                 }\r
1385 \r
1386                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
1387                 {\r
1388                         return XmlConvert.ToTimeSpan (Normalize (s));\r
1389                 }\r
1390 \r
1391                 internal override XsdOrdering Compare(object x, object y) {\r
1392                         /* FIXME: This is really simple so far \r
1393                          *\r
1394                          * In fact in order to do this correctly in XmlSchema, we cannot use TimeSpan as the base type\r
1395                          * Though it turns out that MS .NET is a little broken in this regard too. Not doing comparisons \r
1396                          * correctly.\r
1397                          */\r
1398                         if ((x is TimeSpan) && (y is TimeSpan)) {\r
1399                                 int ret = TimeSpan.Compare((TimeSpan)x, (TimeSpan)y);\r
1400                                 if (ret < 0) { \r
1401                                         return XsdOrdering.LessThan;\r
1402                                 }\r
1403                                 else if (ret > 0) {\r
1404                                         return XsdOrdering.GreaterThan;\r
1405                                 }\r
1406                                 else {\r
1407                                         return XsdOrdering.Equal;\r
1408                                 }\r
1409                         }\r
1410                         return XsdOrdering.Indeterminate;\r
1411                 }\r
1412 \r
1413                 \r
1414                 // Fundamental Facets\r
1415                 public override bool Bounded {\r
1416                         get { return false; }\r
1417                 }\r
1418                 public override bool Finite {\r
1419                         get { return false; }\r
1420                 }\r
1421                 public override bool Numeric {\r
1422                         get { return false; }\r
1423                 }\r
1424                 public override XsdOrderedFacet Ordered {\r
1425                         get { return XsdOrderedFacet.Partial; }\r
1426          \r
1427                 }\r
1428         }\r
1429 \r
1430         // xs:dateTime\r
1431         public class XsdDateTime : XsdAnySimpleType\r
1432         {\r
1433                 internal XsdDateTime ()\r
1434                 {\r
1435                         this.WhitespaceValue = XsdWhitespaceFacet.Collapse;\r
1436                 }\r
1437 \r
1438                 internal override XmlSchemaFacet.Facet AllowedFacets {\r
1439                         get { return durationAllowedFacets; } \r
1440                 }\r
1441 \r
1442                 public override XmlTokenizedType TokenizedType {\r
1443                         get { return XmlTokenizedType.CDATA; }\r
1444                 }\r
1445 \r
1446                 public override Type ValueType {\r
1447                         get { return typeof (DateTime); }\r
1448                 }\r
1449 \r
1450                 public override object ParseValue (string s,\r
1451                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
1452                 {\r
1453                         return ParseValueType (s, nameTable, nsmgr);\r
1454                 }\r
1455 \r
1456                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
1457                 {\r
1458                         return XmlConvert.ToDateTime (Normalize (s));\r
1459                 }\r
1460 \r
1461                 internal override XsdOrdering Compare(object x, object y) {\r
1462                         /* Really simple so far */\r
1463                         if ((x is DateTime) && (y is DateTime)) {\r
1464                                 int ret = DateTime.Compare((DateTime)x, (DateTime)y);\r
1465                                 if (ret < 0) { \r
1466                                         return XsdOrdering.LessThan;\r
1467                                 }\r
1468                                 else if (ret > 0) {\r
1469                                         return XsdOrdering.GreaterThan;\r
1470                                 }\r
1471                                 else {\r
1472                                         return XsdOrdering.Equal;\r
1473                                 }\r
1474                         }\r
1475                         return XsdOrdering.Indeterminate;\r
1476                 }\r
1477 \r
1478                 // Fundamental Facets\r
1479                 public override bool Bounded {\r
1480                         get { return false; }\r
1481                 }\r
1482                 public override bool Finite {\r
1483                         get { return false; }\r
1484                 }\r
1485                 public override bool Numeric {\r
1486                         get { return false; }\r
1487                 }\r
1488                 public override XsdOrderedFacet Ordered {\r
1489                         get { return XsdOrderedFacet.Partial; }\r
1490                 }\r
1491                 \r
1492         }\r
1493 \r
1494         // xs:date\r
1495         public class XsdDate : XsdAnySimpleType\r
1496         {\r
1497                 internal XsdDate ()\r
1498                 {\r
1499                         this.WhitespaceValue = XsdWhitespaceFacet.Collapse;\r
1500                 }\r
1501     \r
1502                 internal override XmlSchemaFacet.Facet AllowedFacets {\r
1503                         get { return durationAllowedFacets; } \r
1504                 }\r
1505                 \r
1506                 public override XmlTokenizedType TokenizedType {\r
1507                         get { return XmlTokenizedType.CDATA; }\r
1508                 }\r
1509 \r
1510                 public override Type ValueType {\r
1511                         get { return typeof (DateTime); }\r
1512                 }\r
1513 \r
1514                 public override object ParseValue (string s,\r
1515                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
1516                 {\r
1517                         return ParseValueType (s, nameTable, nsmgr);\r
1518                 }\r
1519 \r
1520                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
1521                 {\r
1522                         return DateTime.ParseExact (Normalize (s), "yyyy-MM-dd", null);\r
1523                 }\r
1524 \r
1525                 internal override XsdOrdering Compare(object x, object y) {\r
1526                         /* Really simple so far */\r
1527                         if ((x is DateTime) && (y is DateTime)) {\r
1528                                 int ret = DateTime.Compare((DateTime)x, (DateTime)y);\r
1529                                 if (ret < 0) { \r
1530                                         return XsdOrdering.LessThan;\r
1531                                 }\r
1532                                 else if (ret > 0) {\r
1533                                         return XsdOrdering.GreaterThan;\r
1534                                 }\r
1535                                 else {\r
1536                                         return XsdOrdering.Equal;\r
1537                                 }\r
1538                         }\r
1539                         return XsdOrdering.Indeterminate;\r
1540                 }\r
1541                 // Fundamental Facets ... no need to override except for Ordered.\r
1542                 public override XsdOrderedFacet Ordered {\r
1543                         get { return XsdOrderedFacet.Partial; }\r
1544                 }\r
1545                 \r
1546         }\r
1547 \r
1548         // xs:time\r
1549         public class XsdTime : XsdAnySimpleType\r
1550         {\r
1551                 static string [] timeFormats = new string [] {\r
1552                           // copied from XmlConvert.\r
1553                           "HH:mm:ss",\r
1554                           "HH:mm:ss.f",\r
1555                           "HH:mm:ss.ff",\r
1556                           "HH:mm:ss.fff",\r
1557                           "HH:mm:ss.ffff",\r
1558                           "HH:mm:ss.fffff",\r
1559                           "HH:mm:ss.ffffff",\r
1560                           "HH:mm:ss.fffffff",\r
1561                           "HH:mm:sszzz",\r
1562                           "HH:mm:ss.fzzz",\r
1563                           "HH:mm:ss.ffzzz",\r
1564                           "HH:mm:ss.fffzzz",\r
1565                           "HH:mm:ss.ffffzzz",\r
1566                           "HH:mm:ss.fffffzzz",\r
1567                           "HH:mm:ss.ffffffzzz",\r
1568                           "HH:mm:ss.fffffffzzz",\r
1569                           "HH:mm:ssZ",\r
1570                           "HH:mm:ss.fZ",\r
1571                           "HH:mm:ss.ffZ",\r
1572                           "HH:mm:ss.fffZ",\r
1573                           "HH:mm:ss.ffffZ",\r
1574                           "HH:mm:ss.fffffZ",\r
1575                           "HH:mm:ss.ffffffZ",\r
1576                           "HH:mm:ss.fffffffZ"};\r
1577 \r
1578                 internal XsdTime ()\r
1579                 {\r
1580                         this.WhitespaceValue = XsdWhitespaceFacet.Collapse;\r
1581                 }\r
1582 \r
1583                 internal override XmlSchemaFacet.Facet AllowedFacets {\r
1584                         get { return durationAllowedFacets; } \r
1585                 }\r
1586 \r
1587                 public override XmlTokenizedType TokenizedType {\r
1588                         get { return XmlTokenizedType.CDATA; }\r
1589                 }\r
1590 \r
1591                 public override Type ValueType {\r
1592                         get { return typeof (DateTime); }\r
1593                 }\r
1594 \r
1595                 public override object ParseValue (string s,\r
1596                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
1597                 {\r
1598                         return ParseValueType (s, nameTable, nsmgr);\r
1599                 }\r
1600 \r
1601                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
1602                 {\r
1603                         return DateTime.ParseExact (Normalize (s), timeFormats, null, DateTimeStyles.None);\r
1604                 }\r
1605 \r
1606                 internal override XsdOrdering Compare(object x, object y) {\r
1607                         /* Really simple so far */\r
1608                         if ((x is DateTime) && (y is DateTime)) {\r
1609                                 int ret = DateTime.Compare((DateTime)x, (DateTime)y);\r
1610                                 if (ret < 0) { \r
1611                                         return XsdOrdering.LessThan;\r
1612                                 }\r
1613                                 else if (ret > 0) {\r
1614                                         return XsdOrdering.GreaterThan;\r
1615                                 }\r
1616                                 else {\r
1617                                         return XsdOrdering.Equal;\r
1618                                 }\r
1619                         }\r
1620                         return XsdOrdering.Indeterminate;\r
1621                 }\r
1622                 // Fundamental Facets ... no need to override except for Ordered.\r
1623                 public override XsdOrderedFacet Ordered {\r
1624                         get { return XsdOrderedFacet.Partial; }\r
1625                 }\r
1626                 \r
1627         }\r
1628 \r
1629         // xs:gYearMonth\r
1630         public class XsdGYearMonth : XsdAnySimpleType\r
1631         {\r
1632                 internal XsdGYearMonth ()\r
1633                 {\r
1634                         this.WhitespaceValue = XsdWhitespaceFacet.Collapse;\r
1635                 }\r
1636     \r
1637                 internal override XmlSchemaFacet.Facet AllowedFacets {\r
1638                         get { return durationAllowedFacets; } \r
1639                 }\r
1640                 \r
1641                 public override Type ValueType {\r
1642                         get { return typeof (DateTime); }\r
1643                 }\r
1644 \r
1645                 public override object ParseValue (string s,\r
1646                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
1647                 {\r
1648                         return ParseValueType (s, nameTable, nsmgr);\r
1649                 }\r
1650 \r
1651                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
1652                 {\r
1653                         return DateTime.ParseExact (Normalize (s), "yyyy-MM", null);\r
1654                 }\r
1655                 \r
1656                 internal override XsdOrdering Compare(object x, object y) {\r
1657                         /* Really simple so far */\r
1658                         if ((x is DateTime) && (y is DateTime)) {\r
1659                                 int ret = DateTime.Compare((DateTime)x, (DateTime)y);\r
1660                                 if (ret < 0) { \r
1661                                         return XsdOrdering.LessThan;\r
1662                                 }\r
1663                                 else if (ret > 0) {\r
1664                                         return XsdOrdering.GreaterThan;\r
1665                                 }\r
1666                                 else {\r
1667                                         return XsdOrdering.Equal;\r
1668                                 }\r
1669                         }\r
1670                         return XsdOrdering.Indeterminate;\r
1671                 }\r
1672         }\r
1673 \r
1674         // xs:gMonthDay\r
1675         public class XsdGMonthDay : XsdAnySimpleType\r
1676         {\r
1677                 internal XsdGMonthDay ()\r
1678                 {\r
1679                         this.WhitespaceValue = XsdWhitespaceFacet.Collapse;\r
1680                 }\r
1681     \r
1682                 internal override XmlSchemaFacet.Facet AllowedFacets {\r
1683                         get { return durationAllowedFacets; } \r
1684                 }\r
1685                 \r
1686                 public override Type ValueType {\r
1687                         get { return typeof (DateTime); }\r
1688                 }\r
1689 \r
1690                 public override object ParseValue (string s,\r
1691                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
1692                 {\r
1693                         return ParseValueType (s, nameTable, nsmgr);\r
1694                 }\r
1695 \r
1696                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
1697                 {\r
1698                         return DateTime.ParseExact (Normalize (s), "--MM-dd", null);\r
1699                 }\r
1700                 \r
1701                 internal override XsdOrdering Compare(object x, object y) {\r
1702                         /* Really simple so far */\r
1703                         if ((x is DateTime) && (y is DateTime)) {\r
1704                                 int ret = DateTime.Compare((DateTime)x, (DateTime)y);\r
1705                                 if (ret < 0) { \r
1706                                         return XsdOrdering.LessThan;\r
1707                                 }\r
1708                                 else if (ret > 0) {\r
1709                                         return XsdOrdering.GreaterThan;\r
1710                                 }\r
1711                                 else {\r
1712                                         return XsdOrdering.Equal;\r
1713                                 }\r
1714                         }\r
1715                         return XsdOrdering.Indeterminate;\r
1716                 }\r
1717         }\r
1718 \r
1719         // xs:gYear\r
1720         public class XsdGYear : XsdAnySimpleType\r
1721         {\r
1722                 internal XsdGYear ()\r
1723                 {\r
1724                         this.WhitespaceValue = XsdWhitespaceFacet.Collapse;\r
1725                 }\r
1726                 \r
1727                 internal override XmlSchemaFacet.Facet AllowedFacets {\r
1728                         get { return durationAllowedFacets; } \r
1729                 }\r
1730                 \r
1731     public override Type ValueType {\r
1732                         get { return typeof (DateTime); }\r
1733                 }\r
1734 \r
1735                 // LAMESPEC: XML Schema Datatypes allows leading '-' to identify B.C. years,\r
1736                 // but CLR DateTime does not allow such expression.\r
1737                 public override object ParseValue (string s,\r
1738                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
1739                 {\r
1740                         return ParseValueType (s, nameTable, nsmgr);\r
1741                 }\r
1742 \r
1743                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
1744                 {\r
1745                         return DateTime.ParseExact (Normalize(s), "yyyy", null);\r
1746                 }\r
1747                 \r
1748                 internal override XsdOrdering Compare(object x, object y) {\r
1749                         /* Really simple so far */\r
1750                         if ((x is DateTime) && (y is DateTime)) {\r
1751                                 int ret = DateTime.Compare((DateTime)x, (DateTime)y);\r
1752                                 if (ret < 0) { \r
1753                                         return XsdOrdering.LessThan;\r
1754                                 }\r
1755                                 else if (ret > 0) {\r
1756                                         return XsdOrdering.GreaterThan;\r
1757                                 }\r
1758                                 else {\r
1759                                         return XsdOrdering.Equal;\r
1760                                 }\r
1761                         }\r
1762                         return XsdOrdering.Indeterminate;\r
1763                 }\r
1764         }\r
1765 \r
1766         // xs:gMonth\r
1767         public class XsdGMonth : XsdAnySimpleType\r
1768         {\r
1769                 internal XsdGMonth ()\r
1770                 {\r
1771                         this.WhitespaceValue = XsdWhitespaceFacet.Collapse;\r
1772                 }\r
1773                 \r
1774                 internal override XmlSchemaFacet.Facet AllowedFacets {\r
1775                         get { return durationAllowedFacets; } \r
1776                 }\r
1777                 \r
1778                 public override Type ValueType {\r
1779                         get { return typeof (DateTime); }\r
1780                 }\r
1781 \r
1782                 public override object ParseValue (string s,\r
1783                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
1784                 {\r
1785                         return ParseValueType (s, nameTable, nsmgr);\r
1786                 }\r
1787 \r
1788                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
1789                 {\r
1790                         return DateTime.ParseExact (Normalize(s), "--MM--", null);\r
1791                 }\r
1792                 \r
1793                 internal override XsdOrdering Compare(object x, object y) {\r
1794                         /* Really simple so far */\r
1795                         if ((x is DateTime) && (y is DateTime)) {\r
1796                                 int ret = DateTime.Compare((DateTime)x, (DateTime)y);\r
1797                                 if (ret < 0) { \r
1798                                         return XsdOrdering.LessThan;\r
1799                                 }\r
1800                                 else if (ret > 0) {\r
1801                                         return XsdOrdering.GreaterThan;\r
1802                                 }\r
1803                                 else {\r
1804                                         return XsdOrdering.Equal;\r
1805                                 }\r
1806                         }\r
1807                         return XsdOrdering.Indeterminate;\r
1808                 }\r
1809         }\r
1810 \r
1811         // xs:gDay\r
1812         public class XsdGDay : XsdAnySimpleType\r
1813         {\r
1814                 internal XsdGDay ()\r
1815                 {\r
1816                         this.WhitespaceValue = XsdWhitespaceFacet.Collapse;\r
1817                 }\r
1818                 \r
1819                 internal override XmlSchemaFacet.Facet AllowedFacets {\r
1820                         get { return durationAllowedFacets; } \r
1821                 }\r
1822                 \r
1823                 public override Type ValueType {\r
1824                         get { return typeof (DateTime); }\r
1825                 }\r
1826 \r
1827                 public override object ParseValue (string s,\r
1828                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)\r
1829                 {\r
1830                         return ParseValueType (s, nameTable, nsmgr);\r
1831                 }\r
1832 \r
1833                 internal override ValueType ParseValueType (string s, XmlNameTable nameTable, XmlNamespaceManager nsmgr) \r
1834                 {\r
1835                         return DateTime.ParseExact (Normalize(s), "---dd", null);\r
1836                 }\r
1837                 \r
1838                 internal override XsdOrdering Compare(object x, object y) {\r
1839                         /* Really simple so far */\r
1840                         if ((x is DateTime) && (y is DateTime)) {\r
1841                                 int ret = DateTime.Compare((DateTime)x, (DateTime)y);\r
1842                                 if (ret < 0) { \r
1843                                         return XsdOrdering.LessThan;\r
1844                                 }\r
1845                                 else if (ret > 0) {\r
1846                                         return XsdOrdering.GreaterThan;\r
1847                                 }\r
1848                                 else {\r
1849                                         return XsdOrdering.Equal;\r
1850                                 }\r
1851                         }\r
1852                         return XsdOrdering.Indeterminate;\r
1853                 }\r
1854         }\r
1855 \r
1856 }\r