using System; using System.Collections.Generic; using System.IO; using System.Text; namespace etoy { interface IJsonWritable { /// /// 迭代器写入 /// 会自动拼接 ',' /// /// /// /// /// /// IJsonWritable EnumeratorToJson(IEnumerable enumerable, int len, Action callback); /// /// 写入key 自动拼接成 -> \"key\": /// /// /// IJsonWritable AppendKey(string value); /// /// 写入value /// /// /// IJsonWritable Append(int value); /// /// 写入value -> \"value\" /// /// /// IJsonWritable Append(string value); /// /// 强制写入value 不会进行转义 /// /// /// IJsonWritable AppendForce(string value); /// /// [ /// /// IJsonWritable ArrayBracket(); /// /// ] /// /// IJsonWritable EndArrayBracket(); /// /// { /// /// IJsonWritable Bracket(); /// /// } /// /// IJsonWritable EndBracket(); /// /// , /// /// IJsonWritable Dot(); /// /// 换行 /// /// IJsonWritable NewLine(); IJsonWritable Indent(); IJsonWritable Dedent(); } class JsonWriter : IDisposable , IJsonWritable { #region Constructors private readonly TextWriter _w; private MemoryStream _ms = new MemoryStream(); private readonly bool _formatting; private Encoding _utf8WithoutBom = new UTF8Encoding(false); public JsonWriter(bool formatting = false) { _ms = new MemoryStream(); _w = new StreamWriter(_ms, _utf8WithoutBom); _formatting = formatting; } /// /// Return the generated code as a string. /// public string Json { get { _w.Flush(); return _utf8WithoutBom.GetString(_ms.ToArray()); } } public virtual void Dispose() { _w.Close(); } #endregion #region Json Write public IJsonWritable EnumeratorToJson(IEnumerable enumerable, int len, Action callback) { var count = 0; var enumerator = enumerable.GetEnumerator(); while (enumerator.MoveNext()) { callback.Invoke(count, enumerator.Current); if (++count >= len) break; this.Dot(); } enumerator.Dispose(); return this; } public IJsonWritable AppendKey(string value) { _w.Write($"\"{value}\":"); return this; } public IJsonWritable Append(int value) { _w.Write(value); return this; } public IJsonWritable Append(string value) { _w.Write($"\"{value}\""); return this; } /// /// 不拼接引号强制写入 /// /// /// public IJsonWritable AppendForce(string value) { _w.Write($"{value}"); return this; } public IJsonWritable ArrayBracket() { _w.Write('['); return this; } public IJsonWritable EndArrayBracket() { _w.Write(']'); return this; } public IJsonWritable Bracket() { _w.Write('{'); return this; } public IJsonWritable Dot() { _w.Write(','); return this; } public IJsonWritable EndBracket() { _w.Write('}'); return this; } #endregion #region 格式化 public static string IndentPrefix = " "; /// /// Level of indentation /// public int IndentLevel { get; private set; } /// /// Accumulated prefixes over indentations /// string prefix = ""; /// 增加缩进 public IJsonWritable Indent() { IndentLevel += 1; prefix += IndentPrefix; return this; } /// 减少缩进 public IJsonWritable Dedent() { IndentLevel -= 1; if (IndentLevel < 0) throw new InvalidOperationException("Indent error"); prefix = prefix.Substring(0, prefix.Length - IndentPrefix.Length); return this; } public IJsonWritable NewLine() { if (_formatting) { _w.Write("\r\n"); _w.Write(prefix); } return this; } #endregion } }