/Serialization/Descriptors/ArrayDescriptor.cs

http://zeroflag.googlecode.com/ · C# · 276 lines · 137 code · 24 blank · 115 comment · 22 complexity · 0c97f79aac0fdb83aac66d175e77589d MD5 · raw file

  1. #region LGPL License
  2. //********************************************************************
  3. // author: Thomas "zeroflag" Kraemer
  4. // author email: zeroflag >>at<< zeroflag >>dot<< de
  5. //
  6. // Copyright (C) 2006-2009 Thomas "zeroflag" Kraemer
  7. //
  8. // license: (LGPL)
  9. //
  10. // This library is free software; you can redistribute it and/or
  11. // modify it under the terms of the GNU Lesser General Public
  12. // License as published by the Free Software Foundation; either
  13. // version 2.1 of the License, or (at your option) any later version.
  14. //
  15. // This library is distributed in the hope that it will be useful,
  16. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. // Lesser General Public License for more details.
  19. //
  20. // You should have received a copy of the GNU Lesser General Public
  21. // License along with this library; if not, write to the Free Software
  22. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. //
  24. // http://www.gnu.org/licenses/lgpl.html#TOC1
  25. //
  26. //*********************************************************************
  27. #endregion LGPL License
  28. using System;
  29. using System.Collections.Generic;
  30. using System.Text;
  31. namespace zeroflag.Serialization.Descriptors
  32. {
  33. public class ArrayDescriptor : Descriptor<Array>, IListDescriptor
  34. {
  35. //public override Type Type
  36. //{
  37. // get
  38. // {
  39. // return this.Value != null ? this.Value.GetType() : (base.Type == typeof(System.Collections.IEnumerable) ? typeof(System.Collections.Generic.IList<>) : base.Type);
  40. // }
  41. // set
  42. // {
  43. // base.Type = value;
  44. // }
  45. //}
  46. //public override Descriptor Parse(System.Reflection.PropertyInfo info)
  47. //{
  48. // //this.Get = delegate() { return (System.Collections.Generic.IList<T>)info.GetGetMethod().Invoke(this.Owner.GetValue(), null); };
  49. // //this.Set = delegate(T value) { info.GetSetMethod().Invoke(this.Owner.GetValue(), new object[] { value }); };
  50. // return this.Parse();
  51. //}
  52. public const string NameItem = null;
  53. public override void Parse()
  54. {
  55. //if (this.Value != null)
  56. {
  57. CWL( this + " parsing " + ( this.Value ?? this.Type ?? (object)"<null>" ) );
  58. Array arr = this.GetValue();
  59. if ( arr != null )
  60. {
  61. foreach ( object value in arr )
  62. {
  63. Descriptor item = this.Context.Parse( null, this.ItemType, value, this.Value, null );
  64. //item.Name = NameItem;
  65. if ( !this.Inner.Contains( item ) )
  66. this.Inner.Add( item );
  67. }
  68. }
  69. }
  70. }
  71. //protected override object DoGenerate()
  72. //{
  73. // if (this.Value == null)
  74. // this.Value = this.DoCreateInstance();
  75. // IList<T> value = this.GetValue();
  76. // if (value != null && this.Inner.Count > 0)
  77. // {
  78. // value.Clear();
  79. // foreach (Descriptor sub in this.Inner)
  80. // {
  81. // if (sub.Name == NameItem)
  82. // {
  83. // value.Add((T)sub.Generate());
  84. // }
  85. // }
  86. // }
  87. // return this.Value;
  88. //}
  89. public override object GenerateLink()
  90. {
  91. //return base.GenerateLink();
  92. Array arr = this.GetValue();
  93. IArrayCreator ctr = null;
  94. var t = typeof( ArrayCreator<> ).Specialize( this.ItemType );
  95. ctr = (IArrayCreator)t.CreateInstance();
  96. if ( arr != null && arr.Length == this.Inner.Count )
  97. {
  98. try
  99. {
  100. ctr.Array = arr;
  101. }
  102. catch ( Exception exc )
  103. {
  104. Console.WriteLine( exc );
  105. arr = null;
  106. }
  107. }
  108. if ( arr == null || arr.Length != this.Inner.Count )
  109. {
  110. Console.WriteLine( "Creating array..." );
  111. try
  112. {
  113. //Console.WriteLine( "m=" + m );
  114. //m.Invoke( null, new object[] { this.Inner.Count } );
  115. ctr.Create( this.Inner.Count );
  116. this.Value = arr = ctr.Array;
  117. }
  118. catch ( Exception exc )
  119. {
  120. Console.WriteLine( exc );
  121. }
  122. }
  123. if ( arr != null && this.Inner.Count > 0 )
  124. {
  125. //System.Reflection.PropertyInfo indexer = null;
  126. //indexer = arr.GetType().GetProperty( "Item", this.ItemType, new Type[] { typeof( int ) } );
  127. //if ( indexer == null )
  128. // foreach ( var p in arr.GetType().GetProperties() )
  129. // {
  130. // if ( p != null && p.PropertyType == this.ItemType && p.GetIndexParameters().Length == 1 && p.GetIndexParameters()[0].ParameterType == typeof( int ) )
  131. // {
  132. // indexer = p;
  133. // Console.WriteLine( "Manually found indexer: " + indexer );
  134. // break;
  135. // }
  136. // }
  137. //Console.WriteLine( "Found indexer: " + indexer );
  138. int i = 0;
  139. foreach ( Descriptor sub in this.Inner )
  140. {
  141. //if (sub.Name == NameItem)
  142. //{
  143. object item;
  144. //try
  145. {
  146. item = sub.GenerateLink();
  147. }
  148. //catch ( InvalidCastException )
  149. //{
  150. // sub.Value = null;
  151. // sub.GenerateParse();
  152. // sub.GenerateCreate();
  153. // item = (T)sub.GenerateLink();
  154. //}
  155. if ( item != null )
  156. {
  157. ctr[i] = item;
  158. //indexer.SetValue( arr, item, new object[] { i } );
  159. //value.Add( item );
  160. }
  161. //}
  162. i++;
  163. }
  164. }
  165. return this.Value;
  166. }
  167. interface IArrayCreator
  168. {
  169. void Create( int size );
  170. object this[int i] { get; set; }
  171. Array Array { get; set; }
  172. }
  173. class ArrayCreator<T> : IArrayCreator
  174. {
  175. #region Items
  176. private T[] _Items;
  177. /// <summary>
  178. /// The array created.
  179. /// </summary>
  180. public T[] Items
  181. {
  182. get { return _Items; }
  183. set
  184. {
  185. if ( _Items != value )
  186. {
  187. _Items = value;
  188. }
  189. }
  190. }
  191. #endregion Items
  192. public Array Array
  193. {
  194. get
  195. {
  196. return this.Items;
  197. }
  198. set
  199. {
  200. this.Items = (T[])value;
  201. }
  202. }
  203. public void Create( int size )
  204. {
  205. this.CreateArray( size );
  206. }
  207. public T[] CreateArray( int size )
  208. {
  209. return this.Items = new T[size];
  210. }
  211. public object this[int i]
  212. {
  213. get { return this.Items[i]; }
  214. set { this.Items[i] = (T)value; }
  215. }
  216. }
  217. //protected override void SetValue(object on, System.Reflection.PropertyInfo prop)
  218. //{
  219. // this.Value = this.GenerateLink();
  220. // IList<T> value = this.GetValue();
  221. // if (value != null)
  222. // {
  223. // if (prop != null)
  224. // {
  225. // IList<T> onValue = null;
  226. // if ((onValue = prop.GetValue(on, new object[0]) as IList<T>) == null)
  227. // prop.SetValue(on, this.GenerateLink(), new object[] { });
  228. // else
  229. // {
  230. // foreach (T item in value)
  231. // {
  232. // onValue.Add(item);
  233. // }
  234. // }
  235. // }
  236. // }
  237. //}
  238. #region IListDescriptor Members
  239. public Type ItemType
  240. {
  241. get
  242. {
  243. if ( this.Value != null )
  244. return this.Value.GetType().GetElementType();
  245. if ( this.Type != null )
  246. return this.Type.GetElementType();
  247. return null;
  248. }
  249. }
  250. #endregion
  251. }
  252. }