diff --git a/ICD.Common.Utils/Extensions/JsonSerializerExtensions.cs b/ICD.Common.Utils/Extensions/JsonSerializerExtensions.cs index bd7ebaf..7cc93a2 100644 --- a/ICD.Common.Utils/Extensions/JsonSerializerExtensions.cs +++ b/ICD.Common.Utils/Extensions/JsonSerializerExtensions.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Linq; using Newtonsoft.Json; @@ -8,6 +7,9 @@ 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. /// @@ -81,7 +83,15 @@ namespace ICD.Common.Utils.Extensions public static IEnumerable> DeserializeDict(this JsonSerializer extends, JsonReader reader) { - return extends.DeserializeDict(reader, p => (TKey)Convert.ChangeType(p, typeof(TKey), CultureInfo.InvariantCulture)); + 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)); } /// @@ -91,27 +101,13 @@ namespace ICD.Common.Utils.Extensions /// /// /// - /// - public static IEnumerable> DeserializeDict(this JsonSerializer extends, - JsonReader reader, - Func getKey) - { - return extends.DeserializeDict(reader, getKey, (s, r) => extends.Deserialize(reader)); - } - - /// - /// Deserializes a dictionary of items from the reader's current value. - /// - /// - /// - /// - /// - /// + /// /// public static IEnumerable> DeserializeDict(this JsonSerializer extends, JsonReader reader, - Func getKey, - Func readKey, + Func readValue) { if (extends == null) @@ -120,36 +116,39 @@ namespace ICD.Common.Utils.Extensions if (reader == null) throw new ArgumentNullException("reader"); - if (getKey == null) - throw new ArgumentNullException("getKey"); + if (readKey == null) + throw new ArgumentNullException("readKey"); if (readValue == null) throw new ArgumentNullException("readValue"); - if (reader.TokenType == JsonToken.Null) - return Enumerable.Empty>(); + return extends.DeserializeArray(reader, (s, r) => s.DeserializeKeyValuePair(r, readKey, readValue)); + } + + public static KeyValuePair DeserializeKeyValuePair(this JsonSerializer extends, JsonReader reader, + Func readKey, + 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)); - // ToArray to ensure everything gets read before moving onto the next token - return DeserializeDictIterator(extends, reader, getKey, readValue).ToArray(); - } + TKey key = default(TKey); + TValue value = default(TValue); - /// - /// Deserializes a dictionary of items from the reader's current value. - /// - /// - /// - /// - /// - /// - /// - private static IEnumerable> DeserializeDictIterator( - JsonSerializer serializer, JsonReader reader, - Func getKey, - Func readValue) - { // Step into the first property reader.Read(); @@ -158,17 +157,25 @@ namespace ICD.Common.Utils.Extensions if (reader.TokenType != JsonToken.PropertyName) throw new FormatException(); - TKey key = getKey((string)reader.Value); + switch ((string)reader.Value) + { + case PROPERTY_KEY: + key = readKey(extends, reader); + break; - // Step into the value - reader.Read(); + case PROPERTY_VALUE: + value = readValue(extends, reader); + break; - TValue value = readValue(serializer, reader); - yield return new KeyValuePair(key, value); + default: + throw new FormatException(string.Format("Unexpected property {0}", reader.Value)); + } // Step out of the value reader.Read(); } + + return new KeyValuePair(key, value); } /// @@ -228,7 +235,9 @@ namespace ICD.Common.Utils.Extensions public static void SerializeDict(this JsonSerializer extends, JsonWriter writer, IEnumerable> items) { - extends.SerializeDict(writer, items, k => k.ToString()); + extends.SerializeDict(writer, items, + (s, w, k) => s.Serialize(w, k), + (s, w, v) => s.Serialize(w, v)); } /// @@ -239,27 +248,11 @@ namespace ICD.Common.Utils.Extensions /// /// /// - /// - public static void SerializeDict(this JsonSerializer extends, JsonWriter writer, - IEnumerable> items, - Func getPropertyName) - { - extends.SerializeDict(writer, items, getPropertyName, (s, w, v) => s.Serialize(w, v)); - } - - /// - /// Serializes the given sequence of items to the writer. - /// - /// - /// - /// - /// - /// - /// + /// /// public static void SerializeDict(this JsonSerializer extends, JsonWriter writer, IEnumerable> items, - Func getPropertyName, + Action writeKey, Action writeValue) { if (extends == null) @@ -268,26 +261,39 @@ namespace ICD.Common.Utils.Extensions if (writer == null) throw new ArgumentNullException("writer"); - if (getPropertyName == null) - throw new ArgumentNullException("getPropertyName"); + if (writeKey == null) + throw new ArgumentNullException("writeKey"); if (writeValue == null) throw new ArgumentNullException("writeValue"); - if (items == null) - { - writer.WriteNull(); - return; - } + extends.SerializeArray(writer, items, (s, w, kvp) => s.SerializeKeyValuePair(w, kvp, writeKey, writeValue)); + } + + public static void SerializeKeyValuePair(this JsonSerializer extends, JsonWriter writer, + KeyValuePair kvp, + Action writeKey, + 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(); { - foreach (KeyValuePair kvp in items) - { - string propertyName = getPropertyName(kvp.Key); - writer.WritePropertyName(propertyName); - writeValue(extends, writer, kvp.Value); - } + writer.WritePropertyName(PROPERTY_KEY); + writeKey(extends, writer, kvp.Key); + + writer.WritePropertyName(PROPERTY_VALUE); + writeValue(extends, writer, kvp.Value); } writer.WriteEndObject(); }