ObjectFormatter.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. using System;
  2. using System.Reflection;
  3. using System.Text;
  4. namespace IFramework.Serialization
  5. {
  6. public class ObjectFormatter<T> : StringFormatter<T>
  7. {
  8. public override void ConvertToString(T t, StringBuilder builder)
  9. {
  10. if (t == null) return;
  11. var fields = typeof(T).GetFields();
  12. builder.Append(StringConvert.leftBound);
  13. for (int i = 0; i < fields.Length; i++)
  14. {
  15. var field = fields[i];
  16. if (field.IsNotSerialized) continue;
  17. if (field.IsStatic) continue;
  18. StringFormatter c = StringConvert.GetFormatter(field.FieldType);
  19. builder.Append(field.Name);
  20. builder.Append(StringConvert.colon);
  21. c.ConvertToString(field.GetValue(t), builder);
  22. builder.Append(StringConvert.dot);
  23. }
  24. var ps = typeof(T).GetProperties();
  25. for (int i = 0; i < ps.Length; i++)
  26. {
  27. var p = ps[i];
  28. if (!p.CanRead) continue;
  29. if (!p.CanWrite) continue;
  30. StringFormatter c = StringConvert.GetFormatter(p.PropertyType);
  31. builder.Append(p.Name);
  32. builder.Append(StringConvert.colon);
  33. c.ConvertToString(p.GetValue(t), builder);
  34. builder.Append(StringConvert.dot);
  35. }
  36. builder.Append(StringConvert.rightBound);
  37. }
  38. public override bool TryConvert(string self, out T result)
  39. {
  40. object _obj = Activator.CreateInstance<T>();
  41. bool bo = ReadObject(self, (fieldName, inner) =>
  42. {
  43. SetMember(fieldName, inner, _obj);
  44. });
  45. if (bo)
  46. result = (T)_obj;
  47. else
  48. result = MakeDefault();
  49. return bo;
  50. }
  51. private void SetMember(string fieldName, string inner, object _obj)
  52. {
  53. var membders = typeof(T).GetMember(fieldName);
  54. if (membders != null && membders.Length == 1)
  55. {
  56. var membder = membders[0];
  57. if (membder is FieldInfo)
  58. {
  59. FieldInfo f = membder as FieldInfo;
  60. StringFormatter c = StringConvert.GetFormatter(f.FieldType);
  61. object value;
  62. if (c.TryConvertObject(inner, out value))
  63. {
  64. f.SetValue(_obj, value);
  65. }
  66. }
  67. else if (membder is PropertyInfo)
  68. {
  69. PropertyInfo p = membder as PropertyInfo;
  70. StringFormatter c = StringConvert.GetFormatter(p.PropertyType);
  71. object value;
  72. if (c.TryConvertObject(inner, out value))
  73. {
  74. p.SetValue(_obj, value);
  75. }
  76. }
  77. }
  78. }
  79. private static int ReadField(string value, int start, out int colinIndex)
  80. {
  81. colinIndex = value.IndexOf(StringConvert.colon, start);
  82. if (colinIndex < 0) return -1;
  83. int depth = 0;
  84. for (int i = colinIndex + 1; i < value.Length; i++)
  85. {
  86. char data = value[i];
  87. if (data == StringConvert.leftBound || data == StringConvert.midLeftBound)
  88. {
  89. depth++;
  90. }
  91. else if (data == StringConvert.rightBound || data == StringConvert.midRightBound)
  92. {
  93. depth--;
  94. }
  95. else
  96. {
  97. if (data == StringConvert.dot && depth == 0)
  98. {
  99. return i;
  100. }
  101. else
  102. {
  103. continue;
  104. }
  105. }
  106. if (depth == 0)
  107. {
  108. for (int j = i; j < value.Length; j++)
  109. {
  110. if (value[j] == StringConvert.dot)
  111. {
  112. return j;
  113. }
  114. }
  115. return value.Length - 1;
  116. }
  117. }
  118. return value.Length - 1;
  119. }
  120. public static bool ReadObject(string value, Action<string, string> call)
  121. {
  122. try
  123. {
  124. if (!value.StartsWith(StringConvert.leftBound.ToString())) goto ERR;
  125. if (!value.EndsWith(StringConvert.rightBound.ToString())) goto ERR;
  126. value = value.Remove(0, 1);
  127. value = value.Remove(value.Length - 1, 1);
  128. int start = 0;
  129. while (start < value.Length)
  130. {
  131. int colinIndex = 0;
  132. int end = ReadField(value, start, out colinIndex);
  133. if (end == -1)
  134. {
  135. break;
  136. }
  137. string fieldName = value.Substring(start, colinIndex - start);
  138. string inner = value.Substring(colinIndex + 1, end - colinIndex);
  139. if (inner.EndsWith(StringConvert.dot.ToString()))
  140. {
  141. inner = inner.Remove(inner.Length - 1, 1);
  142. }
  143. call?.Invoke(fieldName, inner);
  144. start = end + 1;
  145. }
  146. return true;
  147. }
  148. catch (Exception e)
  149. {
  150. throw e;
  151. }
  152. ERR:
  153. return false;
  154. }
  155. }
  156. }