#if NETFRAMEWORK extern alias RealNewtonsoft; using RealNewtonsoft.Newtonsoft.Json; #else using Newtonsoft.Json; #endif using System; using ICD.Common.Properties; using ICD.Common.Utils.Extensions; namespace ICD.Common.Utils.Json { public abstract class AbstractGenericJsonConverter : JsonConverter { /// /// Creates a new instance of T. /// /// protected virtual T Instantiate() { return ReflectionUtils.CreateInstance(); } /// /// Writes the JSON representation of the object. /// /// The to write to. /// The value. /// The calling serializer. public sealed override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { if (writer == null) throw new ArgumentNullException("writer"); if (serializer == null) throw new ArgumentNullException("serializer"); WriteJson(writer, (T)value, serializer); } /// /// Writes the JSON representation of the object. /// /// The to write to. /// The value. /// The calling serializer. [PublicAPI] public virtual void WriteJson(JsonWriter writer, T value, JsonSerializer serializer) { if (writer == null) throw new ArgumentNullException("writer"); if (serializer == null) throw new ArgumentNullException("serializer"); // ReSharper disable CompareNonConstrainedGenericWithNull if (value == null) // ReSharper restore CompareNonConstrainedGenericWithNull { writer.WriteNull(); return; } WriteObject(writer, value, serializer); } /// /// Override to write the object value to the writer. /// /// /// /// protected virtual void WriteObject(JsonWriter writer, T value, JsonSerializer serializer) { writer.WriteStartObject(); { WriteProperties(writer, value, serializer); } writer.WriteEndObject(); } /// /// Override to write properties to the writer. /// /// /// /// protected virtual void WriteProperties(JsonWriter writer, T value, JsonSerializer serializer) { } /// /// Reads the JSON representation of the object. /// /// The to read from. /// Type of the object. /// The existing value of object being read. /// The calling serializer. /// /// The object value. /// public sealed override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader == null) throw new ArgumentNullException("reader"); if (serializer == null) throw new ArgumentNullException("serializer"); // Casting null blows up struct casts T cast = (T)(existingValue ?? default(T)); return ReadJson(reader, cast, serializer); } /// /// Reads the JSON representation of the object. /// /// The to read from. /// The existing value of object being read. /// The calling serializer. /// /// The object value. /// [PublicAPI] public virtual T ReadJson(JsonReader reader, T existingValue, JsonSerializer serializer) { if (reader == null) throw new ArgumentNullException("reader"); if (serializer == null) throw new ArgumentNullException("serializer"); if (reader.TokenType == JsonToken.Null) return existingValue; if (reader.TokenType != JsonToken.StartObject) throw new FormatException(string.Format("Expected {0} got {1}", JsonToken.StartObject, reader.TokenType)); return ReadObject(reader, existingValue, serializer); } /// /// Override to handle deserialization of the current StartObject token. /// /// /// /// /// protected virtual T ReadObject(JsonReader reader, T existingValue, JsonSerializer serializer) { // ReSharper disable CompareNonConstrainedGenericWithNull // ReSharper disable ConvertConditionalTernaryToNullCoalescing T output = existingValue == null ? Instantiate() : existingValue; // ReSharper restore ConvertConditionalTernaryToNullCoalescing // ReSharper restore CompareNonConstrainedGenericWithNull reader.ReadObject(serializer, (p, r, s) => ReadProperty(p, r, output, s)); return output; } /// /// Override to handle the current property value with the given name. /// /// /// /// /// protected virtual void ReadProperty(string property, JsonReader reader, T instance, JsonSerializer serializer) { reader.Skip(); } /// /// Determines whether this instance can convert the specified object type. /// /// Type of the object. /// /// true if this instance can convert the specified object type; otherwise, false. /// public override bool CanConvert(Type objectType) { return objectType == typeof(T); } } }