Beispiel #1
0
 /// <summary>
 ///		Deserializes collection items with specified <see cref="Unpacker"/> and stores them to <paramref name="collection"/>.
 /// </summary>
 /// <param name="unpacker"><see cref="Unpacker"/> which unpacks values of resulting object tree. This value will not be <c>null</c>.</param>
 /// <param name="collection">Collection that the items to be stored. This value will not be <c>null</c>.</param>
 /// <exception cref="SerializationException">
 ///		Failed to deserialize object due to invalid unpacker state, stream content, or so.
 /// </exception>
 /// <exception cref="NotSupportedException">
 ///		The type of <paramref name="collection" /> is not a collection.
 /// </exception>
 protected internal virtual void UnpackToCore(Unpacker unpacker, object collection)
 {
     throw SerializationExceptions.NewUnpackToIsNotSupported(this._targetType, null);
 }
Beispiel #2
0
        public static SerializationTarget Prepare(SerializationContext context, Type targetType)
        {
            var getters = GetTargetMembers(targetType).OrderBy(entry => entry.Contract.Id).ToArray();

            if (getters.Length == 0)
            {
                throw new SerializationException(String.Format(CultureInfo.CurrentCulture, "Cannot serialize type '{0}' because it does not have any serializable fields nor properties.", targetType));
            }

            bool?canDeserialize   = null;
            var  memberCandidates = getters.Where(entry => CheckTargetEligibility(entry.Member)).ToArray();

            if (memberCandidates.Length == 0)
            {
                var deserializationConstructor = FindDeserializationConstructor(context, targetType, out canDeserialize);
                var complementedMembers        = ComplementMembers(getters, context, targetType);
                var correspondingMemberNames   = FindCorrespondingMemberNames(complementedMembers, deserializationConstructor);
                return
                    (new SerializationTarget(
                         complementedMembers,
                         deserializationConstructor,
                         correspondingMemberNames,
                         canDeserialize
                         ));
            }

            // Try to get default constructor.
            var constructor = targetType.GetConstructor(ReflectionAbstractions.EmptyTypes);

            if (constructor == null && !targetType.GetIsValueType())
            {
                // Try to get deserialization constructor.
                var deserializationConstructor = FindDeserializationConstructor(context, targetType, out canDeserialize);
                if (deserializationConstructor == null && !context.CompatibilityOptions.AllowAsymmetricSerializer)
                {
                    throw SerializationExceptions.NewTargetDoesNotHavePublicDefaultConstructor(targetType);
                }

                constructor = deserializationConstructor;
            }
            else
            {
                // Let's prefer annotated constructor here.
                var markedConstructors = FindExplicitDeserializationConstructors(targetType.GetConstructors());
                if (markedConstructors.Count == 1)
                {
                    // For backward compatibility, no exceptions are thrown here even if mulitiple deserialization constructor attributes in the type
                    // just use default constructor for it.
                    constructor = markedConstructors[0];
                }

                // OK, appropriate constructor and setters are found.
                canDeserialize = true;
            }

            // Because members' order is equal to declared order is NOT guaranteed, so explicit ordering is required.
            IList <SerializingMember> members;

            if (memberCandidates.All(item => item.Contract.Id == DataMemberContract.UnspecifiedId))
            {
                // Alphabetical order.
                members = memberCandidates.OrderBy(item => item.Contract.Name).ToArray();
            }
            else
            {
                // ID order.
                members = ComplementMembers(memberCandidates, context, targetType);
            }

            return
                (new SerializationTarget(
                     members,
                     constructor,
                     FindCorrespondingMemberNames(members, constructor),
                     canDeserialize
                     ));
        }
