1 //------------------------------------------------------------------------------
2 // <copyright file="XmlSchemaDatatype.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 // <owner current="true" primary="true">Microsoft</owner>
6 //------------------------------------------------------------------------------
7 using System.Collections;
8 using System.Diagnostics;
9 using System.ComponentModel;
12 using System.Globalization;
15 namespace System.Xml.Schema {
17 /// <include file='doc\XmlSchemaDatatype.uex' path='docs/doc[@for="XmlSchemaDatatype"]/*' />
19 /// <para>[To be supplied.]</para>
21 public abstract class XmlSchemaDatatype {
23 /// <include file='doc\XmlSchemaDatatype.uex' path='docs/doc[@for="XmlSchemaDatatype.ValueType"]/*' />
25 /// <para>[To be supplied.]</para>
27 public abstract Type ValueType { get; }
29 /// <include file='doc\XmlSchemaDatatype.uex' path='docs/doc[@for="XmlSchemaDatatype.TokenizedType"]/*' />
31 /// <para>[To be supplied.]</para>
33 public abstract XmlTokenizedType TokenizedType { get; }
35 /// <include file='doc\XmlSchemaDatatype.uex' path='docs/doc[@for="XmlSchemaDatatype.ParseValue"]/*' />
37 /// <para>[To be supplied.]</para>
39 public abstract object ParseValue(string s, XmlNameTable nameTable, IXmlNamespaceResolver nsmgr);
41 /// <include file='doc\XmlSchemaDatatype.uex' path='docs/doc[@for="XmlSchemaDatatype.Variety"]/*' />
43 /// <para>[To be supplied.]</para>
45 public virtual XmlSchemaDatatypeVariety Variety { get { return XmlSchemaDatatypeVariety.Atomic; } }
48 /// <include file='doc\XmlSchemaDatatype.uex' path='docs/doc[@for="XmlSchemaDatatype.ChangeType1"]/*' />
50 /// <para>[To be supplied.]</para>
52 public virtual object ChangeType(object value, Type targetType) {
54 throw new ArgumentNullException("value");
56 if (targetType == null) {
57 throw new ArgumentNullException("targetType");
59 return ValueConverter.ChangeType(value, targetType);
62 /// <include file='doc\XmlSchemaDatatype.uex' path='docs/doc[@for="XmlSchemaDatatype.ChangeType2"]/*' />
64 /// <para>[To be supplied.]</para>
66 public virtual object ChangeType(object value, Type targetType, IXmlNamespaceResolver namespaceResolver) {
68 throw new ArgumentNullException("value");
70 if (targetType == null) {
71 throw new ArgumentNullException("targetType");
73 if (namespaceResolver == null) {
74 throw new ArgumentNullException("namespaceResolver");
76 return ValueConverter.ChangeType(value, targetType, namespaceResolver);
79 /// <include file='doc\XmlSchemaDatatype.uex' path='docs/doc[@for="XmlSchemaDatatype.TypeCode"]/*' />
81 /// <para>[To be supplied.]</para>
83 public virtual XmlTypeCode TypeCode { get { return XmlTypeCode.None; } }
85 /// <include file='doc\XmlSchemaDatatype.uex' path='docs/doc[@for="XmlSchemaDatatype.IsDerivedFrom"]/*' />
87 /// <para>[To be supplied.]</para>
89 public virtual bool IsDerivedFrom(XmlSchemaDatatype datatype) {
93 internal abstract bool HasLexicalFacets { get; }
95 internal abstract bool HasValueFacets { get; }
97 internal abstract XmlValueConverter ValueConverter { get; }
99 internal abstract RestrictionFacets Restriction { get; set; }
101 internal abstract int Compare(object value1, object value2);
103 internal abstract object ParseValue(string s, Type typDest, XmlNameTable nameTable, IXmlNamespaceResolver nsmgr);
105 internal abstract object ParseValue(string s, XmlNameTable nameTable, IXmlNamespaceResolver nsmgr, bool createAtomicValue);
107 internal abstract Exception TryParseValue(string s, XmlNameTable nameTable, IXmlNamespaceResolver nsmgr, out object typedValue);
109 internal abstract Exception TryParseValue(object value, XmlNameTable nameTable, IXmlNamespaceResolver namespaceResolver, out object typedValue);
111 internal abstract FacetsChecker FacetsChecker { get; }
113 internal abstract XmlSchemaWhiteSpace BuiltInWhitespaceFacet { get; }
115 internal abstract XmlSchemaDatatype DeriveByRestriction(XmlSchemaObjectCollection facets, XmlNameTable nameTable, XmlSchemaType schemaType) ;
117 internal abstract XmlSchemaDatatype DeriveByList(XmlSchemaType schemaType) ;
119 internal abstract void VerifySchemaValid(XmlSchemaObjectTable notations, XmlSchemaObject caller) ;
121 internal abstract bool IsEqual(object o1, object o2) ;
123 internal abstract bool IsComparable(XmlSchemaDatatype dtype) ;
125 //Error message helper
126 internal string TypeCodeString {
128 string typeCodeString = string.Empty;
129 XmlTypeCode typeCode = this.TypeCode;
130 switch(this.Variety) {
131 case XmlSchemaDatatypeVariety.List:
132 if (typeCode == XmlTypeCode.AnyAtomicType) { //List of union
133 typeCodeString = "List of Union";
136 typeCodeString = "List of " + TypeCodeToString(typeCode);
140 case XmlSchemaDatatypeVariety.Union:
141 typeCodeString = "Union";
144 case XmlSchemaDatatypeVariety.Atomic:
145 if (typeCode == XmlTypeCode.AnyAtomicType) {
146 typeCodeString = "anySimpleType";
149 typeCodeString = TypeCodeToString(typeCode);
153 return typeCodeString;
157 internal string TypeCodeToString(XmlTypeCode typeCode) {
159 case XmlTypeCode.None:
161 case XmlTypeCode.Item:
163 case XmlTypeCode.AnyAtomicType:
164 return "AnyAtomicType";
165 case XmlTypeCode.String:
167 case XmlTypeCode.Boolean:
169 case XmlTypeCode.Decimal:
171 case XmlTypeCode.Float:
173 case XmlTypeCode.Double:
175 case XmlTypeCode.Duration:
177 case XmlTypeCode.DateTime:
179 case XmlTypeCode.Time:
181 case XmlTypeCode.Date:
183 case XmlTypeCode.GYearMonth:
185 case XmlTypeCode.GYear:
187 case XmlTypeCode.GMonthDay:
189 case XmlTypeCode.GDay:
191 case XmlTypeCode.GMonth:
193 case XmlTypeCode.HexBinary:
195 case XmlTypeCode.Base64Binary:
196 return "Base64Binary";
197 case XmlTypeCode.AnyUri:
199 case XmlTypeCode.QName:
201 case XmlTypeCode.Notation:
203 case XmlTypeCode.NormalizedString:
204 return "NormalizedString";
205 case XmlTypeCode.Token:
207 case XmlTypeCode.Language:
209 case XmlTypeCode.NmToken:
211 case XmlTypeCode.Name:
213 case XmlTypeCode.NCName:
217 case XmlTypeCode.Idref:
219 case XmlTypeCode.Entity:
221 case XmlTypeCode.Integer:
223 case XmlTypeCode.NonPositiveInteger:
224 return "NonPositiveInteger";
225 case XmlTypeCode.NegativeInteger:
226 return "NegativeInteger";
227 case XmlTypeCode.Long:
229 case XmlTypeCode.Int:
231 case XmlTypeCode.Short:
233 case XmlTypeCode.Byte:
235 case XmlTypeCode.NonNegativeInteger:
236 return "NonNegativeInteger";
237 case XmlTypeCode.UnsignedLong:
238 return "UnsignedLong";
239 case XmlTypeCode.UnsignedInt:
240 return "UnsignedInt";
241 case XmlTypeCode.UnsignedShort:
242 return "UnsignedShort";
243 case XmlTypeCode.UnsignedByte:
244 return "UnsignedByte";
245 case XmlTypeCode.PositiveInteger:
246 return "PositiveInteger";
249 return typeCode.ToString();
253 internal static string ConcatenatedToString(object value) {
254 Type t = value.GetType();
255 string stringValue = string.Empty;
256 if (t == typeof(IEnumerable) && t != typeof(System.String)) {
257 StringBuilder bldr = new StringBuilder();
258 IEnumerator enumerator = (value as IEnumerable).GetEnumerator();
259 if (enumerator.MoveNext()) {
261 Object cur = enumerator.Current;
262 if (cur is IFormattable) {
263 bldr.Append( ((IFormattable)cur).ToString("", CultureInfo.InvariantCulture) );
266 bldr.Append(cur.ToString());
268 while(enumerator.MoveNext()) {
270 cur = enumerator.Current;
271 if (cur is IFormattable) {
272 bldr.Append( ((IFormattable)cur).ToString("", CultureInfo.InvariantCulture) );
275 bldr.Append(cur.ToString());
279 stringValue = bldr.ToString();
282 else if (value is IFormattable) {
283 stringValue = ((IFormattable)value).ToString("", CultureInfo.InvariantCulture);
286 stringValue = value.ToString();
291 internal static XmlSchemaDatatype FromXmlTokenizedType(XmlTokenizedType token) {
292 return DatatypeImplementation.FromXmlTokenizedType(token);
295 internal static XmlSchemaDatatype FromXmlTokenizedTypeXsd(XmlTokenizedType token) {
296 return DatatypeImplementation.FromXmlTokenizedTypeXsd(token);
299 internal static XmlSchemaDatatype FromXdrName(string name) {
300 return DatatypeImplementation.FromXdrName(name);
303 internal static XmlSchemaDatatype DeriveByUnion(XmlSchemaSimpleType[] types, XmlSchemaType schemaType) {
304 return DatatypeImplementation.DeriveByUnion(types, schemaType);
307 internal static string XdrCanonizeUri(string uri, XmlNameTable nameTable, SchemaNames schemaNames) {
310 bool convert = false;
312 if (uri.Length > 5 && uri.StartsWith("uuid:", StringComparison.Ordinal)) {
315 else if (uri.Length > 9 && uri.StartsWith("urn:uuid:", StringComparison.Ordinal)) {
321 canonicalUri = nameTable.Add(uri.Substring(0, offset) + uri.Substring(offset, uri.Length - offset).ToUpper(CultureInfo.InvariantCulture));
328 Ref.Equal(schemaNames.NsDataTypeAlias, canonicalUri) ||
329 Ref.Equal(schemaNames.NsDataTypeOld , canonicalUri)
331 canonicalUri = schemaNames.NsDataType;
333 else if (Ref.Equal(schemaNames.NsXdrAlias, canonicalUri)) {
334 canonicalUri = schemaNames.NsXdr;
341 private bool CanConvert(object value, System.Type inputType, System.Type defaultType, out string resId) {
343 decimal decimalValue;
344 //TypeCode defaultTypeCode = Type.GetTypeCode(defaultType);
345 if (IsIntegralType(this.TypeCode)){
346 switch (Type.GetTypeCode(inputType)) {
347 case System.TypeCode.Single:
348 case System.TypeCode.Double:
349 decimalValue = new Decimal((double)value);
350 goto case System.TypeCode.Decimal;
351 case System.TypeCode.Decimal:
352 decimalValue = (decimal)value;
353 if (decimal.Truncate(decimalValue) != decimalValue) { //HasFractionDigits
354 resId = Res.Sch_XmlTypeHasFraction;
363 else if (this.TypeCode == XmlTypeCode.Boolean) {
364 if (IsNumericType(inputType)) {
365 decimalValue = (decimal)value;
366 if (decimalValue == 0 || decimalValue == 1) {
369 resId = Res.Sch_InvalidBoolean;
376 private bool IsIntegralType(XmlTypeCode defaultTypeCode) {
377 switch (defaultTypeCode) {
378 case XmlTypeCode.Integer:
379 case XmlTypeCode.NegativeInteger:
380 case XmlTypeCode.NonNegativeInteger:
381 case XmlTypeCode.NonPositiveInteger:
382 case XmlTypeCode.PositiveInteger:
383 case XmlTypeCode.Long:
384 case XmlTypeCode.Int:
385 case XmlTypeCode.Short:
386 case XmlTypeCode.Byte:
387 case XmlTypeCode.UnsignedLong:
388 case XmlTypeCode.UnsignedInt:
389 case XmlTypeCode.UnsignedShort:
390 case XmlTypeCode.UnsignedByte:
397 private bool IsNumericType(System.Type inputType) {
398 switch (Type.GetTypeCode(inputType)) {
399 case System.TypeCode.Decimal:
400 case System.TypeCode.Double:
401 case System.TypeCode.Single:
402 case System.TypeCode.SByte:
403 case System.TypeCode.Byte:
404 case System.TypeCode.Int16:
405 case System.TypeCode.Int32:
406 case System.TypeCode.Int64:
407 case System.TypeCode.UInt16:
408 case System.TypeCode.UInt32:
409 case System.TypeCode.UInt64: