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); } }
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)); } }
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 ); }
/// <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); }