//20150611 applibot modify end


        private static IList <SerializingMember> PrepareCore(SerializationContext context, Type targetType)
        {
            //20150611 applibot modify
            //var entries = GetTargetMembers( targetType ).OrderBy( item => item.Contract.Id ).ToArray();
            var entries = GetTargetMembers(targetType).OrderBy(intDelegateForAOT_).ToArray();

            if (entries.Length == 0)
            {
                throw SerializationExceptions.NewNoSerializableFieldsException(targetType);
            }

            //20150611 applibot modify
            //if ( entries.All( item => item.Contract.Id == DataMemberContract.UnspecifiedId ) )
            if (entries.All(boolDelegateForAOT_))
            {
                // Alphabetical order.
                //20150611 applibot modify
                //return entries.OrderBy( item => item.Contract.Name ).ToArray();
                return(entries.OrderBy(nameDelegateForAOT_).ToArray());
            }

            // ID order.

#if DEBUG && !UNITY
            Contract.Assert(entries[0].Contract.Id >= 0);
#endif // DEBUG && !UNITY

            if (context.CompatibilityOptions.OneBoundDataMemberOrder && entries[0].Contract.Id == 0)
            {
                throw new NotSupportedException("Cannot specify order value 0 on DataMemberAttribute when SerializationContext.CompatibilityOptions.OneBoundDataMemberOrder is set to true.");
            }

            //20150611 applibot modify
            int maxId = 0;
            foreach (SerializingMember item in entries)
            {
                if (maxId < item.Contract.Id)
                {
                    maxId = item.Contract.Id;
                }
            }
            //var maxId = entries.Max( item => item.Contract.Id );
            //var maxId = entries.Max( intDelegateForAOT_ );

            var result = new List <SerializingMember>(maxId + 1);
            for (int source = 0, destination = context.CompatibilityOptions.OneBoundDataMemberOrder ? 1 : 0; source < entries.Length; source++, destination++)
            {
#if DEBUG && !UNITY
                Contract.Assert(entries[source].Contract.Id >= 0);
#endif // DEBUG && !UNITY

                if (entries[source].Contract.Id < destination)
                {
                    throw new SerializationException(String.Format(CultureInfo.CurrentCulture, "The member ID '{0}' is duplicated in the '{1}' elementType.", entries[source].Contract.Id, targetType));
                }

                while (entries[source].Contract.Id > destination)
                {
                    result.Add(new SerializingMember());
                    destination++;
                }

                result.Add(entries[source]);
            }

            return(result);
        }
        /// <summary>
        ///		Retrieves a most appropriate constructor with <see cref="Int32"/> capacity parameter and <see cref="IEqualityComparer{T}"/> comparer parameter or both of them, >or default constructor of the <paramref name="instanceType"/>.
        /// </summary>
        /// <param name="instanceType">The target collection type to be instanciated.</param>
        /// <returns>A constructor of the <paramref name="instanceType"/>.</returns>
        internal static ConstructorInfo GetCollectionConstructor(Type instanceType)
        {
            const int noParameters            = 0;
            const int withCapacity            = 10;
            const int withComparer            = 11;
            const int withComparerAndCapacity = 20;
            const int withCapacityAndComparer = 21;

            ConstructorInfo constructor  = null;
            var             currentScore = -1;

            foreach (var candidate in instanceType.GetConstructors())
            {
                var parameters = candidate.GetParameters();
                switch (parameters.Length)
                {
                case 0:
                {
                    if (currentScore < noParameters)
                    {
                        constructor  = candidate;
                        currentScore = noParameters;
                    }

                    break;
                }

                case 1:
                {
                    if (currentScore < withCapacity && parameters[0].ParameterType == typeof(int))
                    {
                        constructor  = candidate;
                        currentScore = noParameters;
                    }
                    else if (currentScore < withComparer && IsIEqualityComparer(parameters[0].ParameterType))
                    {
                        constructor  = candidate;
                        currentScore = noParameters;
                    }
                    break;
                }

                case 2:
                {
                    if (currentScore < withCapacityAndComparer && parameters[0].ParameterType == typeof(int) && IsIEqualityComparer(parameters[1].ParameterType))
                    {
                        constructor  = candidate;
                        currentScore = withCapacityAndComparer;
                    }
                    else if (currentScore < withComparerAndCapacity && parameters[1].ParameterType == typeof(int) && IsIEqualityComparer(parameters[0].ParameterType))
                    {
                        constructor  = candidate;
                        currentScore = withComparerAndCapacity;
                    }

                    break;
                }
                }
            }

            if (constructor == null)
            {
                SerializationExceptions.ThrowTargetDoesNotHavePublicDefaultConstructorNorInitialCapacity(instanceType);
            }

            return(constructor);
        }
