public void TestIssue13_StringListMapAsMpoDictionary()
        {
            var target = MessagePackSerializer.CreateInternal <Dictionary <MessagePackObject, MessagePackObject> >(SerializationContext.Default);

            using (var buffer = new MemoryStream(Convert.FromBase64String("gadyZXN1bHRzkss/8AAAAAAAAMtAAAAAAAAAAA==")))
            {
                var result = target.Unpack(buffer);
                Assert.That(result.Count, Is.EqualTo(1));
                Assert.That(result.First().Key == "results", "{0}.Key != results", result.First().Key);
                Assert.That(result.First().Value.IsList, "{0}.Value is not list", result.First().Value.UnderlyingType);
            }
        }
Example #2
0
        private static MessagePackSerializer <T> CreateSerializer <T>(EmitterFlavor flavor)
        {
#if NETFX_35 || NETFX_CORE || SILVERLIGHT
            var context = new SerializationContext();
#else
            var context = PreGeneratedSerializerActivator.CreateContext(SerializationMethod.Array, SerializationContext.Default.CompatibilityOptions.PackerCompatibilityOptions);
#endif
#if !XAMIOS && !UNITY_IPHONE
            context.SerializerOptions.EmitterFlavor = flavor;
            return(MessagePackSerializer.CreateInternal <T>(context, PolymorphismSchema.Default));
#else
            return(context.GetSerializer <T>());
#endif // !XAMIOS && !UNITY_IPHONE
        }
        private static void TestDataContractAndMessagePackMemberAndNonSerializedAreMixedCore(SerializationMethod method)
        {
            var context = new SerializationContext {
                SerializationMethod = method
            };

            using (var buffer = new MemoryStream())
            {
                var target = new MessagePackMemberAndDataMemberMixedTarget();
                target.ShouldSerialized1    = 111;
                target.ShouldSerialized2    = 222;
                target.ShouldSerialized3    = 333;
                target.ShouldNotSerialized1 = 444;
                target.ShouldNotSerialized2 = 555;
                var serializer = MessagePackSerializer.CreateInternal <MessagePackMemberAndDataMemberMixedTarget>(context);
                serializer.Pack(buffer, target);

                buffer.Position = 0;
                var intermediate = Unpacking.UnpackObject(buffer);

                if (method == SerializationMethod.Array)
                {
                    var asArray = intermediate.AsList();
                    Assert.That(asArray.Count, Is.EqualTo(3));
                    Assert.That(asArray[0] == target.ShouldSerialized1);
                    Assert.That(asArray[1] == target.ShouldSerialized2);
                    Assert.That(asArray[2] == target.ShouldSerialized3);
                }
                else
                {
                    var asMap = intermediate.AsDictionary();
                    Assert.That(asMap.Count, Is.EqualTo(3));
                    Assert.That(asMap["ShouldSerialized1"] == target.ShouldSerialized1);
                    Assert.That(asMap["ShouldSerialized2"] == target.ShouldSerialized2);
                    Assert.That(asMap["ShouldSerialized3"] == target.ShouldSerialized3);
                }

                buffer.Position = 0;

                var result = serializer.Unpack(buffer);

                Assert.That(result.ShouldSerialized1, Is.EqualTo(target.ShouldSerialized1));
                Assert.That(result.ShouldSerialized2, Is.EqualTo(target.ShouldSerialized2));
                Assert.That(result.ShouldSerialized3, Is.EqualTo(target.ShouldSerialized3));
                Assert.That(result.ShouldNotSerialized1, Is.Not.EqualTo(target.ShouldNotSerialized1).And.EqualTo(0));
                Assert.That(result.ShouldNotSerialized2, Is.Not.EqualTo(target.ShouldNotSerialized2).And.EqualTo(0));
            }
        }
Example #4
0
        private static MessagePackSerializer <T> CreateSerializer <T>(EmitterFlavor flavor)
        {
            var context =
#if AOT
                flavor != EmitterFlavor.ReflectionBased
                                ? PreGeneratedSerializerActivator.CreateContext(SerializationMethod.Array, SerializationContext.Default.CompatibilityOptions.PackerCompatibilityOptions) :
#endif // AOT
                new SerializationContext();

#if !AOT
            context.SerializerOptions.EmitterFlavor = flavor;
            return(MessagePackSerializer.CreateInternal <T>(context, PolymorphismSchema.Default));
#else
            return(context.GetSerializer <T>());
#endif // !AOT
        }
        private static void TestDataContractAndNonSerializableAreMixedCore(SerializationMethod method)
        {
            var context = new SerializationContext {
                SerializationMethod = method
            };

            using (var buffer = new MemoryStream())
            {
                var target = new DataContractAndNonSerializedMixedTarget();
                target.ShouldSerialized = 111;
                var serializer = MessagePackSerializer.CreateInternal <DataContractAndNonSerializedMixedTarget>(context);
                serializer.Pack(buffer, target);

                buffer.Position = 0;
                var intermediate = Unpacking.UnpackObject(buffer);

                if (method == SerializationMethod.Array)
                {
                    var asArray = intermediate.AsList();
                    Assert.That(asArray.Count, Is.EqualTo(1));
                    Assert.That(asArray[0] == target.ShouldSerialized);
                }
                else
                {
                    var asMap = intermediate.AsDictionary();
                    Assert.That(asMap.Count, Is.EqualTo(1));
                    Assert.That(asMap["ShouldSerialized"] == target.ShouldSerialized);
                }

                buffer.Position = 0;

                var result = serializer.Unpack(buffer);

                Assert.That(result.ShouldSerialized, Is.EqualTo(target.ShouldSerialized));
            }
        }
		/// <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 DEBUG && !NETFX_40 && !NETFX_35 && !SILVERLIGHT && !UNITY
					Contract.Assert( Monitor.IsEntered( aquiredLock ), "Monitor.IsEntered(aquiredLock)" );
