JsonWriter.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. 
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Text;
  6. namespace etoy
  7. {
  8. interface IJsonWritable
  9. {
  10. /// <summary>
  11. /// 迭代器写入
  12. /// 会自动拼接 ','
  13. /// </summary>
  14. /// <typeparam name="T"></typeparam>
  15. /// <param name="enumerable"></param>
  16. /// <param name="len"></param>
  17. /// <param name="callback"></param>
  18. /// <returns></returns>
  19. IJsonWritable EnumeratorToJson<T>(IEnumerable<T> enumerable, int len, Action<int, T> callback);
  20. /// <summary>
  21. /// 写入key 自动拼接成 -> \"key\":
  22. /// </summary>
  23. /// <param name="value"></param>
  24. /// <returns></returns>
  25. IJsonWritable AppendKey(string value);
  26. /// <summary>
  27. /// 写入value
  28. /// </summary>
  29. /// <param name="value"></param>
  30. /// <returns></returns>
  31. IJsonWritable Append(int value);
  32. /// <summary>
  33. /// 写入value -> \"value\"
  34. /// </summary>
  35. /// <param name="value"></param>
  36. /// <returns></returns>
  37. IJsonWritable Append(string value);
  38. /// <summary>
  39. /// 强制写入value 不会进行转义
  40. /// </summary>
  41. /// <param name="value"></param>
  42. /// <returns></returns>
  43. IJsonWritable AppendForce(string value);
  44. /// <summary>
  45. /// [
  46. /// </summary>
  47. /// <returns></returns>
  48. IJsonWritable ArrayBracket();
  49. /// <summary>
  50. /// ]
  51. /// </summary>
  52. /// <returns></returns>
  53. IJsonWritable EndArrayBracket();
  54. /// <summary>
  55. /// {
  56. /// </summary>
  57. /// <returns></returns>
  58. IJsonWritable Bracket();
  59. /// <summary>
  60. /// }
  61. /// </summary>
  62. /// <returns></returns>
  63. IJsonWritable EndBracket();
  64. /// <summary>
  65. /// ,
  66. /// </summary>
  67. /// <returns></returns>
  68. IJsonWritable Dot();
  69. /// <summary>
  70. /// 换行
  71. /// </summary>
  72. /// <returns></returns>
  73. IJsonWritable NewLine();
  74. IJsonWritable Indent();
  75. IJsonWritable Dedent();
  76. }
  77. class JsonWriter : IDisposable
  78. , IJsonWritable
  79. {
  80. #region Constructors
  81. private readonly TextWriter _w;
  82. private MemoryStream _ms = new MemoryStream();
  83. private readonly bool _formatting;
  84. private Encoding _utf8WithoutBom = new UTF8Encoding(false);
  85. public JsonWriter(bool formatting = false)
  86. {
  87. _ms = new MemoryStream();
  88. _w = new StreamWriter(_ms, _utf8WithoutBom);
  89. _formatting = formatting;
  90. }
  91. /// <summary>
  92. /// Return the generated code as a string.
  93. /// </summary>
  94. public string Json
  95. {
  96. get
  97. {
  98. _w.Flush();
  99. return _utf8WithoutBom.GetString(_ms.ToArray());
  100. }
  101. }
  102. public virtual void Dispose()
  103. {
  104. _w.Close();
  105. }
  106. #endregion
  107. #region Json Write
  108. public IJsonWritable EnumeratorToJson<T>(IEnumerable<T> enumerable, int len, Action<int, T> callback)
  109. {
  110. var count = 0;
  111. var enumerator = enumerable.GetEnumerator();
  112. while (enumerator.MoveNext())
  113. {
  114. callback.Invoke(count, enumerator.Current);
  115. if (++count >= len) break;
  116. this.Dot();
  117. }
  118. enumerator.Dispose();
  119. return this;
  120. }
  121. public IJsonWritable AppendKey(string value)
  122. {
  123. _w.Write($"\"{value}\":");
  124. return this;
  125. }
  126. public IJsonWritable Append(int value)
  127. {
  128. _w.Write(value);
  129. return this;
  130. }
  131. public IJsonWritable Append(string value)
  132. {
  133. _w.Write($"\"{value}\"");
  134. return this;
  135. }
  136. /// <summary>
  137. /// 不拼接引号强制写入
  138. /// </summary>
  139. /// <param name="value"></param>
  140. /// <returns></returns>
  141. public IJsonWritable AppendForce(string value)
  142. {
  143. _w.Write($"{value}");
  144. return this;
  145. }
  146. public IJsonWritable ArrayBracket()
  147. {
  148. _w.Write('[');
  149. return this;
  150. }
  151. public IJsonWritable EndArrayBracket()
  152. {
  153. _w.Write(']');
  154. return this;
  155. }
  156. public IJsonWritable Bracket()
  157. {
  158. _w.Write('{');
  159. return this;
  160. }
  161. public IJsonWritable Dot()
  162. {
  163. _w.Write(',');
  164. return this;
  165. }
  166. public IJsonWritable EndBracket()
  167. {
  168. _w.Write('}');
  169. return this;
  170. }
  171. #endregion
  172. #region 格式化
  173. public static string IndentPrefix = " ";
  174. /// <summary>
  175. /// Level of indentation
  176. /// </summary>
  177. public int IndentLevel { get; private set; }
  178. /// <summary>
  179. /// Accumulated prefixes over indentations
  180. /// </summary>
  181. string prefix = "";
  182. ///<summary> 增加缩进 </summary>
  183. public IJsonWritable Indent()
  184. {
  185. IndentLevel += 1;
  186. prefix += IndentPrefix;
  187. return this;
  188. }
  189. ///<summary> 减少缩进 </summary>
  190. public IJsonWritable Dedent()
  191. {
  192. IndentLevel -= 1;
  193. if (IndentLevel < 0)
  194. throw new InvalidOperationException("Indent error");
  195. prefix = prefix.Substring(0, prefix.Length - IndentPrefix.Length);
  196. return this;
  197. }
  198. public IJsonWritable NewLine()
  199. {
  200. if (_formatting)
  201. {
  202. _w.Write("\r\n");
  203. _w.Write(prefix);
  204. }
  205. return this;
  206. }
  207. #endregion
  208. }
  209. }