Пример #1
0
        /// <summary>
        /// Encodes the given method call to a RPC message.
        /// </summary>
        public static RpcMessage Encode(RpcMethod methodCall)
        {
            byte[] name            = Encoding.UTF8.GetBytes(methodCall.Name);
            int    parametersCount = methodCall.Parameters?.Count ?? 0;
            int    length          = 2 /* Header */ + 8 /* ID */ +
                                     name.Length + 1 +                                           /* Method name and ";" */
                                     1 + (methodCall.Parameters?.Sum(it => 4 + it.Length) ?? 0); /* Parameters: Count, and for each: length and data */

            byte[] data = new byte[length];
            int    pos  = 0;

            data[pos++] = (byte)'1';                                           // Header
            data[pos++] = (byte)'M';
            Array.Copy(BitConverter.GetBytes(methodCall.ID), 0, data, pos, 8); // ID
            pos += 8;
            Array.Copy(name, 0, data, pos, name.Length);                       // Name
            pos        += name.Length;
            data[pos++] = (byte)';';
            data[pos++] = (byte)parametersCount;
            if (parametersCount > 0)
            {
                foreach (var param in methodCall.Parameters !)
                {
                    Array.Copy(BitConverter.GetBytes(param.Length), 0, data, pos, 4); // Param length
                    pos += 4;
                    Array.Copy(param, 0, data, pos, param.Length);                    // Param data
                    pos += param.Length;
                }
            }
            return(new RpcMessage {
                Data = data
            });
        }
Пример #2
0
 public static Div FromMethod(RpcMethod method)
 {
     if (method.Name != methodName)
     {
         throw new Exception("Wrong method name");
     }
     return(new Div {
         methodID = method.ID,
         dividend = method.Parameters[0][0],
         divisor = method.Parameters[1][0]
     });
 }
Пример #3
0
 /// <summary>
 /// Gets the <see cref="RpcMethod"/> content of this message or throws an exception, if it
 /// is no valid message of this type.
 /// <see cref="IsRpcMethod"/> can be called before to find out the type of this message.
 /// </summary>
 public RpcMethod DecodeRpcMethod()
 {
     if (false == IsRpcMethod())
     {
         throw new FormatException("Header wrong");
     }
     try {
         int pos = 2;
         var ret = new RpcMethod();
         // ID
         ret.ID = BitConverter.ToUInt64(Data, pos);
         pos   += 8;
         // Method name
         int methodNameEnd = Array.FindIndex(Data, pos, it => it == (byte)';');
         if (methodNameEnd == -1)
         {
             throw new FormatException("Method end not found");
         }
         ret.Name = Encoding.UTF8.GetString(Data, pos, methodNameEnd - pos);
         pos      = methodNameEnd + 1;
         // Parameters
         byte paramsCount = Data[pos++];
         if (paramsCount > 0)
         {
             ret.Parameters = new List <byte[]>(capacity: paramsCount);
             for (byte iParam = 0; iParam < paramsCount; iParam++)
             {
                 int paramLength = BitConverter.ToInt32(Data, pos);
                 pos += 4;
                 ret.Parameters.Add(
                     new ArraySegment <byte>(Data, pos, paramLength).ToArray());
                 pos += paramLength;
             }
         }
         return(ret);
     } catch (Exception ex) {
         throw new FormatException("Content wrong: " + ex.Message, ex);
     }
 }