コード例 #1
0
        /// <summary>
        ///		Unpack Message ID part on request message.
        /// </summary>
        /// <param name="context">Context information.</param>
        /// <returns>
        ///		<c>true</c>, if the pipeline is finished;
        ///		<c>false</c>, the pipeline is interruppted because extra data is needed.
        /// </returns>
        private bool UnpackMessageId(ServerRequestContext context)
        {
            Contract.Assert(context != null);

            if (!context.ReadFromHeaderUnpacker())
            {
                MsgPackRpcServerProtocolsTrace.TraceEvent(
                    MsgPackRpcServerProtocolsTrace.NeedMessageId,
                    "Message ID is needed. {{ \"SessionID\" : {0} }}",
                    context.SessionId
                    );
                return(false);
            }

            try
            {
                context.MessageId = unchecked (( int )context.HeaderUnpacker.LastReadData.AsUInt32());
            }
            catch (InvalidOperationException)
            {
                this.HandleDeserializationError(
                    context,
                    "Invalid request message stream. ID must be UInt32 compatible integer.",
                    () => context.UnpackingBuffer.ToArray()
                    );
                return(true);
            }

            context.NextProcess = this.UnpackMethodName;
            return(context.NextProcess(context));
        }
コード例 #2
0
        /// <summary>
        ///		Unpack Method Name part on request/notification message.
        /// </summary>
        /// <param name="context">Context information.</param>
        /// <returns>
        ///		<c>true</c>, if the pipeline is finished;
        ///		<c>false</c>, the pipeline is interruppted because extra data is needed.
        /// </returns>
        private bool UnpackMethodName(ServerRequestContext context)
        {
            Contract.Assert(context != null);

            if (!context.ReadFromHeaderUnpacker())
            {
                MsgPackRpcServerProtocolsTrace.TraceEvent(
                    MsgPackRpcServerProtocolsTrace.NeedMethodName,
                    "Method Name is needed. {{ \"SessionID\" : {0} }}",
                    context.SessionId
                    );
                return(false);
            }

            try
            {
                context.MethodName = context.HeaderUnpacker.LastReadData.AsString();
            }
            catch (InvalidOperationException)
            {
                this.HandleDeserializationError(
                    context,
                    "Invalid request/notify message stream. Method name must be UTF-8 string.",
                    () => context.UnpackingBuffer.ToArray()
                    );
                return(true);
            }

            context.NextProcess = this.UnpackArgumentsHeader;
            return(context.NextProcess(context));
        }
コード例 #3
0
        /// <summary>
        ///		Unpack Message Type part on request/notification message.
        /// </summary>
        /// <param name="context">Context information.</param>
        /// <returns>
        ///		<c>true</c>, if the pipeline is finished;
        ///		<c>false</c>, the pipeline is interruppted because extra data is needed.
        /// </returns>
        private bool UnpackMessageType(ServerRequestContext context)
        {
            Contract.Assert(context != null);

            if (!context.ReadFromHeaderUnpacker())
            {
                MsgPackRpcServerProtocolsTrace.TraceEvent(
                    MsgPackRpcServerProtocolsTrace.NeedMessageType,
                    "Message Type is needed. {{ \"SessionID\" : {0} }}",
                    context.SessionId
                    );
                return(false);
            }

            int numericType;

            try
            {
                numericType = context.HeaderUnpacker.LastReadData.AsInt32();
            }
            catch (InvalidOperationException)
            {
                this.HandleDeserializationError(context, "Invalid request/notify message stream. Message Type must be Int32 compatible integer.", () => context.UnpackingBuffer.ToArray());
                return(true);
            }

            MessageType type = ( MessageType )numericType;

            context.MessageType = type;

            switch (type)
            {
            case MessageType.Request:
            {
                context.NextProcess = this.UnpackMessageId;
                break;
            }

            case MessageType.Notification:
            {
                context.NextProcess = this.UnpackMethodName;
                break;
            }

            default:
            {
                this.HandleDeserializationError(
                    context,
                    String.Format(CultureInfo.CurrentCulture, "Unknown message type '{0:x8}'", numericType),
                    () => context.UnpackingBuffer.ToArray()
                    );
                return(true);
            }
            }

            return(context.NextProcess(context));
        }
