public bool TryGetFormatter(Type type, FormatterLocationStep step, ISerializationPolicy policy, out IFormatter formatter) { if (!type.IsArray) { formatter = null; return(false); } if (type.GetArrayRank() == 1) { if (FormatterUtilities.IsPrimitiveArrayType(type.GetElementType())) { formatter = (IFormatter)Activator.CreateInstance(typeof(PrimitiveArrayFormatter <>).MakeGenericType(type.GetElementType())); } else { formatter = (IFormatter)Activator.CreateInstance(typeof(ArrayFormatter <>).MakeGenericType(type.GetElementType())); } } else { formatter = (IFormatter)Activator.CreateInstance(typeof(MultiDimensionalArrayFormatter <,>).MakeGenericType(type, type.GetElementType())); } return(true); }
private void RegisterType(Type type, ISerializationPolicy policy = null) { if (!this.allowRegisteringScannedTypes) { return; } if (type.IsAbstract || type.IsInterface) { return; } if (type.IsGenericType && (type.IsGenericTypeDefinition || !type.IsFullyConstructedGenericType())) { return; } //if (this.seenSerializedTypes.Add(new SupportedType { Type = type, Policy = policy })) //{ // Debug.Log("Added " + type.GetNiceFullName()); //} this.seenSerializedTypes.Add(new SupportedType { Type = type, Policy = policy }); if (type.IsGenericType) { foreach (var arg in type.GetGenericArguments()) { this.RegisterType(arg, policy); } } }
public USerializer(ISerializationPolicy serializationPolicy, ISerializationProvider[] providers, DataTypesDatabase dataTypesDatabase, ILogger logger) { SerializationPolicy = serializationPolicy; _providers = providers; DataTypesDatabase = dataTypesDatabase; Logger = logger; }
/// <summary> /// Resets the configuration to a default configuration, as if the constructor had just been called. /// </summary> public void ResetToDefault() { lock (this.LOCK) { this.serializationPolicy = null; this.debugContext = null; } }
public bool TryGetFormatter(Type type, FormatterLocationStep step, ISerializationPolicy policy, out IFormatter formatter) { if (!typeof(Type).IsAssignableFrom(type)) { formatter = null; return(false); } formatter = new TypeFormatter(); return(true); }
public bool TryGetFormatter(Type type, FormatterLocationStep step, ISerializationPolicy policy, out IFormatter formatter) { if (!typeof(Delegate).IsAssignableFrom(type)) { formatter = null; return(false); } formatter = (IFormatter)Activator.CreateInstance(typeof(DelegateFormatter <>).MakeGenericType(type)); return(true); }
/// <summary> /// Creates a transaction log that uses the specified underlying key/value store for the per-artifact operation tables. /// </summary> /// <param name="keyValueStore">The underlying key/value store to use.</param> /// <param name="policy">The serialization policy to use when serializing objects.</param> /// <param name="version">A monotonically increasing version number; each transaction creates a unique version of the tables.</param> public TransactionLog(IKeyValueStore keyValueStore, ISerializationPolicy policy, long version) { _keyValueStore = keyValueStore; SubjectFactories = GetArtifactTable(_keyValueStore, policy, version, SubjectFactoriesKey); Observers = GetArtifactTable(_keyValueStore, policy, version, ObserversKey); Observables = GetArtifactTable(_keyValueStore, policy, version, ObservablesKey); Subjects = GetArtifactTable(_keyValueStore, policy, version, SubjectsKey); Subscriptions = GetArtifactTable(_keyValueStore, policy, version, SubscriptionsKey); SubscriptionFactories = GetArtifactTable(_keyValueStore, policy, version, SubscriptionFactoriesKey); }
/// <summary> /// Resets the configuration to a default configuration, as if the constructor had just been called. /// </summary> public void ResetToDefault() { lock (this.LOCK) { this.serializationPolicy = null; if (!object.ReferenceEquals(this.debugContext, null)) { this.debugContext.ResetToDefault(); } } }
public bool TryGetFormatter(Type type, FormatterLocationStep step, ISerializationPolicy policy, out IFormatter formatter) { if (step == FormatterLocationStep.BeforeRegisteredFormatters && type.FullName == "UnityEngine.UI.ColorBlock") { var formatterType = typeof(ColorBlockFormatter <>).MakeGenericType(type); formatter = (IFormatter)Activator.CreateInstance(formatterType); return(true); } formatter = null; return(false); }
public bool TryGetFormatter(Type type, FormatterLocationStep step, ISerializationPolicy policy, out IFormatter formatter) { Type elementType; if (step != FormatterLocationStep.AfterRegisteredFormatters || !GenericCollectionFormatter.CanFormat(type, out elementType)) { formatter = null; return(false); } formatter = (IFormatter)Activator.CreateInstance(typeof(GenericCollectionFormatter <,>).MakeGenericType(type, elementType)); return(true); }
/// <summary> /// Creates a new transaction log manager. /// </summary> /// <param name="engineId">The engine this transaction log manager is used for. Only used for logging purposes.</param> /// <param name="keyValueStore">The key/value store to write transaction logs to.</param> /// <param name="policy">The serialization policy to use when serializing objects.</param> public TransactionLogManager(Uri engineId, IKeyValueStore keyValueStore, ISerializationPolicy policy) { _engineId = engineId; _keyValueStore = keyValueStore; _policy = policy; _lock = new AsyncLock(); _versionedLogs = new Queue <ITransactionLog>(); _metadataTable = new SerializingKeyValueTable <string>( _keyValueStore.GetTable(MetadataTableName), (str, s) => { using var writer = new BinaryWriter(s); writer.Write(str); }, s => { using var reader = new BinaryReader(s); return(reader.ReadString()); } ); using (var t = _keyValueStore.CreateTransaction()) { var tx = _metadataTable.Enter(t); if (!tx.Contains(ActiveCountKey)) { Invariant.Assert(!tx.Contains(LatestKey) && !tx.Contains(HeldCountKey), "Transaction log versioning keys are only partially populated."); _activeCount = _heldCount = _latest = 0; } else { Invariant.Assert(tx.Contains(LatestKey) && tx.Contains(HeldCountKey), "Transaction log versioning keys are only partially populated."); _activeCount = long.Parse(tx[ActiveCountKey], CultureInfo.InvariantCulture); _heldCount = long.Parse(tx[HeldCountKey], CultureInfo.InvariantCulture); _latest = long.Parse(tx[LatestKey], CultureInfo.InvariantCulture); } } Tracing.Transaction_Log_Initialization(null, _engineId, _latest, _activeCount, _heldCount); for (var i = _latest - _heldCount + 1; i <= _latest; i++) { _versionedLogs.Enqueue(new TransactionLog(_keyValueStore, _policy, i)); } }
public bool TryGetFormatter(Type type, FormatterLocationStep step, ISerializationPolicy policy, out IFormatter formatter) { formatter = null; if (!typeof(ISelfFormatter).IsAssignableFrom(type)) return false; if ((step == FormatterLocationStep.BeforeRegisteredFormatters && type.IsDefined<AlwaysFormatsSelfAttribute>()) || step == FormatterLocationStep.AfterRegisteredFormatters) { formatter = (IFormatter)Activator.CreateInstance(typeof(SelfFormatterFormatter<>).MakeGenericType(type)); return true; } return false; }
private void OnLocatedEmitType(Type type, ISerializationPolicy policy) { var typeFlags = AssemblyUtilities.GetAssemblyTypeFlag(type.Assembly); if ((typeFlags & AssemblyTypeFlags.UnityEditorTypes) == AssemblyTypeFlags.UnityEditorTypes) { return; } if ((typeFlags & AssemblyTypeFlags.UserEditorTypes) == AssemblyTypeFlags.UserEditorTypes) { return; } this.RegisterType(type, policy); }
private static IFormatter <T> GetBaseFormatter(ISerializationPolicy serializationPolicy) { // This is an optimization - it's a lot cheaper to compare three references and do a null check, // than it is to look something up in a dictionary. By far most of the time, we will be using // one of these three policies. if (object.ReferenceEquals(serializationPolicy, UnityPolicy)) { if (UnityPolicyFormatter == null) { UnityPolicyFormatter = FormatterLocator.GetFormatter <T>(UnityPolicy); } return(UnityPolicyFormatter); } else if (object.ReferenceEquals(serializationPolicy, EverythingPolicy)) { if (EverythingPolicyFormatter == null) { EverythingPolicyFormatter = FormatterLocator.GetFormatter <T>(EverythingPolicy); } return(EverythingPolicyFormatter); } else if (object.ReferenceEquals(serializationPolicy, StrictPolicy)) { if (StrictPolicyFormatter == null) { StrictPolicyFormatter = FormatterLocator.GetFormatter <T>(StrictPolicy); } return(StrictPolicyFormatter); } IFormatter <T> formatter; lock (FormattersByPolicy_LOCK) { if (!FormattersByPolicy.TryGetValue(serializationPolicy, out formatter)) { formatter = FormatterLocator.GetFormatter <T>(serializationPolicy); FormattersByPolicy.Add(serializationPolicy, formatter); } } return(formatter); }
/// <summary> /// Gets an emitted formatter for a given type. /// <para /> /// NOTE: Some platforms do not support emitting. On such platforms, this method logs an error and returns null. Check whether you can emit on the current platform using <see cref="EmitUtilities.CanEmit"/>. /// </summary> /// <param name="type">The type to emit a formatter for.</param> /// <param name="policy">The serialization policy to use to determine which members the emitted formatter should serialize. If null, <see cref="SerializationPolicies.Strict"/> is used.</param> /// <returns>The type of the emitted formatter.</returns> /// <exception cref="System.ArgumentNullException">The type argument is null.</exception> public static IFormatter GetEmittedFormatter(Type type, ISerializationPolicy policy) { #if !CAN_EMIT Debug.LogError("Cannot use Reflection.Emit on the current platform. The FormatterEmitter class is currently disabled. Check whether emitting is currently possible with EmitUtilities.CanEmit."); return(null); #else if (type == null) { throw new ArgumentNullException("type"); } if (policy == null) { policy = SerializationPolicies.Strict; } IFormatter result = null; if (Formatters.TryGetInnerValue(policy, type, out result) == false) { lock (LOCK) { if (Formatters.TryGetInnerValue(policy, type, out result) == false) { EnsureRuntimeAssembly(); try { result = CreateGenericFormatter(type, runtimeEmittedModule, policy); } catch (Exception ex) { Debug.LogError("The following error occurred while emitting a formatter for the type " + type.Name); Debug.LogException(ex); } Formatters.AddInner(policy, type, result); } } } return(result); #endif }
private void OnLocatedFormatter(IFormatter formatter, ISerializationPolicy policy) { var typeFlags = AssemblyUtilities.GetAssemblyTypeFlag(formatter.SerializedType.Assembly); if ((typeFlags & AssemblyTypeFlags.UnityEditorTypes) == AssemblyTypeFlags.UnityEditorTypes) { return; } if ((typeFlags & AssemblyTypeFlags.UserEditorTypes) == AssemblyTypeFlags.UserEditorTypes) { return; } var type = formatter.SerializedType; if (type != null) { this.RegisterType(type, policy); } }
/// <summary> /// Gets an array of all serializable members on the given type. /// </summary> /// <param name="type">The type to get serializable members for.</param> /// <param name="policy">The serialization policy to use. If null, <see cref="SerializationPolicies.Strict"/> is used.</param> /// <returns>An array of all serializable members on the given type.</returns> public static MemberInfo[] GetSerializableMembers(Type type, ISerializationPolicy policy) { MemberInfo[] result; if (policy == null) { policy = SerializationPolicies.Strict; } lock (LOCK) { if (MemberArrayCache.TryGetInnerValue(policy, type, out result) == false) { List <MemberInfo> list = new List <MemberInfo>(); FindSerializableMembers(type, list, policy); result = list.ToArray(); MemberArrayCache.AddInner(policy, type, result); } } return(result); }
/// <summary> /// Tries to get a serialization policy by its id, in case a serialization graph has the policy used for serialization stored by name. /// </summary> public static bool TryGetByID(string name, out ISerializationPolicy policy) { switch (name) { case "OdinSerializerPolicies.Everything": policy = SerializationPolicies.Everything; break; case "OdinSerializerPolicies.Unity": policy = SerializationPolicies.Unity; break; case "OdinSerializerPolicies.Strict": policy = SerializationPolicies.Strict; break; default: policy = null; break; } return(policy != null); }
private static IFormatter CreateFormatter(Type type, ISerializationPolicy policy) { if (FormatterUtilities.IsPrimitiveType(type)) { throw new ArgumentException("Cannot create formatters for a primitive type like " + type.Name); } // First call formatter locators before checking for registered formatters for (int i = 0; i < FormatterLocators.Count; i++) { try { IFormatter result; if (FormatterLocators[i].LocatorInstance.TryGetFormatter(type, FormatterLocationStep.BeforeRegisteredFormatters, policy, out result)) { return(result); } } catch (TargetInvocationException ex) { throw ex; } catch (TypeInitializationException ex) { throw ex; } #pragma warning disable CS0618 // Type or member is obsolete catch (ExecutionEngineException ex) #pragma warning restore CS0618 // Type or member is obsolete { throw ex; } catch (Exception ex) { Debug.LogException(new Exception("Exception was thrown while calling FormatterLocator " + FormatterLocators[i].GetType().FullName + ".", ex)); } } // Then check for valid registered formatters for (int i = 0; i < FormatterInfos.Count; i++) { var info = FormatterInfos[i]; Type formatterType = null; if (type == info.TargetType) { formatterType = info.FormatterType; } else if (info.FormatterType.IsGenericType && info.TargetType.IsGenericParameter) { Type[] inferredArgs; if (info.FormatterType.TryInferGenericParameters(out inferredArgs, type)) { formatterType = info.FormatterType.GetGenericTypeDefinition().MakeGenericType(inferredArgs); } } else if (type.IsGenericType && info.FormatterType.IsGenericType && info.TargetType.IsGenericType && type.GetGenericTypeDefinition() == info.TargetType.GetGenericTypeDefinition()) { Type[] args = type.GetGenericArguments(); if (info.FormatterType.AreGenericConstraintsSatisfiedBy(args)) { formatterType = info.FormatterType.GetGenericTypeDefinition().MakeGenericType(args); } } if (formatterType != null) { var instance = GetFormatterInstance(formatterType); if (instance == null) { continue; } if (info.AskIfCanFormatTypes && !((IAskIfCanFormatTypes)instance).CanFormatType(type)) { continue; } return(instance); } } // Then call formatter locators after checking for registered formatters for (int i = 0; i < FormatterLocators.Count; i++) { try { IFormatter result; if (FormatterLocators[i].LocatorInstance.TryGetFormatter(type, FormatterLocationStep.AfterRegisteredFormatters, policy, out result)) { return(result); } } catch (TargetInvocationException ex) { throw ex; } catch (TypeInitializationException ex) { throw ex; } #pragma warning disable CS0618 // Type or member is obsolete catch (ExecutionEngineException ex) #pragma warning restore CS0618 // Type or member is obsolete { throw ex; } catch (Exception ex) { Debug.LogException(new Exception("Exception was thrown while calling FormatterLocator " + FormatterLocators[i].GetType().FullName + ".", ex)); } } // If we can, emit a formatter to handle serialization of this object { if (EmitUtilities.CanEmit) { var result = FormatterEmitter.GetEmittedFormatter(type, policy); if (result != null) { return(result); } } } if (EmitUtilities.CanEmit) { Debug.LogWarning("Fallback to reflection for type " + type.Name + " when emit is possible on this platform."); } // Finally, we fall back to a reflection-based formatter if nothing else has been found return((IFormatter)Activator.CreateInstance(typeof(ReflectionFormatter <>).MakeGenericType(type))); }
internal static List <IFormatter> GetAllCompatiblePredefinedFormatters(Type type, ISerializationPolicy policy) { if (FormatterUtilities.IsPrimitiveType(type)) { throw new ArgumentException("Cannot create formatters for a primitive type like " + type.Name); } List <IFormatter> formatters = new List <IFormatter>(); // First call formatter locators before checking for registered formatters for (int i = 0; i < FormatterLocators.Count; i++) { try { IFormatter result; if (FormatterLocators[i].LocatorInstance.TryGetFormatter(type, FormatterLocationStep.BeforeRegisteredFormatters, policy, out result)) { formatters.Add(result); } } catch (TargetInvocationException ex) { throw ex; } catch (TypeInitializationException ex) { throw ex; } #pragma warning disable CS0618 // Type or member is obsolete catch (ExecutionEngineException ex) #pragma warning restore CS0618 // Type or member is obsolete { throw ex; } catch (Exception ex) { Debug.LogException(new Exception("Exception was thrown while calling FormatterLocator " + FormatterLocators[i].GetType().FullName + ".", ex)); } } // Then check for valid registered formatters for (int i = 0; i < FormatterInfos.Count; i++) { var info = FormatterInfos[i]; Type formatterType = null; if (type == info.TargetType) { formatterType = info.FormatterType; } else if (info.FormatterType.IsGenericType && info.TargetType.IsGenericParameter) { Type[] inferredArgs; if (info.FormatterType.TryInferGenericParameters(out inferredArgs, type)) { formatterType = info.FormatterType.GetGenericTypeDefinition().MakeGenericType(inferredArgs); } } else if (type.IsGenericType && info.FormatterType.IsGenericType && info.TargetType.IsGenericType && type.GetGenericTypeDefinition() == info.TargetType.GetGenericTypeDefinition()) { Type[] args = type.GetGenericArguments(); if (info.FormatterType.AreGenericConstraintsSatisfiedBy(args)) { formatterType = info.FormatterType.GetGenericTypeDefinition().MakeGenericType(args); } } if (formatterType != null) { var instance = GetFormatterInstance(formatterType); if (instance == null) { continue; } if (info.AskIfCanFormatTypes && !((IAskIfCanFormatTypes)instance).CanFormatType(type)) { continue; } formatters.Add(instance); } } // Then call formatter locators after checking for registered formatters for (int i = 0; i < FormatterLocators.Count; i++) { try { IFormatter result; if (FormatterLocators[i].LocatorInstance.TryGetFormatter(type, FormatterLocationStep.AfterRegisteredFormatters, policy, out result)) { formatters.Add(result); } } catch (TargetInvocationException ex) { throw ex; } catch (TypeInitializationException ex) { throw ex; } #pragma warning disable CS0618 // Type or member is obsolete catch (ExecutionEngineException ex) #pragma warning restore CS0618 // Type or member is obsolete { throw ex; } catch (Exception ex) { Debug.LogException(new Exception("Exception was thrown while calling FormatterLocator " + FormatterLocators[i].GetType().FullName + ".", ex)); } } formatters.Add((IFormatter)Activator.CreateInstance(typeof(ReflectionFormatter <>).MakeGenericType(type))); return(formatters); }
/// <summary> /// Gets a formatter for a given type. /// </summary> /// <param name="type">The type to get a formatter for.</param> /// <param name="policy">The serialization policy to use if a formatter has to be emitted. If null, <see cref="SerializationPolicies.Strict"/> is used.</param> /// <returns> /// A formatter for the given type. /// </returns> /// <exception cref="System.ArgumentNullException">The type argument is null.</exception> public static IFormatter GetFormatter(Type type, ISerializationPolicy policy) { if (type == null) { throw new ArgumentNullException("type"); } if (policy == null) { policy = SerializationPolicies.Strict; } IFormatter result; lock (LOCK) { if (TypeFormatterMap.TryGetInnerValue(type, policy, out result) == false) { // System.ExecutionEngineException is marked obsolete in .NET 4.6. // That's all very good for .NET, but Unity still uses it, and that means we use it as well! #pragma warning disable 618 try { result = CreateFormatter(type, policy); } catch (TargetInvocationException ex) { if (ex.GetBaseException() is ExecutionEngineException) { LogAOTError(type, ex.GetBaseException() as ExecutionEngineException); } else { throw ex; } } catch (TypeInitializationException ex) { if (ex.GetBaseException() is ExecutionEngineException) { LogAOTError(type, ex.GetBaseException() as ExecutionEngineException); } else { throw ex; } } catch (ExecutionEngineException ex) { LogAOTError(type, ex); } TypeFormatterMap.AddInner(type, policy, result); #pragma warning restore 618 } } #if UNITY_EDITOR if (OnLocatedFormatter != null) { OnLocatedFormatter(result); } if (OnLocatedEmittableFormatterForType != null && result.GetType().IsGenericType) { #if CAN_EMIT if (result.GetType().GetGenericTypeDefinition() == typeof(FormatterEmitter.RuntimeEmittedFormatter <>)) { OnLocatedEmittableFormatterForType(type); } else #endif if (result.GetType().GetGenericTypeDefinition() == typeof(ReflectionFormatter <>)) { OnLocatedEmittableFormatterForType(type); } } #endif return(result); }
/// <summary> /// Gets a formatter for the type <see cref="T" />. /// </summary> /// <typeparam name="T">The type to get a formatter for.</typeparam> /// <param name="policy">The serialization policy to use if a formatter has to be emitted. If null, <see cref="SerializationPolicies.Strict"/> is used.</param> /// <returns> /// A formatter for the type <see cref="T" />. /// </returns> public static IFormatter <T> GetFormatter <T>(ISerializationPolicy policy) { return((IFormatter <T>)GetFormatter(typeof(T), policy)); }
public ReflectionFormatter(ISerializationPolicy overridePolicy) { this.OverridePolicy = overridePolicy; }
/// <summary> /// Gets a map of all serializable members on the given type. This will also properly map names extracted from <see cref="UnityEngine.Serialization.FormerlySerializedAsAttribute"/> and <see cref="PreviouslySerializedAsAttribute"/> to their corresponding members. /// </summary> /// <param name="type">The type to get a map for.</param> /// <param name="policy">The serialization policy to use. If null, <see cref="SerializationPolicies.Strict"/> is used.</param> /// <returns>A map of all serializable members on the given type.</returns> public static Dictionary <string, MemberInfo> GetSerializableMembersMap(Type type, ISerializationPolicy policy) { Dictionary <string, MemberInfo> result; if (policy == null) { policy = SerializationPolicies.Strict; } lock (LOCK) { if (MemberMapCache.TryGetInnerValue(policy, type, out result) == false) { result = FindSerializableMembersMap(type, policy); MemberMapCache.AddInner(policy, type, result); } } return(result); }
private static void FindSerializableMembers(Type type, List <MemberInfo> members, ISerializationPolicy policy) { const BindingFlags Flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly; if (type.BaseType != typeof(object) && type.BaseType != null) { FindSerializableMembers(type.BaseType, members, policy); } foreach (var member in type.GetMembers(Flags).Where(n => n is FieldInfo || n is PropertyInfo)) { if (policy.ShouldSerializeMember(member)) { bool nameAlreadyExists = members.Any(n => n.Name == member.Name); if (MemberIsPrivate(member) && nameAlreadyExists) { members.Add(GetPrivateMemberAlias(member)); } else if (nameAlreadyExists) { members.Add(GetPrivateMemberAlias(member)); } else { members.Add(member); } } } }
/// <summary> /// Emits a formatter for a given type into a given module builder, using a given serialization policy to determine which members to serialize. /// </summary> /// <param name="formattedType">Type to create a formatter for.</param> /// <param name="moduleBuilder">The module builder to emit a formatter into.</param> /// <param name="policy">The serialization policy to use for creating the formatter.</param> /// <returns>The fully constructed, emitted formatter type.</returns> public static Type EmitAOTFormatter(Type formattedType, ModuleBuilder moduleBuilder, ISerializationPolicy policy) { Dictionary <string, MemberInfo> serializableMembers = FormatterUtilities.GetSerializableMembersMap(formattedType, policy); string formatterName = moduleBuilder.Name + "." + formattedType.GetCompilableNiceFullName() + "__AOTFormatter"; string formatterHelperName = moduleBuilder.Name + "." + formattedType.GetCompilableNiceFullName() + "__FormatterHelper"; if (serializableMembers.Count == 0) { return(moduleBuilder.DefineType( formatterName, TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Class, typeof(EmptyAOTEmittedFormatter <>).MakeGenericType(formattedType) ).CreateType()); } Dictionary <Type, MethodInfo> serializerReadMethods; Dictionary <Type, MethodInfo> serializerWriteMethods; Dictionary <Type, FieldBuilder> serializerFields; FieldBuilder dictField; Dictionary <MemberInfo, List <string> > memberNames; BuildHelperType( moduleBuilder, formatterHelperName, formattedType, serializableMembers, out serializerReadMethods, out serializerWriteMethods, out serializerFields, out dictField, out memberNames ); TypeBuilder formatterType = moduleBuilder.DefineType( formatterName, TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Class, typeof(AOTEmittedFormatter <>).MakeGenericType(formattedType) ); // Read { MethodInfo readBaseMethod = formatterType.BaseType.GetMethod("ReadDataEntry", Flags.InstanceAnyVisibility); MethodBuilder readMethod = formatterType.DefineMethod( readBaseMethod.Name, MethodAttributes.Family | MethodAttributes.Virtual, readBaseMethod.ReturnType, readBaseMethod.GetParameters().Select(n => n.ParameterType).ToArray() ); readBaseMethod.GetParameters().ForEach(n => readMethod.DefineParameter(n.Position, n.Attributes, n.Name)); EmitReadMethodContents(readMethod.GetILGenerator(), formattedType, dictField, serializerFields, memberNames, serializerReadMethods); } // Write { MethodInfo writeBaseMethod = formatterType.BaseType.GetMethod("WriteDataEntries", Flags.InstanceAnyVisibility); MethodBuilder dynamicWriteMethod = formatterType.DefineMethod( writeBaseMethod.Name, MethodAttributes.Family | MethodAttributes.Virtual, writeBaseMethod.ReturnType, writeBaseMethod.GetParameters().Select(n => n.ParameterType).ToArray() ); writeBaseMethod.GetParameters().ForEach(n => dynamicWriteMethod.DefineParameter(n.Position + 1, n.Attributes, n.Name)); EmitWriteMethodContents(dynamicWriteMethod.GetILGenerator(), formattedType, serializerFields, memberNames, serializerWriteMethods); } var result = formatterType.CreateType(); // Register the formatter on the assembly ((AssemblyBuilder)moduleBuilder.Assembly).SetCustomAttribute(new CustomAttributeBuilder(typeof(RegisterFormatterAttribute).GetConstructor(new Type[] { typeof(Type), typeof(int) }), new object[] { formatterType, -1 })); return(result); }
/// <summary> /// Creates a <see cref="TransactionLogOperationReader"/> to read operations from the specified <paramref name="stream"/>. /// </summary> /// <param name="stream">The stream to load from.</param> /// <param name="policy">The serialization policy to use when serializing objects.</param> public TransactionLogOperationReader(Stream stream, ISerializationPolicy policy) : base(stream, policy) { }
public EntityWriter(Stream stream, ISerializationPolicy policy) : base(stream, policy) { }
private static IFormatter CreateGenericFormatter(Type formattedType, ModuleBuilder moduleBuilder, ISerializationPolicy policy) { Dictionary <string, MemberInfo> serializableMembers = FormatterUtilities.GetSerializableMembersMap(formattedType, policy); if (serializableMembers.Count == 0) { return((IFormatter)Activator.CreateInstance(typeof(EmptyTypeFormatter <>).MakeGenericType(formattedType))); } string helperTypeName = moduleBuilder.Name + "." + formattedType.GetCompilableNiceFullName() + "___" + formattedType.Assembly.GetName().Name + "___FormatterHelper___" + Guid.NewGuid().ToString(); Dictionary <Type, MethodInfo> serializerReadMethods; Dictionary <Type, MethodInfo> serializerWriteMethods; Dictionary <Type, FieldBuilder> serializerFields; FieldBuilder dictField; Dictionary <MemberInfo, List <string> > memberNames; BuildHelperType( moduleBuilder, helperTypeName, formattedType, serializableMembers, out serializerReadMethods, out serializerWriteMethods, out serializerFields, out dictField, out memberNames ); Type formatterType = typeof(RuntimeEmittedFormatter <>).MakeGenericType(formattedType); Delegate del1, del2; // Read { Type readDelegateType = typeof(ReadDataEntryMethodDelegate <>).MakeGenericType(formattedType); MethodInfo readDataEntryMethod = formatterType.GetMethod("ReadDataEntry", Flags.InstanceAnyVisibility); DynamicMethod dynamicReadMethod = new DynamicMethod("Dynamic_" + formattedType.GetCompilableNiceFullName(), null, readDataEntryMethod.GetParameters().Select(n => n.ParameterType).ToArray(), true); readDataEntryMethod.GetParameters().ForEach(n => dynamicReadMethod.DefineParameter(n.Position, n.Attributes, n.Name)); EmitReadMethodContents(dynamicReadMethod.GetILGenerator(), formattedType, dictField, serializerFields, memberNames, serializerReadMethods); del1 = dynamicReadMethod.CreateDelegate(readDelegateType); } // Write { Type writeDelegateType = typeof(WriteDataEntriesMethodDelegate <>).MakeGenericType(formattedType); MethodInfo writeDataEntriesMethod = formatterType.GetMethod("WriteDataEntries", Flags.InstanceAnyVisibility); DynamicMethod dynamicWriteMethod = new DynamicMethod("Dynamic_Write_" + formattedType.GetCompilableNiceFullName(), null, writeDataEntriesMethod.GetParameters().Select(n => n.ParameterType).ToArray(), true); writeDataEntriesMethod.GetParameters().ForEach(n => dynamicWriteMethod.DefineParameter(n.Position + 1, n.Attributes, n.Name)); EmitWriteMethodContents(dynamicWriteMethod.GetILGenerator(), formattedType, serializerFields, memberNames, serializerWriteMethods); del2 = dynamicWriteMethod.CreateDelegate(writeDelegateType); } return((IFormatter)Activator.CreateInstance(formatterType, del1, del2)); }
private static Dictionary <string, MemberInfo> FindSerializableMembersMap(Type type, ISerializationPolicy policy) { var map = GetSerializableMembers(type, policy).ToDictionary(n => n.Name, n => n); // foreach (var member in map.Values.ToList()) // { // var serializedAsAttributes = member.GetAttributes<UnityEngine.Serialization.FormerlySerializedAsAttribute>(); // foreach (var attr in serializedAsAttributes) // { // if (map.ContainsKey(attr.oldName) == false) // { // map.Add(attr.oldName, member); // } // } // } return(map); }