Skip to content

Commit 86fac62

Browse files
committed
Merge branch 'fix-map-skipped-keys' of https://github.com/undead-lewis/msgpack-cli into 0.5
2 parents 931fc8f + f34f0eb commit 86fac62

File tree

8 files changed

+103
-2
lines changed

8 files changed

+103
-2
lines changed

src/MsgPack/Serialization/AbstractSerializers/SerializerBuilderContract`3.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,17 @@ protected override TConstruct EmitStringSwitchStatement( TContext context, TCons
462462
return default( TConstruct );
463463
}
464464

465+
protected override TConstruct EmitStringSwitchStatement (TContext context, TConstruct target, TConstruct defaultCase, IDictionary<string, TConstruct> cases) {
466+
Contract.Requires(context != null);
467+
Contract.Requires(target != null);
468+
Contract.Requires(defaultCase != null);
469+
Contract.Requires(cases != null);
470+
Contract.Requires(cases.Count > 0);
471+
Contract.Ensures(Contract.Result<TConstruct>() != null);
472+
Contract.Ensures(Contract.Result<TConstruct>().ContextType == typeof(void));
473+
return default(TConstruct);
474+
}
475+
465476
protected override TConstruct EmitForLoop( TContext context, TConstruct count, Func<ForLoopContext, TConstruct> loopBodyEmitter )
466477
{
467478
Contract.Requires( context != null );

src/MsgPack/Serialization/AbstractSerializers/SerializerBuilder`3.CommonConstructs.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,6 +1298,18 @@ protected abstract TConstruct EmitStringSwitchStatement(
12981298
TContext context, TConstruct target, IDictionary<string, TConstruct> cases
12991299
);
13001300

1301+
/// <summary>
1302+
/// Emits string switch statement.
1303+
/// </summary>
1304+
/// <param name="context">The generation context.</param>
1305+
/// <param name="target">Target string expression.</param>
1306+
/// <param name="defaultCase">Default case expression.</param>
1307+
/// <param name="cases">The case statements. The keys are case condition, and values are actual statement.</param>
1308+
/// <returns>The switch statement.</returns>
1309+
protected abstract TConstruct EmitStringSwitchStatement (
1310+
TContext context, TConstruct target, TConstruct defaultCase, IDictionary<string, TConstruct> cases
1311+
);
1312+
13011313
/// <summary>
13021314
/// Emits the return statement
13031315
/// </summary>

src/MsgPack/Serialization/AbstractSerializers/SerializerBuilder`3.Object.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,11 @@ private IEnumerable<TConstruct> EmitObjectUnpackFromMapCore( TContext context, T
440440
this.EmitStringSwitchStatement(
441441
context,
442442
key,
443+
this.EmitInvokeVoidMethod(
444+
context,
445+
context.Unpacker,
446+
typeof( Unpacker ).GetMethod( "Skip" )
447+
),
443448
entries.Where( e => e.Member != null ).ToDictionary(
444449
entry => entry.Contract.Name,
445450
entry =>

src/MsgPack/Serialization/CodeDomSerializers/CodeDomSerializerBuilder`1.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,30 @@ protected override CodeDomConstruct EmitStringSwitchStatement( CodeDomContext co
670670
);
671671
}
672672

