// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Tools.DotNETCommon { /// /// Writer for JSON data, which indents the output text appropriately, and adds commas and newlines between fields /// public class JsonWriter : IDisposable { TextWriter Writer; bool bLeaveOpen; bool bRequiresComma; string Indent; /// /// Constructor /// /// File to write to public JsonWriter(string FileName) : this(new StreamWriter(FileName)) { } /// /// Constructor /// /// File to write to public JsonWriter(FileReference FileName) : this(new StreamWriter(FileName.FullName)) { } /// /// Constructor /// /// The text writer to output to /// Whether to leave the writer open when the object is disposed public JsonWriter(TextWriter Writer, bool bLeaveOpen = false) { this.Writer = Writer; this.bLeaveOpen = bLeaveOpen; Indent = ""; } /// /// Dispose of any managed resources /// public void Dispose() { if(!bLeaveOpen && Writer != null) { Writer.Dispose(); Writer = null; } } /// /// Write the opening brace for an object /// public void WriteObjectStart() { WriteCommaNewline(); Writer.Write(Indent); Writer.Write("{"); Indent += "\t"; bRequiresComma = false; } /// /// Write the name and opening brace for an object /// /// Name of the field public void WriteObjectStart(string ObjectName) { WriteCommaNewline(); Writer.Write("{0}\"{1}\": ", Indent, ObjectName); bRequiresComma = false; WriteObjectStart(); } /// /// Write the closing brace for an object /// public void WriteObjectEnd() { Indent = Indent.Substring(0, Indent.Length - 1); Writer.WriteLine(); Writer.Write(Indent); Writer.Write("}"); bRequiresComma = true; } /// /// Write the name and opening bracket for an array /// /// Name of the field public void WriteArrayStart(string ArrayName) { WriteCommaNewline(); Writer.Write("{0}\"{1}\": [", Indent, ArrayName); Indent += "\t"; bRequiresComma = false; } /// /// Write the closing bracket for an array /// public void WriteArrayEnd() { Indent = Indent.Substring(0, Indent.Length - 1); Writer.WriteLine(); Writer.Write("{0}]", Indent); bRequiresComma = true; } /// /// Write an array of strings /// /// Name of the field /// Values for the field public void WriteStringArrayField(string Name, IEnumerable Values) { WriteArrayStart(Name); foreach(string Value in Values) { WriteValue(Value); } WriteArrayEnd(); } /// /// Write an array of enum values /// /// Name of the field /// Values for the field public void WriteEnumArrayField(string Name, IEnumerable Values) where T : struct { WriteStringArrayField(Name, Values.Select(x => x.ToString())); } /// /// Write a value with no field name, for the contents of an array /// /// Value to write public void WriteValue(string Value) { WriteCommaNewline(); Writer.Write(Indent); WriteEscapedString(Value); bRequiresComma = true; } /// /// Write a field name and string value /// /// Name of the field /// Value for the field public void WriteValue(string Name, string Value) { WriteCommaNewline(); Writer.Write("{0}\"{1}\": ", Indent, Name); WriteEscapedString(Value); bRequiresComma = true; } /// /// Write a field name and integer value /// /// Name of the field /// Value for the field public void WriteValue(string Name, int Value) { WriteValueInternal(Name, Value.ToString()); } /// /// Write a field name and double value /// /// Name of the field /// Value for the field public void WriteValue(string Name, double Value) { WriteValueInternal(Name, Value.ToString()); } /// /// Write a field name and bool value /// /// Name of the field /// Value for the field public void WriteValue(string Name, bool Value) { WriteValueInternal(Name, Value ? "true" : "false"); } /// /// Write a field name and enum value /// /// The enum type /// Name of the field /// Value for the field public void WriteEnumValue(string Name, T Value) where T : struct { WriteValue(Name, Value.ToString()); } void WriteCommaNewline() { if (bRequiresComma) { Writer.WriteLine(","); } else if (Indent.Length > 0) { Writer.WriteLine(); } } void WriteValueInternal(string Name, string Value) { WriteCommaNewline(); Writer.Write("{0}\"{1}\": {2}", Indent, Name, Value); bRequiresComma = true; } void WriteEscapedString(string Value) { // Escape any characters which may not appear in a JSON string (see http://www.json.org). Writer.Write("\""); if (Value != null) { Writer.Write(Json.EscapeString(Value)); } Writer.Write("\""); } } }