コード例 #4
0
        /// <summary>
        ///		Unpack array header of Arguments part on request/notification message.
        /// </summary>
        /// <param name="context">Context information.</param>
        /// <returns>
        ///		<c>true</c>, if the pipeline is finished;
        ///		<c>false</c>, the pipeline is interruppted because extra data is needed.
        /// </returns>
        private bool UnpackArgumentsHeader(ServerRequestContext context)
        {
            Contract.Assert(context != null);

            if (!context.ReadFromHeaderUnpacker())
            {
                MsgPackRpcServerProtocolsTrace.TraceEvent(
                    MsgPackRpcServerProtocolsTrace.NeedArgumentsArrayHeader,
                    "Arguments array header is needed. {{ \"SessionID\" : {0} }}",
                    context.SessionId
                    );
                return(false);
            }

            if (!context.HeaderUnpacker.IsArrayHeader)
            {
                this.HandleDeserializationError(
                    context,
                    "Invalid request/notify message stream. Arguments must be array.",
                    () => context.UnpackingBuffer.ToArray()
                    );
                return(true);
            }

            // TODO: Avoid actual unpacking to improve performance.
            context.ArgumentsBufferUnpacker = context.HeaderUnpacker.ReadSubtree();

            if (Int32.MaxValue < context.ArgumentsBufferUnpacker.ItemsCount)
            {
                this.HandleDeserializationError(
                    context,
                    RpcError.MessageTooLargeError,
                    "Too many arguments.",
                    context.ArgumentsBufferUnpacker.ItemsCount.ToString("#,0", CultureInfo.CurrentCulture),
                    () => context.UnpackingBuffer.ToArray()
                    );
                return(true);
            }

            context.ArgumentsCount        = unchecked (( int )(context.ArgumentsBufferUnpacker.ItemsCount));
            context.ArgumentsBufferPacker = Packer.Create(context.ArgumentsBuffer, false);
            context.ArgumentsBufferPacker.PackArrayHeader(context.ArgumentsCount);
            context.UnpackedArgumentsCount = 0;
            context.NextProcess            = this.UnpackArguments;
            return(context.NextProcess(context));
        }
コード例 #5
0
		/// <summary>
		///		Unpack array header of Arguments part on request/notification message.
		/// </summary>
		/// <param name="context">Context information.</param>
		/// <returns>
		///		<c>true</c>, if the pipeline is finished;
		///		<c>false</c>, the pipeline is interruppted because extra data is needed.
		/// </returns>
		private bool UnpackArgumentsHeader( ServerRequestContext context )
		{
			Contract.Assert( context != null );

			if ( !context.ReadFromHeaderUnpacker() )
			{
				MsgPackRpcServerProtocolsTrace.TraceEvent( 
					MsgPackRpcServerProtocolsTrace.NeedArgumentsArrayHeader,
					"Arguments array header is needed. {{ \"SessionID\" : {0} }}",
					context.SessionId 
				);
				return false;
			}

			if ( !context.HeaderUnpacker.IsArrayHeader )
			{
				this.HandleDeserializationError(
					context,
					"Invalid request/notify message stream. Arguments must be array.",
					() => context.UnpackingBuffer.ToArray()
				);
				return true;
			}

			// TODO: Avoid actual unpacking to improve performance.
			context.ArgumentsBufferUnpacker = context.HeaderUnpacker.ReadSubtree();

			if ( Int32.MaxValue < context.ArgumentsBufferUnpacker.ItemsCount )
			{
				this.HandleDeserializationError(
					context,
					RpcError.MessageTooLargeError,
					"Too many arguments.",
					context.ArgumentsBufferUnpacker.ItemsCount.ToString( "#,0", CultureInfo.CurrentCulture ),
					() => context.UnpackingBuffer.ToArray()
				);
				return true;
			}

			context.ArgumentsCount = unchecked( ( int )( context.ArgumentsBufferUnpacker.ItemsCount ) );
			context.ArgumentsBufferPacker = Packer.Create( context.ArgumentsBuffer, false );
			context.ArgumentsBufferPacker.PackArrayHeader( context.ArgumentsCount );
			context.UnpackedArgumentsCount = 0;
			context.NextProcess = this.UnpackArguments;
			return context.NextProcess( context );
		}