673+
protected override CodeDomConstruct EmitStringSwitchStatement (CodeDomContext context, CodeDomConstruct target, CodeDomConstruct defaultCase, IDictionary<string, CodeDomConstruct> cases) {
674+
#if DEBUG
675+
Contract.Assert(target.IsExpression);
676+
Contract.Assert(defaultCase.IsStatement);
677+
Contract.Assert(cases.Values.All(c => c.IsStatement));
678+
#endif
679+
680+
var statements = cases.Aggregate<KeyValuePair<string, CodeDomConstruct>, CodeConditionStatement>(
681+
null,
682+
(current, caseStatement) =>
683+
new CodeConditionStatement(
684+
new CodeBinaryOperatorExpression(
685+
target.AsExpression(),
686+
CodeBinaryOperatorType.ValueEquality,
687+
new CodePrimitiveExpression(caseStatement.Key)
688+
),
689+
caseStatement.Value.AsStatements().ToArray(),
690+
current == null ? defaultCase.AsStatements().ToArray() : new CodeStatement[] { current }
691+
)
692+
);
693+
694+
return CodeDomConstruct.Statement(statements);
695+
}
696+
673697
[System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods", MessageId = "1", Justification = "Asserted internally" )]
674698
protected override CodeDomConstruct EmitRetrunStatement( CodeDomContext context, CodeDomConstruct expression )
675699
{

src/MsgPack/Serialization/EmittingSerializers/ILEmittingSerializerBuilder`2.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,29 @@ protected override ILConstruct EmitStringSwitchStatement( TContext context, ILCo
701701
return @else;
702702
}
703703

704+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods", MessageId = "2", Justification = "Asserted internally")]
705+
protected override ILConstruct EmitStringSwitchStatement (TContext context, ILConstruct target, ILConstruct defaultCase, IDictionary<string, ILConstruct> cases) {
706+
// Simple if statements
707+
ILConstruct @else = defaultCase;
708+
foreach (var @case in cases) {
709+
@else =
710+
this.EmitConditionalExpression(
711+
context,
712+
this.EmitInvokeMethodExpression(
713+
context,
714+
null,
715+
Metadata._String.op_Equality,
716+
target,
717+
this.MakeStringLiteral(context, @case.Key)
718+
),
719+
@case.Value,
720+
@else
721+
);
722+
}
723+
724+
return @else;
725+
}
726+
704727
protected override ILConstruct EmitForLoop( TContext context, ILConstruct count, Func<ForLoopContext, ILConstruct> loopBodyEmitter )
705728
{
706729
var i =

src/MsgPack/Serialization/ExpressionSerializers/ExpressionTreeSerializerBuilder`1.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,19 @@ protected override ExpressionConstruct EmitStringSwitchStatement(
481481
);
482482
}
483483

484+
protected override ExpressionConstruct EmitStringSwitchStatement (
485+
ExpressionTreeContext context, ExpressionConstruct target, ExpressionConstruct defaultCase, IDictionary<string, ExpressionConstruct> cases
486+
) {
487+
return
488+
Expression.Switch(
489+
typeof( void ),
490+
target,
491+
defaultCase,
492+
Metadata._String.op_Equality,
493+
cases.Select( kv => Expression.SwitchCase( kv.Value, Expression.Constant( kv.Key ) ) ).ToArray()
494+
);
495+
}
496+
484497
[System.Diagnostics.CodeAnalysis.SuppressMessage( "Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods", MessageId = "2", Justification = "Asserted internally" )]
485498
protected override ExpressionConstruct EmitForLoop( ExpressionTreeContext context, ExpressionConstruct count, Func<ForLoopContext, ExpressionConstruct> loopBodyEmitter )
486499
{

src/MsgPack/Serialization/ReflectionSerializers/ReflectionObjectMessagePackSerializer`1.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,18 @@ protected internal override T UnpackFromCore( Unpacker unpacker )
157157
continue;
158158
}
159159

160-
result = this.UnpackMemberValue( result, unpacker, itemsCount, ref unpacked, this._memberIndexes[ name ], i );
160+
int index;
161+
if ( !this._memberIndexes.TryGetValue(name, out index) )
162+
{
163+
// key does not exist in the object, skip the associated value
164+
if ( unpacker.Skip() == null )
165+
{
166+
throw SerializationExceptions.NewMissingItem( i );
167+
}
168+
continue;
169+
}
170+
171+
result = this.UnpackMemberValue(result, unpacker, itemsCount, ref unpacked, index, i);
161172
}
162173
}
163174

test/MsgPack.UnitTest/Serialization/VersioningTest.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,11 @@ private static void TestExtraFieldCore<T>( SerializationMethod method, EmitterFl
6464
else
6565
{
6666
var packer = Packer.Create( stream, false );
67-
packer.PackMapHeader( 4 );
67+
packer.PackMapHeader( 5 );
6868
packer.Pack( "Field1" );
6969
packer.Pack( 1 );
70+
packer.Pack( "Extra" );
71+
packer.PackNull();
7072
packer.Pack( "Field2" );
7173
packer.Pack( -1 );
7274
packer.Pack( "Field3" );

0 commit comments

Comments
 (0)