#if NETFRAMEWORK extern alias RealNewtonsoft; using RealNewtonsoft.Newtonsoft.Json; #else using Newtonsoft.Json; #endif using System; using System.Collections.Generic; using System.Linq; using ICD.Common.Properties; namespace ICD.Common.Utils.Extensions { public static class JsonSerializerExtensions { private const string PROPERTY_KEY = "k"; private const string PROPERTY_VALUE = "v"; /// /// Deserializes an array of items from the reader's current value. /// /// /// /// [CanBeNull] public static IEnumerable DeserializeArray([NotNull] this JsonSerializer extends, [NotNull] JsonReader reader) { if (extends == null) throw new ArgumentNullException("extends"); if (reader == null) throw new ArgumentNullException("reader"); return extends.DeserializeArray(reader, (s, r) => extends.Deserialize(reader)); } /// /// Deserializes an array of items from the reader's current value. /// /// /// /// /// [CanBeNull] public static IEnumerable DeserializeArray([NotNull] this JsonSerializer extends, [NotNull] JsonReader reader, [NotNull] Func read) { if (extends == null) throw new ArgumentNullException("extends"); if (reader == null) throw new ArgumentNullException("reader"); if (read == null) throw new ArgumentNullException("read"); if (reader.TokenType == JsonToken.Null) return null; if (reader.TokenType != JsonToken.StartArray) throw new FormatException(string.Format("Expected token {0} got {1}", JsonToken.StartArray, reader.TokenType)); // ToArray to ensure everything gets read before moving onto the next token return DeserializeArrayIterator(extends, reader, read).ToArray(); } /// /// Deserializes an array of items from the reader's current value. /// /// /// /// /// [NotNull] private static IEnumerable DeserializeArrayIterator( [NotNull] JsonSerializer serializer, [NotNull] JsonReader reader, [NotNull] Func read) { // Step into the first value reader.Read(); while (reader.TokenType != JsonToken.EndArray) { TItem output = read(serializer, reader); yield return output; // Step out of the value reader.Read(); } } /// /// Deserializes a dictionary of items from the reader's current value. /// /// /// /// /// [CanBeNull] public static IEnumerable> DeserializeDict( [NotNull] this JsonSerializer extends, [NotNull] JsonReader reader) { if (extends == null) throw new ArgumentNullException("extends"); if (reader == null) throw new ArgumentNullException("reader"); return extends.DeserializeDict(reader, (s, r) => s.Deserialize(r), (s, r) => s.Deserialize(r)); } /// /// Deserializes a dictionary of items from the reader's current value. /// /// /// /// /// /// /// [CanBeNull] public static IEnumerable> DeserializeDict( [NotNull] this JsonSerializer extends, [NotNull] JsonReader reader, [NotNull] Func readKey, [NotNull] Func readValue) { if (extends == null) throw new ArgumentNullException("extends"); if (reader == null) throw new ArgumentNullException("reader"); if (readKey == null) throw new ArgumentNullException("readKey"); if (readValue == null) throw new ArgumentNullException("readValue"); return extends.DeserializeArray(reader, (s, r) => s.DeserializeKeyValuePair(r, readKey, readValue)); } public static KeyValuePair DeserializeKeyValuePair( [NotNull] this JsonSerializer extends, [NotNull] JsonReader reader, [NotNull] Func readKey, [NotNull] Func readValue) { if (extends == null) throw new ArgumentNullException("extends"); if (reader == null) throw new ArgumentNullException("reader"); if (readKey == null) throw new ArgumentNullException("readKey"); if (readValue == null) throw new ArgumentNullException("readValue"); if (reader.TokenType != JsonToken.StartObject) throw new FormatException(string.Format("Expected token {0} got {1}", JsonToken.StartObject, reader.TokenType)); TKey key = default(TKey); TValue value = default(TValue); // Step into the first property reader.Read(); while (reader.TokenType != JsonToken.EndObject) { if (reader.TokenType != JsonToken.PropertyName) throw new FormatException(string.Format("Expected token {0} got {1}", JsonToken.PropertyName, reader.TokenType)); string propertyName = (string)reader.Value; // Step into the value reader.Read(); switch (propertyName) { case PROPERTY_KEY: key = readKey(extends, reader); break; case PROPERTY_VALUE: value = readValue(extends, reader); break; default: throw new FormatException(string.Format("Unexpected property {0}", reader.Value)); } // Step out of the value reader.Read(); } return new KeyValuePair(key, value); } /// /// Serializes the given sequence of items to the writer. /// /// /// /// /// public static void SerializeArray([NotNull] this JsonSerializer extends, [NotNull] JsonWriter writer, [CanBeNull] IEnumerable items) { if (extends == null) throw new ArgumentNullException("extends"); if (writer == null) throw new ArgumentNullException("writer"); extends.SerializeArray(writer, items, (s, w, item) => s.Serialize(w, item)); } /// /// Serializes the given sequence of items to the writer. /// /// /// /// /// /// public static void SerializeArray([NotNull] this JsonSerializer extends, [NotNull] JsonWriter writer, [CanBeNull] IEnumerable items, [NotNull] Action write) { if (extends == null) throw new ArgumentNullException("extends"); if (writer == null) throw new ArgumentNullException("writer"); if (write == null) throw new ArgumentNullException("write"); if (items == null) { writer.WriteNull(); return; } writer.WriteStartArray(); { foreach (TItem item in items) write(extends, writer, item); } writer.WriteEndArray(); } /// /// Serializes the given sequence of items to the writer. /// /// /// /// /// /// public static void SerializeDict([NotNull] this JsonSerializer extends, [NotNull] JsonWriter writer, [CanBeNull] IEnumerable> items) { extends.SerializeDict(writer, items, (s, w, k) => s.Serialize(w, k), (s, w, v) => s.Serialize(w, v)); } /// /// Serializes the given sequence of items to the writer. /// /// /// /// /// /// /// /// public static void SerializeDict([NotNull] this JsonSerializer extends, [NotNull] JsonWriter writer, [CanBeNull] IEnumerable> items, [NotNull] Action writeKey, [NotNull] Action writeValue) { if (extends == null) throw new ArgumentNullException("extends"); if (writer == null) throw new ArgumentNullException("writer"); if (writeKey == null) throw new ArgumentNullException("writeKey"); if (writeValue == null) throw new ArgumentNullException("writeValue"); extends.SerializeArray(writer, items, (s, w, kvp) => s.SerializeKeyValuePair(w, kvp, writeKey, writeValue)); } public static void SerializeKeyValuePair( [NotNull] this JsonSerializer extends, [NotNull] JsonWriter writer, KeyValuePair kvp, [NotNull] Action writeKey, [NotNull] Action writeValue) { if (extends == null) throw new ArgumentNullException("extends"); if (writer == null) throw new ArgumentNullException("writer"); if (writeKey == null) throw new ArgumentNullException("writeKey"); if (writeValue == null) throw new ArgumentNullException("writeValue"); writer.WriteStartObject(); { writer.WritePropertyName(PROPERTY_KEY); writeKey(extends, writer, kvp.Key); writer.WritePropertyName(PROPERTY_VALUE); writeValue(extends, writer, kvp.Value); } writer.WriteEndObject(); } } }