Beispiel #5
0
        public static void UnpackMapTo(Unpacker unpacker, IDictionary dictionary)
        {
#if DEBUG
            if (unpacker == null)
            {
                throw new ArgumentNullException("unpacker");
            }

            if (dictionary == null)
            {
                throw new ArgumentNullException("dictionary");
            }

            if (!unpacker.IsMapHeader)
            {
                throw SerializationExceptions.NewIsNotMapHeader();
            }

            Contract.EndContractBlock();
#endif

            int count = GetItemsCount(unpacker);
            for (int i = 0; i < count; i++)
            {
                if (!unpacker.Read())
                {
                    throw SerializationExceptions.NewMissingItem(i);
                }

                MessagePackObject key;
                if (!unpacker.IsArrayHeader && !unpacker.IsMapHeader)
                {
                    key = _messagePackObjectSerializer.UnpackFrom(unpacker);
                }
                else
                {
                    using (Unpacker subtreeUnpacker = unpacker.ReadSubtree())
                    {
                        key = _messagePackObjectSerializer.UnpackFrom(subtreeUnpacker);
                    }
                }


                if (!unpacker.Read())
                {
                    throw SerializationExceptions.NewMissingItem(i);
                }

                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);
            }
        }
        public static void UnpackMapTo <TKey, TValue>(Unpacker unpacker, MessagePackSerializer <TKey> keySerializer, MessagePackSerializer <TValue> valueSerializer, IDictionary <TKey, TValue> dictionary)
        {
            if (unpacker == null)
            {
                SerializationExceptions.ThrowArgumentNullException("unpacker");
            }

            if (keySerializer == null)
            {
                SerializationExceptions.ThrowArgumentNullException("keySerializer");
            }

            if (valueSerializer == null)
            {
                SerializationExceptions.ThrowArgumentNullException("valueSerializer");
            }

            if (dictionary == null)
            {
                SerializationExceptions.ThrowArgumentNullException("dictionary");
            }

#if ASSERT
            Contract.Assert(unpacker != null);
            Contract.Assert(keySerializer != null);
            Contract.Assert(valueSerializer != 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);
                }

                TKey key;
                if (!unpacker.IsArrayHeader && !unpacker.IsMapHeader)
                {
                    key = keySerializer.UnpackFrom(unpacker);
                }
                else
                {
                    using (Unpacker subtreeUnpacker = unpacker.ReadSubtree())
                    {
                        key = keySerializer.UnpackFrom(subtreeUnpacker);
                    }
                }


                if (!unpacker.Read())
                {
                    SerializationExceptions.ThrowMissingItem(i, unpacker);
                }

                TValue value;
                if (!unpacker.IsArrayHeader && !unpacker.IsMapHeader)
                {
                    value = valueSerializer.UnpackFrom(unpacker);
                }
                else
                {
                    using (Unpacker subtreeUnpacker = unpacker.ReadSubtree())
                    {
                        value = valueSerializer.UnpackFrom(subtreeUnpacker);
                    }
                }

                dictionary.Add(key, value);
            }
        }
        public static void UnpackCollectionTo <T, TDiscarded>(Unpacker unpacker, MessagePackSerializer <T> serializer, IEnumerable <T> collection, Func <T, TDiscarded> addition)
        {
            if (unpacker == null)
            {
                SerializationExceptions.ThrowArgumentNullException("unpacker");
            }

            if (serializer == null)
            {
                SerializationExceptions.ThrowArgumentNullException("serializer");
            }

            if (collection == null)
            {
                SerializationExceptions.ThrowArgumentNullException("collection");
            }

            if (addition == null)
            {
                SerializationExceptions.ThrowArgumentNullException("addition");
            }

#if ASSERT
            Contract.Assert(unpacker != null);
            Contract.Assert(serializer != null);
            Contract.Assert(collection != null);
            Contract.Assert(addition != null);
#endif // ASSERT

            if (!unpacker.IsArrayHeader)
            {
                SerializationExceptions.ThrowIsNotArrayHeader(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);
                }

                T item;
                if (!unpacker.IsArrayHeader && !unpacker.IsMapHeader)
                {
                    item = serializer.UnpackFrom(unpacker);
                }
                else
                {
                    using (Unpacker subtreeUnpacker = unpacker.ReadSubtree())
                    {
                        item = serializer.UnpackFrom(subtreeUnpacker);
                    }
                }

                addition(item);
            }
        }
 /// <summary>
 ///		Deserializes collection items with specified <see cref="Unpacker"/> and stores them to <paramref name="collection"/>.
 /// </summary>
 /// <param name="unpacker"><see cref="Unpacker"/> which unpacks values of resulting object tree. This value will not be <c>null</c>.</param>
 /// <param name="collection">Collection that the items to be stored. This value will not be <c>null</c>.</param>
 /// <exception cref="SerializationException">
 ///		Failed to deserialize object due to invalid unpacker state, stream content, or so.
 /// </exception>
 /// <exception cref="NotSupportedException">
 ///		<typeparamref name="T"/> is not collection.
 /// </exception>
 protected internal virtual void UnpackToCore(Unpacker unpacker, T collection)
 {
     throw SerializationExceptions.NewUnpackToIsNotSupported(typeof(T), null);
 }
