/// <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 }); }
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] }); }
/// <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); } }