From 15740faf9fe9fe4be08965098bbf2947e096aeeb Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 14 Aug 2019 22:50:43 +0800 Subject: +Unity Runtime code --- .../Export/Serialization/UnitySurrogateSelector.cs | 115 +++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 Runtime/Export/Serialization/UnitySurrogateSelector.cs (limited to 'Runtime/Export/Serialization/UnitySurrogateSelector.cs') diff --git a/Runtime/Export/Serialization/UnitySurrogateSelector.cs b/Runtime/Export/Serialization/UnitySurrogateSelector.cs new file mode 100644 index 0000000..17f09e4 --- /dev/null +++ b/Runtime/Export/Serialization/UnitySurrogateSelector.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace UnityEngine.Serialization +{ +#if !UNITY_WINRT + /// + /// Serialization support for and that doesn't rely on reflection + /// of private members in order to be useable under the CoreCLR security model (WebPlayer). + /// + public class UnitySurrogateSelector : ISurrogateSelector + { + public ISerializationSurrogate GetSurrogate(Type type, StreamingContext context, out ISurrogateSelector selector) + { + if (type.IsGenericType) + { + var genericTypeDefinition = type.GetGenericTypeDefinition(); + if (genericTypeDefinition == typeof(List<>)) + { + selector = this; + return ListSerializationSurrogate.Default; + } + if (genericTypeDefinition == typeof(Dictionary<,>)) + { + selector = this; + var dictSurrogateType = typeof(DictionarySerializationSurrogate<,>).MakeGenericType(type.GetGenericArguments()); + return (ISerializationSurrogate) Activator.CreateInstance(dictSurrogateType); + } + } + + selector = null; + return null; + } + + public void ChainSelector(ISurrogateSelector selector) + { + throw new NotImplementedException(); + } + + public ISurrogateSelector GetNextSelector() + { + throw new NotImplementedException(); + } + } + + /// + /// Serialization support for that doesn't rely on reflection of private members. + /// + class ListSerializationSurrogate : ISerializationSurrogate + { + public static readonly ISerializationSurrogate Default = new ListSerializationSurrogate(); + + public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) + { + var list = (IList)obj; + info.AddValue("_size", list.Count); + info.AddValue("_items", ArrayFromGenericList(list)); + info.AddValue("_version", 0); // required for compatibility with platform deserialization + } + + public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) + { + var list = (IList)Activator.CreateInstance(obj.GetType()); + var size = info.GetInt32("_size"); + if (size == 0) + return list; + + var items = ((IEnumerable)info.GetValue("_items", typeof(IEnumerable))).GetEnumerator(); + for (var i = 0; i < size; ++i) + { + if (!items.MoveNext()) + throw new InvalidOperationException(); + list.Add(items.Current); + } + return list; + } + + private static Array ArrayFromGenericList(IList list) + { + var items = Array.CreateInstance(list.GetType().GetGenericArguments()[0], list.Count); + list.CopyTo(items, 0); + return items; + } + } + + /// + /// Serialization support for that doesn't rely on non public members. + /// + class DictionarySerializationSurrogate : ISerializationSurrogate + { + public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) + { + var dictionary = ((Dictionary)obj); + dictionary.GetObjectData(info, context); + } + + public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) + { + var comparer = (IEqualityComparer)info.GetValue("Comparer", typeof(IEqualityComparer)); + var dictionary = new Dictionary(comparer); + if (info.MemberCount > 3) // KeyValuePairs might not be present if the dictionary was empty + { + var keyValuePairs = + (KeyValuePair[]) info.GetValue("KeyValuePairs", typeof(KeyValuePair[])); + if (keyValuePairs != null) + foreach (var kvp in keyValuePairs) + dictionary.Add(kvp.Key, kvp.Value); + } + return dictionary; + } + } +#endif +} -- cgit v1.1-26-g67d0