Beispiel #9
0
        public static SerializationTarget Prepare(SerializationContext context, Type targetType)
        {
            VerifyCanSerializeTargetType(context, targetType);

            var getters = GetTargetMembers(targetType).OrderBy(entry => entry.Contract.Id).ToArray();

            if (getters.Length == 0 &&
                !typeof(IPackable).IsAssignableFrom(targetType) &&
                !typeof(IUnpackable).IsAssignableFrom(targetType)
#if FEATURE_TAP
                && (context.SerializerOptions.WithAsync &&
                    (!typeof(IAsyncPackable).IsAssignableFrom(targetType) &&
                     !typeof(IAsyncUnpackable).IsAssignableFrom(targetType)
                    )
                    )
#endif // FEATURE_TAP
                )
            {
                throw new SerializationException(String.Format(CultureInfo.CurrentCulture, "Cannot serialize type '{0}' because it does not have any serializable fields nor properties.", targetType));
            }

            var memberCandidates = getters.Where(entry => CheckTargetEligibility(context, entry.Member)).ToArray();

            if (memberCandidates.Length == 0)
            {
                ConstructorKind constructorKind;
                var             deserializationConstructor = FindDeserializationConstructor(context, targetType, out constructorKind);
                var             complementedMembers        = ComplementMembers(getters, context, targetType);
                var             correspondingMemberNames   = FindCorrespondingMemberNames(complementedMembers, deserializationConstructor);
                return
                    (new SerializationTarget(
                         complementedMembers,
                         deserializationConstructor,
                         correspondingMemberNames,
                         DetermineCanDeserialize(constructorKind, context, targetType, correspondingMemberNames, allowDefault: false)
                         ));
            }
            else
            {
                bool?           canDeserialize;
                ConstructorKind constructorKind;

                // Try to get default constructor.
                var constructor = targetType.GetConstructor(ReflectionAbstractions.EmptyTypes);
                if (constructor == null && !targetType.GetIsValueType())
                {
                    // Try to get deserialization constructor.
                    var deserializationConstructor = FindDeserializationConstructor(context, targetType, out constructorKind);
                    if (deserializationConstructor == null && !context.CompatibilityOptions.AllowAsymmetricSerializer)
                    {
                        throw SerializationExceptions.NewTargetDoesNotHavePublicDefaultConstructor(targetType);
                    }

                    constructor    = deserializationConstructor;
                    canDeserialize = null;
                }
                else
                {
                    constructorKind = ConstructorKind.Default;
                    // Let's prefer annotated constructor here.
                    var markedConstructors = FindExplicitDeserializationConstructors(targetType.GetConstructors());
                    if (markedConstructors.Count == 1)
                    {
                        // For backward compatibility, no exceptions are thrown here even if mulitiple deserialization constructor attributes in the type
                        // just use default constructor for it.
                        constructor     = markedConstructors[0];
                        constructorKind = ConstructorKind.Marked;
                    }

                    // OK, appropriate constructor and setters are found.
                    canDeserialize = true;
                }

                if (constructor != null && constructor.GetParameters().Any())
                {
                    // Recalculate members because getter-only/readonly members should be included for constructor deserialization.
                    memberCandidates = getters;
                }

                // Because members' order is equal to declared order is NOT guaranteed, so explicit ordering is required.
                IList <SerializingMember> members;
                if (memberCandidates.All(item => item.Contract.Id == DataMemberContract.UnspecifiedId))
                {
                    // Alphabetical order.
                    members = memberCandidates.OrderBy(item => item.Contract.Name).ToArray();
                }
                else
                {
                    // ID order.
                    members = ComplementMembers(memberCandidates, context, targetType);
                }

                var correspondingMemberNames = FindCorrespondingMemberNames(members, constructor);
                return
                    (new SerializationTarget(
                         members,
                         constructor,
                         correspondingMemberNames,
                         canDeserialize ?? DetermineCanDeserialize(constructorKind, context, targetType, correspondingMemberNames, allowDefault: true)
                         ));
            }
        }
Beispiel #10
0
        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
        }