Handle more type conversion.
[mono.git] / mcs / class / System.XML / System.Xml.Schema / XmlSchemaDatatype.cs
1 //
2 // System.Xml.Schema.XmlSchemaDatatype.cs
3 //
4 // Authors:
5 //      Dwivedi, Ajay kumar <Adwiv@Yahoo.com>
6 //      Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
7 //
8
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29 using System;
30 using System.Collections;
31 using System.Text;
32 using System.Xml;
33 using Mono.Xml.Schema;
34
35 namespace System.Xml.Schema
36 {
37         public abstract class XmlSchemaDatatype
38         {
39                 protected XmlSchemaDatatype()
40                 {
41                 }
42                 
43                 internal XsdWhitespaceFacet WhitespaceValue =
44                         XsdWhitespaceFacet.Preserve;
45
46                 // Common Facets
47                 internal virtual XsdWhitespaceFacet Whitespace {
48                         get { return WhitespaceValue; }
49                 }
50
51 #if NET_2_0
52                 public virtual XmlTypeCode TypeCode {
53                         // Actually no way to verify default value, since
54                         // in .NET 2.0 it cannot be derived externally anymore.
55                         get { return XmlTypeCode.None; }
56                 }
57
58                 public virtual XmlSchemaDatatypeVariety Variety {
59                         get {
60                                 return XmlSchemaDatatypeVariety.Atomic;
61                         }
62                 }
63 #endif
64
65                 public abstract XmlTokenizedType TokenizedType {  get; }
66                 public abstract Type ValueType {  get; }
67
68                 // Methods
69 #if NET_2_0
70                 [MonoTODO]
71                 public virtual object ChangeType (object value, Type targetType)
72                 {
73                         return ChangeType (value, targetType, null);
74                 }
75
76                 [MonoTODO]
77                 public virtual object ChangeType (object value, Type targetType, IXmlNamespaceResolver nsResolver)
78                 {
79                         throw new NotImplementedException ();
80                 }
81
82                 public virtual bool IsDerivedFrom (XmlSchemaDatatype datatype)
83                 {
84                         // It is documented to return always false, but
85                         // actually returns true when the argument is for
86                         // the same type (and it does not check null argument).
87                         return this == datatype;
88                 }
89 #endif
90
91 #if NET_2_0
92                 public abstract object ParseValue (string s, 
93                         XmlNameTable nameTable, IXmlNamespaceResolver nsmgr);
94
95                 internal virtual ValueType ParseValueType (string s,
96                         XmlNameTable nameTable, IXmlNamespaceResolver nsmgr)
97                 {
98                         return null;
99                 }
100 #else
101                 public abstract object ParseValue (string s, 
102                         XmlNameTable nameTable, XmlNamespaceManager nsmgr);
103
104                 internal virtual ValueType ParseValueType (string s,
105                         XmlNameTable nameTable, XmlNamespaceManager nsmgr)
106                 {
107                         return null;
108                 }
109 #endif
110
111                 static char [] wsChars = new char [] {' ', '\t', '\n', '\r'};
112
113                 StringBuilder sb = new StringBuilder ();
114                 internal string Normalize (string s)
115                 {
116                         return Normalize (s, Whitespace);
117                 }
118
119                 internal string Normalize (string s, XsdWhitespaceFacet whitespaceFacet)
120                 {
121                         int idx = s.IndexOfAny (wsChars);
122                         if (idx < 0)
123                                 return s;
124                         switch (whitespaceFacet) {
125                         case XsdWhitespaceFacet.Collapse:
126                                 string [] arr = s.Trim ().Split (wsChars);
127                                 for (int i = 0; i < arr.Length; i++) {
128                                         string one = arr [i];
129                                         if (one != "") {
130                                                 sb.Append (one);
131                                                 sb.Append (" ");
132                                         }
133                                 }
134                                 string result = sb.ToString ();
135                                 sb.Length = 0;
136                                 return result.Trim ();
137                         case XsdWhitespaceFacet.Replace:
138                                 sb.Length = 0;
139                                 sb.Append (s);
140                                 for (int i = 0; i < sb.Length; i++)
141                                         switch (sb [i]) {
142                                         case '\r':
143                                         case '\n':
144                                         case '\t':
145                                                 sb [i] = ' ';
146                                                 break;
147                                         }
148                                 result = sb.ToString ();
149                                 sb.Length = 0;
150                                 return result;
151                         default:
152                                 return s;
153                         }
154                 }
155
156                 internal static XmlSchemaDatatype FromName (XmlQualifiedName qname)
157                 {
158                         return FromName (qname.Name, qname.Namespace);
159                 }
160
161                 internal static XmlSchemaDatatype FromName (string localName, string ns)
162                 {
163                         switch (ns) {
164                         case XmlSchema.Namespace:
165                                 break;
166 #if NET_2_0
167                         case XmlSchema.XdtNamespace:
168                                 switch (localName) {
169                                 case "anyAtomicType":
170                                         return datatypeAnyAtomicType;
171                                 case "untypedAtomic":
172                                         return datatypeUntypedAtomic;
173                                 case "dayTimeDuration":
174                                         return datatypeDayTimeDuration;
175                                 case "yearMonthDuration":
176                                         return datatypeYearMonthDuration;
177                                 }
178                                 return null;
179 #endif
180                         default:
181                                 // Maybe invalid name was specified. In such cases, let processors handle them.
182                                 return null;
183                         }
184
185                         switch (localName) {
186                         case "anySimpleType":
187                                 return datatypeAnySimpleType;
188                         case "string":
189                                 return datatypeString;
190                         case "normalizedString":
191                                 return datatypeNormalizedString;
192                         case "token":
193                                 return datatypeToken;
194                         case "language":
195                                 return datatypeLanguage;
196                         case "NMTOKEN":
197                                 return datatypeNMToken;
198                         case "NMTOKENS":
199                                 return datatypeNMTokens;
200                         case "Name":
201                                 return datatypeName;
202                         case "NCName":
203                                 return datatypeNCName;
204                         case "ID":
205                                 return datatypeID;
206                         case "IDREF":
207                                 return datatypeIDRef;
208                         case "IDREFS":
209                                 return datatypeIDRefs;
210                         case "ENTITY":
211                                 return datatypeEntity;
212                         case "ENTITIES":
213                                 return datatypeEntities;
214                         case "NOTATION":
215                                 return datatypeNotation;
216                         case "decimal":
217                                 return datatypeDecimal;
218                         case "integer":
219                                 return datatypeInteger;
220                         case "long":
221                                 return datatypeLong;
222                         case "int":
223                                 return datatypeInt;
224                         case "short":
225                                 return datatypeShort;
226                         case "byte":
227                                 return datatypeByte;
228                         case "nonPositiveInteger":
229                                 return datatypeNonPositiveInteger;
230                         case "negativeInteger":
231                                 return datatypeNegativeInteger;
232                         case "nonNegativeInteger":
233                                 return datatypeNonNegativeInteger;
234                         case "unsignedLong":
235                                 return datatypeUnsignedLong;
236                         case "unsignedInt":
237                                 return datatypeUnsignedInt;
238                         case "unsignedShort":
239                                 return datatypeUnsignedShort;
240                         case "unsignedByte":
241                                 return datatypeUnsignedByte;
242                         case "positiveInteger":
243                                 return datatypePositiveInteger;
244                         case "float":
245                                 return datatypeFloat;
246                         case "double":
247                                 return datatypeDouble;
248                         case "base64Binary":
249                                 return datatypeBase64Binary;
250                         case "boolean":
251                                 return datatypeBoolean;
252                         case "anyURI":
253                                 return datatypeAnyURI;
254                         case "duration":
255                                 return datatypeDuration;
256                         case "dateTime":
257                                 return datatypeDateTime;
258                         case "date":
259                                 return datatypeDate;
260                         case "time":
261                                 return datatypeTime;
262                         case "hexBinary":
263                                 return datatypeHexBinary;
264                         case "QName":
265                                 return datatypeQName;
266                         case "gYearMonth":
267                                 return datatypeGYearMonth;
268                         case "gMonthDay":
269                                 return datatypeGMonthDay;
270                         case "gYear":
271                                 return datatypeGYear;
272                         case "gMonth":
273                                 return datatypeGMonth;
274                         case "gDay":
275                                 return datatypeGDay;
276                         default:
277                                 // Maybe invalid name was specified. In such cases, let processors handle them.
278                                 return null;
279                         }
280                 }
281
282                 static readonly XsdAnySimpleType datatypeAnySimpleType =XsdAnySimpleType.Instance;
283                 static readonly XsdString datatypeString = new XsdString ();
284                 static readonly XsdNormalizedString datatypeNormalizedString = new XsdNormalizedString ();
285                 static readonly XsdToken datatypeToken = new XsdToken ();
286                 static readonly XsdLanguage datatypeLanguage = new XsdLanguage ();
287                 static readonly XsdNMToken datatypeNMToken = new XsdNMToken ();
288                 static readonly XsdNMTokens datatypeNMTokens = new XsdNMTokens ();
289                 static readonly XsdName datatypeName = new XsdName ();
290                 static readonly XsdNCName datatypeNCName = new XsdNCName ();
291                 static readonly XsdID datatypeID = new XsdID ();
292                 static readonly XsdIDRef datatypeIDRef = new XsdIDRef ();
293                 static readonly XsdIDRefs datatypeIDRefs = new XsdIDRefs ();
294                 static readonly XsdEntity datatypeEntity = new XsdEntity ();
295                 static readonly XsdEntities datatypeEntities = new XsdEntities ();
296                 static readonly XsdNotation datatypeNotation = new XsdNotation ();
297                 static readonly XsdDecimal datatypeDecimal = new XsdDecimal ();
298                 static readonly XsdInteger datatypeInteger = new XsdInteger ();
299                 static readonly XsdLong datatypeLong = new XsdLong ();
300                 static readonly XsdInt datatypeInt = new XsdInt ();
301                 static readonly XsdShort datatypeShort = new XsdShort ();
302                 static readonly XsdByte datatypeByte = new XsdByte ();
303                 static readonly XsdNonNegativeInteger datatypeNonNegativeInteger = new XsdNonNegativeInteger ();
304                 static readonly XsdPositiveInteger datatypePositiveInteger = new XsdPositiveInteger ();
305                 static readonly XsdUnsignedLong datatypeUnsignedLong = new XsdUnsignedLong ();
306                 static readonly XsdUnsignedInt datatypeUnsignedInt = new XsdUnsignedInt ();
307                 static readonly XsdUnsignedShort datatypeUnsignedShort = new XsdUnsignedShort ();
308                 static readonly XsdUnsignedByte datatypeUnsignedByte = new XsdUnsignedByte ();
309                 static readonly XsdNonPositiveInteger datatypeNonPositiveInteger = new XsdNonPositiveInteger ();
310                 static readonly XsdNegativeInteger datatypeNegativeInteger = new XsdNegativeInteger ();
311                 static readonly XsdFloat datatypeFloat = new XsdFloat ();
312                 static readonly XsdDouble datatypeDouble = new XsdDouble ();
313                 static readonly XsdBase64Binary datatypeBase64Binary = new XsdBase64Binary ();
314                 static readonly XsdBoolean datatypeBoolean = new XsdBoolean ();
315                 static readonly XsdAnyURI datatypeAnyURI = new XsdAnyURI ();
316                 static readonly XsdDuration datatypeDuration = new XsdDuration ();
317                 static readonly XsdDateTime datatypeDateTime = new XsdDateTime ();
318                 static readonly XsdDate datatypeDate = new XsdDate ();
319                 static readonly XsdTime datatypeTime = new XsdTime ();
320                 static readonly XsdHexBinary datatypeHexBinary = new XsdHexBinary ();
321                 static readonly XsdQName datatypeQName = new XsdQName ();
322                 static readonly XsdGYearMonth datatypeGYearMonth = new XsdGYearMonth ();
323                 static readonly XsdGMonthDay datatypeGMonthDay = new XsdGMonthDay ();
324                 static readonly XsdGYear datatypeGYear = new XsdGYear ();
325                 static readonly XsdGMonth datatypeGMonth = new XsdGMonth ();
326                 static readonly XsdGDay datatypeGDay = new XsdGDay ();
327 #if NET_2_0
328                 static readonly XdtAnyAtomicType datatypeAnyAtomicType
329                         = new XdtAnyAtomicType ();
330                 static readonly XdtUntypedAtomic datatypeUntypedAtomic
331                         = new XdtUntypedAtomic ();
332                 static readonly XdtDayTimeDuration datatypeDayTimeDuration
333                         = new XdtDayTimeDuration ();
334                 static readonly XdtYearMonthDuration datatypeYearMonthDuration
335                         = new XdtYearMonthDuration ();
336 #endif
337
338         }
339 }