Exemple #1
0
 internal SerializationContext(SerializerRepository serializers)
 {
     this._emitterFlavor = MsgPack.Serialization.EmitterFlavor.FieldBased;
     Contract.Requires(serializers != null);
     this._compatibilityOptions = new SerializationCompatibilityOptions();
     this._serializers          = serializers;
     this._typeLock             = new HashSet <Type>();
 }
 public SerializerRepository(SerializerRepository copiedFrom)
 {
     if (copiedFrom == null)
     {
         throw new ArgumentNullException("copiedFrom");
     }
     this._repository = new TypeKeyRepository(copiedFrom._repository);
 }
        internal SerializationContext(SerializerRepository serializers)
        {
            Contract.Requires(serializers != null);

            this._compatibilityOptions = new SerializationCompatibilityOptions();
            this._serializers          = serializers;
#if SILVERLIGHT || NETFX_35
            this._typeLock = new HashSet <Type>();
#else
            this._typeLock = new ConcurrentDictionary <Type, object>();
#endif
        }
Exemple #4
0
        internal SerializationContext(
            SerializerRepository serializers, PackerCompatibilityOptions packerCompatibilityOptions)
        {
            Contract.Requires(serializers != null);

            this._compatibilityOptions =
                new SerializationCompatibilityOptions()
            {
                PackerCompatibilityOptions =
                    packerCompatibilityOptions
            };
            this._serializers            = serializers;
            this._typeLock               = new HashSet <Type>();
            this._defaultCollectionTypes = new DefaultConcreteTypeRepository();
        }
        internal SerializationContext(
            SerializerRepository serializers, PackerCompatibilityOptions packerCompatibilityOptions)
        {
            Contract.Requires(serializers != null);

            this._compatibilityOptions =
                new SerializationCompatibilityOptions()
            {
                PackerCompatibilityOptions =
                    packerCompatibilityOptions
            };
            this._serializers = serializers;
#if SILVERLIGHT || NETFX_35
            this._typeLock = new HashSet <Type>();
#else
            this._typeLock = new ConcurrentDictionary <Type, object>();
#endif
            this._defaultCollectionTypes = new DefaultConcreteTypeRepository();
        }
        internal SerializationContext(
            SerializerRepository serializers, PackerCompatibilityOptions packerCompatibilityOptions)
        {
            this._compatibilityOptions =
                new SerializationCompatibilityOptions
            {
                PackerCompatibilityOptions =
                    packerCompatibilityOptions
            };
            this._serializers = serializers;
#if !XAMIOS && !XAMDROID && !UNITY
#if SILVERLIGHT || NETFX_35
            this._typeLock = new Dictionary <Type, object>();
#else
            this._typeLock = new ConcurrentDictionary <Type, object>();
#endif // SILVERLIGHT || NETFX_35
#endif // !XAMIOS && !XAMDROID && !UNITY
            this._defaultCollectionTypes = new DefaultConcreteTypeRepository();
        }
Exemple #7
0
		/// <summary>
		///		Initializes a new instance of the <see cref="SerializationContext"/> class with copy of <see cref="SerializerRepository.GetDefault()"/> for specified <see cref="PackerCompatibilityOptions"/>.
		/// </summary>
		/// <param name="packerCompatibilityOptions"><see cref="PackerCompatibilityOptions"/> which will be used on built-in serializers.</param>
		public SerializationContext( PackerCompatibilityOptions packerCompatibilityOptions )
		{
			this._compatibilityOptions =
				new SerializationCompatibilityOptions
				{
					PackerCompatibilityOptions =
						packerCompatibilityOptions
				};

			this._serializers = new SerializerRepository( SerializerRepository.GetDefault( this ) );

#if SILVERLIGHT || NETFX_35 || UNITY
			this._typeLock = new Dictionary<Type, object>();
#else
			this._typeLock = new ConcurrentDictionary<Type, object>();
#endif // SILVERLIGHT || NETFX_35 || UNITY
			this._generationLock = new object();
			this._defaultCollectionTypes = new DefaultConcreteTypeRepository();
			this._serializerGeneratorOptions = new SerializerOptions();
		}
		/// <summary>
		///		Initializes a new instance of the <see cref="SerializationContext"/> class with copy of <see cref="SerializerRepository.GetDefault()"/> for specified <see cref="PackerCompatibilityOptions"/>.
		/// </summary>
		/// <param name="packerCompatibilityOptions"><see cref="PackerCompatibilityOptions"/> which will be used on built-in serializers.</param>
		public SerializationContext( PackerCompatibilityOptions packerCompatibilityOptions )
		{
			this._compatibilityOptions =
				new SerializationCompatibilityOptions
				{
					PackerCompatibilityOptions =
						packerCompatibilityOptions
				};

			this._serializers = new SerializerRepository( SerializerRepository.GetDefault( this ) );

#if !FEATURE_CONCURRENT
			this._typeLock = new Dictionary<Type, object>();
#else
			this._typeLock = new ConcurrentDictionary<Type, object>();
#endif // !FEATURE_CONCURRENT
			this._generationLock = new object();
			this._defaultCollectionTypes = new DefaultConcreteTypeRepository();
			this._serializerGeneratorOptions = new SerializerOptions();
			this._dictionarySerializationOptions = new DictionarySerlaizationOptions();
			this._enumSerializationOptions = new EnumSerializationOptions();
		}
		/// <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
				}
			}
		}
Exemple #10
0
        public void TestDefaultTableCapacity()
        {
            var table = SerializerRepository.InitializeDefaultTable(new SerializationContext());

            Assert.That(table.Count, Is.LessThanOrEqualTo(SerializerRepository.DefaultTableCapacity));
        }
Exemple #11
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
					}
				}
			}
		}
Exemple #12
0
 /// <summary>
 ///		Initializes a new instance of the <see cref="SerializationContext"/> class with copy of <see cref="SerializerRepository.GetDefault(PackerCompatibilityOptions)"/> for specified <see cref="PackerCompatibilityOptions"/>.
 /// </summary>
 /// <param name="packerCompatibilityOptions"><see cref="PackerCompatibilityOptions"/> which will be used on built-in serializers.</param>
 public SerializationContext(PackerCompatibilityOptions packerCompatibilityOptions)
     : this(new SerializerRepository(SerializerRepository.GetDefault(packerCompatibilityOptions)), packerCompatibilityOptions)
 {
 }
 // For default init.
 private SerializationContext(SerializerRepository allwaysNull)
     : this(allwaysNull, PackerCompatibilityOptions.Classic)               // TODO: configurable
 {
     this._serializers = new SerializerRepository(SerializerRepository.GetDefault(this));
 }