public MessagePackSerializer Create(SerializationContext context, Type targetType, CollectionTraits collectionTraits, PolymorphismSchema schema, SerializationTarget targetInfo) { var itemSchema = schema ?? PolymorphismSchema.Default; return(new ReflectionCollectionMessagePackSerializer <TCollection, TItem>(context, targetType, collectionTraits, itemSchema, targetInfo)); }
public MessagePackSerializer Create(SerializationContext context, Type targetType, CollectionTraits collectionTraits, PolymorphismSchema schema, SerializationTarget targetInfo) { return(new ReflectionNonGenericDictionaryMessagePackSerializer <T>(context, targetType, collectionTraits, schema, targetInfo)); }
public static void GetMetadata( Type targetType, IList <SerializingMember> members, SerializationContext context, out Func <object, object>[] getters, out Action <object, object>[] setters, out MemberInfo[] memberInfos, out DataMemberContract[] contracts, out MessagePackSerializer[] serializers ) { SerializationTarget.VerifyCanSerializeTargetType(context, targetType); if (members.Count == 0) { if (!typeof(IPackable).IsAssignableFrom(targetType)) { throw new SerializationException( String.Format( CultureInfo.CurrentCulture, "At least one serializable member is required because type '{0}' does not implement IPackable interface.", targetType ) ); } if (!typeof(IUnpackable).IsAssignableFrom(targetType)) { throw new SerializationException( String.Format( CultureInfo.CurrentCulture, "At least one serializable member is required because type '{0}' does not implement IUnpackable interface.", targetType ) ); } #if FEATURE_TAP if (context.SerializerOptions.WithAsync) { if (!typeof(IAsyncPackable).IsAssignableFrom(targetType)) { throw new SerializationException( String.Format( CultureInfo.CurrentCulture, "At least one serializable member is required because type '{0}' does not implement IAsyncPackable interface.", targetType ) ); } if (!typeof(IAsyncUnpackable).IsAssignableFrom(targetType)) { throw new SerializationException( String.Format( CultureInfo.CurrentCulture, "At least one serializable member is required because type '{0}' does not implement IAsyncUnpackable interface.", targetType ) ); } } #endif // FEATURE_TAP } getters = new Func <object, object> [members.Count]; setters = new Action <object, object> [members.Count]; memberInfos = new MemberInfo[members.Count]; contracts = new DataMemberContract[members.Count]; serializers = new MessagePackSerializer[members.Count]; for (var i = 0; i < members.Count; i++) { var member = members[i]; if (member.Member == null) { // Missing member exist because of unconbinous Id of MessagePackMember or Order of DataMember. #if UNITY contracts[i] = DataMemberContract.Null; #endif // UNITY continue; } FieldInfo asField; if ((asField = member.Member as FieldInfo) != null) { if (context.SerializerOptions.DisablePrivilegedAccess && !asField.GetIsPublic()) { continue; } getters[i] = asField.GetValue; if (!asField.IsInitOnly) { setters[i] = asField.SetValue; } } else { var property = member.Member as PropertyInfo; #if DEBUG Contract.Assert(property != null, "member.Member is PropertyInfo"); #endif // DEBUG if (context.SerializerOptions.DisablePrivilegedAccess && !property.GetIsPublic()) { continue; } var getter = property.GetGetMethod(true); if (getter == null) { ThrowMissingGetterException(targetType, i, property); } getters[i] = target => getter.InvokePreservingExceptionType(target, null); var setter = property.GetSetMethod(true); if (setter != null && (!context.SerializerOptions.DisablePrivilegedAccess || setter.GetIsPublic())) { setters[i] = (target, value) => setter.InvokePreservingExceptionType(target, new[] { value }); } } memberInfos[i] = member.Member; #if !UNITY contracts[i] = member.Contract; #else contracts[i] = member.Contract ?? DataMemberContract.Null; #endif // !UNITY var memberType = member.Member.GetMemberValueType(); if (memberType.GetIsEnum()) { serializers[i] = context.GetSerializer( memberType, EnumMessagePackSerializerHelpers.DetermineEnumSerializationMethod( context, memberType, member.GetEnumMemberSerializationMethod() ) ); } else if (DateTimeMessagePackSerializerHelpers.IsDateTime(memberType)) { serializers[i] = context.GetSerializer( memberType, DateTimeMessagePackSerializerHelpers.DetermineDateTimeConversionMethod( context, member.GetDateTimeMemberConversionMethod() ) ); } else { serializers[i] = context.GetSerializer(memberType, PolymorphismSchema.Create(memberType, member)); } } }
public Func <SerializationContext, PolymorphismSchema, MessagePackSerializer> CreateObjectConstructor( AssemblyBuilderEmittingContext context, AssemblyBuilderSerializerBuilder builder, SerializationTarget targetInfo, SerializerCapabilities?capabilities ) { var hasPackActions = targetInfo != null && !typeof(IPackable).IsAssignableFrom(builder.TargetType); var hasUnpackActions = targetInfo != null && !typeof(IUnpackable).IsAssignableFrom(builder.TargetType); var hasUnpackActionTables = hasUnpackActions && targetInfo.Members.Any(m => m.Member != null); // Except tuples #if FEATURE_TAP var hasPackAsyncActions = targetInfo != null && !typeof(IAsyncPackable).IsAssignableFrom(builder.TargetType); var hasUnpackAsyncActions = targetInfo != null && !typeof(IAsyncUnpackable).IsAssignableFrom(builder.TargetType); var hasUnpackAsyncActionTables = hasUnpackAsyncActions && targetInfo.Members.Any(m => m.Member != null); // Except tuples #endif // FEATURE_TAP // ReSharper disable RedundantDelegateCreation Func <bool, Func <ILConstruct> > packActionsInitialization = isAsync => new Func <ILConstruct>(() => builder.EmitPackOperationListInitialization(context, targetInfo, isAsync)); Func <bool, Func <ILConstruct> > packActionTableInitialization = isAsync => new Func <ILConstruct>(() => builder.EmitPackOperationTableInitialization(context, targetInfo, isAsync)); Func <ILConstruct> nullCheckerTableInitializtion = () => builder.EmitPackNullCheckerTableInitialization(context, targetInfo); Func <bool, Func <ILConstruct> > unpackActionsInitialization = isAsync => new Func <ILConstruct>(() => builder.EmitUnpackOperationListInitialization(context, targetInfo, isAsync)); Func <bool, Func <ILConstruct> > unpackActionTableInitialization = isAsync => new Func <ILConstruct>(() => builder.EmitUnpackOperationTableInitialization(context, targetInfo, isAsync)); // ReSharper restore RedundantDelegateCreation var contextfulConstructor = this.CreateConstructor( MethodAttributes.Public, ConstructorParameterTypesWithoutCapabilities, (type, il) => this.CreateContextfulObjectConstructor( context, type, capabilities, il, hasPackActions ? packActionsInitialization(false) : default(Func <ILConstruct>), hasPackActions ? packActionTableInitialization(false) : default(Func <ILConstruct>), #if DEBUG !SerializerDebugging.UseLegacyNullMapEntryHandling && #endif // DEBUG hasPackActions #if FEATURE_TAP || hasPackAsyncActions #endif // FEATURE_TAP ? nullCheckerTableInitializtion : default(Func <ILConstruct>), hasUnpackActions ? unpackActionsInitialization(false) : default(Func <ILConstruct>), hasUnpackActionTables ? unpackActionTableInitialization(false) : default(Func <ILConstruct>), #if FEATURE_TAP hasPackAsyncActions&& context.SerializationContext.SerializerOptions.WithAsync ? packActionsInitialization(true) : default(Func <ILConstruct>), hasPackAsyncActions && context.SerializationContext.SerializerOptions.WithAsync ? packActionTableInitialization(true) : default(Func <ILConstruct>), hasUnpackAsyncActions && context.SerializationContext.SerializerOptions.WithAsync ? unpackActionsInitialization(true) : default(Func <ILConstruct>), hasUnpackAsyncActionTables && context.SerializationContext.SerializerOptions.WithAsync ? unpackActionTableInitialization(true) : default(Func <ILConstruct>), #endif // FEATURE_TAP ( hasUnpackActions #if FEATURE_TAP || hasUnpackAsyncActions #endif // FEATURE_TAP ) ? () => builder.EmitMemberListInitialization(context, targetInfo) : default(Func <ILConstruct>), context.IsUnpackToUsed ? () => builder.EmitUnpackToInitialization(context) : default(Func <ILConstruct>) ) ); this.CreateConstructor( MethodAttributes.Public, ReflectionAbstractions.EmptyTypes, (_, il) => CreateDefaultObjectConstructor(contextfulConstructor, il) ); #if !NETSTANDARD1_1 && !NETSTANDARD1_3 var ctor = this._typeBuilder.CreateType().GetConstructor(ConstructorParameterTypesWithoutCapabilities); #else var ctor = this._typeBuilder.CreateTypeInfo().GetConstructor(ConstructorParameterTypesWithoutCapabilities); #endif // !NETSTANDARD1_1 && !NETSTANDARD1_3 #if DEBUG Contract.Assert(ctor != null, "ctor != null"); #endif var actualFunc = ctor.CreateConstructorDelegate <Func <SerializationContext, MessagePackSerializer> >(); return((c, _) => actualFunc(c)); }
private void BuildCollectionSerializer( TContext context, Type concreteType, PolymorphismSchema schema, out SerializationTarget targetInfo ) { #if DEBUG Contract.Assert(this.CollectionTraits.DetailedCollectionType != CollectionDetailedKind.Array); #endif // DEBUG bool isUnpackFromRequired; bool isAddItemRequired; this.DetermineSerializationStrategy(context, concreteType, out targetInfo, out isUnpackFromRequired, out isAddItemRequired); if (typeof(IPackable).IsAssignableFrom(this.TargetType)) { this.BuildIPackablePackTo(context); } #if FEATURE_TAP if (this.WithAsync(context)) { if (typeof(IAsyncPackable).IsAssignableFrom(this.TargetType)) { this.BuildIAsyncPackablePackTo(context); } } #endif // FEATURE_TAP this.BuildCollectionCreateInstance(context, targetInfo.DeserializationConstructor, targetInfo.CanDeserialize); var useUnpackable = false; if (typeof(IUnpackable).IsAssignableFrom(concreteType ?? this.TargetType)) { this.BuildIUnpackableUnpackFrom(context, this.GetUnpackableCollectionInstantiation(context), targetInfo.CanDeserialize); useUnpackable = true; } #if FEATURE_TAP if (this.WithAsync(context)) { if (typeof(IAsyncUnpackable).IsAssignableFrom(concreteType ?? this.TargetType)) { this.BuildIAsyncUnpackableUnpackFrom(context, this.GetUnpackableCollectionInstantiation(context), targetInfo.CanDeserialize); useUnpackable = true; } } #endif // FEATURE_TAP if (isAddItemRequired) { if (useUnpackable || !targetInfo.CanDeserialize) { // AddItem should never called because UnpackFromCore calls IUnpackable/IAsyncUnpackable this.BuildCollectionAddItemNotImplemented(context); } else { // For IEnumerable implements and IReadOnlyXXX implements this.BuildCollectionAddItem( context, this.CollectionTraits.AddMethod != null ? this.CollectionTraits // For declared collection. : (concreteType ?? this.TargetType).GetCollectionTraits(CollectionTraitOptions.Full, context.SerializationContext.CompatibilityOptions.AllowNonCollectionEnumerableTypes) // For concrete collection. ); } } if (isUnpackFromRequired && !useUnpackable) { this.BuildCollectionUnpackFromCore(context, concreteType, schema, targetInfo.CanDeserialize, isAsync: false); #if FEATURE_TAP if (this.WithAsync(context)) { this.BuildCollectionUnpackFromCore(context, concreteType, schema, targetInfo.CanDeserialize, isAsync: true); } #endif // FEATURE_TAP } this.BuildRestoreSchema(context, schema); }
private void DetermineSerializationStrategy( TContext context, Type concreteType, out SerializationTarget targetInfo, out bool isUnpackFromRequired, out bool isAddItemRequired ) { targetInfo = UnpackHelpers.DetermineCollectionSerializationStrategy( concreteType ?? this.TargetType, context.SerializationContext.CompatibilityOptions.AllowAsymmetricSerializer ); switch (this.CollectionTraits.DetailedCollectionType) { case CollectionDetailedKind.NonGenericEnumerable: case CollectionDetailedKind.NonGenericCollection: { isUnpackFromRequired = true; isAddItemRequired = true; break; } case CollectionDetailedKind.NonGenericList: { isUnpackFromRequired = false; isAddItemRequired = false; break; } case CollectionDetailedKind.NonGenericDictionary: { isUnpackFromRequired = false; isAddItemRequired = false; break; } case CollectionDetailedKind.GenericEnumerable: { isUnpackFromRequired = true; isAddItemRequired = true; break; } case CollectionDetailedKind.GenericDictionary: { isUnpackFromRequired = false; isAddItemRequired = false; break; } #if !NET35 && !UNITY && !NET40 && !(SILVERLIGHT && !WINDOWS_PHONE) case CollectionDetailedKind.GenericReadOnlyDictionary: { isUnpackFromRequired = false; isAddItemRequired = true; break; } case CollectionDetailedKind.GenericReadOnlyList: case CollectionDetailedKind.GenericReadOnlyCollection: { isUnpackFromRequired = false; isAddItemRequired = true; break; } #endif // !NET35 && !UNITY && !NET40 && !( SILVERLIGHT && !WINDOWS_PHONE ) default: { isUnpackFromRequired = false; isAddItemRequired = false; break; } } // switch }