203 lines
6.2 KiB
C#
203 lines
6.2 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
namespace JD.Serialization
|
|
{
|
|
/// <summary>
|
|
/// Writes to Json format.
|
|
/// </summary>
|
|
/// <remarks>Reading is not supported yet!</remarks>
|
|
public class JsonSerializer : Serializer
|
|
{
|
|
public JsonSerializer()
|
|
: base(JD.Serialization.TypeMap.Instance)
|
|
{ }
|
|
|
|
protected override object LoadObjectFromFileImplementation(string file, Type type)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
protected override bool SaveObjectToFileImplementation(object obj, string file)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Saves the content of the object and returns it as a Json string.
|
|
/// </summary>
|
|
public string Serialize(object toSerialize)
|
|
{
|
|
var stringWriter = new StringWriter();
|
|
|
|
using (var writer = new JsonWriter(stringWriter))
|
|
{
|
|
WriteClass(writer, toSerialize);
|
|
}
|
|
|
|
return stringWriter.ToString();
|
|
}
|
|
|
|
public void Deserialize(string content, object toRead)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
#region Implementation
|
|
|
|
private void WriteClass(JsonWriter writer, object instance)
|
|
{
|
|
if (instance == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
using (writer.Indent())
|
|
{
|
|
string typeName = FormatTypeName(instance.GetType());
|
|
WriteProperty(writer, "__class", typeName);
|
|
|
|
foreach (var field in SerializableFields(instance.GetType()))
|
|
{
|
|
var isDefaultValue = instance.HasDefaultValue(field);
|
|
|
|
if (isDefaultValue && writer.CommentDefaultValues)
|
|
{
|
|
writer.CommentCount++;
|
|
}
|
|
else if (isDefaultValue && writer.IgnoreDefaultValues)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
WriteProperty(writer, FormatPropertyName(field), field.GetValue(instance, null));
|
|
|
|
if (isDefaultValue && writer.CommentDefaultValues)
|
|
{
|
|
writer.CommentCount--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void WriteProperty(JsonWriter writer, string propertyName, object propertyValue)
|
|
{
|
|
if (propertyValue == null)
|
|
return;
|
|
|
|
var valueType = propertyValue.GetType();
|
|
|
|
if (BasicTypeList.IsBasicType(valueType))
|
|
{
|
|
// Adds comment for enumerations to describe the effective value.
|
|
var comment = string.Empty;
|
|
if (valueType.IsEnum)
|
|
{
|
|
comment = $" /*{propertyValue}*/";
|
|
}
|
|
|
|
writer.WriteLine("{0}:{1}{2},", FormatPropertyName(propertyName), ConvertBaseTypeToJsonString(propertyValue), comment);
|
|
}
|
|
else if (IsCollection(valueType))
|
|
{
|
|
if (((IUAFCollection)propertyValue).Count > 0)
|
|
{
|
|
writer.WriteLine("{0}:", FormatPropertyName(propertyName));
|
|
WriteCollection(writer, (IUAFCollection)propertyValue);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
writer.WriteLine("{0}:", FormatPropertyName(propertyName));
|
|
WriteClass(writer, propertyValue);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Engine serializes the property with a lower case as its first character.
|
|
/// </summary>
|
|
private string FormatPropertyName(string propertyName)
|
|
{
|
|
var result = new StringBuilder(propertyName);
|
|
result[0] = char.ToLower(result[0]);
|
|
return Quote(result.ToString());
|
|
}
|
|
|
|
private void WriteCollection(JsonWriter writer, IUAFCollection collection)
|
|
{
|
|
using ( collection is IUAFList ? writer.IndentArrayBlock() : writer.Indent())
|
|
{
|
|
if (BasicTypeList.IsBasicType(collection.ElementType))
|
|
{
|
|
foreach (var item in collection.SerializableElements)
|
|
{
|
|
writer.WriteLine("{0},", ConvertBaseTypeToJsonString(item));
|
|
}
|
|
}
|
|
else if (collection is IUAFDictionary)
|
|
{
|
|
foreach (ISerializableKeyValuePair pair in collection.SerializableElements)
|
|
{
|
|
WriteProperty(writer, pair.Key.ToString(), pair.Value);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (var item in collection.SerializableElements)
|
|
{
|
|
WriteClass(writer, item);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private string ConvertBaseTypeToJsonString(object obj)
|
|
{
|
|
if (obj.GetType().IsEnum)
|
|
{
|
|
return (Convert.ToInt32(obj)).ToString();
|
|
}
|
|
if (obj is float)
|
|
{
|
|
return ((double)(float)obj).ToString("0.000000");
|
|
}
|
|
if (obj is double)
|
|
{
|
|
return ((double)obj).ToString("0.000000");
|
|
}
|
|
|
|
switch (obj.GetType().Name)
|
|
{
|
|
case "String":
|
|
case "String8":
|
|
case "StringID":
|
|
case "ObjectPath":
|
|
case "Path":
|
|
case "Platform":
|
|
return $"\"{(obj.ToString() ?? "").Replace("\"", "\\\"")}\"";
|
|
|
|
case "Color":
|
|
return $"\"0x{((Color) obj).ToArgb():X8}\"";
|
|
|
|
case "Angle":
|
|
return $"{((Angle) obj).ToDegree()}";
|
|
|
|
case "Boolean":
|
|
return obj.ToString().ToLower();
|
|
}
|
|
|
|
return obj.ToString();
|
|
}
|
|
|
|
private string Quote(string value)
|
|
{
|
|
const string quote = "\"";
|
|
return string.Concat(quote, value, quote);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
}
|