using System; using System.Collections; using System.Collections.Generic; namespace Gaia.FullSerializer.Internal { public class fsDictionaryConverter : fsConverter { public override bool CanProcess(Type type) { return typeof(IDictionary).IsAssignableFrom(type); } public override object CreateInstance(fsData data, Type storageType) { return fsMetaType.Get(storageType).CreateInstance(); } public override fsResult TryDeserialize(fsData data, ref object instance_, Type storageType) { IDictionary dictionary = (IDictionary)instance_; fsResult success = fsResult.Success; GetKeyValueTypes(dictionary.GetType(), out var keyStorageType, out var valueStorageType); fsResult result5; if (data.IsList) { List asList = data.AsList; for (int i = 0; i < asList.Count; i++) { fsData data2 = asList[i]; if ((success += CheckType(data2, fsDataType.Object)).Failed) { return success; } if ((success += CheckKey(data2, "Key", out var subitem)).Failed) { return success; } if ((success += CheckKey(data2, "Value", out var subitem2)).Failed) { return success; } object result = null; object result2 = null; if ((success += Serializer.TryDeserialize(subitem, keyStorageType, ref result)).Failed) { return success; } if ((success += Serializer.TryDeserialize(subitem2, valueStorageType, ref result2)).Failed) { return success; } AddItemToDictionary(dictionary, result, result2); } } else { if (!data.IsDictionary) { return FailExpectedType(data, fsDataType.Array, fsDataType.Object); } foreach (KeyValuePair item in data.AsDictionary) { if (fsSerializer.IsReservedKeyword(item.Key)) { continue; } fsData data3 = new fsData(item.Key); fsData value = item.Value; object result3 = null; object result4 = null; result5 = (success += Serializer.TryDeserialize(data3, keyStorageType, ref result3)); if (result5.Failed) { result5 = success; } else { fsResult fsResult2 = (success += Serializer.TryDeserialize(value, valueStorageType, ref result4)); if (!fsResult2.Failed) { AddItemToDictionary(dictionary, result3, result4); continue; } result5 = success; } goto IL_01fb; } } return success; IL_01fb: return result5; } public override fsResult TrySerialize(object instance_, out fsData serialized, Type storageType) { serialized = fsData.Null; fsResult success = fsResult.Success; IDictionary obj = (IDictionary)instance_; GetKeyValueTypes(obj.GetType(), out var keyStorageType, out var valueStorageType); IDictionaryEnumerator enumerator = obj.GetEnumerator(); bool flag = true; List list = new List(obj.Count); List list2 = new List(obj.Count); while (enumerator.MoveNext()) { if ((success += Serializer.TrySerialize(keyStorageType, enumerator.Key, out var data)).Failed) { return success; } if ((success += Serializer.TrySerialize(valueStorageType, enumerator.Value, out var data2)).Failed) { return success; } list.Add(data); list2.Add(data2); flag &= data.IsString; } if (flag) { serialized = fsData.CreateDictionary(); Dictionary asDictionary = serialized.AsDictionary; for (int i = 0; i < list.Count; i++) { fsData fsData2 = list[i]; fsData value = list2[i]; asDictionary[fsData2.AsString] = value; } } else { serialized = fsData.CreateList(list.Count); List asList = serialized.AsList; for (int j = 0; j < list.Count; j++) { fsData value2 = list[j]; fsData value3 = list2[j]; Dictionary dictionary = new Dictionary(); dictionary["Key"] = value2; dictionary["Value"] = value3; asList.Add(new fsData(dictionary)); } } return success; } private fsResult AddItemToDictionary(IDictionary dictionary, object key, object value) { if (key == null || value == null) { Type type = fsReflectionUtility.GetInterface(dictionary.GetType(), typeof(ICollection<>)); if (type == null) { return fsResult.Warn(dictionary.GetType()?.ToString() + " does not extend ICollection"); } object obj = Activator.CreateInstance(type.GetGenericArguments()[0], key, value); type.GetFlattenedMethod("Add").Invoke(dictionary, new object[1] { obj }); return fsResult.Success; } dictionary[key] = value; return fsResult.Success; } private static void GetKeyValueTypes(Type dictionaryType, out Type keyStorageType, out Type valueStorageType) { Type type = fsReflectionUtility.GetInterface(dictionaryType, typeof(IDictionary<, >)); if (type != null) { Type[] genericArguments = type.GetGenericArguments(); keyStorageType = genericArguments[0]; valueStorageType = genericArguments[1]; } else { keyStorageType = typeof(object); valueStorageType = typeof(object); } } } }