5 // John Donagher (john@webmeta.com)
6 // Lluis Sanchez Gual (lluis@ximian.com)
8 // (C) 2002 John Donagher
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System
.Collections
;
35 using System
.Globalization
;
36 using System
.Xml
.Schema
;
37 using System
.Reflection
;
39 namespace System
.Xml
.Serialization
41 public class XmlTypeMapping
: XmlMapping
43 private string xmlType
;
44 private string xmlTypeNamespace
;
46 XmlTypeMapping baseMap
;
47 bool multiReferenceType
= false;
51 bool isNullable
= true;
54 ArrayList _derivedTypes
= new ArrayList();
56 internal XmlTypeMapping(string elementName
, string ns
, TypeData typeData
, string xmlType
, string xmlTypeNamespace
)
57 : base (elementName
, ns
)
60 this.xmlType
= xmlType
;
61 this.xmlTypeNamespace
= xmlTypeNamespace
;
65 public string TypeFullName
67 get { return type.FullTypeName; }
70 public string TypeName
72 get { return type.TypeName; }
75 public string XsdTypeName
77 get { return XmlType; }
80 public string XsdTypeNamespace
82 get { return XmlTypeNamespace; }
85 internal TypeData TypeData
90 internal string XmlType
92 get { return xmlType; }
93 set { xmlType = value; }
96 internal string XmlTypeNamespace
98 get { return xmlTypeNamespace ?? string.Empty; }
99 set { xmlTypeNamespace = value; }
102 internal bool HasXmlTypeNamespace
104 get { return xmlTypeNamespace != null; }
107 internal ArrayList DerivedTypes
109 get { return _derivedTypes; }
110 set { _derivedTypes = value; }
113 internal bool MultiReferenceType
115 get { return multiReferenceType; }
116 set { multiReferenceType = value; }
119 internal XmlTypeMapping BaseMap
121 get { return baseMap; }
122 set { baseMap = value; }
125 internal bool IsSimpleType
127 get { return isSimpleType; }
128 set { isSimpleType = value; }
131 internal string Documentation
133 set { documentation = value; }
134 get { return documentation; }
137 internal bool IncludeInSchema
139 get { return includeInSchema; }
140 set { includeInSchema = value; }
143 internal bool IsNullable
145 get { return isNullable; }
146 set { isNullable = value; }
151 get { return isAny; }
152 set { isAny = value; }
155 internal XmlTypeMapping
GetRealTypeMap (Type objectType
)
157 if (TypeData
.SchemaType
== SchemaTypes
.Enum
)
160 // Returns the map for a subtype of this map's type
161 if (TypeData
.Type
== objectType
) return this;
162 for (int n
=0; n
<_derivedTypes
.Count
; n
++) {
163 XmlTypeMapping map
= (XmlTypeMapping
) _derivedTypes
[n
];
164 if (map
.TypeData
.Type
== objectType
) return map
;
170 internal XmlTypeMapping
GetRealElementMap (string name
, string ens
)
172 if (xmlType
== name
&& XmlTypeNamespace
== ens
) return this;
173 foreach (XmlTypeMapping map
in _derivedTypes
)
174 if (map
.xmlType
== name
&& map
.XmlTypeNamespace
== ens
) return map
;
179 internal void UpdateRoot (XmlQualifiedName qname
)
182 this._elementName
= qname
.Name
;
183 this._namespace
= qname
.Namespace
;
189 // Mapping info for XmlSerializable
190 internal class XmlSerializableMapping
: XmlTypeMapping
193 XmlSchemaComplexType _schemaType
;
194 XmlQualifiedName _schemaTypeName
;
196 internal XmlSerializableMapping(XmlRootAttribute root
, string elementName
, string ns
, TypeData typeData
, string xmlType
, string xmlTypeNamespace
)
197 : base(elementName
, ns
, typeData
, xmlType
, xmlTypeNamespace
)
199 XmlSchemaProviderAttribute schemaProvider
= (XmlSchemaProviderAttribute
) Attribute
.GetCustomAttribute (typeData
.Type
, typeof (XmlSchemaProviderAttribute
));
201 if (schemaProvider
!= null) {
202 _schemaTypeName
= XmlQualifiedName
.Empty
;
204 if (schemaProvider
.IsAny
) {
209 string method
= schemaProvider
.MethodName
;
210 MethodInfo mi
= typeData
.Type
.GetMethod (method
, BindingFlags
.Static
| BindingFlags
.Public
| BindingFlags
.FlattenHierarchy
);
212 throw new InvalidOperationException (String
.Format ("Type '{0}' must implement public static method '{1}'", typeData
.Type
, method
));
213 if (!typeof (XmlQualifiedName
).IsAssignableFrom (mi
.ReturnType
) &&
214 // LAMESPEC: it is undocumented. (We don't have to tell users about it in the error message.)
215 // Also do not add such a silly compatibility test to assert that it does not raise an error.
216 !typeof (XmlSchemaComplexType
).IsAssignableFrom (mi
.ReturnType
))
217 throw new InvalidOperationException (String
.Format ("Method '{0}' indicated by XmlSchemaProviderAttribute must have its return type as XmlQualifiedName", method
));
218 XmlSchemaSet xs
= new XmlSchemaSet ();
219 object retVal
= mi
.Invoke (null, new object [] { xs }
);
223 if (retVal
is XmlSchemaComplexType
) {
224 _schemaType
= (XmlSchemaComplexType
) retVal
;
225 if (!_schemaType
.QualifiedName
.IsEmpty
)
226 _schemaTypeName
= _schemaType
.QualifiedName
;
228 _schemaTypeName
= new XmlQualifiedName (xmlType
, xmlTypeNamespace
);
230 else if (retVal
is XmlQualifiedName
) {
231 _schemaTypeName
= (XmlQualifiedName
)retVal
;
234 throw new InvalidOperationException (
235 String
.Format ("Method {0}.{1}() specified by XmlSchemaProviderAttribute has invalid signature: return type must be compatible with System.Xml.XmlQualifiedName.", typeData
.Type
.Name
, method
));
237 // defaultNamespace at XmlReflectionImporter takes precedence for Namespace, but not for XsdTypeNamespace.
238 UpdateRoot (new XmlQualifiedName (root
!= null ? root
.ElementName
: _schemaTypeName
.Name
, root
!= null ? root
.Namespace
: Namespace
?? _schemaTypeName
.Namespace
));
239 XmlTypeNamespace
= _schemaTypeName
.Namespace
;
240 XmlType
= _schemaTypeName
.Name
;
242 if (!_schemaTypeName
.IsEmpty
&& xs
.Count
> 0) {
243 XmlSchema
[] schemas
= new XmlSchema
[xs
.Count
];
244 xs
.CopyTo (schemas
, 0);
245 _schema
= schemas
[0];
251 IXmlSerializable serializable
= (IXmlSerializable
)Activator
.CreateInstance (typeData
.Type
, true);
253 _schema
= serializable
.GetSchema();
254 } catch (Exception
) {
255 // LAMESPEC: .NET has a bad exception catch and swallows it silently.
260 if (_schema
.Id
== null || _schema
.Id
.Length
== 0)
261 throw new InvalidOperationException("Schema Id is missing. The schema returned from " + typeData
.Type
.FullName
+ ".GetSchema() must have an Id.");
265 internal XmlSchema Schema
267 get { return _schema; }
270 internal XmlSchemaType SchemaType
{
271 get { return _schemaType; }
274 internal XmlQualifiedName SchemaTypeName
{
275 get { return _schemaTypeName; }
280 // Mapping info for classes and structs
282 internal class ClassMap
: ObjectMap
284 Hashtable _elements
= new Hashtable ();
285 ArrayList _elementMembers
;
286 Hashtable _attributeMembers
;
287 XmlTypeMapMemberAttribute
[] _attributeMembersArray
;
288 XmlTypeMapElementInfo
[] _elementsByIndex
;
289 ArrayList _flatLists
;
290 ArrayList _allMembers
= new ArrayList ();
291 ArrayList _membersWithDefault
;
292 ArrayList _listMembers
;
293 XmlTypeMapMemberAnyElement _defaultAnyElement
;
294 XmlTypeMapMemberAnyAttribute _defaultAnyAttribute
;
295 XmlTypeMapMemberNamespaces _namespaceDeclarations
;
296 XmlTypeMapMember _xmlTextCollector
;
297 XmlTypeMapMember _returnMember
;
298 bool _ignoreMemberNamespace
;
299 bool _canBeSimpleType
= true;
300 bool? _isOrderDependentMap
;
302 public void AddMember (XmlTypeMapMember member
)
304 // If GlobalIndex has not been set, set it now
305 if (member
.GlobalIndex
== -1)
306 member
.GlobalIndex
= _allMembers
.Count
;
308 _allMembers
.Add (member
);
310 if (!(member
.DefaultValue
is System
.DBNull
) && member
.DefaultValue
!= null) {
311 if (_membersWithDefault
== null) _membersWithDefault
= new ArrayList ();
312 _membersWithDefault
.Add (member
);
315 if (member
.IsReturnValue
)
316 _returnMember
= member
;
318 if (member
is XmlTypeMapMemberAttribute
)
320 XmlTypeMapMemberAttribute atm
= (XmlTypeMapMemberAttribute
)member
;
321 if (_attributeMembers
== null) _attributeMembers
= new Hashtable();
322 string key
= BuildKey (atm
.AttributeName
, atm
.Namespace
, -1);
323 if (_attributeMembers
.ContainsKey (key
))
324 throw new InvalidOperationException ("The XML attribute named '" + atm
.AttributeName
+ "' from namespace '" + atm
.Namespace
+ "' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the attribute.");
325 member
.Index
= _attributeMembers
.Count
;
326 _attributeMembers
.Add (key
, member
);
329 else if (member
is XmlTypeMapMemberFlatList
)
331 RegisterFlatList ((XmlTypeMapMemberFlatList
)member
);
333 else if (member
is XmlTypeMapMemberAnyElement
)
335 XmlTypeMapMemberAnyElement mem
= (XmlTypeMapMemberAnyElement
) member
;
336 if (mem
.IsDefaultAny
) _defaultAnyElement
= mem
;
337 if (mem
.TypeData
.IsListType
) RegisterFlatList (mem
);
339 else if (member
is XmlTypeMapMemberAnyAttribute
)
341 _defaultAnyAttribute
= (XmlTypeMapMemberAnyAttribute
) member
;
344 else if (member
is XmlTypeMapMemberNamespaces
)
346 _namespaceDeclarations
= (XmlTypeMapMemberNamespaces
) member
;
350 if (member
is XmlTypeMapMemberElement
&& ((XmlTypeMapMemberElement
)member
).IsXmlTextCollector
)
352 if (_xmlTextCollector
!= null) throw new InvalidOperationException ("XmlTextAttribute can only be applied once in a class");
353 _xmlTextCollector
= member
;
356 if (_elementMembers
== null) {
357 _elementMembers
= new ArrayList();
358 _elements
= new Hashtable();
361 member
.Index
= _elementMembers
.Count
;
362 _elementMembers
.Add (member
);
364 ICollection elemsInfo
= ((XmlTypeMapMemberElement
)member
).ElementInfo
;
365 foreach (XmlTypeMapElementInfo elem
in elemsInfo
)
367 string key
= BuildKey (elem
.ElementName
, elem
.Namespace
, elem
.ExplicitOrder
);
368 if (_elements
.ContainsKey (key
))
369 throw new InvalidOperationException ("The XML element named '" + elem
.ElementName
+ "' from namespace '" + elem
.Namespace
+ "' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the element.");
370 _elements
.Add (key
, elem
);
373 if (member
.TypeData
.IsListType
&& member
.TypeData
.Type
!= null && !member
.TypeData
.Type
.IsArray
) {
374 if (_listMembers
== null) _listMembers
= new ArrayList ();
375 _listMembers
.Add (member
);
379 void RegisterFlatList (XmlTypeMapMemberExpandable member
)
381 if (_flatLists
== null) _flatLists
= new ArrayList ();
382 member
.FlatArrayIndex
= _flatLists
.Count
;
383 _flatLists
.Add (member
);
386 public XmlTypeMapMemberAttribute
GetAttribute (string name
, string ns
)
388 if (_attributeMembers
== null) return null;
389 return (XmlTypeMapMemberAttribute
)_attributeMembers
[BuildKey (name
,ns
, -1)];
392 public XmlTypeMapElementInfo
GetElement(string name
, string ns
, int minimalOrder
)
394 if (_elements
== null)
397 XmlTypeMapElementInfo selected
= null;
398 foreach (XmlTypeMapElementInfo info
in _elements
.Values
) {
399 if (info
.ElementName
== name
&& info
.Namespace
== ns
) {
400 if (info
.ExplicitOrder
< minimalOrder
)
403 if (selected
== null || selected
.ExplicitOrder
> info
.ExplicitOrder
) {
412 public XmlTypeMapElementInfo
GetElement(string name
, string ns
)
414 if (_elements
== null) return null;
416 foreach (XmlTypeMapElementInfo info
in _elements
.Values
)
417 if (info
.ElementName
== name
&& info
.Namespace
== ns
)
423 public XmlTypeMapElementInfo
GetElement (int index
)
425 if (_elements
== null) return null;
427 if (_elementsByIndex
== null)
429 _elementsByIndex
= new XmlTypeMapElementInfo
[_elementMembers
.Count
];
430 foreach (XmlTypeMapMemberElement mem
in _elementMembers
)
432 if (mem
.ElementInfo
.Count
!= 1)
433 throw new InvalidOperationException ("Read by order only possible for encoded/bare format");
435 _elementsByIndex
[mem
.Index
] = (XmlTypeMapElementInfo
) mem
.ElementInfo
[0];
438 if (index
>= _elementMembers
.Count
)
440 return _elementsByIndex
[index
];
443 private string BuildKey (string name
, string ns
, int explicitOrder
)
445 if (_ignoreMemberNamespace
) return name
;
446 else return name
+ " / " + ns
+ (explicitOrder
< 0 ? "" : "/" + explicitOrder
);
449 public ICollection AllElementInfos
451 get { return _elements.Values; }
455 public bool IgnoreMemberNamespace
457 get { return _ignoreMemberNamespace; }
458 set { _ignoreMemberNamespace = value; }
461 public bool IsOrderDependentMap
{
463 if (_isOrderDependentMap
== null) {
464 _isOrderDependentMap
= false;
465 foreach (XmlTypeMapElementInfo ei
in _elements
.Values
)
466 if (ei
.ExplicitOrder
>= 0) {
467 _isOrderDependentMap
= true;
471 return (bool) _isOrderDependentMap
;
475 public XmlTypeMapMember
FindMember (string name
)
477 for (int n
=0; n
<_allMembers
.Count
; n
++)
478 if (((XmlTypeMapMember
)_allMembers
[n
]).Name
== name
) return (XmlTypeMapMember
)_allMembers
[n
];
482 public XmlTypeMapMemberAnyElement DefaultAnyElementMember
484 get { return _defaultAnyElement; }
487 public XmlTypeMapMemberAnyAttribute DefaultAnyAttributeMember
489 get { return _defaultAnyAttribute; }
492 public XmlTypeMapMemberNamespaces NamespaceDeclarations
494 get { return _namespaceDeclarations; }
497 public ICollection AttributeMembers
501 if (_attributeMembers
== null) return null;
502 if (_attributeMembersArray
!= null) return _attributeMembersArray
;
504 _attributeMembersArray
= new XmlTypeMapMemberAttribute
[_attributeMembers
.Count
];
505 foreach (XmlTypeMapMemberAttribute mem
in _attributeMembers
.Values
)
506 _attributeMembersArray
[mem
.Index
] = mem
;
507 return _attributeMembersArray
;
511 public ICollection ElementMembers
513 get { return _elementMembers; }
516 public ArrayList AllMembers
518 get { return _allMembers; }
521 public ArrayList FlatLists
523 get { return _flatLists; }
526 public ArrayList MembersWithDefault
528 get { return _membersWithDefault; }
531 public ArrayList ListMembers
533 get { return _listMembers; }
536 public XmlTypeMapMember XmlTextCollector
538 get { return _xmlTextCollector; }
541 public XmlTypeMapMember ReturnMember
543 get { return _returnMember; }
546 public XmlQualifiedName SimpleContentBaseType
550 if (!_canBeSimpleType
|| _elementMembers
== null || _elementMembers
.Count
!= 1) return null;
551 XmlTypeMapMemberElement member
= (XmlTypeMapMemberElement
) _elementMembers
[0];
552 if (member
.ElementInfo
.Count
!= 1) return null;
553 XmlTypeMapElementInfo einfo
= (XmlTypeMapElementInfo
) member
.ElementInfo
[0];
554 if (!einfo
.IsTextElement
) return null;
555 if (member
.TypeData
.SchemaType
== SchemaTypes
.Primitive
|| member
.TypeData
.SchemaType
== SchemaTypes
.Enum
)
556 return new XmlQualifiedName (einfo
.TypeData
.XmlType
, einfo
.DataTypeNamespace
);
561 public void SetCanBeSimpleType (bool can
)
563 _canBeSimpleType
= can
;
566 public bool HasSimpleContent
570 return SimpleContentBaseType
!= null;
576 // Mapping info for arrays and lists
578 internal class ListMap
: ObjectMap
580 XmlTypeMapElementInfoList _itemInfo
;
581 bool _gotNestedMapping
;
582 XmlTypeMapping _nestedArrayMapping
;
583 string _choiceMember
;
585 public bool IsMultiArray
589 return (NestedArrayMapping
!= null);
593 public string ChoiceMember
595 get { return _choiceMember; }
596 set { _choiceMember = value; }
599 public XmlTypeMapping NestedArrayMapping
603 if (_gotNestedMapping
) return _nestedArrayMapping
;
604 _gotNestedMapping
= true;
606 _nestedArrayMapping
= ((XmlTypeMapElementInfo
)_itemInfo
[0]).MappedType
;
608 if (_nestedArrayMapping
== null) return null;
610 if (_nestedArrayMapping
.TypeData
.SchemaType
!= SchemaTypes
.Array
) {
611 _nestedArrayMapping
= null; return null;
614 foreach (XmlTypeMapElementInfo elem
in _itemInfo
)
615 if (elem
.MappedType
!= _nestedArrayMapping
) {
616 _nestedArrayMapping
= null;
620 return _nestedArrayMapping
;
624 public XmlTypeMapElementInfoList ItemInfo
627 get { return _itemInfo; }
628 set { _itemInfo = value; }
631 public XmlTypeMapElementInfo
FindElement (object ob
, int index
, object memberValue
)
633 if (_itemInfo
.Count
== 1)
634 return (XmlTypeMapElementInfo
) _itemInfo
[0];
635 else if (_choiceMember
!= null && index
!= -1)
637 Array values
= (Array
) XmlTypeMapMember
.GetValue (ob
, _choiceMember
);
638 if (values
== null || index
>= values
.Length
)
639 throw new InvalidOperationException ("Invalid or missing choice enum value in member '" + _choiceMember
+ "'.");
640 object val
= values
.GetValue (index
);
641 foreach (XmlTypeMapElementInfo elem
in _itemInfo
)
642 if (elem
.ChoiceValue
!= null && elem
.ChoiceValue
.Equals (val
))
647 if (memberValue
== null) return null;
648 Type type
= memberValue
.GetType();
649 XmlTypeMapElementInfo bestMatch
= null;
650 foreach (XmlTypeMapElementInfo elem
in _itemInfo
) {
651 if (elem
.TypeData
.Type
== type
)
653 if (elem
.TypeData
.Type
.IsAssignableFrom (type
) &&
654 (bestMatch
== null || elem
.TypeData
.Type
.IsAssignableFrom (bestMatch
.TypeData
.Type
)))
662 public XmlTypeMapElementInfo
FindElement (string elementName
, string ns
)
664 foreach (XmlTypeMapElementInfo elem
in _itemInfo
)
665 if (elem
.ElementName
== elementName
&& elem
.Namespace
== ns
) return elem
;
669 public XmlTypeMapElementInfo
FindTextElement ()
671 foreach (XmlTypeMapElementInfo elem
in _itemInfo
)
672 if (elem
.IsTextElement
) return elem
;
676 public string GetSchemaArrayName ()
678 XmlTypeMapElementInfo einfo
= (XmlTypeMapElementInfo
) _itemInfo
[0];
679 if (einfo
.MappedType
!= null) return TypeTranslator
.GetArrayName (einfo
.MappedType
.XmlType
);
680 else return TypeTranslator
.GetArrayName (einfo
.TypeData
.XmlType
);
683 public void GetArrayType (int itemCount
, out string localName
, out string ns
)
686 if (itemCount
!= -1) arrayDim
= "[" + itemCount
+ "]";
687 else arrayDim
= "[]";
689 XmlTypeMapElementInfo info
= (XmlTypeMapElementInfo
) _itemInfo
[0];
690 if (info
.TypeData
.SchemaType
== SchemaTypes
.Array
)
693 ((ListMap
)info
.MappedType
.ObjectMap
).GetArrayType (-1, out nm
, out ns
);
694 localName
= nm
+ arrayDim
;
698 if (info
.MappedType
!= null)
700 localName
= info
.MappedType
.XmlType
+ arrayDim
;
701 ns
= info
.MappedType
.Namespace
;
705 localName
= info
.TypeData
.XmlType
+ arrayDim
;
706 ns
= info
.DataTypeNamespace
;
711 public override bool Equals (object other
)
713 ListMap lmap
= other
as ListMap
;
714 if (lmap
== null) return false;
716 if (_itemInfo
.Count
!= lmap
._itemInfo
.Count
) return false;
717 for (int n
=0; n
<_itemInfo
.Count
; n
++)
718 if (!_itemInfo
[n
].Equals (lmap
._itemInfo
[n
])) return false;
722 public override int GetHashCode ()
724 return base.GetHashCode ();
728 internal class EnumMap
: ObjectMap
730 readonly EnumMapMember
[] _members
;
731 readonly bool _isFlags
;
732 readonly string[] _enumNames
= null;
733 readonly string[] _xmlNames
= null;
734 readonly long[] _values
= null;
736 public class EnumMapMember
738 readonly string _xmlName
;
739 readonly string _enumName
;
740 readonly long _value
;
741 string _documentation
;
743 public EnumMapMember (string xmlName
, string enumName
)
744 : this (xmlName
, enumName
, 0)
748 public EnumMapMember (string xmlName
, string enumName
, long value)
751 _enumName
= enumName
;
755 public string XmlName
757 get { return _xmlName; }
760 public string EnumName
762 get { return _enumName; }
767 get { return _value; }
770 public string Documentation
772 get { return _documentation; }
773 set { _documentation = value; }
777 public EnumMap (EnumMapMember
[] members
, bool isFlags
)
782 _enumNames
= new string[_members
.Length
];
783 _xmlNames
= new string[_members
.Length
];
784 _values
= new long[_members
.Length
];
786 for (int i
= 0; i
< _members
.Length
; i
++) {
787 EnumMapMember mem
= _members
[i
];
788 _enumNames
[i
] = mem
.EnumName
;
789 _xmlNames
[i
] = mem
.XmlName
;
790 _values
[i
] = mem
.Value
;
796 get { return _isFlags; }
799 public EnumMapMember
[] Members
801 get { return _members; }
804 public string[] EnumNames
811 public string[] XmlNames
825 public string GetXmlName (string typeName
, object enumValue
)
827 if (enumValue
is string) {
828 throw new InvalidCastException ();
834 value = ((IConvertible
) enumValue
).ToInt64 (CultureInfo
.CurrentCulture
);
835 } catch (FormatException
) {
836 throw new InvalidCastException ();
839 for (int i
= 0; i
< Values
.Length
; i
++) {
840 if (Values
[i
] == value)
844 if (IsFlags
&& value == 0)
847 string xmlName
= string.Empty
;
849 xmlName
= XmlCustomFormatter
.FromEnum (value, XmlNames
, Values
, typeName
);
852 if (xmlName
.Length
== 0) {
853 throw new InvalidOperationException (string.Format(CultureInfo
.CurrentCulture
,
854 "'{0}' is not a valid value for {1}.", value, typeName
));
859 public string GetEnumName (string typeName
, string xmlName
)
862 xmlName
= xmlName
.Trim ();
863 if (xmlName
.Length
== 0)
866 System
.Text
.StringBuilder sb
= new System
.Text
.StringBuilder ();
867 string[] enumNames
= xmlName
.Split (null);
868 foreach (string name
in enumNames
) {
869 if (name
== string.Empty
) continue;
870 string foundEnumValue
= null;
871 for (int i
= 0; i
< XmlNames
.Length
; i
++)
872 if (XmlNames
[i
] == name
) {
873 foundEnumValue
= EnumNames
[i
];
877 if (foundEnumValue
!= null) {
880 sb
.Append (foundEnumValue
);
882 throw new InvalidOperationException (string.Format (CultureInfo
.CurrentCulture
,
883 "'{0}' is not a valid value for {1}.", name
, typeName
));
886 return sb
.ToString ();
889 foreach (EnumMapMember mem
in _members
)
890 if (mem
.XmlName
== xmlName
) return mem
.EnumName
;