From 21e73a13cc17495e03388007d313ccff6c472240 Mon Sep 17 00:00:00 2001 From: Victor Maia Aldecoa Date: Wed, 18 Jun 2025 09:52:22 -0300 Subject: [PATCH] Add support for lists and dictionaries of any supported types --- PlistCS/Src/Plist.cs | 112 +++++++++++++++---------------------------- 1 file changed, 39 insertions(+), 73 deletions(-) diff --git a/PlistCS/Src/Plist.cs b/PlistCS/Src/Plist.cs index f4c56a3..4eecc75 100644 --- a/PlistCS/Src/Plist.cs +++ b/PlistCS/Src/Plist.cs @@ -298,7 +298,7 @@ private static List parseArray(XmlNode node) return array; } - private static void composeArray(List value, XmlWriter writer) + private static void composeArray(IEnumerable value, XmlWriter writer) { writer.WriteStartElement("array"); foreach (object obj in value) @@ -341,7 +341,6 @@ private static object parse(XmlNode node) private static void compose(object value, XmlWriter writer) { - if (value == null || value is string) { writer.WriteElementString("string", value as string); @@ -350,25 +349,9 @@ private static void compose(object value, XmlWriter writer) { writer.WriteElementString("integer", ((int)value).ToString(System.Globalization.NumberFormatInfo.InvariantInfo)); } - else if (value is System.Collections.Generic.Dictionary || - value.GetType().ToString().StartsWith("System.Collections.Generic.Dictionary`2[System.String")) - { - //Convert to Dictionary - Dictionary dic = value as Dictionary; - if (dic == null) - { - dic = new Dictionary(); - IDictionary idic = (IDictionary)value; - foreach (var key in idic.Keys) - { - dic.Add(key.ToString(), idic[key]); - } - } - writeDictionaryValues(dic, writer); - } - else if (value is List) + else if (value is IDictionary dictionary) { - composeArray((List)value, writer); + writeDictionaryValues(dictionary, writer); } else if (value is byte[]) { @@ -388,13 +371,18 @@ private static void compose(object value, XmlWriter writer) { writer.WriteElementString(value.ToString().ToLower(), ""); } + // IEnumerable has to come after IDictionary, string and byte[], otherwise it will match those types + else if (value is IEnumerable enumerable) + { + composeArray(enumerable, writer); + } else { throw new Exception(String.Format("Value type '{0}' is unhandled", value.GetType().ToString())); } } - private static void writeDictionaryValues(Dictionary dictionary, XmlWriter writer) + private static void writeDictionaryValues(IDictionary dictionary, XmlWriter writer) { writer.WriteStartElement("dict"); foreach (string key in dictionary.Keys) @@ -409,24 +397,24 @@ private static void writeDictionaryValues(Dictionary dictionary, private static int countObject(object value) { int count = 0; - switch (value.GetType().ToString()) + switch (value) { - case "System.Collections.Generic.Dictionary`2[System.String,System.Object]": - Dictionary dict = (Dictionary)value; - foreach (string key in dict.Keys) + case IDictionary dictionary: + foreach (var dictValue in dictionary.Values) { - count += countObject(dict[key]); + count += countObject(dictValue); } - count += dict.Keys.Count; + count += dictionary.Keys.Count; count++; + break; - case "System.Collections.Generic.List`1[System.Object]": - List list = (List)value; - foreach (object obj in list) + case IEnumerable enumerable: + foreach (var item in enumerable) { - count += countObject(obj); + count += countObject(item); } count++; + break; default: count++; @@ -435,7 +423,7 @@ private static int countObject(object value) return count; } - private static byte[] writeBinaryDictionary(Dictionary dictionary) + private static byte[] writeBinaryDictionary(IDictionary dictionary) { List buffer = new List(); List header = new List(); @@ -485,8 +473,13 @@ private static byte[] writeBinaryDictionary(Dictionary dictionar return buffer.ToArray(); } - private static byte[] composeBinaryArray(List objects) + private static byte[] writeBinaryArray(IEnumerable enumerable) { + List objects = new List(); + foreach (object obj in enumerable) + { + objects.Add(obj); + } List buffer = new List(); List header = new List(); List refs = new List(); @@ -523,46 +516,19 @@ private static byte[] composeBinaryArray(List objects) return buffer.ToArray(); } - private static byte[] composeBinary(object obj) - { - byte[] value; - switch (obj.GetType().ToString()) - { - case "System.Collections.Generic.Dictionary`2[System.String,System.Object]": - value = writeBinaryDictionary((Dictionary)obj); - return value; - - case "System.Collections.Generic.List`1[System.Object]": - value = composeBinaryArray((List)obj); - return value; - - case "System.Byte[]": - value = writeBinaryByteArray((byte[])obj); - return value; - - case "System.Double": - value = writeBinaryDouble((double)obj); - return value; - - case "System.Int32": - value = writeBinaryInteger((int)obj, true); - return value; - - case "System.String": - value = writeBinaryString((string)obj, true); - return value; - - case "System.DateTime": - value = writeBinaryDate((DateTime)obj); - return value; - - case "System.Boolean": - value = writeBinaryBool((bool)obj); - return value; - - default: - return new byte[0]; - } + private static byte[] composeBinary(object obj) { + return obj switch { + IDictionary dictionary => writeBinaryDictionary(dictionary), + byte[] byteArray => writeBinaryByteArray(byteArray), + double d => writeBinaryDouble(d), + int i => writeBinaryInteger(i, true), + string s => writeBinaryString(s, true), + DateTime dt => writeBinaryDate(dt), + bool b => writeBinaryBool(b), + // IEnumerable has to come after IDictionary, string and byte[], otherwise it will match those types + IEnumerable enumerable => writeBinaryArray(enumerable), + _ => new byte[0] + }; } public static byte[] writeBinaryDate(DateTime obj)