internal ValueCollection(MessagePackObjectDictionary dictionary)
            {
                Contract.Assert(dictionary != null, "dictionary != null");

                this._dictionary = dictionary;
            }
コード例 #2
0
        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
コード例 #3
0
        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);
        }
コード例 #4
0
 /// <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);
 }
コード例 #5
0
        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
                          );
            }
        }
コード例 #6
0
        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));
        }
コード例 #7
0
        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));
                }
            }
        }
コード例 #8
0
        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
            }
            }
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        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[]));
            }
        }
コード例 #11
0
        // 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
        }
コード例 #12
0
        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
        }
コード例 #13
0
        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();
        }
コード例 #14
0
        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));
        }
コード例 #15
0
ファイル: PackHelpers.cs プロジェクト: ailen0ada/msgpack-cli
#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);
                }
            }
        }
コード例 #16
0
        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);
        }
コード例 #17
0
        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));
        }
コード例 #18
0
        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();
                }
コード例 #20
0
        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
                         )
                     ));
        }
コード例 #21
0
 // TODO: NLiblet
 public void EmitAnyStloc(LocalBuilder local)
 {
     Contract.Assert(local != null);
     this.EmitAnyStloc(local.LocalIndex);
 }
コード例 #22
0
        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);
        }
コード例 #23
0
        /// <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;
            }
            }
        }
コード例 #24
0
        /// <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);
                }
            }
        }
コード例 #25
0
        }         // 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[]));
            }
        }
コード例 #26
0
		/// <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
					}
				}
			}
		}
コード例 #27
0
        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);
            }
            }
        }
コード例 #28
0
ファイル: PackHelpers.cs プロジェクト: ailen0ada/msgpack-cli
        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
        }
コード例 #29
0
        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));
            }
            }
        }
コード例 #30
0
        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);
            }
        }