コード例 #6
0
		/// <summary>
		///		Unpack Method Name part on request/notification message.
		/// </summary>
		/// <param name="context">Context information.</param>
		/// <returns>
		///		<c>true</c>, if the pipeline is finished;
		///		<c>false</c>, the pipeline is interruppted because extra data is needed.
		/// </returns>
		private bool UnpackMethodName( ServerRequestContext context )
		{
			Contract.Assert( context != null );

			if ( !context.ReadFromHeaderUnpacker() )
			{
				MsgPackRpcServerProtocolsTrace.TraceEvent( 
					MsgPackRpcServerProtocolsTrace.NeedMethodName,
					"Method Name is needed. {{ \"SessionID\" : {0} }}",
					context.SessionId 
				);
				return false;
			}

			try
			{
				context.MethodName = context.HeaderUnpacker.LastReadData.AsString();
			}
			catch ( InvalidOperationException )
			{
				this.HandleDeserializationError(
					context,
					"Invalid request/notify message stream. Method name must be UTF-8 string.",
					() => context.UnpackingBuffer.ToArray()
				);
				return true;
			}

			context.NextProcess = this.UnpackArgumentsHeader;
			return context.NextProcess( context );
		}
コード例 #7
0
		/// <summary>
		///		Unpack Message ID part on request message.
		/// </summary>
		/// <param name="context">Context information.</param>
		/// <returns>
		///		<c>true</c>, if the pipeline is finished;
		///		<c>false</c>, the pipeline is interruppted because extra data is needed.
		/// </returns>
		private bool UnpackMessageId( ServerRequestContext context )
		{
			Contract.Assert( context != null );

			if ( !context.ReadFromHeaderUnpacker() )
			{
				MsgPackRpcServerProtocolsTrace.TraceEvent( 
					MsgPackRpcServerProtocolsTrace.NeedMessageId,
					"Message ID is needed. {{ \"SessionID\" : {0} }}", 
					context.SessionId 
				);
				return false;
			}

			try
			{
				context.MessageId = unchecked( ( int )context.HeaderUnpacker.LastReadData.AsUInt32() );
			}
			catch ( InvalidOperationException )
			{
				this.HandleDeserializationError(
					context,
					"Invalid request message stream. ID must be UInt32 compatible integer.",
					() => context.UnpackingBuffer.ToArray()
				);
				return true;
			}

			context.NextProcess = this.UnpackMethodName;
			return context.NextProcess( context );
		}
コード例 #8
0
		/// <summary>
		///		Unpack Message Type part on request/notification message.
		/// </summary>
		/// <param name="context">Context information.</param>
		/// <returns>
		///		<c>true</c>, if the pipeline is finished;
		///		<c>false</c>, the pipeline is interruppted because extra data is needed.
		/// </returns>
		private bool UnpackMessageType( ServerRequestContext context )
		{
			Contract.Assert( context != null );
			
			if ( !context.ReadFromHeaderUnpacker() )
			{
				MsgPackRpcServerProtocolsTrace.TraceEvent( 
					MsgPackRpcServerProtocolsTrace.NeedMessageType,
					"Message Type is needed. {{ \"SessionID\" : {0} }}",
					context.SessionId 
				);
				return false;
			}

			int numericType;
			try
			{
				numericType = context.HeaderUnpacker.LastReadData.AsInt32();
			}
			catch ( InvalidOperationException )
			{
				this.HandleDeserializationError( context, "Invalid request/notify message stream. Message Type must be Int32 compatible integer.", () => context.UnpackingBuffer.ToArray() );
				return true;
			}

			MessageType type = ( MessageType )numericType;
			context.MessageType = type;

			switch ( type )
			{
				case MessageType.Request:
				{
					context.NextProcess = this.UnpackMessageId;
					break;
				}
				case MessageType.Notification:
				{
					context.NextProcess = this.UnpackMethodName;
					break;
				}
				default:
				{
					this.HandleDeserializationError(
						context,
						String.Format( CultureInfo.CurrentCulture, "Unknown message type '{0:x8}'", numericType ),
						() => context.UnpackingBuffer.ToArray()
					);
					return true;
				}
			}

			return context.NextProcess( context );
		}