Ejemplo n.º 1
0
 /// <summary>
 /// Gets the <see cref="RpcResult"/> content of this message or throws an exception, if it
 /// is no valid message of this type.
 /// <see cref="IsRpcResult"/> can be called before to find out the type of this message.
 /// </summary>
 public RpcResult DecodeRpcResult()
 {
     if (false == IsRpcResult())
     {
         throw new FormatException("Header wrong");
     }
     try {
         int pos = 2;
         var ret = new RpcResult();
         // ID
         ret.MethodID = BitConverter.ToUInt64(Data, pos);
         pos         += 8;
         // Success or failure
         bool isSuccess = Data[pos++] == (byte)'S';
         if (isSuccess)
         {
             // Successful
             int returnValueLength = BitConverter.ToInt32(Data, pos);
             pos += 4;
             if (returnValueLength > 0)
             {
                 ret.ReturnValue = new ArraySegment <byte>(Data, pos, returnValueLength).ToArray();
                 pos            += returnValueLength;
             }
         }
         else
         {
             // Failure
             ret.Failure = new RpcFailure();
             // Failure type
             int failureTypeEnd = Array.FindIndex(Data, pos, it => it == (byte)';');
             if (failureTypeEnd == -1)
             {
                 throw new FormatException("FailureType end not found");
             }
             ret.Failure.Type = Enum.Parse <RpcFailureType>(
                 Encoding.UTF8.GetString(Data, pos, failureTypeEnd - pos));
             pos = failureTypeEnd + 1;
             // Message
             int messageLength = BitConverter.ToInt32(Data, pos);
             pos += 4;
             if (messageLength > 0)
             {
                 ret.Failure.Message = Encoding.UTF8.GetString(Data, pos, messageLength);
                 pos += messageLength;
             }
         }
         return(ret);
     } catch (Exception ex) {
         throw new FormatException("Content wrong: " + ex.Message, ex);
     }
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Call this method as soon as a result was received for this call.
 /// </summary>
 public void Finish(RpcResult result) =>
 completionHelper.TrySetResult(result);
Ejemplo n.º 3
0
        /// <summary>
        /// Encodes the given RPC result to a RPC message.
        /// </summary>
        public static RpcMessage Encode(RpcResult result)
        {
            int length = 2 /* Header */ + 8 /* ID */ + 1 /* Success/Failure */;

            byte[]? failureType = null;
            int failureMessageLength = 0;

            byte[]? failureMessage = null;
            int returnValueLength = result.ReturnValue?.Length ?? 0;

            if (result.Failure == null)
            {
                // Successful
                length += 4 + returnValueLength; /* Length and data */
            }
            else
            {
                // Failure
                failureType          = Encoding.UTF8.GetBytes("" + result.Failure.Type);
                failureMessageLength = result.Failure.Message?.Length ?? 0;
                if (failureMessageLength > 0)
                {
                    failureMessage = Encoding.UTF8.GetBytes(result.Failure.Message !);
                }
                length += failureType.Length + 1 /* ";" */ + 4 + failureMessageLength;
            }
            byte[] data = new byte[length];
            int    pos  = 0;

            data[pos++] = (byte)'1';                                             // Header
            data[pos++] = (byte)'R';
            Array.Copy(BitConverter.GetBytes(result.MethodID), 0, data, pos, 8); // ID
            pos += 8;
            // Success or failure
            if (result.Failure == null)
            {
                // Successful
                data[pos++] = (byte)'S';
                Array.Copy(BitConverter.GetBytes(returnValueLength), 0, data, pos, 4); // Return value length
                pos += 4;
                if (returnValueLength > 0)
                {
                    Array.Copy(result.ReturnValue !, 0, data, pos, returnValueLength); // Return value data
                    pos += returnValueLength;
                }
            }
            else
            {
                // Failure
                data[pos++] = (byte)'F';
                Array.Copy(failureType !, 0, data, pos, failureType !.Length); // Failure type
                pos        += failureType !.Length;
                data[pos++] = (byte)';';
                Array.Copy(BitConverter.GetBytes(failureMessageLength), 0, data, pos, 4); // Failure message length
                pos += 4;
                if (failureMessageLength > 0)
                {
                    Array.Copy(failureMessage !, 0, data, pos, failureMessageLength); // Failure message
                    pos += failureMessageLength;
                }
            }
            return(new RpcMessage {
                Data = data
            });
        }