internal ValueCollection(MessagePackObjectDictionary dictionary) { Contract.Assert(dictionary != null, "dictionary != null"); this._dictionary = dictionary; }
private async Task <object> UnpackMemberValueAsync(object objectGraph, Unpacker unpacker, int itemsCount, int unpacked, int index, int unpackerOffset, CancellationToken cancellationToken) { object nullable = null; var setter = index < this._setters.Length ? this._setters[index] : null; if (unpacked < itemsCount) { if (!unpacker.Read()) { SerializationExceptions.ThrowMissingItem(unpackerOffset, unpacker); } if (!unpacker.LastReadData.IsNil) { if (setter != null || this._constructorParameters != null) { nullable = await this.UnpackSingleValueAsync(unpacker, index, cancellationToken).ConfigureAwait(false); } else if (this._getters[index] != null) // null getter supposes undeclared member (should be treated as nil) { await this.UnpackAndAddCollectionItemAsync(objectGraph, unpacker, index, cancellationToken).ConfigureAwait(false); } } } if (this._constructorParameters != null) { #if DEBUG Contract.Assert(objectGraph is object[], "objectGraph is object[]"); #endif // DEBUG int argumentIndex; if (this._constructorArgumentIndexes.TryGetValue(index, out argumentIndex)) { if (nullable == null) { ReflectionNilImplicationHandler.Instance.OnUnpacked( new ReflectionSerializerNilImplicationHandlerOnUnpackedParameter( this._memberInfos[index].GetMemberValueType(), // ReSharper disable once PossibleNullReferenceException value => (objectGraph as object[])[argumentIndex] = nullable, this._contracts[index].Name, this._memberInfos[index].DeclaringType ), this._contracts[index].NilImplication )(null); } else { (objectGraph as object[])[argumentIndex] = nullable; } } } else if (setter != null) { if (nullable == null) { ReflectionNilImplicationHandler.Instance.OnUnpacked( new ReflectionSerializerNilImplicationHandlerOnUnpackedParameter( this._memberInfos[index].GetMemberValueType(), value => setter(objectGraph, nullable), this._contracts[index].Name, this._memberInfos[index].DeclaringType ), this._contracts[index].NilImplication )(null); } else { setter(objectGraph, nullable); } } return(objectGraph); } // UnpackMemberValueAsync
private static IList <SerializingMember> ComplementMembers(IList <SerializingMember> candidates, SerializationContext context, Type targetType) { if (candidates.Count == 0) { return(candidates); } if (candidates[0].Contract.Id < 0) { return(candidates); } if (context.CompatibilityOptions.OneBoundDataMemberOrder && candidates[0].Contract.Id == 0) { throw new NotSupportedException( "Cannot specify order value 0 on DataMemberAttribute when SerializationContext.CompatibilityOptions.OneBoundDataMemberOrder is set to true." ); } #if !UNITY var maxId = candidates.Max(item => item.Contract.Id); #else int maxId = -1; foreach (var id in candidates.Select(item => item.Contract.Id)) { maxId = Math.Max(id, maxId); } #endif var result = new List <SerializingMember>(maxId + 1); for (int source = 0, destination = context.CompatibilityOptions.OneBoundDataMemberOrder ? 1 : 0; source < candidates.Count; source++, destination++) { #if DEBUG Contract.Assert(candidates[source].Contract.Id >= 0, "candidates[ source ].Contract.Id >= 0"); #endif // DEBUG if (candidates[source].Contract.Id < destination) { throw new SerializationException( String.Format( CultureInfo.CurrentCulture, "The member ID '{0}' is duplicated in the '{1}' elementType.", candidates[source].Contract.Id, targetType ) ); } while (candidates[source].Contract.Id > destination) { result.Add(new SerializingMember()); destination++; } result.Add(candidates[source]); } VerifyNilImplication(targetType, result); VerifyKeyUniqueness(result); return(result); }
/// <summary> /// Emit array element storing instructions. /// Post condition is evaluation stack will no be modified as previous state. /// </summary> /// <param name="elementType"><see cref="Type"/> of array element. This can be generaic parameter.</param> /// <param name="arrayLoadingEmitter"> /// Delegate to emittion of array loading instruction. /// 1st argument is this instance. /// Post condition is that exactly one target array will be added on the top of stack and its element type is <paramref name="elementType"/>. /// </param> /// <param name="index">Index of array element.</param> /// <param name="elementLoadingEmitter"> /// Delegate to emittion of storing element loading instruction. /// 1st argument is this instance. /// Post condition is that exactly one storing element will be added on the top of stack and its type is <paramref name="elementType"/> compatible. /// </param> public void EmitAnyStelem(Type elementType, Action <TracingILGenerator> arrayLoadingEmitter, long index, Action <TracingILGenerator> elementLoadingEmitter) { Contract.Assert(0 <= index); this.EmitAnyStelem(elementType, arrayLoadingEmitter, il => il.EmitLiteralInteger(index), elementLoadingEmitter); }
public static void ValidateNamespace(string @namespace, string parameterName) { if (@namespace == null) { throw new ArgumentNullException("namespace"); } if (@namespace.Length == 0) { // Global is OK. return; } var matches = NamespacePattern.Matches(@namespace); if (matches.Count == 1 && matches[0].Success && matches[0].Index == 0 && matches[0].Length == @namespace.Length) { return; } // Get invalid value. int position = 0; int validLength = 0; for (int i = 0; i < matches.Count; i++) { if (matches[i].Index == validLength) { validLength += matches[i].Length; } else { position = validLength; break; } } Contract.Assert(position >= 0, "position >= 0"); var category = CharUnicodeInfo.GetUnicodeCategory(@namespace, position); if (IsPrintable(category)) { throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, "Char at {0}('{1}'\\u{2}[{3}] is not used for namespace.", position, @namespace[position], ( ushort )@namespace[position], category ), parameterName ); } else { throw new ArgumentException( String.Format( CultureInfo.CurrentCulture, "Char at {0}(\\u{1}[{2}] is not used for namespace.", position, ( ushort )@namespace[position], category ), parameterName ); } }
private void GetDatePartBC(out long year, out int month, out int day, out int dayOfYear) { Contract.Assert(this.unixEpochSeconds < -UnixEpochInSeconds, this.unixEpochSeconds + " > " + (-UnixEpochInSeconds)); // From coreclr System.DateTime.cs // https://github.com/dotnet/coreclr/blob/0825741447c14a6a70c60b7c429e16f95214e74e/src/mscorlib/shared/System/DateTime.cs#L863 // First, use 0001-01-01 as epoch to simplify leap year calculation. // This method calculate negative offset from 0001-01-01. var seconds = unchecked (( ulong )((this.unixEpochSeconds + UnixEpochInSeconds) * -1)); // number of days since 0001-01-01 var daysOffset = seconds / SecondsPerDay; daysOffset += (seconds % SecondsPerDay) > 0 ? 1u : 0u; // number of whole 400-year periods since 0001-01-01 var numberOf400Years = (daysOffset - 1) / DaysPer400Years; // decrement offset 1 to adjust 1 to 12-31 // day number within 400-year period var daysIn400Years = unchecked (( uint )(daysOffset - numberOf400Years * DaysPer400Years)); // number of whole 100-year periods within 400-year period var numberOf100Years = daysIn400Years <= (DaysPer100Years + 1) // 1st year is leap year (power of 400) ? 0 : ((daysIn400Years - 2) / DaysPer100Years); // decrement 1st leap year day and offset 1 to adjust 1 to 12-31 // day number within 100-year period var daysIn100Years = daysIn400Years - numberOf100Years * DaysPer100Years; // number of whole 4-year periods within 100-year period var numberOf4years = daysIn100Years == 0 ? 0 : ((daysIn100Years - 1) / DaysPer4Years); // decrement offset 1 to adjust 1 to 12-31 // day number within 4-year period var daysIn4Years = daysIn100Years - numberOf4years * DaysPer4Years; // number of whole years within 4-year period var numberOf1Year = daysIn4Years <= (DaysPerYear + (numberOf4years != 0 ? 1 : 0)) // is leap year in 4 years range? ? 0 : ((daysIn4Years - 2) / DaysPerYear); // decrement 1st leap year day and offset 1 to adjust 1 to 12-31 // compute year, note that 0001 -1 is 0000 (=B.C.1) year = -unchecked (( long )(numberOf400Years * 400 + numberOf100Years * 100 + numberOf4years * 4 + numberOf1Year)); var isLeapYear = numberOf1Year == 0 && (numberOf4years != 0 || numberOf100Years == 0); // day number within year var daysInYear = isLeapYear ? (366 - daysIn4Years) : (365 - (daysIn4Years - 1 - numberOf1Year * DaysPerYear)); dayOfYear = unchecked (( int )(daysInYear + 1)); // Leap year calculation var days = isLeapYear ? DaysToMonth366 : DaysToMonth365; // All months have more than 32 days, so n >> 5 is a good conservative // estimate for the month var numberOfMonth = (daysInYear >> 5) + 1; #if DEBUG Contract.Assert(numberOfMonth <= 12, numberOfMonth + "<= 12, daysInYear = " + daysInYear); #endif // DEBUG // m = 1-based month number while (daysInYear >= days[numberOfMonth]) { numberOfMonth++; #if DEBUG Contract.Assert(numberOfMonth <= 12, numberOfMonth + "<= 12, daysInYear = " + daysInYear); #endif // DEBUG } // compute month and day month = unchecked (( int )numberOfMonth); day = unchecked (( int )(daysInYear - days[numberOfMonth - 1] + 1)); }
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)); } } }
private static ImmutableCollectionType DetermineImmutableCollectionType(Type targetType) { if (targetType.Namespace != "System.Collections.Immutable") { return(ImmutableCollectionType.Unknown); } if (!targetType.GetIsGenericType()) { return(ImmutableCollectionType.Unknown); } switch (targetType.GetGenericTypeDefinition().Name) { case "ImmutableArray`1": { return(ImmutableCollectionType.ImmutableArray); } case "ImmutableList`1": { return(ImmutableCollectionType.ImmutableList); } case "ImmutableHashSet`1": { return(ImmutableCollectionType.ImmutableHashSet); } case "ImmutableSortedSet`1": { return(ImmutableCollectionType.ImmutableSortedSet); } case "ImmutableQueue`1": { return(ImmutableCollectionType.ImmutableQueue); } case "ImmutableStack`1": { return(ImmutableCollectionType.ImmutableStack); } case "ImmutableDictionary`2": { return(ImmutableCollectionType.ImmutableDictionary); } case "ImmutableSortedDictionary`2": { return(ImmutableCollectionType.ImmutableSortedDictionary); } default: { #if DEBUG && !UNITY Contract.Assert(false, "Unknown type:" + targetType); #endif // DEBUG && !UNITY // ReSharper disable HeuristicUnreachableCode return(ImmutableCollectionType.Unknown); // ReSharper restore HeuristicUnreachableCode } } }
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); }
protected internal override T UnpackFromCore(Unpacker unpacker) { object result = this._constructorParameters == null ? ReflectionExtensions.CreateInstancePreservingExceptionType(typeof(T)) : this._constructorParameters.Select(p => p.GetHasDefaultValue() ? p.DefaultValue : p.ParameterType.GetIsValueType() ? ReflectionExtensions.CreateInstancePreservingExceptionType(p.ParameterType) : null ).ToArray(); var unpacked = 0; var asUnpackable = result as IUnpackable; if (asUnpackable != null) { asUnpackable.UnpackFromMessage(unpacker); return(( T )result); } if (unpacker.IsArrayHeader) { var itemsCount = UnpackHelpers.GetItemsCount(unpacker); for (int i = 0; i < itemsCount; i++) { result = this.UnpackMemberValue(result, unpacker, itemsCount, ref unpacked, i, i); } } else { #if DEBUG && !UNITY Contract.Assert(unpacker.IsMapHeader, "unpacker.IsMapHeader"); #endif // DEBUG && !UNITY var itemsCount = UnpackHelpers.GetItemsCount(unpacker); for (int i = 0; i < itemsCount; i++) { string name; if (!unpacker.ReadString(out name)) { throw SerializationExceptions.NewUnexpectedEndOfStream(); } if (name == null) { // missing member, drain the value and discard it. if (!unpacker.Read()) { throw SerializationExceptions.NewMissingItem(i); } continue; } int index; if (!this._memberIndexes.TryGetValue(name, out index)) { // key does not exist in the object, skip the associated value if (unpacker.Skip() == null) { throw SerializationExceptions.NewMissingItem(i); } continue; } result = this.UnpackMemberValue(result, unpacker, itemsCount, ref unpacked, index, i); } } if (this._constructorParameters == null) { return(( T )result); } else { return(ReflectionExtensions.CreateInstancePreservingExceptionType <T>(typeof(T), result as object[])); } }
// ReSharper disable UnusedParameter.Local private static MessagePackSerializer TryCreateImmutableCollectionSerializer(SerializationContext context, Type targetType, PolymorphismSchema schema) { #if NET35 || NET40 || SILVERLIGHT // ImmutableCollections does not support above platforms. return(null); #else if (targetType.Namespace != "System.Collections.Immutable" && targetType.Namespace != "Microsoft.FSharp.Collections") { return(null); } if (!targetType.GetIsGenericType()) { return(null); } var itemSchema = (schema ?? PolymorphismSchema.Default); switch (DetermineImmutableCollectionType(targetType)) { case ImmutableCollectionType.ImmutableArray: case ImmutableCollectionType.ImmutableList: case ImmutableCollectionType.ImmutableHashSet: case ImmutableCollectionType.ImmutableSortedSet: case ImmutableCollectionType.ImmutableQueue: { return (ReflectionExtensions.CreateInstancePreservingExceptionType <IGenericBuiltInSerializerFactory>( typeof(ImmutableCollectionSerializerFactory <,>).MakeGenericType(targetType, targetType.GetGenericArguments()[0]) ).Create(context, itemSchema)); } case ImmutableCollectionType.ImmutableStack: { return (ReflectionExtensions.CreateInstancePreservingExceptionType <IGenericBuiltInSerializerFactory>( typeof(ImmutableStackSerializerFactory <,>).MakeGenericType(targetType, targetType.GetGenericArguments()[0]) ).Create(context, itemSchema)); } case ImmutableCollectionType.ImmutableDictionary: case ImmutableCollectionType.ImmutableSortedDictionary: { return (ReflectionExtensions.CreateInstancePreservingExceptionType <IGenericBuiltInSerializerFactory>( typeof(ImmutableDictionarySerializerFactory <, ,>).MakeGenericType(targetType, targetType.GetGenericArguments()[0], targetType.GetGenericArguments()[1]) ).Create(context, itemSchema)); } case ImmutableCollectionType.FSharpList: { return (ReflectionExtensions.CreateInstancePreservingExceptionType <IGenericBuiltInSerializerFactory>( typeof(FSharpCollectionSerializerFactory <,>).MakeGenericType(targetType, targetType.GetGenericArguments()[0]), "ListModule" ).Create(context, itemSchema)); } case ImmutableCollectionType.FSharpSet: { return (ReflectionExtensions.CreateInstancePreservingExceptionType <IGenericBuiltInSerializerFactory>( typeof(FSharpCollectionSerializerFactory <,>).MakeGenericType(targetType, targetType.GetGenericArguments()[0]), "SetModule" ).Create(context, itemSchema)); } case ImmutableCollectionType.FSharpMap: { return (ReflectionExtensions.CreateInstancePreservingExceptionType <IGenericBuiltInSerializerFactory>( typeof(FSharpMapSerializerFactory <, ,>).MakeGenericType(targetType, targetType.GetGenericArguments()[0], targetType.GetGenericArguments()[1]) ).Create(context, itemSchema)); } default: { #if DEBUG Contract.Assert(false, "Unknown type:" + targetType); #endif // DEBUG // ReSharper disable HeuristicUnreachableCode return(null); // ReSharper restore HeuristicUnreachableCode } } #endif // NET35 || NET40 || SILVERLIGHT }
public static IMessagePackSingleObjectSerializer Create(Type targetType, SerializationContext context) { if (targetType == null) { throw new ArgumentNullException("targetType"); } if (context == null) { throw new ArgumentNullException("context"); } #if !UNITY Contract.Ensures(Contract.Result <IMessagePackSerializer>() != null); #endif // !UNITY #if XAMIOS || XAMDROID || UNITY return(CreateInternal(context, targetType, null)); #else // MPS.Create should always return new instance, and creator delegate should be cached for performance. #if NETFX_CORE var factory = _creatorCache.GetOrAdd( targetType, type => { var contextParameter = Expression.Parameter(typeof(SerializationContext), "context"); // Utilize covariance of delegate. return (Expression.Lambda <Func <SerializationContext, IMessagePackSingleObjectSerializer> >( Expression.Call( null, Metadata._MessagePackSerializer.Create1_Method.MakeGenericMethod(type), contextParameter ), contextParameter ).Compile()); } ); #elif SILVERLIGHT || NETFX_35 Func <SerializationContext, IMessagePackSingleObjectSerializer> factory; lock ( _syncRoot ) { _creatorCache.TryGetValue(targetType, out factory); } if (factory == null) { // Utilize covariance of delegate. factory = Delegate.CreateDelegate( typeof(Func <SerializationContext, IMessagePackSingleObjectSerializer>), Metadata._MessagePackSerializer.Create1_Method.MakeGenericMethod(targetType) ) as Func <SerializationContext, IMessagePackSingleObjectSerializer>; Contract.Assert(factory != null); lock ( _syncRoot ) { _creatorCache[targetType] = factory; } } #else var factory = _creatorCache.GetOrAdd( targetType, type => // Utilize covariance of delegate. Delegate.CreateDelegate( typeof(Func <SerializationContext, IMessagePackSingleObjectSerializer>), Metadata._MessagePackSerializer.Create1_Method.MakeGenericMethod(type) ) as Func <SerializationContext, IMessagePackSingleObjectSerializer> ); #endif // NETFX_CORE return(factory(context)); #endif // XAMIOS || XAMDROID || UNITY else }
private void CreateContextfulObjectConstructor( AssemblyBuilderEmittingContext context, Type baseType, SerializerCapabilities?capabilities, TracingILGenerator il, Func <ILConstruct> packActionListInitializerProvider, Func <ILConstruct> packActionTableInitializerProvider, Func <ILConstruct> nullCheckerTableInitializerProvider, Func <ILConstruct> unpackActionListInitializerProvider, Func <ILConstruct> unpackActionTableInitializerProvider, #if FEATURE_TAP Func <ILConstruct> packAsyncActionListInitializerProvider, Func <ILConstruct> packAsyncActionTableInitializerProvider, Func <ILConstruct> unpackAsyncActionListInitializerProvider, Func <ILConstruct> unpackAsyncActionTableInitializerProvider, #endif // FEATURE_TAP Func <ILConstruct> memberNamesInitializerProvider, Func <ILConstruct> unpackToInitializerProvider ) { /* * .ctor( SerializationContext context ) * : base( ( context ?? SerializationContext.Default ).CompabilityOptions.PackerCompatibilityOptions ) * { * this._serializer0 = context.GetSerializer<T0>(); * this._serializer1 = context.GetSerializer<T1>(); * this._serializer2 = context.GetSerializer<T2>(); * : * } */ // : base() il.EmitLdarg_0(); il.EmitLdarg_1(); if (this._specification.TargetCollectionTraits.CollectionType == CollectionKind.NotCollection) { if (capabilities.HasValue) { il.EmitAnyLdc_I4(( int )capabilities.Value); il.EmitCallConstructor( baseType.GetRuntimeConstructor(ConstructorParameterTypesWithCapabilities) ); } else { il.EmitCallConstructor( baseType.GetRuntimeConstructor(ConstructorParameterTypesWithoutCapabilities) ); } } else { Contract.Assert(capabilities.HasValue); il.EmitCall(this._methodTable[MethodName.RestoreSchema]); il.EmitAnyLdc_I4(( int )capabilities.Value); il.EmitCallConstructor( baseType.GetRuntimeConstructor(CollectionConstructorParameterTypes) ); } // this._serializerN = context.GetSerializer<T>(); foreach (var entry in this._serializers) { var targetType = Type.GetTypeFromHandle(entry.Key.TypeHandle); MethodInfo getMethod = Metadata._SerializationContext.GetSerializer1_Parameter_Method.MakeGenericMethod(targetType); il.EmitLdarg_0(); il.EmitLdarg_1(); if (targetType.GetIsEnum()) { il.EmitLdarg_1(); il.EmitTypeOf(targetType); il.EmitAnyLdc_I4(( int )entry.Key.EnumSerializationMethod); il.EmitCall(Metadata._EnumMessagePackSerializerHelpers.DetermineEnumSerializationMethodMethod); il.EmitBox(typeof(EnumSerializationMethod)); } else if (DateTimeMessagePackSerializerHelpers.IsDateTime(targetType)) { il.EmitLdarg_1(); il.EmitAnyLdc_I4(( int )entry.Key.DateTimeConversionMethod); il.EmitCall(Metadata._DateTimeMessagePackSerializerHelpers.DetermineDateTimeConversionMethodMethod); il.EmitBox(typeof(DateTimeConversionMethod)); } else { if (entry.Key.PolymorphismSchema == null) { il.EmitLdnull(); } else { entry.Value.SchemaProvider(il); } } il.EmitCallvirt(getMethod); il.EmitStfld(entry.Value.Field); } foreach (var entry in this._cachedFieldInfos) { il.EmitLdarg_0(); il.EmitLdtoken(entry.Value.Target); il.EmitLdtoken(entry.Value.Target.DeclaringType); il.EmitCall(Metadata._FieldInfo.GetFieldFromHandle); il.EmitStfld(entry.Value.StorageFieldBuilder); } foreach (var entry in this._cachedMethodBases) { il.EmitLdarg_0(); il.EmitLdtoken(entry.Value.Target); il.EmitLdtoken(entry.Value.Target.DeclaringType); il.EmitCall(Metadata._MethodBase.GetMethodFromHandle); il.EmitStfld(entry.Value.StorageFieldBuilder); } if (packActionListInitializerProvider != null) { packActionListInitializerProvider().Evaluate(il); } #if FEATURE_TAP if (packAsyncActionListInitializerProvider != null) { packAsyncActionListInitializerProvider().Evaluate(il); } #endif // FEATURE_TAP if (nullCheckerTableInitializerProvider != null) { nullCheckerTableInitializerProvider().Evaluate(il); } if (packActionTableInitializerProvider != null) { packActionTableInitializerProvider().Evaluate(il); } #if FEATURE_TAP if (packAsyncActionTableInitializerProvider != null) { packAsyncActionTableInitializerProvider().Evaluate(il); } #endif // FEATURE_TAP if (unpackActionListInitializerProvider != null) { unpackActionListInitializerProvider().Evaluate(il); } #if FEATURE_TAP if (unpackAsyncActionListInitializerProvider != null) { unpackAsyncActionListInitializerProvider().Evaluate(il); } #endif // FEATURE_TAP if (unpackActionTableInitializerProvider != null) { unpackActionTableInitializerProvider().Evaluate(il); } #if FEATURE_TAP if (unpackAsyncActionTableInitializerProvider != null) { unpackAsyncActionTableInitializerProvider().Evaluate(il); } #endif // FEATURE_TAP if (memberNamesInitializerProvider != null) { memberNamesInitializerProvider().Evaluate(il); } if (unpackToInitializerProvider != null) { unpackToInitializerProvider().Evaluate(il); } foreach (var cachedDelegateInfo in context.GetCachedDelegateInfos()) { // this for stfld il.EmitLdargThis(); var delegateType = cachedDelegateInfo.BackingField.FieldType.ResolveRuntimeType(); // Declare backing field now. var field = context.GetDeclaredField(cachedDelegateInfo.BackingField.FieldName).ResolveRuntimeField(); if (cachedDelegateInfo.IsThisInstance) { il.EmitLdargThis(); } else { il.EmitLdnull(); } // OK this should not be ldvirtftn because target is private or static. il.EmitLdftn(cachedDelegateInfo.TargetMethod.ResolveRuntimeMethod()); // call extern .ctor(Object, void*) il.EmitNewobj(delegateType.GetConstructors().Single()); il.EmitStfld(field); } il.EmitRet(); }
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 && !NETSTANDARD2_0 var ctor = this._typeBuilder.CreateType().GetConstructor(ConstructorParameterTypesWithoutCapabilities); #else var ctor = this._typeBuilder.CreateTypeInfo().GetConstructor(ConstructorParameterTypesWithoutCapabilities); #endif // !NETSTANDARD1_1 && !NETSTANDARD1_3 && !NETSTANDARD2_0 #if DEBUG Contract.Assert(ctor != null, "ctor != null"); #endif var actualFunc = ctor.CreateConstructorDelegate <Func <SerializationContext, MessagePackSerializer> >(); return((c, _) => actualFunc(c)); }
#pragma warning restore 618 private static async Task PackToMapAsyncCore <TObject>( SerializationContext serializationContext, Packer packer, TObject target, IDictionary <string, Func <Packer, TObject, CancellationToken, Task> > operations, IDictionary <string, Func <TObject, bool> > nullCheckers, CancellationToken cancellationToken ) { #if ASSERT Contract.Assert(packer != null); Contract.Assert(operations != null); #endif // ASSERT if (nullCheckers != null && serializationContext != null && serializationContext.DictionarySerlaizationOptions.OmitNullEntry) { #if ASSERT Contract.Assert(!SerializerDebugging.UseLegacyNullMapEntryHandling); #endif // ASSERT // Skipping causes the entries count header reducing, so count up null entries first. var nullCount = 0; foreach (var nullChecker in nullCheckers) { if (nullChecker.Value(target)) { nullCount++; } } await packer.PackMapHeaderAsync(operations.Count - nullCount, cancellationToken).ConfigureAwait(false); foreach (var operation in operations) { Func <TObject, bool> nullChecker; if (nullCheckers.TryGetValue(operation.Key, out nullChecker)) { if (nullChecker(target)) { continue; } } await packer.PackStringAsync(operation.Key, cancellationToken).ConfigureAwait(false); await operation.Value(packer, target, cancellationToken).ConfigureAwait(false); } } else { await packer.PackMapHeaderAsync(operations.Count, cancellationToken).ConfigureAwait(false); foreach (var operation in operations) { // Compat path await packer.PackStringAsync(operation.Key, cancellationToken).ConfigureAwait(false); await operation.Value(packer, target, cancellationToken).ConfigureAwait(false); } } }
public static CollectionTraits GetCollectionTraits(this Type source, CollectionTraitOptions options) { #if DEBUG Contract.Assert(!source.GetContainsGenericParameters(), "!source.GetContainsGenericParameters()"); #endif // DEBUG /* * SPEC * If the object has single public method TEnumerator GetEnumerator() ( where TEnumerator implements IEnumerator<TItem>), * then the object is considered as the collection of TItem. * When the object is considered as the collection of TItem, TItem is KeyValuePair<TKey,TValue>, * and the object implements IDictionary<TKey,TValue>, then the object is considered as dictionary of TKey and TValue. * Else, if the object has single public method IEnumerator GetEnumerator(), then the object is considered as the collection of Object. * When it also implements IDictionary, however, it is considered dictionary of Object and Object. * Otherwise, that means it implements multiple collection interface, is following. * First, if the object implements IDictionary<MessagePackObject,MessagePackObject>, then it is considered as MPO dictionary. * Second, if the object implements IEnumerable<MPO>, then it is considered as MPO dictionary. * Third, if the object implement SINGLE IDictionary<TKey,TValue> and multiple IEnumerable<T>, then it is considered as dictionary of TKey and TValue. * Fourth, the object is considered as UNSERIALIZABLE member. This behavior similer to DataContract serialization behavor * (see http://msdn.microsoft.com/en-us/library/aa347850.aspx ). */ if (!source.IsAssignableTo(typeof(IEnumerable))) { return(CollectionTraits.NotCollection); } if (source.IsArray) { return (new CollectionTraits( CollectionDetailedKind.Array, source.GetElementType(), null, // Never used for array. null, // Never used for array. null // Never used for array. )); } MethodInfo getEnumerator = source.GetMethod("GetEnumerator", ReflectionAbstractions.EmptyTypes); if (getEnumerator != null && getEnumerator.ReturnType.IsAssignableTo(typeof(IEnumerator))) { // If public 'GetEnumerator' is found, it is primary collection traits. CollectionTraits result; if (TryCreateCollectionTraitsForHasGetEnumeratorType(source, options, getEnumerator, out result)) { return(result); } } Type ienumerableT = null; Type icollectionT = null; #if !NETFX_35 && !UNITY Type isetT = null; #endif // !NETFX_35 && !UNITY Type ilistT = null; Type idictionaryT = null; #if !NETFX_35 && !UNITY && !NETFX_40 && !(SILVERLIGHT && !WINDOWS_PHONE) Type ireadOnlyCollectionT = null; Type ireadOnlyListT = null; Type ireadOnlyDictionaryT = null; #endif // !NETFX_35 && !UNITY && !NETFX_40 && !( SILVERLIGHT && !WINDOWS_PHONE ) Type ienumerable = null; Type icollection = null; Type ilist = null; Type idictionary = null; var sourceInterfaces = source.FindInterfaces(FilterCollectionType, null); if (source.GetIsInterface() && FilterCollectionType(source, null)) { var originalSourceInterfaces = sourceInterfaces.ToArray(); var concatenatedSourceInterface = new Type[originalSourceInterfaces.Length + 1]; concatenatedSourceInterface[0] = source; for (int i = 0; i < originalSourceInterfaces.Length; i++) { concatenatedSourceInterface[i + 1] = originalSourceInterfaces[i]; } sourceInterfaces = concatenatedSourceInterface; } foreach (var type in sourceInterfaces) { CollectionTraits result; if (TryCreateGenericCollectionTraits(source, type, options, out result)) { return(result); } if (!DetermineCollectionInterfaces( type, ref idictionaryT, #if !NETFX_35 && !UNITY && !NETFX_40 && !(SILVERLIGHT && !WINDOWS_PHONE) ref ireadOnlyDictionaryT, #endif // !NETFX_35 && !UNITY && !NETFX_40 && !( SILVERLIGHT && !WINDOWS_PHONE ) ref ilistT, #if !NETFX_35 && !UNITY && !NETFX_40 && !(SILVERLIGHT && !WINDOWS_PHONE) ref ireadOnlyListT, #endif // !NETFX_35 && !UNITY && !NETFX_40 && !( SILVERLIGHT && !WINDOWS_PHONE ) #if !NETFX_35 && !UNITY ref isetT, #endif // !NETFX_35 && !UNITY ref icollectionT, #if !NETFX_35 && !UNITY && !NETFX_40 && !(SILVERLIGHT && !WINDOWS_PHONE) ref ireadOnlyCollectionT, #endif // !NETFX_35 && !UNITY && !NETFX_40 && !( SILVERLIGHT && !WINDOWS_PHONE ) ref ienumerableT, ref idictionary, ref ilist, ref icollection, ref ienumerable ) ) { return(CollectionTraits.Unserializable); } } if (idictionaryT != null) { var elementType = typeof(KeyValuePair <,>).MakeGenericType(idictionaryT.GetGenericArguments()); var genericArguments = idictionaryT.GetGenericArguments(); return (new CollectionTraits( CollectionDetailedKind.GenericDictionary, elementType, GetGetEnumeratorMethodFromElementType(source, elementType, options), GetAddMethod(source, genericArguments[0], genericArguments[1], options), GetCountGetterMethod(source, elementType, options) )); } #if !NETFX_35 && !UNITY && !NETFX_40 && !(SILVERLIGHT && !WINDOWS_PHONE) if (ireadOnlyDictionaryT != null) { var elementType = typeof(KeyValuePair <,>).MakeGenericType(ireadOnlyDictionaryT.GetGenericArguments()); return (new CollectionTraits( CollectionDetailedKind.GenericReadOnlyDictionary, elementType, GetGetEnumeratorMethodFromElementType(source, elementType, options), null, // add GetCountGetterMethod(source, elementType, options) )); } #endif // !NETFX_35 && !UNITY && !NETFX_40 && !( SILVERLIGHT && !WINDOWS_PHONE ) if (ienumerableT != null) { var elementType = ienumerableT.GetGenericArguments()[0]; return (new CollectionTraits( (ilistT != null) ? CollectionDetailedKind.GenericList #if !NETFX_35 && !UNITY : (isetT != null) ? CollectionDetailedKind.GenericSet #endif // !NETFX_35 && !UNITY : (icollectionT != null) ? CollectionDetailedKind.GenericCollection #if !NETFX_35 && !UNITY && !NETFX_40 && !(SILVERLIGHT && !WINDOWS_PHONE) : (ireadOnlyListT != null) ? CollectionDetailedKind.GenericReadOnlyList #endif // !NETFX_35 && !UNITY && !NETFX_40 && !( SILVERLIGHT && !WINDOWS_PHONE ) #if !NETFX_35 && !UNITY && !NETFX_40 && !(SILVERLIGHT && !WINDOWS_PHONE) : (ireadOnlyCollectionT != null) ? CollectionDetailedKind.GenericReadOnlyCollection #endif // !NETFX_35 && !UNITY && !NETFX_40 && !( SILVERLIGHT && !WINDOWS_PHONE ) : CollectionDetailedKind.GenericEnumerable, elementType, GetGetEnumeratorMethodFromEnumerableType(source, ienumerableT, options), GetAddMethod(source, elementType, options), GetCountGetterMethod(source, elementType, options) )); } if (idictionary != null) { return (new CollectionTraits( CollectionDetailedKind.NonGenericDictionary, typeof(object), GetGetEnumeratorMethodFromEnumerableType(source, idictionary, options), GetAddMethod(source, typeof(object), typeof(object), options), GetCountGetterMethod(source, typeof(object), options) )); } if (ienumerable != null) { var addMethod = GetAddMethod(source, typeof(object), options | CollectionTraitOptions.WithAddMethod); if (addMethod != null) { return (new CollectionTraits( (ilist != null) ? CollectionDetailedKind.NonGenericList : (icollection != null) ? CollectionDetailedKind.NonGenericCollection : CollectionDetailedKind.NonGenericEnumerable, typeof(object), GetGetEnumeratorMethodFromEnumerableType(source, ienumerable, options), addMethod, GetCountGetterMethod(source, typeof(object), options) )); } } return(CollectionTraits.NotCollection); }
private void GetDatePartAD(out long year, out int month, out int day, out int dayOfYear) { Contract.Assert(this.unixEpochSeconds >= -UnixEpochInSeconds, this.unixEpochSeconds + " > " + (-UnixEpochInSeconds)); // From coreclr System.DateTime.cs // https://github.com/dotnet/coreclr/blob/0825741447c14a6a70c60b7c429e16f95214e74e/src/mscorlib/shared/System/DateTime.cs#L863 // First, use 0001-01-01 as epoch to simplify leap year calculation var seconds = unchecked (( ulong )(this.unixEpochSeconds + UnixEpochInSeconds)); // number of days since 0001-01-01 var daysOffset = seconds / SecondsPerDay; // number of whole 400-year periods since 0001-01-01 var numberOf400Years = daysOffset / DaysPer400Years; // day number within 400-year period var daysIn400Years = unchecked (( uint )(daysOffset - numberOf400Years * DaysPer400Years)); // number of whole 100-year periods within 400-year period var numberOf100Years = daysIn400Years / DaysPer100Years; // Last 100-year period has an extra day, so decrement result if 4 if (numberOf100Years == 4) { numberOf100Years = 3; } // day number within 100-year period var daysIn100Years = daysIn400Years - numberOf100Years * DaysPer100Years; // number of whole 4-year periods within 100-year period var numberOf4years = daysIn100Years / DaysPer4Years; // day number within 4-year period var daysIn4Years = daysIn100Years - numberOf4years * DaysPer4Years; // number of whole years within 4-year period var numberOf1Year = daysIn4Years / DaysPerYear; // Last year has an extra day, so decrement result if 4 if (numberOf1Year == 4) { numberOf1Year = 3; } // compute year year = unchecked (( long )(numberOf400Years * 400 + numberOf100Years * 100 + numberOf4years * 4 + numberOf1Year + 1)); // day number within year var daysInYear = daysIn4Years - numberOf1Year * DaysPerYear; dayOfYear = unchecked (( int )(daysInYear + 1)); // Leap year calculation var isLeapYear = numberOf1Year == 3 && (numberOf4years != 24 || numberOf100Years == 3); var days = isLeapYear ? DaysToMonth366 : DaysToMonth365; // All months have less than 32 days, so n >> 5 is a good conservative // estimate for the month var numberOfMonth = (daysInYear >> 5) + 1; #if DEBUG Contract.Assert(numberOfMonth <= 12, numberOfMonth + "<= 12, daysInYear = " + daysInYear); #endif // DEBUG // m = 1-based month number while (daysInYear >= days[numberOfMonth]) { numberOfMonth++; #if DEBUG Contract.Assert(numberOfMonth <= 12, numberOfMonth + "<= 12, daysInYear = " + daysInYear); #endif // DEBUG } // compute month and day month = unchecked (( int )numberOfMonth); day = unchecked (( int )(daysInYear - days[numberOfMonth - 1] + 1)); }
public static void GetMetadata( IList <SerializingMember> members, SerializationContext context, out Func <object, object>[] getters, out Action <object, object>[] setters, out MemberInfo[] memberInfos, out DataMemberContract[] contracts, out IMessagePackSerializer[] serializers) { 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 IMessagePackSerializer[members.Count]; for (var i = 0; i < members.Count; i++) { var member = members[i]; if (member.Member == null) { #if UNITY contracts[i] = DataMemberContract.Null; #endif // UNITY continue; } FieldInfo asField; if ((asField = member.Member as FieldInfo) != null) { getters[i] = asField.GetValue; setters[i] = asField.SetValue; } else { var property = member.Member as PropertyInfo; #if DEBUG && !UNITY Contract.Assert(property != null, "member.Member is PropertyInfo"); #endif // DEBUG && !UNITY getters[i] = target => property.GetGetMethod(true).InvokePreservingExceptionType(target, null); var setter = property.GetSetMethod(true); if (setter != null) { 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)); } } }
internal Enumerator(MessagePackObjectDictionary dictionary) { Contract.Assert(dictionary != null, "dictionary != null"); this._underlying = dictionary.GetEnumerator(); }
private IEnumerable <TConstruct> BuildTupleUnpackFromCore(TContext context, IList <Type> itemTypes, IList <PolymorphismSchema> itemSchemaList, bool isAsync) { var tupleTypeList = TupleItems.CreateTupleTypeList(itemTypes); yield return (this.EmitCheckIsArrayHeaderExpression(context, context.Unpacker)); yield return (this.EmitCheckTupleCardinarityExpression( context, context.Unpacker, itemTypes.Count )); var unpackingContext = this.GetTupleUnpackingContextInfo(context, itemTypes); foreach (var statement in unpackingContext.Statements) { yield return(statement); } var unpackValueArguments = new[] { context.Unpacker, context.UnpackingContextInUnpackValueMethods, context.IndexOfItem, context.ItemsCount } #if FEATURE_TAP .Concat(isAsync ? new[] { this.ReferCancellationToken(context, 2) } : NoConstructs).ToArray() #endif // FEATURE_TAP ; for (var i = 0; i < itemTypes.Count; i++) { var propertyName = SerializationTarget.GetTupleItemNameFromIndex(i); var unpackedItem = context.DefineUnpackedItemParameterInSetValueMethods(itemTypes[i]); var setUnpackValueOfMethodName = MethodNamePrefix.SetUnpackedValueOf + propertyName; var index = i; this.ExtractPrivateMethod( context, AdjustName(MethodNamePrefix.UnpackValue + propertyName, isAsync), false, // isStatic #if FEATURE_TAP isAsync ? TypeDefinition.TaskType : #endif // FEATURE_TAP TypeDefinition.VoidType, () => this.EmitUnpackItemValueStatement( context, itemTypes[index], this.MakeStringLiteral(context, propertyName), context.TupleItemNilImplication, null, // memberInfo itemSchemaList.Count == 0 ? null : itemSchemaList[index], context.Unpacker, context.UnpackingContextInUnpackValueMethods, context.IndexOfItem, context.ItemsCount, context.IsDeclaredMethod(setUnpackValueOfMethodName) ? this.EmitGetPrivateMethodDelegateExpression( context, context.GetDeclaredMethod(setUnpackValueOfMethodName) ) : this.ExtractPrivateMethod( context, setUnpackValueOfMethodName, false, // isStatic TypeDefinition.VoidType, () => this.EmitSetField( context, context.UnpackingContextInSetValueMethods, unpackingContext.VariableType, propertyName, unpackedItem ), context.UnpackingContextInSetValueMethods, unpackedItem ), isAsync ), unpackValueArguments ); } TConstruct currentTuple = null; for (int nest = tupleTypeList.Count - 1; nest >= 0; nest--) { var gets = Enumerable.Range(nest * 7, Math.Min(itemTypes.Count - nest * 7, 7)) .Select(i => this.EmitGetFieldExpression( context, context.UnpackingContextInCreateObjectFromContext, new FieldDefinition( unpackingContext.VariableType, SerializationTarget.GetTupleItemNameFromIndex(i), itemTypes[i] ) ) ); if (currentTuple != null) { gets = gets.Concat(new[] { currentTuple }); } currentTuple = this.EmitCreateNewObjectExpression( context, null, // Tuple is reference contextType. tupleTypeList[nest].GetConstructors().Single(), gets.ToArray() ); } #if DEBUG Contract.Assert(currentTuple != null); #endif unpackingContext.Factory = this.EmitNewPrivateMethodDelegateExpressionWithCreation( context, new MethodDefinition( MethodName.CreateObjectFromContext, null, null, true, // isStatic this.TargetType, unpackingContext.Type ), () => this.EmitRetrunStatement( context, currentTuple ), context.UnpackingContextInCreateObjectFromContext ); var unpackHelperArguments = new[] { context.Unpacker, unpackingContext.Variable, unpackingContext.Factory, this.EmitGetMemberNamesExpression(context), this.EmitGetActionsExpression(context, ActionType.UnpackFromArray, isAsync) } #if FEATURE_TAP .Concat(isAsync ? new[] { this.ReferCancellationToken(context, 2) } : NoConstructs).ToArray() #endif // FEATURE_TAP ; yield return (this.EmitRetrunStatement( context, this.EmitInvokeMethodExpression( context, null, new MethodDefinition( AdjustName(MethodName.UnpackFromArray, isAsync), new [] { unpackingContext.Type, this.TargetType }, TypeDefinition.UnpackHelpersType, true, // isStatic #if FEATURE_TAP isAsync ? typeof(Task <>).MakeGenericType(this.TargetType) : #endif // FEATURE_TAP this.TargetType, unpackHelperArguments.Select(a => a.ContextType).ToArray() ), unpackHelperArguments ) )); }
// TODO: NLiblet public void EmitAnyStloc(LocalBuilder local) { Contract.Assert(local != null); this.EmitAnyStloc(local.LocalIndex); }
private IEnumerable <TConstruct> BuildTuplePackToCore(TContext context, IList <Type> itemTypes, IList <PolymorphismSchema> itemSchemaList, bool isAsync) { // Note: cardinality is put as array length by PackHelper. var depth = -1; var tupleTypeList = TupleItems.CreateTupleTypeList(itemTypes); var propertyInvocationChain = new List <PropertyInfo>(itemTypes.Count % 7 + 1); var packValueArguments = new[] { context.Packer, context.PackToTarget } #if FEATURE_TAP .Concat(isAsync ? new[] { this.ReferCancellationToken(context, 3) } : NoConstructs).ToArray() #endif // FEATURE_TAP ; for (int i = 0; i < itemTypes.Count; i++) { if (i % 7 == 0) { depth++; } for (int j = 0; j < depth; j++) { // .TRest.TRest ... var restProperty = tupleTypeList[j].GetProperty("Rest"); #if DEBUG Contract.Assert(restProperty != null); #endif propertyInvocationChain.Add(restProperty); } var itemNProperty = tupleTypeList[depth].GetProperty("Item" + ((i % 7) + 1)); propertyInvocationChain.Add(itemNProperty); #if DEBUG Contract.Assert( itemNProperty != null, tupleTypeList[depth].GetFullName() + "::Item" + ((i % 7) + 1) + " [ " + depth + " ] @ " + i ); #endif var count = i; DefinePrivateMethod( context, AdjustName(MethodNamePrefix.PackValue + SerializationTarget.GetTupleItemNameFromIndex(i), isAsync), false, // isStatic #if FEATURE_TAP isAsync ? TypeDefinition.TaskType : #endif // FEATURE_TAP TypeDefinition.VoidType, () => this.EmitSequentialStatements( context, TypeDefinition.VoidType, this.EmitPackTupleItemStatements( context, itemTypes[count], context.Packer, context.PackToTarget, propertyInvocationChain, itemSchemaList.Count == 0 ? null : itemSchemaList[count], isAsync ) ), packValueArguments ); propertyInvocationChain.Clear(); } var packHelperArguments = new Dictionary <string, TConstruct> { { "Packer", context.Packer }, { "Target", context.PackToTarget }, { "Operations", this.EmitGetActionsExpression(context, ActionType.PackToArray, isAsync) } }; #if FEATURE_TAP if (isAsync) { packHelperArguments.Add("CancellationToken", this.ReferCancellationToken(context, 3)); } #endif // FEATURE_TAP var packHelperParameterTypeDefinition = #if FEATURE_TAP isAsync ? typeof(PackToArrayAsyncParameters <>) : #endif // FEATURE_TAP typeof(PackToArrayParameters <>); var packHelperParameterType = TypeDefinition.GenericValueType(packHelperParameterTypeDefinition, this.TargetType); var packHelperMethod = new MethodDefinition( AdjustName(MethodName.PackToArray, isAsync), new [] { TypeDefinition.Object(this.TargetType) }, TypeDefinition.PackHelpersType, true, // isStatic #if FEATURE_TAP isAsync ? TypeDefinition.TaskType : #endif // FEATURE_TAP TypeDefinition.VoidType, packHelperParameterType ); var packHelperParameters = this.DeclareLocal(context, packHelperParameterType, "packHelperParameters"); yield return(packHelperParameters); foreach (var construct in this.CreatePackUnpackHelperArgumentInitialization(context, packHelperParameters, packHelperArguments)) { yield return(construct); } var methodInvocation = this.EmitInvokeMethodExpression( context, null, packHelperMethod, this.EmitMakeRef(context, packHelperParameters) ); if (isAsync) { // Wrap with return to return Task methodInvocation = this.EmitRetrunStatement(context, methodInvocation); } yield return(methodInvocation); }
/// <summary> /// Emit array element storing instructions. /// Post condition is evaluation stack will no be modified as previous state. /// </summary> /// <param name="elementType"><see cref="Type"/> of array element. This can be generaic parameter.</param> /// <param name="arrayLoadingEmitter"> /// Delegate to emittion of array loading instruction. /// 1st argument is this instance. /// Post condition is that exactly one target array will be added on the top of stack and its element type is <paramref name="elementType"/>. /// </param> /// <param name="indexEmitter"> /// Delegate to emittion of array index. /// 1st argument is this instance. /// Post condition is that int4 or int8 type value will be added on the top of stack and its element type is <paramref name="elementType"/>. /// </param> /// <param name="elementLoadingEmitter"> /// Delegate to emittion of storing element loading instruction. /// 1st argument is this instance. /// Post condition is that exactly one storing element will be added on the top of stack and its type is <paramref name="elementType"/> compatible. /// </param> public void EmitAnyStelem(Type elementType, Action <TracingILGenerator> arrayLoadingEmitter, Action <TracingILGenerator> indexEmitter, Action <TracingILGenerator> elementLoadingEmitter) { Contract.Assert(elementType != null); Contract.Assert(indexEmitter != null); Contract.Assert(arrayLoadingEmitter != null); Contract.Assert(elementLoadingEmitter != null); arrayLoadingEmitter(this); indexEmitter(this); elementLoadingEmitter(this); if (elementType.IsGenericParameter) { this.EmitStelem(elementType); return; } if (!elementType.GetIsValueType()) { // ref this.EmitStelem_Ref(); return; } #if !NETSTANDARD1_1 && !NETSTANDARD1_3 switch (Type.GetTypeCode(elementType)) #else switch (NetStandardCompatibility.GetTypeCode(elementType)) #endif // !NETSTANDARD1_1 && !NETSTANDARD1_3 { case System.TypeCode.Boolean: case System.TypeCode.SByte: case System.TypeCode.Byte: { this.EmitStelem_I1(); break; } case System.TypeCode.Int16: case System.TypeCode.UInt16: case System.TypeCode.Char: { this.EmitStelem_I2(); break; } case System.TypeCode.Int32: case System.TypeCode.UInt32: { this.EmitStelem_I4(); break; } case System.TypeCode.Int64: case System.TypeCode.UInt64: { this.EmitStelem_I8(); break; } case System.TypeCode.Single: { this.EmitStelem_R4(); break; } case System.TypeCode.Double: { this.EmitStelem_R8(); break; } default: { // Other value type this.EmitLdelema(elementType); elementLoadingEmitter(this); this.EmitStobj(elementType); break; } } }
/// <summary> /// Gets the <see cref="MessagePackSerializer{T}"/> with this instance. /// </summary> /// <typeparam name="T">Type of serialization/deserialization target.</typeparam> /// <param name="providerParameter">A provider specific parameter. See remarks section for details.</param> /// <returns> /// <see cref="MessagePackSerializer{T}"/>. /// If there is exiting one, returns it. /// Else the new instance will be created. /// </returns> /// <remarks> /// <para> /// This method automatically register new instance via <see cref="SerializerRepository.Register{T}(MessagePackSerializer{T})"/>. /// </para> /// <para> /// Currently, only following provider parameters are supported. /// <list type="table"> /// <listheader> /// <term>Target type</term> /// <description>Provider parameter</description> /// </listheader> /// <item> /// <term><see cref="EnumMessagePackSerializer{TEnum}"/> or its descendants.</term> /// <description><see cref="EnumSerializationMethod"/>. The returning instance corresponds to this value for serialization.</description> /// </item> /// </list> /// <note><c>null</c> is valid value for <paramref name="providerParameter"/> and it indeicates default behavior of parameter.</note> /// </para> /// </remarks> public MessagePackSerializer <T> GetSerializer <T>(object providerParameter) { #if !UNITY Contract.Ensures(Contract.Result <MessagePackSerializer <T> >() != null); #endif // !UNITY var schema = providerParameter as PolymorphismSchema; // Explicitly generated serializer should always used, so get it first. MessagePackSerializer <T> serializer = this._serializers.Get <T>(this, providerParameter); if (serializer != null) { return(serializer); } object aquiredLock = null; bool lockTaken = false; try { try { } finally { var newLock = new object(); #if SILVERLIGHT || NETFX_35 || UNITY Monitor.Enter(newLock); try { lock (this._typeLock) { lockTaken = !this._typeLock.TryGetValue(typeof(T), out aquiredLock); if (lockTaken) { aquiredLock = newLock; this._typeLock.Add(typeof(T), newLock); } } #else bool newLockTaken = false; try { Monitor.Enter(newLock, ref newLockTaken); aquiredLock = this._typeLock.GetOrAdd(typeof(T), _ => newLock); lockTaken = newLock == aquiredLock; #endif // if SILVERLIGHT || NETFX_35 || UNITY } finally { #if SILVERLIGHT || NETFX_35 || UNITY if (!lockTaken) #else if (!lockTaken && newLockTaken) #endif // if SILVERLIGHT || NETFX_35 || UNITY { // Release the lock which failed to become 'primary' lock. Monitor.Exit(newLock); } } } if (Monitor.TryEnter(aquiredLock)) { // Decrement monitor counter. Monitor.Exit(aquiredLock); if (lockTaken) { // First try to create generic serializer w/o code generation. serializer = GenericSerializer.Create <T>(this, schema); if (serializer == null) { #if !XAMIOS && !XAMDROID && !UNITY if (this.IsRuntimeGenerationDisabled) { #endif // !XAMIOS && !XAMDROID && !UNITY // On debugging, or AOT only envs, use reflection based aproach. serializer = this.GetSerializerWithoutGeneration <T>(schema) ?? MessagePackSerializer.CreateReflectionInternal <T>(this, this.EnsureConcreteTypeRegistered(typeof(T)), schema); #if !XAMIOS && !XAMDROID && !UNITY } else { // This thread creating new type serializer. serializer = MessagePackSerializer.CreateInternal <T>(this, schema); } #endif // !XAMIOS && !XAMDROID && !UNITY } } else { // This thread owns existing lock -- thus, constructing self-composite type. // Prevent release owned lock. aquiredLock = null; return(new LazyDelegatingMessagePackSerializer <T>(this, providerParameter)); } // Some types always have to use provider. MessagePackSerializerProvider provider; var asEnumSerializer = serializer as ICustomizableEnumSerializer; if (asEnumSerializer != null) { #if DEBUG && !UNITY Contract.Assert(typeof(T).GetIsEnum(), typeof(T) + " is not enum but generated serializer is ICustomizableEnumSerializer"); #endif // DEBUG && !UNITY provider = new EnumMessagePackSerializerProvider(typeof(T), asEnumSerializer); } else { #if DEBUG && !UNITY Contract.Assert(!typeof(T).GetIsEnum(), typeof(T) + " is enum but generated serializer is not ICustomizableEnumSerializer : " + (serializer == null ? "null" : serializer.GetType().FullName)); #endif // DEBUG && !UNITY // Creates provider even if no schema -- the schema might be specified future for the type. // It is OK to use polymorphic provider for value type. #if !UNITY provider = new PolymorphicSerializerProvider <T>(serializer); #else provider = new PolymorphicSerializerProvider <T>(this, serializer); #endif // !UNITY } this._serializers.Register(typeof(T), provider); } else { // Wait creation by other thread. // Acquire as 'waiting' lock. Monitor.Enter(aquiredLock); } // Re-get to avoid duplicated registration and handle provider parameter or get the one created by prececing thread. // If T is null and schema is not provided or default schema is provided, then exception will be thrown here from the new provider. return(this._serializers.Get <T>(this, providerParameter)); } finally { if (lockTaken) { #if SILVERLIGHT || NETFX_35 || UNITY lock (this._typeLock) { this._typeLock.Remove(typeof(T)); } #else object dummy; this._typeLock.TryRemove(typeof(T), out dummy); #endif // if SILVERLIGHT || NETFX_35 || UNITY } if (aquiredLock != null) { // Release primary lock or waiting lock. Monitor.Exit(aquiredLock); } } }
} // UnpackAndAddCollectionItem #if FEATURE_TAP protected internal override async Task <T> UnpackFromAsyncCore(Unpacker unpacker, CancellationToken cancellationToken) { object result = this._constructorParameters == null ? ReflectionExtensions.CreateInstancePreservingExceptionType(typeof(T)) : this._constructorParameters.Select(p => p.GetHasDefaultValue() ? p.DefaultValue : p.ParameterType.GetIsValueType() ? ReflectionExtensions.CreateInstancePreservingExceptionType(p.ParameterType) : null ).ToArray(); var unpacked = 0; var asAsyncUnpackable = result as IAsyncUnpackable; if (asAsyncUnpackable != null) { await asAsyncUnpackable.UnpackFromMessageAsync(unpacker, cancellationToken).ConfigureAwait(false); return(( T )result); } var asUnpackable = result as IUnpackable; if (asUnpackable != null) { await Task.Run(() => asUnpackable.UnpackFromMessage(unpacker), cancellationToken).ConfigureAwait(false); return(( T )result); } if (unpacker.IsArrayHeader) { var itemsCount = UnpackHelpers.GetItemsCount(unpacker); for (int i = 0; i < itemsCount; i++) { result = await this.UnpackMemberValueAsync(result, unpacker, itemsCount, unpacked, i, i, cancellationToken).ConfigureAwait(false); unpacked++; } } else { #if DEBUG Contract.Assert(unpacker.IsMapHeader, "unpacker.IsMapHeader"); #endif // DEBUG var itemsCount = UnpackHelpers.GetItemsCount(unpacker); for (int i = 0; i < itemsCount; i++) { var name = await unpacker.ReadStringAsync(cancellationToken).ConfigureAwait(false); if (!name.Success) { SerializationExceptions.ThrowUnexpectedEndOfStream(unpacker); } if (name.Value == null) { // missing member, drain the value and discard it. if (!unpacker.Read() && i < itemsCount - 1) { SerializationExceptions.ThrowMissingKey(i + 1, unpacker); } continue; } int index; if (!this._memberIndexes.TryGetValue(name.Value, out index)) { // key does not exist in the object, skip the associated value if (unpacker.Skip() == null) { SerializationExceptions.ThrowMissingItem(i, unpacker); } continue; } result = await this.UnpackMemberValueAsync(result, unpacker, itemsCount, unpacked, index, i, cancellationToken).ConfigureAwait(false); unpacked++; } } if (this._constructorParameters == null) { return(( T )result); } else { return(ReflectionExtensions.CreateInstancePreservingExceptionType <T>(typeof(T), result as object[])); } }
/// <summary> /// Gets the <see cref="MessagePackSerializer{T}"/> with this instance. /// </summary> /// <typeparam name="T">Type of serialization/deserialization target.</typeparam> /// <param name="providerParameter">A provider specific parameter. See remarks section for details.</param> /// <returns> /// <see cref="MessagePackSerializer{T}"/>. /// If there is exiting one, returns it. /// Else the new instance will be created. /// </returns> /// <remarks> /// <para> /// This method automatically register new instance via <see cref="SerializerRepository.Register{T}(MessagePackSerializer{T})"/>. /// </para> /// <para> /// Currently, only following provider parameters are supported. /// <list type="table"> /// <listheader> /// <term>Target type</term> /// <description>Provider parameter</description> /// </listheader> /// <item> /// <term><see cref="EnumMessagePackSerializer{TEnum}"/> or its descendants.</term> /// <description><see cref="EnumSerializationMethod"/>. The returning instance corresponds to this value for serialization.</description> /// </item> /// </list> /// <note><c>null</c> is valid value for <paramref name="providerParameter"/> and it indeicates default behavior of parameter.</note> /// </para> /// </remarks> public MessagePackSerializer<T> GetSerializer<T>( object providerParameter ) { #if DEBUG Contract.Ensures( Contract.Result<MessagePackSerializer<T>>() != null ); #endif // DEBUG // Explicitly generated serializer should always used, so get it first. MessagePackSerializer<T> serializer = this._serializers.Get<T>( this, providerParameter ); if ( serializer != null ) { return serializer; } bool lockTaken = false; lock ( this._generationLock ) { // Re-get to check because other thread might create the serializer when I wait the lock. serializer = this._serializers.Get<T>( this, providerParameter ); if ( serializer != null ) { return serializer; } try { try { } finally { #if !FEATURE_CONCURRENT lock ( this._typeLock ) { var typeLock = new object(); object aquiredLock; lockTaken = !this._typeLock.TryGetValue( typeof( T ), out aquiredLock ); if ( lockTaken ) { this._typeLock.Add( typeof( T ), typeLock ); } } #else var typeLock = new object(); var aquiredTypeLock = this._typeLock.GetOrAdd( typeof( T ), _ => typeLock ); lockTaken = typeLock == aquiredTypeLock; #endif // !FEATURE_CONCURRENT } if ( lockTaken ) { // First try to create generic serializer w/o code generation. var schema = ( providerParameter ?? PolymorphismSchema.Create( typeof( T ), null ) ) as PolymorphismSchema; serializer = GenericSerializer.Create<T>( this, schema ); if ( serializer == null ) { #if !UNITY if ( !this._serializerGeneratorOptions.CanRuntimeCodeGeneration ) { #endif // !UNITY // On debugging, or AOT only envs, use reflection based aproach. serializer = this.GetSerializerWithoutGeneration<T>( schema ) ?? this.OnResolveSerializer<T>( schema ) ?? MessagePackSerializer.CreateReflectionInternal<T>( this, this.EnsureConcreteTypeRegistered( typeof( T ) ), schema ); #if !UNITY } else { // This thread creating new type serializer. serializer = this.OnResolveSerializer<T>( schema ) ?? MessagePackSerializer.CreateInternal<T>( this, schema ); } #endif // !UNITY } } else { // This thread owns existing lock -- thus, constructing self-composite type. return new LazyDelegatingMessagePackSerializer<T>( this, providerParameter ); } // Some types always have to use provider. MessagePackSerializerProvider provider; var asEnumSerializer = serializer as ICustomizableEnumSerializer; if ( asEnumSerializer != null ) { #if DEBUG Contract.Assert( typeof( T ).GetIsEnum(), typeof( T ) + " is not enum but generated serializer is ICustomizableEnumSerializer" ); #endif // DEBUG provider = new EnumMessagePackSerializerProvider( typeof( T ), asEnumSerializer ); } else { #if DEBUG Contract.Assert( !typeof( T ).GetIsEnum(), typeof( T ) + " is enum but generated serializer is not ICustomizableEnumSerializer : " + ( serializer == null ? "null" : serializer.GetType().FullName ) ); #endif // DEBUG // Creates provider even if no schema -- the schema might be specified future for the type. // It is OK to use polymorphic provider for value type. #if !UNITY provider = new PolymorphicSerializerProvider<T>( serializer ); #else provider = new PolymorphicSerializerProvider<T>( this, serializer ); #endif // !UNITY } #if !UNITY Type nullableType; MessagePackSerializerProvider nullableSerializerProvider; SerializerRepository.GetNullableCompanion( typeof( T ), this, serializer, out nullableType, out nullableSerializerProvider ); this._serializers.Register( typeof( T ), provider, nullableType, nullableSerializerProvider, SerializerRegistrationOptions.WithNullable ); #else this._serializers.Register( typeof( T ), provider, null, null, SerializerRegistrationOptions.None ); #endif // !UNITY // Re-get to avoid duplicated registration and handle provider parameter or get the one created by prececing thread. // If T is null and schema is not provided or default schema is provided, then exception will be thrown here from the new provider. return this._serializers.Get<T>( this, providerParameter ); } finally { if ( lockTaken ) { #if !FEATURE_CONCURRENT lock ( this._typeLock ) { this._typeLock.Remove( typeof( T ) ); } #else object dummy; this._typeLock.TryRemove( typeof( T ), out dummy ); #endif // !FEATURE_CONCURRENT } } } }
private static bool CheckTargetEligibility(SerializationContext context, MemberInfo member) { var asProperty = member as PropertyInfo; var asField = member as FieldInfo; Type returnType; if (asProperty != null) { if (asProperty.GetIndexParameters().Length > 0) { // Indexer cannot be target except the type itself implements IDictionary or IDictionary<TKey,TValue> return(false); } #if !NETSTANDARD1_1 && !NETSTANDARD1_3 var setter = asProperty.GetSetMethod(true); #else var setter = asProperty.SetMethod; #endif // !NETSTANDARD1_1 && !NETSTANDARD1_3 if (setter != null) { if (setter.GetIsPublic()) { return(true); } if (!context.SerializerOptions.DisablePrivilegedAccess) { // Can deserialize non-public setter if privileged. return(true); } } returnType = asProperty.PropertyType; } else if (asField != null) { if (!asField.IsInitOnly) { return(true); } returnType = asField.FieldType; } else { #if DEBUG Contract.Assert(false, "Unknown type member " + member); #endif // DEBUG // ReSharper disable once HeuristicUnreachableCode return(true); } var traits = returnType.GetCollectionTraits(CollectionTraitOptions.WithAddMethod, allowNonCollectionEnumerableTypes: false); switch (traits.CollectionType) { case CollectionKind.Array: case CollectionKind.Map: { return(traits.AddMethod != null); } default: { return(false); } } }
public static void PackToMap <TObject>( ref PackToMapParameters <TObject> parameter ) { if (parameter.Packer == null) { SerializationExceptions.ThrowArgumentNullException("parameter", "Packer"); } if (parameter.Operations == null) { SerializationExceptions.ThrowArgumentNullException("parameter", "Operations"); } #if ASSERT Contract.Assert(parameter.Packer != null); Contract.Assert(parameter.Operations != null); #endif // ASSERT if (parameter.NullCheckers != null && parameter.SerializationContext != null && parameter.SerializationContext.DictionarySerlaizationOptions.OmitNullEntry) { #if ASSERT Contract.Assert(!SerializerDebugging.UseLegacyNullMapEntryHandling); #endif // ASSERT // Skipping causes the entries count header reducing, so count up null entries first. var nullCount = 0; foreach (var nullChecker in parameter.NullCheckers) { if (nullChecker.Value(parameter.Target)) { nullCount++; } } parameter.Packer.PackMapHeader(parameter.Operations.Count - nullCount); foreach (var operation in parameter.Operations) { Func <TObject, bool> nullChecker; if (parameter.NullCheckers.TryGetValue(operation.Key, out nullChecker)) { if (nullChecker(parameter.Target)) { continue; } } parameter.Packer.PackString(operation.Key); operation.Value(parameter.Packer, parameter.Target); } } else { parameter.Packer.PackMapHeader(parameter.Operations.Count); // Compatible path foreach (var operation in parameter.Operations) { parameter.Packer.PackString(operation.Key); operation.Value(parameter.Packer, parameter.Target); } } #pragma warning restore 618 }
private static Type DetermineBaseClass(Type targetType, CollectionTraits traits) { #if DEBUG Contract.Assert( traits.DetailedCollectionType != CollectionDetailedKind.Unserializable, targetType + "(" + traits.DetailedCollectionType + ") != CollectionDetailedKind.Unserializable" ); #endif // DEBUG switch (traits.DetailedCollectionType) { case CollectionDetailedKind.GenericEnumerable: { return(typeof(EnumerableMessagePackSerializer <,>).MakeGenericType(targetType, traits.ElementType)); } case CollectionDetailedKind.GenericCollection: #if !NET35 case CollectionDetailedKind.GenericSet: #endif // !NET35 case CollectionDetailedKind.GenericList: { return(typeof(CollectionMessagePackSerializer <,>).MakeGenericType(targetType, traits.ElementType)); } #if !NET35 && !NET40 && !(SILVERLIGHT && !WINDOWS_PHONE) case CollectionDetailedKind.GenericReadOnlyCollection: case CollectionDetailedKind.GenericReadOnlyList: { return(typeof(ReadOnlyCollectionMessagePackSerializer <,>).MakeGenericType(targetType, traits.ElementType)); } #endif // !NET35 && !NET40 && !( SILVERLIGHT && !WINDOWS_PHONE ) case CollectionDetailedKind.GenericDictionary: { var keyValuePairGenericArguments = traits.ElementType.GetGenericArguments(); return (typeof(DictionaryMessagePackSerializer <, ,>).MakeGenericType( targetType, keyValuePairGenericArguments[0], keyValuePairGenericArguments[1] )); } #if !NET35 && !NET40 && !(SILVERLIGHT && !WINDOWS_PHONE) case CollectionDetailedKind.GenericReadOnlyDictionary: { var keyValuePairGenericArguments = traits.ElementType.GetGenericArguments(); return (typeof(ReadOnlyDictionaryMessagePackSerializer <, ,>).MakeGenericType( targetType, keyValuePairGenericArguments[0], keyValuePairGenericArguments[1] )); } #endif // !NET35 && !NET40 && !( SILVERLIGHT && !WINDOWS_PHONE ) case CollectionDetailedKind.NonGenericEnumerable: { return(typeof(NonGenericEnumerableMessagePackSerializer <>).MakeGenericType(targetType)); } case CollectionDetailedKind.NonGenericCollection: { return(typeof(NonGenericCollectionMessagePackSerializer <>).MakeGenericType(targetType)); } case CollectionDetailedKind.NonGenericList: { return(typeof(NonGenericListMessagePackSerializer <>).MakeGenericType(targetType)); } case CollectionDetailedKind.NonGenericDictionary: { return(typeof(NonGenericDictionaryMessagePackSerializer <>).MakeGenericType(targetType)); } case CollectionDetailedKind.Array: { // Should be handled by GenericSerializer throw new NotSupportedException("Array is not supported."); } default: { #if DEBUG Contract.Assert( traits.DetailedCollectionType == CollectionDetailedKind.NotCollection, "Unknown type:" + traits.DetailedCollectionType ); #endif // DEBUG return (targetType.GetIsEnum() ? typeof(EnumMessagePackSerializer <>).MakeGenericType(targetType) : typeof(MessagePackSerializer <>).MakeGenericType(targetType)); } } }
public static void UnpackMapTo(Unpacker unpacker, IDictionary dictionary) { if (unpacker == null) { SerializationExceptions.ThrowArgumentNullException("unpacker"); } if (dictionary == null) { SerializationExceptions.ThrowArgumentNullException("dictionary"); } #if ASSERT Contract.Assert(unpacker != null); Contract.Assert(dictionary != null); #endif // ASSERT if (!unpacker.IsMapHeader) { SerializationExceptions.ThrowIsNotMapHeader(unpacker); } #if ASSERT Contract.EndContractBlock(); #endif // ASSERT int count = GetItemsCount(unpacker); for (int i = 0; i < count; i++) { if (!unpacker.Read()) { SerializationExceptions.ThrowMissingItem(i, unpacker); } MessagePackObject key; if (!unpacker.IsArrayHeader && !unpacker.IsMapHeader) { key = _messagePackObjectSerializer.UnpackFrom(unpacker); } else { using (Unpacker subtreeUnpacker = unpacker.ReadSubtree()) { key = _messagePackObjectSerializer.UnpackFrom(subtreeUnpacker); } } if (!unpacker.Read()) { SerializationExceptions.ThrowMissingItem(i, unpacker); } MessagePackObject value; if (!unpacker.IsArrayHeader && !unpacker.IsMapHeader) { value = _messagePackObjectSerializer.UnpackFrom(unpacker); } else { using (Unpacker subtreeUnpacker = unpacker.ReadSubtree()) { value = _messagePackObjectSerializer.UnpackFrom(subtreeUnpacker); } } dictionary.Add(key, value); } }