RealWorldTerrainJsonArray.cs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /* INFINITY CODE 2013-2019 */
  2. /* http://www.infinity-code.com */
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Reflection;
  6. using System.Text;
  7. using InfinityCode.RealWorldTerrain.Utils;
  8. namespace InfinityCode.RealWorldTerrain.JSON
  9. {
  10. /// <summary>
  11. /// The wrapper for an array of JSON elements.
  12. /// </summary>
  13. public class RealWorldTerrainJsonArray : RealWorldTerrainJsonItem
  14. {
  15. private List<RealWorldTerrainJsonItem> _items;
  16. private int _count;
  17. public List<RealWorldTerrainJsonItem> items
  18. {
  19. get { return _items; }
  20. }
  21. /// <summary>
  22. /// Count elements
  23. /// </summary>
  24. public int count
  25. {
  26. get { return _count; }
  27. }
  28. public override RealWorldTerrainJsonItem this[int index]
  29. {
  30. get
  31. {
  32. if (index < 0 || index >= _count) return null;
  33. return _items[index];
  34. }
  35. }
  36. public override RealWorldTerrainJsonItem this[string key]
  37. {
  38. get { return Get(key); }
  39. }
  40. /// <summary>
  41. /// Constructor
  42. /// </summary>
  43. public RealWorldTerrainJsonArray()
  44. {
  45. _items = new List<RealWorldTerrainJsonItem>();
  46. }
  47. /// <summary>
  48. /// Adds an element to the array.
  49. /// </summary>
  50. /// <param name="item">Element</param>
  51. public void Add(RealWorldTerrainJsonItem item)
  52. {
  53. _items.Add(item);
  54. _count++;
  55. }
  56. /// <summary>
  57. /// Adds an elements to the array.
  58. /// </summary>
  59. /// <param name="collection">Array of elements</param>
  60. public void AddRange(RealWorldTerrainJsonArray collection)
  61. {
  62. if (collection == null) return;
  63. _items.AddRange(collection._items);
  64. _count += collection._count;
  65. }
  66. public void AddRange(RealWorldTerrainJsonItem collection)
  67. {
  68. AddRange(collection as RealWorldTerrainJsonArray);
  69. }
  70. public RealWorldTerrainJsonObject CreateObject()
  71. {
  72. RealWorldTerrainJsonObject obj = new RealWorldTerrainJsonObject();
  73. Add(obj);
  74. return obj;
  75. }
  76. public override object Deserialize(Type type, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public)
  77. {
  78. if (_count == 0) return null;
  79. if (type.IsArray)
  80. {
  81. Type elementType = type.GetElementType();
  82. Array v = Array.CreateInstance(elementType, _count);
  83. if (_items[0] is RealWorldTerrainJsonObject)
  84. {
  85. IEnumerable<MemberInfo> members = RealWorldTerrainReflectionHelper.GetMembers(elementType, bindingFlags);
  86. for (int i = 0; i < _count; i++)
  87. {
  88. RealWorldTerrainJsonItem child = _items[i];
  89. object item = (child as RealWorldTerrainJsonObject).Deserialize(elementType, members, bindingFlags);
  90. v.SetValue(item, i);
  91. }
  92. }
  93. else
  94. {
  95. for (int i = 0; i < _count; i++)
  96. {
  97. RealWorldTerrainJsonItem child = _items[i];
  98. object item = child.Deserialize(elementType, bindingFlags);
  99. v.SetValue(item, i);
  100. }
  101. }
  102. return v;
  103. }
  104. if (RealWorldTerrainReflectionHelper.IsGenericType(type))
  105. {
  106. Type listType = RealWorldTerrainReflectionHelper.GetGenericArguments(type)[0];
  107. object v = Activator.CreateInstance(type);
  108. if (_items[0] is RealWorldTerrainJsonObject)
  109. {
  110. IEnumerable<MemberInfo> members = RealWorldTerrainReflectionHelper.GetMembers(listType, BindingFlags.Instance | BindingFlags.Public);
  111. for (int i = 0; i < _count; i++)
  112. {
  113. RealWorldTerrainJsonItem child = _items[i];
  114. object item = (child as RealWorldTerrainJsonObject).Deserialize(listType, members);
  115. try
  116. {
  117. MethodInfo methodInfo = RealWorldTerrainReflectionHelper.GetMethod(type, "Add");
  118. if (methodInfo != null) methodInfo.Invoke(v, new[] { item });
  119. }
  120. catch
  121. {
  122. }
  123. }
  124. }
  125. else
  126. {
  127. for (int i = 0; i < _count; i++)
  128. {
  129. RealWorldTerrainJsonItem child = _items[i];
  130. object item = child.Deserialize(listType);
  131. try
  132. {
  133. MethodInfo methodInfo = RealWorldTerrainReflectionHelper.GetMethod(type, "Add");
  134. if (methodInfo != null) methodInfo.Invoke(v, new[] { item });
  135. }
  136. catch
  137. {
  138. }
  139. }
  140. }
  141. return v;
  142. }
  143. return null;
  144. }
  145. private RealWorldTerrainJsonItem Get(string key)
  146. {
  147. if (string.IsNullOrEmpty(key)) return null;
  148. if (key.StartsWith("//"))
  149. {
  150. string k = key.Substring(2);
  151. if (string.IsNullOrEmpty(k) || k.StartsWith("//")) return null;
  152. return GetAll(k);
  153. }
  154. return GetThis(key);
  155. }
  156. private RealWorldTerrainJsonItem GetThis(string key)
  157. {
  158. int kindex;
  159. if (key.Contains("/"))
  160. {
  161. int index = key.IndexOf("/");
  162. string k = key.Substring(0, index);
  163. string nextPart = key.Substring(index + 1);
  164. if (k == "*")
  165. {
  166. RealWorldTerrainJsonArray arr = new RealWorldTerrainJsonArray();
  167. for (int i = 0; i < _count; i++)
  168. {
  169. RealWorldTerrainJsonItem item = _items[i][nextPart];
  170. if (item != null) arr.Add(item);
  171. }
  172. return arr;
  173. }
  174. if (int.TryParse(k, out kindex))
  175. {
  176. if (kindex < 0 || kindex >= _count) return null;
  177. RealWorldTerrainJsonItem item = _items[kindex];
  178. return item[nextPart];
  179. }
  180. }
  181. if (key == "*") return this;
  182. if (int.TryParse(key, out kindex)) return this[kindex];
  183. return null;
  184. }
  185. public override RealWorldTerrainJsonItem GetAll(string k)
  186. {
  187. RealWorldTerrainJsonItem item = GetThis(k);
  188. RealWorldTerrainJsonArray arr = null;
  189. if (item != null)
  190. {
  191. arr = new RealWorldTerrainJsonArray();
  192. arr.Add(item);
  193. }
  194. for (int i = 0; i < _count; i++)
  195. {
  196. item = _items[i];
  197. RealWorldTerrainJsonArray subArr = item.GetAll(k) as RealWorldTerrainJsonArray;
  198. if (subArr != null)
  199. {
  200. if (arr == null) arr = new RealWorldTerrainJsonArray();
  201. arr.AddRange(subArr);
  202. }
  203. }
  204. return arr;
  205. }
  206. public override IEnumerator<RealWorldTerrainJsonItem> GetEnumerator()
  207. {
  208. return _items.GetEnumerator();
  209. }
  210. /// <summary>
  211. /// Parse a string that contains an array
  212. /// </summary>
  213. /// <param name="json">JSON string</param>
  214. /// <returns>Instance</returns>
  215. public static RealWorldTerrainJsonArray ParseArray(string json)
  216. {
  217. return RealWorldTerrainJson.Parse(json) as RealWorldTerrainJsonArray;
  218. }
  219. public override void ToJSON(StringBuilder b)
  220. {
  221. b.Append("[");
  222. for (int i = 0; i < _count; i++)
  223. {
  224. if (i != 0) b.Append(",");
  225. _items[i].ToJSON(b);
  226. }
  227. b.Append("]");
  228. }
  229. public override object Value(Type type)
  230. {
  231. if (RealWorldTerrainReflectionHelper.IsValueType(type)) return Activator.CreateInstance(type);
  232. return null;
  233. }
  234. }
  235. }