2 // XmlTypeMapMember.cs:
5 // Lluis Sanchez Gual (lluis@ximian.com)
7 // (C) 2002, 2003 Ximian, Inc. http://www.ximian.com
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Collections;
33 using System.Reflection;
35 namespace System.Xml.Serialization
38 // A member of a class that must be serialized
40 internal class XmlTypeMapMember
44 int _globalIndex = -1;
45 int _specifiedGlobalIndex = -1;
48 MemberInfo _specifiedMember;
49 MethodInfo _shouldSerialize;
50 object _defaultValue = System.DBNull.Value;
54 const int OPTIONAL = 1;
55 const int RETURN_VALUE = 2;
58 public XmlTypeMapMember()
65 set { _name = value; }
68 public object DefaultValue
70 get { return _defaultValue; }
71 set { _defaultValue = value; }
74 public string Documentation
76 set { documentation = value; }
77 get { return documentation; }
80 public bool IsReadOnly (Type type)
82 if (_member == null) InitMember (type);
83 return (_member is PropertyInfo) && !((PropertyInfo)_member).CanWrite;
86 public static object GetValue (object ob, string name)
88 MemberInfo[] mems = ob.GetType().GetMember (name, BindingFlags.Instance|BindingFlags.Public);
89 if (mems[0] is PropertyInfo) return ((PropertyInfo)mems[0]).GetValue (ob, null);
90 else return ((FieldInfo)mems[0]).GetValue (ob);
93 public object GetValue (object ob)
95 if (_member == null) InitMember (ob.GetType());
96 if (_member is PropertyInfo) return ((PropertyInfo)_member).GetValue (ob, null);
97 else return ((FieldInfo)_member).GetValue (ob);
100 public void SetValue (object ob, object value)
102 if (_member == null) InitMember (ob.GetType());
103 _typeData.ConvertForAssignment (ref value);
104 if (_member is PropertyInfo) ((PropertyInfo)_member).SetValue (ob, value, null);
105 else ((FieldInfo)_member).SetValue (ob, value);
108 public static void SetValue (object ob, string name, object value)
110 MemberInfo[] mems = ob.GetType().GetMember (name, BindingFlags.Instance|BindingFlags.Public);
111 if (mems[0] is PropertyInfo) ((PropertyInfo)mems[0]).SetValue (ob, value, null);
112 else ((FieldInfo)mems[0]).SetValue (ob, value);
115 void InitMember (Type type)
117 MemberInfo[] mems = type.GetMember (_name, BindingFlags.Instance|BindingFlags.Public);
120 mems = type.GetMember (_name + "Specified", BindingFlags.Instance|BindingFlags.Public);
121 if (mems.Length > 0) _specifiedMember = mems[0];
122 if (_specifiedMember is PropertyInfo && !((PropertyInfo) _specifiedMember).CanRead)
123 _specifiedMember = null;
125 var method = type.GetMethod ("ShouldSerialize" + _name, BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null);
126 if (method != null && method.ReturnType == typeof (bool) && !method.IsGenericMethod)
127 _shouldSerialize = method;
130 public TypeData TypeData
132 get { return _typeData; }
133 set { _typeData = value; }
138 get { return _index; }
139 set { _index = value; }
142 public int GlobalIndex
144 get { return _globalIndex; }
145 set { _globalIndex = value; }
148 public int SpecifiedGlobalIndex
150 get { return _specifiedGlobalIndex; }
153 public bool IsOptionalValueType
155 get { return (_flags & OPTIONAL) != 0; }
156 set { _flags = value ? (_flags | OPTIONAL) : (_flags & ~OPTIONAL); }
159 public bool IsReturnValue
161 get { return (_flags & RETURN_VALUE) != 0; }
162 set { _flags = value ? (_flags | RETURN_VALUE) : (_flags & ~RETURN_VALUE); }
167 get { return (_flags & IGNORE) != 0; }
168 set { _flags = value ? (_flags | IGNORE) : (_flags & ~IGNORE); }
171 public void CheckOptionalValueType (Type type)
173 // Used when reflecting a type
174 if (_member == null) InitMember (type);
175 IsOptionalValueType = (_specifiedMember != null || _shouldSerialize != null);
178 public void CheckOptionalValueType (XmlReflectionMember[] members)
180 // Used when reflecting a list of members (e.g. web service parameters)
181 for (int n=0; n<members.Length; n++) {
182 XmlReflectionMember m = members [n];
183 if (m.MemberName == Name + "Specified" && m.MemberType == typeof(bool) && m.XmlAttributes.XmlIgnore) {
184 IsOptionalValueType = true;
185 _specifiedGlobalIndex = n;
191 public bool HasSpecified {
192 get { return _specifiedMember != null; }
195 public bool HasShouldSerialize {
196 get { return _shouldSerialize != null; }
199 public bool GetValueSpecified (object ob)
201 if (_specifiedGlobalIndex != -1) {
202 object[] array = (object[])ob;
203 return _specifiedGlobalIndex < array.Length && (bool) array [_specifiedGlobalIndex];
205 bool specified = true;
207 if (_specifiedMember != null) {
208 if (_specifiedMember is PropertyInfo)
209 specified = (bool)((PropertyInfo)_specifiedMember).GetValue (ob, null);
211 specified = (bool)((FieldInfo)_specifiedMember).GetValue (ob);
213 if (_shouldSerialize != null)
214 specified = specified && (bool)_shouldSerialize.Invoke (ob, new object [] {});
219 public bool IsValueSpecifiedSettable () {
220 if (_specifiedMember is PropertyInfo)
221 return ((PropertyInfo) _specifiedMember).CanWrite;
223 if (_specifiedMember is FieldInfo)
224 return ((FieldInfo) _specifiedMember).IsInitOnly;
229 public void SetValueSpecified (object ob, bool value)
231 if (_specifiedGlobalIndex != -1)
232 ((object[])ob) [_specifiedGlobalIndex] = value;
233 else if (_specifiedMember is PropertyInfo) {
234 if (!((PropertyInfo) _specifiedMember).CanWrite)
236 ((PropertyInfo)_specifiedMember).SetValue (ob, value, null);
237 } else if (_specifiedMember is FieldInfo)
238 ((FieldInfo)_specifiedMember).SetValue (ob, value);
241 public virtual bool RequiresNullable {
242 get { return false; }