summaryrefslogtreecommitdiff
path: root/Runtime/Export/Serialization
diff options
context:
space:
mode:
Diffstat (limited to 'Runtime/Export/Serialization')
-rw-r--r--Runtime/Export/Serialization/IManagedLivenessAnalysis.cs11
-rw-r--r--Runtime/Export/Serialization/IPPtrRemapper.cs9
-rw-r--r--Runtime/Export/Serialization/ISerializedStateReader.cs25
-rw-r--r--Runtime/Export/Serialization/ISerializedStateWriter.cs25
-rw-r--r--Runtime/Export/Serialization/IUnityAssetsReferenceHolder.cs9
-rw-r--r--Runtime/Export/Serialization/IUnitySerializable.cs11
-rw-r--r--Runtime/Export/Serialization/ManagedLivenessAnalysis.txt67
-rw-r--r--Runtime/Export/Serialization/PPtrRemapper.txt53
-rw-r--r--Runtime/Export/Serialization/SerializedStateReader.txt214
-rw-r--r--Runtime/Export/Serialization/SerializedStateWriter.txt220
-rw-r--r--Runtime/Export/Serialization/UnitySurrogateSelector.cs115
11 files changed, 759 insertions, 0 deletions
diff --git a/Runtime/Export/Serialization/IManagedLivenessAnalysis.cs b/Runtime/Export/Serialization/IManagedLivenessAnalysis.cs
new file mode 100644
index 0000000..e9d8f00
--- /dev/null
+++ b/Runtime/Export/Serialization/IManagedLivenessAnalysis.cs
@@ -0,0 +1,11 @@
+namespace UnityEngine
+{
+#if ENABLE_SERIALIZATION_BY_CODEGENERATION
+ public interface IManagedLivenessAnalysis
+ {
+ void Reset();
+ bool HasBeenProcessed(object value);
+ object GetNewInstanceToReplaceOldInstance(object value);
+ }
+#endif
+} \ No newline at end of file
diff --git a/Runtime/Export/Serialization/IPPtrRemapper.cs b/Runtime/Export/Serialization/IPPtrRemapper.cs
new file mode 100644
index 0000000..047615c
--- /dev/null
+++ b/Runtime/Export/Serialization/IPPtrRemapper.cs
@@ -0,0 +1,9 @@
+namespace UnityEngine
+{
+#if ENABLE_SERIALIZATION_BY_CODEGENERATION
+ public interface IPPtrRemapper
+ {
+ object GetNewInstanceToReplaceOldInstance(object value);
+ }
+#endif
+} \ No newline at end of file
diff --git a/Runtime/Export/Serialization/ISerializedStateReader.cs b/Runtime/Export/Serialization/ISerializedStateReader.cs
new file mode 100644
index 0000000..cc96a7b
--- /dev/null
+++ b/Runtime/Export/Serialization/ISerializedStateReader.cs
@@ -0,0 +1,25 @@
+using System.Collections.Generic;
+
+namespace UnityEngine
+{
+#if ENABLE_SERIALIZATION_BY_CODEGENERATION
+ public interface ISerializedStateReader
+ {
+ void Align();
+ byte ReadByte();
+ int ReadInt32();
+ float ReadSingle();
+ double ReadDouble();
+ bool ReadBoolean();
+ string ReadString();
+ object ReadUnityEngineObject();
+ object ReadAnimationCurve();
+ object ReadGradient();
+ object ReadGUIStyle();
+ object ReadRectOffset();
+
+ byte[] ReadArrayOfByte();
+ List<byte> ReadListOfByte();
+ }
+#endif
+}
diff --git a/Runtime/Export/Serialization/ISerializedStateWriter.cs b/Runtime/Export/Serialization/ISerializedStateWriter.cs
new file mode 100644
index 0000000..2bcea66
--- /dev/null
+++ b/Runtime/Export/Serialization/ISerializedStateWriter.cs
@@ -0,0 +1,25 @@
+using System.Collections.Generic;
+
+namespace UnityEngine
+{
+#if ENABLE_SERIALIZATION_BY_CODEGENERATION
+ public interface ISerializedStateWriter
+ {
+ void Align();
+ void WriteByte(byte value);
+ void WriteInt32(int value);
+ void WriteSingle(float value);
+ void WriteDouble(double value);
+ void WriteBoolean(bool value);
+ void WriteString(string value);
+ void WriteUnityEngineObject(object value);
+ void WriteAnimationCurve(object value);
+ void WriteGradient(object value);
+ void WriteGUIStyle(object value);
+ void WriteRectOffset(object value);
+
+ void WriteArrayOfByte(byte[] value);
+ void WriteListOfByte(List<byte> value);
+ }
+#endif
+}
diff --git a/Runtime/Export/Serialization/IUnityAssetsReferenceHolder.cs b/Runtime/Export/Serialization/IUnityAssetsReferenceHolder.cs
new file mode 100644
index 0000000..64fff2d
--- /dev/null
+++ b/Runtime/Export/Serialization/IUnityAssetsReferenceHolder.cs
@@ -0,0 +1,9 @@
+namespace UnityEngine
+{
+#if ENABLE_SERIALIZATION_BY_CODEGENERATION
+ public interface IUnityAssetsReferenceHolder
+ {
+ void Unity_LivenessCheck();
+ }
+#endif
+} \ No newline at end of file
diff --git a/Runtime/Export/Serialization/IUnitySerializable.cs b/Runtime/Export/Serialization/IUnitySerializable.cs
new file mode 100644
index 0000000..2abeb4f
--- /dev/null
+++ b/Runtime/Export/Serialization/IUnitySerializable.cs
@@ -0,0 +1,11 @@
+namespace UnityEngine
+{
+#if ENABLE_SERIALIZATION_BY_CODEGENERATION
+ public interface IUnitySerializable
+ {
+ void Unity_Serialize();
+ void Unity_Deserialize();
+ void Unity_RemapPPtrs();
+ }
+#endif
+} \ No newline at end of file
diff --git a/Runtime/Export/Serialization/ManagedLivenessAnalysis.txt b/Runtime/Export/Serialization/ManagedLivenessAnalysis.txt
new file mode 100644
index 0000000..4f9800e
--- /dev/null
+++ b/Runtime/Export/Serialization/ManagedLivenessAnalysis.txt
@@ -0,0 +1,67 @@
+C++RAW
+#include "UnityPrefix.h"
+#include "Configuration/UnityConfigure.h"
+#include "Runtime/Mono/MonoBehaviour.h"
+#if ENABLE_SERIALIZATION_BY_CODEGENERATION
+#include "Runtime/Mono/MonoBehaviourSerialization_ByCodeGeneration.h"
+#endif
+
+CSRAW
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using Object=UnityEngine.Object;
+using System.Runtime.CompilerServices;
+
+namespace UnityEngine.Serialization
+{
+
+CONDITIONAL ENABLE_SERIALIZATION_BY_CODEGENERATION
+CLASS public ManagedLivenessAnalysis : IManagedLivenessAnalysis
+
+ CSRAW public static IManagedLivenessAnalysis Instance = null;
+ CSRAW public readonly HashSet<int> _state = new HashSet<int>();
+
+ CSRAW public static void Init()
+ {
+ if(Instance == null)
+ Instance = new ManagedLivenessAnalysis();
+ }
+ CSRAW public static void ResetState()
+ {
+ Instance.Reset();
+ }
+ CSRAW public static void SetInstance(IManagedLivenessAnalysis analysis)
+ {
+ Instance = analysis;
+ }
+ CSRAW public void Reset()
+ {
+ ((ManagedLivenessAnalysis)Instance)._state.Clear();
+ }
+ CSRAW public bool HasBeenProcessed(object value)
+ {
+ return !_state.Add(RuntimeHelpers.GetHashCode(value));
+ }
+ CSRAW public object GetNewInstanceToReplaceOldInstance(object value)
+ {
+ return INTERNAL_GetNewInstanceToReplaceOldInstance(((UnityEngine.Object)value).GetInstanceID());
+ }
+
+ THREAD_SAFE
+ CUSTOM private static object INTERNAL_GetNewInstanceToReplaceOldInstance(int instance_id)
+ {
+ return NativeExt_MonoBehaviourSerialization_GetNewInstanceToReplaceOldInstance(instance_id);
+ }
+
+END
+
+CONDITIONAL !ENABLE_SERIALIZATION_BY_CODEGENERATION && UNITY_WINRT
+CLASS public ManagedLivenessAnalysis
+ CSRAW public static void SetInstance(IManagedLivenessAnalysis analysis)
+ {
+ }
+END
+
+CSRAW
+}
diff --git a/Runtime/Export/Serialization/PPtrRemapper.txt b/Runtime/Export/Serialization/PPtrRemapper.txt
new file mode 100644
index 0000000..e1fd2a7
--- /dev/null
+++ b/Runtime/Export/Serialization/PPtrRemapper.txt
@@ -0,0 +1,53 @@
+C++RAW
+#include "UnityPrefix.h"
+#include "Configuration/UnityConfigure.h"
+#include "Runtime/Mono/MonoBehaviour.h"
+#if ENABLE_SERIALIZATION_BY_CODEGENERATION
+#include "Runtime/Mono/MonoBehaviourSerialization_ByCodeGeneration.h"
+#endif
+
+CSRAW
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using Object=UnityEngine.Object;
+
+namespace UnityEngine.Serialization
+{
+
+CONDITIONAL ENABLE_SERIALIZATION_BY_CODEGENERATION
+CLASS public PPtrRemapper : IPPtrRemapper
+
+ CSRAW public static IPPtrRemapper Instance = null;
+
+ CSRAW public static void Init()
+ {
+ if(Instance == null)
+ Instance = new PPtrRemapper();
+ }
+ CSRAW public static void SetInstance(IPPtrRemapper remapper)
+ {
+ Instance = remapper;
+ }
+ CSRAW public object GetNewInstanceToReplaceOldInstance(object value)
+ {
+ return INTERNAL_GetNewInstanceToReplaceOldInstance(((UnityEngine.Object)value).GetInstanceID());
+ }
+
+ THREAD_SAFE
+ CUSTOM private static object INTERNAL_GetNewInstanceToReplaceOldInstance(int instance_id)
+ {
+ return NativeExt_MonoBehaviourSerialization_GetNewInstanceToReplaceOldInstance(instance_id);
+ }
+
+END
+
+CONDITIONAL !ENABLE_SERIALIZATION_BY_CODEGENERATION && UNITY_METRO
+CLASS public PPtrRemapper
+ CSRAW public static void SetInstance(IPPtrRemapper reader)
+ {
+ }
+END
+
+CSRAW
+}
diff --git a/Runtime/Export/Serialization/SerializedStateReader.txt b/Runtime/Export/Serialization/SerializedStateReader.txt
new file mode 100644
index 0000000..35f6f0c
--- /dev/null
+++ b/Runtime/Export/Serialization/SerializedStateReader.txt
@@ -0,0 +1,214 @@
+C++RAW
+
+#include "UnityPrefix.h"
+
+#include "Configuration/UnityConfigure.h"
+#include "Runtime/Mono/MonoBehaviour.h"
+#include "Runtime/Scripting/ScriptingObjectWithIntPtrField.h"
+
+#if ENABLE_SERIALIZATION_BY_CODEGENERATION
+# include "Runtime/Mono/MonoBehaviourSerialization_ByCodeGeneration.h"
+#endif
+
+CSRAW
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using Object=UnityEngine.Object;
+
+namespace UnityEngine.Serialization
+{
+
+CONDITIONAL ENABLE_SERIALIZATION_BY_CODEGENERATION
+CLASS public SerializedStateReader : ISerializedStateReader
+
+ CSRAW public static ISerializedStateReader Instance = null;
+
+ CSRAW public static void Init()
+ {
+ if(Instance == null)
+ Instance = new SerializedStateReader();
+ }
+ CSRAW public static void SetInstance(ISerializedStateReader reader)
+ {
+ Instance = reader;
+ }
+ CSRAW public void Align()
+ {
+ INTERNAL_Align();
+ }
+
+ THREAD_SAFE
+ CUSTOM private static void INTERNAL_Align()
+ {
+ NativeExt_MonoBehaviourSerialization_ReaderAlign();
+ }
+
+ CSRAW public byte ReadByte()
+ {
+ return INTERNAL_ReadByte();
+ }
+
+ THREAD_SAFE
+ CUSTOM private static byte INTERNAL_ReadByte()
+ {
+ return NativeExt_MonoBehaviourSerialization_ReadByte();
+ }
+
+ CSRAW public int ReadInt32()
+ {
+ return INTERNAL_ReadInt32();
+ }
+
+ THREAD_SAFE
+ CUSTOM private static int INTERNAL_ReadInt32()
+ {
+ return NativeExt_MonoBehaviourSerialization_ReadInt();
+ }
+
+ CSRAW public float ReadSingle()
+ {
+ return INTERNAL_ReadSingle();
+ }
+
+ THREAD_SAFE
+ CUSTOM private static float INTERNAL_ReadSingle()
+ {
+ return NativeExt_MonoBehaviourSerialization_ReadFloat();
+ }
+
+ CSRAW public double ReadDouble()
+ {
+ return INTERNAL_ReadDouble();
+ }
+
+ THREAD_SAFE
+ CUSTOM private static double INTERNAL_ReadDouble()
+ {
+ return NativeExt_MonoBehaviourSerialization_ReadDouble();
+ }
+
+ CSRAW public bool ReadBoolean()
+ {
+ return INTERNAL_ReadBoolean();
+ }
+
+ THREAD_SAFE
+ CUSTOM private static bool INTERNAL_ReadBoolean()
+ {
+ return NativeExt_MonoBehaviourSerialization_ReadBool() == 1;
+ }
+
+ CSRAW public string ReadString()
+ {
+ return INTERNAL_ReadString();
+ }
+
+ THREAD_SAFE
+ CUSTOM private static string INTERNAL_ReadString()
+ {
+ return NativeExt_MonoBehaviourSerialization_ReadString();
+ }
+
+ CSRAW public object ReadUnityEngineObject()
+ {
+ return INTERNAL_ReadUnityEngineObject();
+ }
+
+ THREAD_SAFE
+ CUSTOM private static object INTERNAL_ReadUnityEngineObject()
+ {
+ return NativeExt_MonoBehaviourSerialization_ReadUnityEngineObject();
+ }
+
+ CSRAW public object ReadAnimationCurve()
+ {
+ var animation_curve = new AnimationCurve();
+ INTERNAL_ReadAnimationCurve(animation_curve);
+ return animation_curve;
+ }
+
+ THREAD_SAFE
+ CUSTOM private static void INTERNAL_ReadAnimationCurve(AnimationCurve animation_curve)
+ {
+ NativeExt_MonoBehaviourSerialization_ReadAnimationCurve(animation_curve);
+ }
+
+ CSRAW public object ReadGradient()
+ {
+ var gradient = new Gradient();
+ INTERNAL_ReadGradient(gradient);
+ return gradient;
+ }
+
+ THREAD_SAFE
+ CUSTOM private static void INTERNAL_ReadGradient(Gradient gradient)
+ {
+ NativeExt_MonoBehaviourSerialization_ReadGradient(gradient);
+ }
+
+ CSRAW public object ReadGUIStyle()
+ {
+ var style = new GUIStyle();
+ INTERNAL_ReadGUIStyle(style);
+ return style;
+ }
+
+ THREAD_SAFE
+ CUSTOM private static void INTERNAL_ReadGUIStyle(GUIStyle style)
+ {
+ NativeExt_MonoBehaviourSerialization_ReadGUIStyle(style);
+ }
+
+ CSRAW public object ReadRectOffset()
+ {
+ var rect_offset = new RectOffset();
+ INTERNAL_RectOffset(rect_offset);
+ return rect_offset;
+ }
+
+ THREAD_SAFE
+ CUSTOM private static void INTERNAL_RectOffset(RectOffset rect_offset)
+ {
+ NativeExt_MonoBehaviourSerialization_ReadRectOffset(rect_offset);
+ }
+
+ CSRAW public byte[] ReadArrayOfByte()
+ {
+ return ReadArrayInternal<byte>(ReadByte);
+ }
+
+ CSRAW public List<byte> ReadListOfByte()
+ {
+ return ReadListInternal<byte>(ReadByte);
+ }
+
+ CSRAW private T[] ReadArrayInternal<T>(Func<T> reader)
+ {
+ var length = ReadInt32();
+ var result = new T[length];
+ for(var i = 0; i < length; ++i)
+ result[i] = reader();
+ return result;
+ }
+
+ CSRAW private List<T> ReadListInternal<T>(Func<T> reader)
+ {
+ var length = ReadInt32();
+ var result = new List<T>(length);
+ for(var i = 0; i < length; ++i)
+ result.Add(reader());
+ return result;
+ }
+
+END
+
+CONDITIONAL !ENABLE_SERIALIZATION_BY_CODEGENERATION && UNITY_METRO
+CLASS public SerializedStateReader
+ CSRAW public static void SetInstance(ISerializedStateReader reader)
+ {
+ }
+END
+
+CSRAW
+}
diff --git a/Runtime/Export/Serialization/SerializedStateWriter.txt b/Runtime/Export/Serialization/SerializedStateWriter.txt
new file mode 100644
index 0000000..fb3a07c
--- /dev/null
+++ b/Runtime/Export/Serialization/SerializedStateWriter.txt
@@ -0,0 +1,220 @@
+C++RAW
+
+#include "UnityPrefix.h"
+
+#include "Configuration/UnityConfigure.h"
+#include "Runtime/Mono/MonoBehaviour.h"
+#include "Runtime/Scripting/ScriptingObjectWithIntPtrField.h"
+
+#if ENABLE_SERIALIZATION_BY_CODEGENERATION
+# include "Runtime/Mono/MonoBehaviourSerialization_ByCodeGeneration.h"
+#endif
+
+CSRAW
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using Object=UnityEngine.Object;
+
+namespace UnityEngine.Serialization
+{
+
+CONDITIONAL ENABLE_SERIALIZATION_BY_CODEGENERATION
+CLASS public SerializedStateWriter : ISerializedStateWriter
+
+ CSRAW public static ISerializedStateWriter Instance = null;
+
+ CSRAW public static void Init()
+ {
+ if(Instance == null)
+ Instance = new SerializedStateWriter();
+ }
+
+ CSRAW public static void SetInstance(ISerializedStateWriter writer)
+ {
+ Instance = writer;
+ }
+
+ CSRAW public void Align()
+ {
+ INTERNAL_Align();
+ }
+
+ THREAD_SAFE
+ CUSTOM private static void INTERNAL_Align()
+ {
+ NativeExt_MonoBehaviourSerialization_WriterAlign();
+ }
+
+ CSRAW public void WriteByte(byte value)
+ {
+ INTERNAL_WriteByte(value);
+ }
+
+ THREAD_SAFE
+ CUSTOM private static void INTERNAL_WriteByte(byte value)
+ {
+ NativeExt_MonoBehaviourSerialization_WriteByte(value);
+ }
+
+ CSRAW public void WriteInt32(int value)
+ {
+ INTERNAL_WriteInt32(value);
+ }
+
+ THREAD_SAFE
+ CUSTOM private static void INTERNAL_WriteInt32(int value)
+ {
+ NativeExt_MonoBehaviourSerialization_WriteInt(value);
+ }
+
+ CSRAW public void WriteSingle(float value)
+ {
+ INTERNAL_WriteSingle(value);
+ }
+
+ THREAD_SAFE
+ CUSTOM private static void INTERNAL_WriteSingle(float value)
+ {
+ NativeExt_MonoBehaviourSerialization_WriteFloat(value);
+ }
+
+ CSRAW public void WriteDouble(double value)
+ {
+ INTERNAL_WriteDouble(value);
+ }
+
+ THREAD_SAFE
+ CUSTOM private static void INTERNAL_WriteDouble(double value)
+ {
+ NativeExt_MonoBehaviourSerialization_WriteDouble(value);
+ }
+
+ CSRAW public void WriteBoolean(bool value)
+ {
+ INTERNAL_WriteBoolean(value ? 1 : 0);
+ }
+
+ THREAD_SAFE
+ CUSTOM private static void INTERNAL_WriteBoolean(int value)
+ {
+ NativeExt_MonoBehaviourSerialization_WriteBool(value);
+ }
+
+ CSRAW public void WriteString(string value)
+ {
+ INTERNAL_WriteString(value);
+ }
+
+ THREAD_SAFE
+ CUSTOM private static void INTERNAL_WriteString(string value)
+ {
+ NativeExt_MonoBehaviourSerialization_WriteString(const_cast<char*>(value.AsUTF8().c_str()), value.Length());
+ }
+
+ CSRAW public void WriteUnityEngineObject(object value)
+ {
+ if(typeof(UnityEngine.Object).IsAssignableFrom(value.GetType()))
+ INTERNAL_WriteUnityEngineObject(((UnityEngine.Object)value).GetInstanceID());
+ else
+ throw new NotImplementedException("WriteUnityEngineObject on " + value.GetType().Name + " is not supported");
+ }
+
+ THREAD_SAFE
+ CUSTOM private static void INTERNAL_WriteUnityEngineObject(int value)
+ {
+ NativeExt_MonoBehaviourSerialization_WriteUnityEngineObject(value);
+ }
+
+ CSRAW public void WriteIDeserializable(object value, Type type)
+ {
+ throw new NotImplementedException("WriteIDeserializable");
+ }
+
+ CSRAW public void WriteAnimationCurve(object value)
+ {
+ INTERNAL_WriteAnimationCurve((UnityEngine.AnimationCurve)value);
+ }
+
+ THREAD_SAFE
+ CUSTOM private static void INTERNAL_WriteAnimationCurve(AnimationCurve value)
+ {
+ NativeExt_MonoBehaviourSerialization_WriteAnimationCurve(value);
+ }
+
+ CSRAW public void WriteGradient(object value)
+ {
+ INTERNAL_WriteGradient((UnityEngine.Gradient)value);
+ }
+
+ THREAD_SAFE
+ CUSTOM private static void INTERNAL_WriteGradient(Gradient value)
+ {
+ NativeExt_MonoBehaviourSerialization_WriteGradient(value);
+ }
+
+ CSRAW public void WriteGUIStyle(object value)
+ {
+ INTERNAL_WriteGUIStyle((UnityEngine.GUIStyle)value);
+ }
+
+ THREAD_SAFE
+ CUSTOM private static void INTERNAL_WriteGUIStyle(GUIStyle value)
+ {
+ NativeExt_MonoBehaviourSerialization_WriteGUIStyle(value);
+ }
+
+ CSRAW public void WriteRectOffset(object value)
+ {
+ INTERNAL_WriteRectOffset((UnityEngine.RectOffset)value);
+ }
+
+ THREAD_SAFE
+ CUSTOM private static void INTERNAL_WriteRectOffset(RectOffset value)
+ {
+ NativeExt_MonoBehaviourSerialization_WriteRectOffset(value);
+ }
+
+ CSRAW public void WriteArrayOfByte(byte[] value)
+ {
+ WriteArrayInternal(value, WriteByte);
+ }
+
+ CSRAW public void WriteListOfByte(List<byte> value)
+ {
+ WriteListInternal(value, WriteByte);
+ }
+
+ CSRAW private void WriteArrayInternal<T>(T[] value, Action<T> writer)
+ {
+ if(value != null)
+ {
+ WriteInt32(value.Length);
+ foreach(var item in value)
+ writer(item);
+ } else
+ WriteInt32(0);
+ }
+
+ CSRAW private void WriteListInternal<T>(List<T> value, Action<T> writer)
+ {
+ if(value != null)
+ {
+ WriteInt32(value.Count);
+ foreach(var item in value)
+ writer(item);
+ } else
+ WriteInt32(0);
+ }
+
+END
+
+CONDITIONAL !ENABLE_SERIALIZATION_BY_CODEGENERATION && UNITY_METRO
+CLASS public SerializedStateWriter
+ CSRAW public static void SetInstance(ISerializedStateWriter reader)
+ {
+ }
+END
+
+CSRAW
+}
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
+ /// <summary>
+ /// Serialization support for <see cref="List{T}" /> and <see cref="Dictionary{TKey,TValue}" /> that doesn't rely on reflection
+ /// of private members in order to be useable under the CoreCLR security model (WebPlayer).
+ /// </summary>
+ 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();
+ }
+ }
+
+ /// <summary>
+ /// Serialization support for <see cref="List{T}" /> that doesn't rely on reflection of private members.
+ /// </summary>
+ 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;
+ }
+ }
+
+ /// <summary>
+ /// Serialization support for <see cref="Dictionary{TKey,TValue}" /> that doesn't rely on non public members.
+ /// </summary>
+ class DictionarySerializationSurrogate<TKey, TValue> : ISerializationSurrogate
+ {
+ public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+ {
+ var dictionary = ((Dictionary<TKey, TValue>)obj);
+ dictionary.GetObjectData(info, context);
+ }
+
+ public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
+ {
+ var comparer = (IEqualityComparer<TKey>)info.GetValue("Comparer", typeof(IEqualityComparer<TKey>));
+ var dictionary = new Dictionary<TKey, TValue>(comparer);
+ if (info.MemberCount > 3) // KeyValuePairs might not be present if the dictionary was empty
+ {
+ var keyValuePairs =
+ (KeyValuePair<TKey, TValue>[]) info.GetValue("KeyValuePairs", typeof(KeyValuePair<TKey, TValue>[]));
+ if (keyValuePairs != null)
+ foreach (var kvp in keyValuePairs)
+ dictionary.Add(kvp.Key, kvp.Value);
+ }
+ return dictionary;
+ }
+ }
+#endif
+}