#endif // DEBUG && !NETFX_40 && !NETFX_35 !SILVERLIGHT && && !UNITY

					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 )
									?? this.OnResolveSerializer<T>( schema )
									?? MessagePackSerializer.CreateReflectionInternal<T>( this, this.EnsureConcreteTypeRegistered( typeof( T ) ), schema );
#if !XAMIOS && !XAMDROID && !UNITY
							}
							else
							{
								// This thread creating new type serializer.
								serializer = this.OnResolveSerializer<T>( schema ) ?? 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
					}

#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
				}
				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 );
#if DEBUG && !NETFX_40 && !NETFX_35 && !SILVERLIGHT && !UNITY
					Contract.Assert( !Monitor.IsEntered( aquiredLock ), "!Monitor.IsEntered(aquiredLock)" );
#endif // DEBUG && !NETFX_40 && !NETFX_35 && !SILVERLIGHT && !UNITY
				}
			}
		}
 private MessagePackSerializer <T> CreateTarget <T>(SerializationContext context)
 {
     return(MessagePackSerializer.CreateInternal <T>(context));
 }
		private MessagePackSerializer<T> CreateTarget<T>( SerializationContext context )
		{
			return MessagePackSerializer.CreateInternal<T>( context, PolymorphismSchema.Default );
		}
Example #9
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
					}
				}
			}
		}
        /// <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

            MessagePackSerializer <T> serializer = null;
            while (serializer == null)
            {
                serializer = this._serializers.Get <T>(this, providerParameter) ?? GenericSerializer.Create <T>(this);
                if (serializer == null)
                {
#if !XAMIOS && !XAMDROID && !UNITY
                    if (this.IsRuntimeGenerationDisabled)
                    {
#endif // !XAMIOS && !XAMDROID && !UNITY
                    serializer =
                        this.GetSerializerWithoutGeneration(typeof(T)) as MessagePackSerializer <T>
                        ?? MessagePackSerializer.CreateReflectionInternal <T>(this);
#if !XAMIOS && !XAMDROID && !UNITY
                }
                else
                {
                    object aquiredLock = null;
                    bool   lockTaken   = false;
                    try
                    {
                        try { }
                        finally
                        {
                            var newLock = new object();
#if SILVERLIGHT || NETFX_35
                            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
                            }
                            finally
                            {
#if SILVERLIGHT || NETFX_35
                                if (!lockTaken)
#else
                                if (!lockTaken && newLockTaken)
#endif // if SILVERLIGHT || NETFX_35
                                {
                                    // Release the lock which failed to become 'primary' lock.
                                    Monitor.Exit(newLock);
                                }
                            }
                        }

                        if (Monitor.TryEnter(aquiredLock))
                        {
                            // Decrement monitor counter.
                            Monitor.Exit(aquiredLock);

                            if (lockTaken)
                            {
                                // This thread creating new type serializer.
                                serializer = MessagePackSerializer.CreateInternal <T>(this);
                            }
                            else
                            {
                                // This thread owns existing lock -- thus, constructing self-composite type.

                                // Prevent release owned lock.
                                aquiredLock = null;
                                return(new LazyDelegatingMessagePackSerializer <T>(this, providerParameter));
                            }
                        }
                        else
                        {
                            // Wait creation by other thread.
                            // Acquire as 'waiting' lock.
                            Monitor.Enter(aquiredLock);
                        }
                    }
                    finally
                    {
                        if (lockTaken)
                        {
#if SILVERLIGHT || NETFX_35
                            lock (this._typeLock)
                            {
                                this._typeLock.Remove(typeof(T));
                            }
#else
                            object dummy;
                            this._typeLock.TryRemove(typeof(T), out dummy);
#endif // if SILVERLIGHT || NETFX_35
                        }

                        if (aquiredLock != null)
                        {
                            // Release primary lock or waiting lock.
                            Monitor.Exit(aquiredLock);
                        }
                    }
                }
#endif // !XAMIOS && !XAMDROID && !UNITY
                }
            }

            if (!this._serializers.Register(serializer) || providerParameter != null)
            {
                // Re-get to avoid duplicated registration and handle provider parameter.
                serializer = this._serializers.Get <T>(this, providerParameter);
            }

            return(serializer);
        }