JSON.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Data;
  5. using System.Reflection;
  6. using System.Reflection.Emit;
  7. using System.Text;
  8. using System.IO;
  9. namespace CP.Common.fastJSON
  10. {
  11. public class JSON
  12. {
  13. public readonly static JSON Instance = new JSON();
  14. private JSON()
  15. {
  16. }
  17. public string ToJSON(object obj)
  18. {
  19. return new JSONSerializer().ConvertToJSON(obj);
  20. }
  21. public object ToObject(string json)
  22. {
  23. Dictionary<string, object> ht = (Dictionary<string, object>)JsonParser.JsonDecode(json);
  24. if (ht == null)
  25. return null;
  26. return ht;
  27. //return ParseDictionary(ht);
  28. }
  29. #region [ PROPERTY GET SET CACHE ]
  30. SafeDictionary<string, Type> _typecache = new SafeDictionary<string, Type>();
  31. private Type GetTypeFromCache(string typename)
  32. {
  33. if (_typecache.ContainsKey(typename))
  34. return _typecache[typename];
  35. else
  36. {
  37. Type t = Type.GetType(typename);
  38. _typecache.Add(typename, t);
  39. return t;
  40. }
  41. }
  42. SafeDictionary<string, PropertyInfo> _propertycache = new SafeDictionary<string, PropertyInfo>();
  43. private PropertyInfo getproperty(Type type, string propertyname)
  44. {
  45. if (propertyname == "$type")
  46. return null;
  47. StringBuilder sb = new StringBuilder();
  48. sb.Append(type.Name);
  49. sb.Append("|");
  50. sb.Append(propertyname);
  51. string n = sb.ToString();
  52. if (_propertycache.ContainsKey(n))
  53. {
  54. return _propertycache[n];
  55. }
  56. else
  57. {
  58. PropertyInfo[] pr = type.GetProperties();
  59. foreach (PropertyInfo p in pr)
  60. {
  61. StringBuilder sbb = new StringBuilder();
  62. sbb.Append(type.Name);
  63. sbb.Append("|");
  64. sbb.Append(p.Name);
  65. string nn = sbb.ToString();
  66. if (_propertycache.ContainsKey(nn) == false)
  67. _propertycache.Add(nn, p);
  68. }
  69. return _propertycache[n];
  70. }
  71. }
  72. private delegate void GenericSetter(object target, object value);
  73. private static GenericSetter CreateSetMethod(PropertyInfo propertyInfo)
  74. {
  75. MethodInfo setMethod = propertyInfo.GetSetMethod();
  76. if (setMethod == null)
  77. return null;
  78. Type[] arguments = new Type[2];
  79. arguments[0] = arguments[1] = typeof(object);
  80. DynamicMethod setter = new DynamicMethod(
  81. String.Concat("_Set", propertyInfo.Name, "_"),
  82. typeof(void), arguments, propertyInfo.DeclaringType);
  83. ILGenerator il = setter.GetILGenerator();
  84. il.Emit(OpCodes.Ldarg_0);
  85. il.Emit(OpCodes.Castclass, propertyInfo.DeclaringType);
  86. il.Emit(OpCodes.Ldarg_1);
  87. if (propertyInfo.PropertyType.IsClass)
  88. il.Emit(OpCodes.Castclass, propertyInfo.PropertyType);
  89. else
  90. il.Emit(OpCodes.Unbox_Any, propertyInfo.PropertyType);
  91. il.EmitCall(OpCodes.Callvirt, setMethod, null);
  92. il.Emit(OpCodes.Ret);
  93. return (GenericSetter)setter.CreateDelegate(typeof(GenericSetter));
  94. }
  95. public delegate object GenericGetter(object target);
  96. private static GenericGetter CreateGetMethod(PropertyInfo propertyInfo)
  97. {
  98. MethodInfo getMethod = propertyInfo.GetGetMethod();
  99. if (getMethod == null)
  100. return null;
  101. Type[] arguments = new Type[1];
  102. arguments[0] = typeof(object);
  103. DynamicMethod getter = new DynamicMethod(
  104. String.Concat("_Get", propertyInfo.Name, "_"),
  105. typeof(object), arguments, propertyInfo.DeclaringType);
  106. ILGenerator il = getter.GetILGenerator();
  107. il.DeclareLocal(typeof(object));
  108. il.Emit(OpCodes.Ldarg_0);
  109. il.Emit(OpCodes.Castclass, propertyInfo.DeclaringType);
  110. il.EmitCall(OpCodes.Callvirt, getMethod, null);
  111. if (!propertyInfo.PropertyType.IsClass)
  112. il.Emit(OpCodes.Box, propertyInfo.PropertyType);
  113. il.Emit(OpCodes.Ret);
  114. return (GenericGetter)getter.CreateDelegate(typeof(GenericGetter));
  115. }
  116. SafeDictionary<Type, List<Getters>> _getterscache = new SafeDictionary<Type, List<Getters>>();
  117. internal List<Getters> GetGetters(Type type)
  118. {
  119. if (_getterscache.ContainsKey(type))
  120. return _getterscache[type];
  121. else
  122. {
  123. PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
  124. List<Getters> getters = new List<Getters>();
  125. foreach (PropertyInfo p in props)
  126. {
  127. GenericGetter g = CreateGetMethod(p);
  128. if (g != null)
  129. {
  130. Getters gg = new Getters();
  131. gg.Name = p.Name;
  132. gg.Getter = g;
  133. getters.Add(gg);
  134. }
  135. }
  136. _getterscache.Add(type, getters);
  137. return getters;
  138. }
  139. }
  140. SafeDictionary<PropertyInfo, GenericSetter> _settercache = new SafeDictionary<PropertyInfo, GenericSetter>();
  141. private GenericSetter GetSetter(PropertyInfo prop)
  142. {
  143. if (_settercache.ContainsKey(prop))
  144. return _settercache[prop];
  145. else
  146. {
  147. GenericSetter s = CreateSetMethod(prop);
  148. _settercache.Add(prop, s);
  149. return s;
  150. }
  151. }
  152. #endregion
  153. private object ParseDictionary(Dictionary<string, object> d)
  154. {
  155. string tn = "" + d["$type"];
  156. Type type = GetTypeFromCache(tn);
  157. object o = Activator.CreateInstance(type);
  158. foreach (string name in d.Keys)
  159. {
  160. PropertyInfo pi = getproperty(type, name);
  161. if (pi != null)
  162. {
  163. object v = d[name];
  164. if (v != null)
  165. {
  166. object oset = null;
  167. GenericSetter setter;
  168. Type pt = pi.PropertyType;
  169. object dic = pt.GetInterface("IDictionary");
  170. if (pt.IsGenericType && pt.IsValueType == false && dic == null)
  171. {
  172. IList col = (IList)Activator.CreateInstance(pt);
  173. // create an array of objects
  174. foreach (object ob in (ArrayList)v)
  175. col.Add(ParseDictionary((Dictionary<string, object>)ob));
  176. oset = col;
  177. }
  178. else if (pt == typeof(byte[]))
  179. {
  180. oset = Convert.FromBase64String((string)v);
  181. }
  182. else if (pt.IsArray && pt.IsValueType == false)
  183. {
  184. ArrayList col = new ArrayList();
  185. // create an array of objects
  186. foreach (object ob in (ArrayList)v)
  187. col.Add(ParseDictionary((Dictionary<string, object>)ob));
  188. oset = col.ToArray(pi.PropertyType.GetElementType());
  189. }
  190. else if (pt == typeof(Guid) || pt == typeof(Guid?))
  191. oset = new Guid("" + v);
  192. else if (pt == typeof(DataSet))
  193. oset = CreateDataset((Dictionary<string, object>)v);
  194. else if (pt == typeof(Hashtable))
  195. oset = CreateDictionary((ArrayList)v, pt);
  196. else if (dic != null)
  197. oset = CreateDictionary((ArrayList)v, pt);
  198. else
  199. oset = ChangeType(v, pt);
  200. setter = GetSetter(pi);
  201. setter(o, oset);
  202. }
  203. }
  204. }
  205. return o;
  206. }
  207. private object CreateDictionary(ArrayList reader, Type pt)
  208. {
  209. IDictionary col = (IDictionary)Activator.CreateInstance(pt);
  210. Type[] types = col.GetType().GetGenericArguments();
  211. foreach (object o in reader)
  212. {
  213. Dictionary<string, object> values = (Dictionary<string, object>)o;
  214. object key;
  215. object val;
  216. if (values["k"] is Dictionary<string, object>)
  217. key = ParseDictionary((Dictionary<string, object>)values["k"]);
  218. else
  219. key = ChangeType(values["k"], types[0]);
  220. if (values["v"] is Dictionary<string, object>)
  221. val = ParseDictionary((Dictionary<string, object>)values["v"]);
  222. else
  223. val = ChangeType(values["v"], types[1]);
  224. col.Add(key, val);
  225. }
  226. return col;
  227. }
  228. public object ChangeType(object value, Type conversionType)
  229. {
  230. if (conversionType.IsGenericType &&
  231. conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
  232. {
  233. System.ComponentModel.NullableConverter nullableConverter
  234. = new System.ComponentModel.NullableConverter(conversionType);
  235. conversionType = nullableConverter.UnderlyingType;
  236. }
  237. return Convert.ChangeType(value, conversionType);
  238. }
  239. private Hashtable CreateHashtable(ArrayList reader)
  240. {
  241. Hashtable ht = new Hashtable();
  242. foreach (object o in reader)
  243. {
  244. Dictionary<string, object> values = (Dictionary<string, object>)o;
  245. ht.Add(
  246. ParseDictionary((Dictionary<string, object>)values["k"]),
  247. ParseDictionary((Dictionary<string, object>)values["v"])
  248. );
  249. }
  250. return ht;
  251. }
  252. private DataSet CreateDataset(Dictionary<string, object> reader)
  253. {
  254. DataSet ds = new DataSet();
  255. // read dataset schema here
  256. string s = "" + reader["$schema"];
  257. TextReader tr = new StringReader(s);
  258. ds.ReadXmlSchema(tr);
  259. foreach (string key in reader.Keys)
  260. {
  261. if (key == "$type" || key == "$schema")
  262. continue;
  263. object tb = reader[key];
  264. if (tb != null && tb.GetType() == typeof(ArrayList))
  265. {
  266. ArrayList rows = (ArrayList)tb;
  267. foreach (Dictionary<string, object> row in rows)
  268. {
  269. DataRow dr = ds.Tables[key].NewRow();
  270. foreach (string col in row.Keys)
  271. {
  272. dr[col] = row[col];
  273. }
  274. ds.Tables[key].Rows.Add(dr);
  275. }
  276. }
  277. }
  278. return ds;
  279. }
  280. }
  281. }