/// <summary> /// Process response message after deserialization. /// </summary> /// <param name="context">Context information of deserializing message.</param> protected abstract void ProcessCore( ResponseMessageDeserializationContext context );
private static void DeserializeCore( IEnumerable<byte> sequence, ResponseMessageDeserializationContext context ) { using ( var unpacker = new Unpacker( sequence ) ) { MessagePackObject? response = unpacker.UnpackObject(); if ( response == null ) { if ( context.SerializationError.IsSuccess ) { // Since entire stream was readed and its length was in quota, the stream may be coruppted. context.SetSerializationError( new RpcErrorMessage( RpcError.MessageRefusedError, "Invalid message.", "Cannot deserialize message stream." ) ); } return; } if ( !response.Value.IsTypeOf<IList<MessagePackObject>>().GetValueOrDefault() ) { context.SetSerializationError( new RpcErrorMessage( RpcError.MessageRefusedError, "Invalid message.", "Response message is not array." ) ); return; } var requestFields = response.Value.AsList(); if ( requestFields.Count != 4 ) { context.SetSerializationError( new RpcErrorMessage( RpcError.MessageRefusedError, "Invalid message.", "Response message is not 4 element array." ) ); return; } if ( !requestFields[ 0 ].IsTypeOf<int>().GetValueOrDefault() ) { context.SetSerializationError( new RpcErrorMessage( RpcError.MessageRefusedError, "Invalid message.", "Message type of response message is not int 32." ) ); return; } if ( requestFields[ 0 ].AsInt32() != ( int )MessageType.Response ) { context.SetSerializationError( new RpcErrorMessage( RpcError.MessageRefusedError, "Invalid message.", "Message type of response message is not Response(2)." ) ); return; } if ( !requestFields[ 1 ].IsTypeOf<uint>().GetValueOrDefault() ) { context.SetSerializationError( new RpcErrorMessage( RpcError.MessageRefusedError, "Invalid message.", "Message ID of response message is not int32." ) ); return; } // For CLS compliance store uint32 value as int32. unchecked { context.MessageId = ( int )requestFields[ 1 ].AsUInt32(); } // Error is should be string identifier of error, but arbitary objects are supported. context.Error = requestFields[ 2 ]; // If error is specified, this value should be nil by original spec, but currently should specify error information. context.DeserializedResult = requestFields[ 3 ]; } }
/// <summary> /// Process response message after deserialization. /// </summary> /// <param name="context">Context information of deserializing message.</param> internal void Process( ResponseMessageDeserializationContext context ) { Contract.Assert( context != null ); this.ProcessCore( context ); }
/// <summary> /// Deserialize response message from specified buffer. /// </summary> /// <param name="input">Buffer which stores serialized request/notification stream.</param> /// <param name="result">Deserialied packed message will be stored.</param> /// <returns>Error information.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="input"/> is null. /// </exception> /// <exception cref="InvalidOperationException"> /// Some filters violate contract. /// </exception> public RpcErrorMessage Deserialize( IEnumerable<byte> input, out ResponseMessage result ) { if ( input == null ) { throw new ArgumentNullException( "input" ); } Contract.EndContractBlock(); var context = new ResponseMessageDeserializationContext( input, this._maxRequestLength ); var sequence = context.ReadBytes(); foreach ( var preDeserializationFilter in this._preDeserializationFilters ) { var processed = preDeserializationFilter.GetFilter().Process( sequence, context ); if ( !context.SerializationError.IsSuccess ) { result = default( ResponseMessage ); return context.SerializationError; } if ( processed == null ) { throw new InvalidOperationException( "Deserialization filter did not return sequence." ); } sequence = processed; } DeserializeCore( sequence, context ); if ( !context.SerializationError.IsSuccess ) { result = default( ResponseMessage ); return context.SerializationError; } foreach ( var postDeserializationFilter in this._postDeserializationFilters ) { postDeserializationFilter.GetFilter().Process( context ); if ( !context.SerializationError.IsSuccess ) { result = default( ResponseMessage ); return context.SerializationError; } } if ( !context.Error.IsNil ) { result = new ResponseMessage( context.MessageId, RpcException.FromMessage( context.Error, context.DeserializedResult ) ); } else { result = new ResponseMessage( context.MessageId, context.DeserializedResult ); } return RpcErrorMessage.Success; }