// ProtocolRequestToMessage // // Converts an incoming Ice Protocol Request stream from requestStream // into a new IMethodCallMessage. isBatched specifies if the request // is a batched request or not. public static IMessage ProtocolRequestToMessage(Stream requestStream, bool isBatched) { Ice.ProtocolReader pr = new Ice.ProtocolReader(requestStream); Ice.Identity id; string methodname; int requestId; Ice.OperationMode mode; Ice.Context context; if (!isBatched) { Ice.MessageRequest req = pr.ReadMessageRequest(); requestId = req.requestId; id = req.id; methodname = req.operation; mode = (Ice.OperationMode)Enum.ToObject(typeof(Ice.OperationMode), req.mode); context = req.context; } else { Ice.MessageBatchRequest req = pr.ReadMessageBatchRequest(); requestId = 0; id = req.id; methodname = req.operation; mode = (Ice.OperationMode)Enum.ToObject(typeof(Ice.OperationMode), req.mode); context = req.context; // FIXME -- if this is a batch, we really want to return multiple // messages. We need to extend both this function and the callee // to understand an array return. throw new NotImplementedException("Batch execution detected"); } string uri = id.ToUri(); Type svrType = RemotingServices.GetServerTypeForUri(uri); if (svrType == null) { throw new RemotingException("No registered server for uri " + uri); } MethodInfo mi = svrType.GetMethod(methodname); if (mi == null) { throw new Ice.OperationNotExistException(); } int encapsSize = pr.ReadEncapsulationHeader(); Trace.WriteLine("ProtocolRequestToMessage method: " + methodname + " -> " + mi); ParameterInfo[] paramInfos = mi.GetParameters(); int inParams = 0, outParams = 0; int readInParams = 0; object[] methodArgs; if (encapsSize == 0) { for (int i = 0; i < paramInfos.Length; i++) { if (paramInfos[i].IsOut) { outParams++; } else { inParams++; } } methodArgs = new object[0]; } else { ArrayList args = new ArrayList(); for (int i = 0; i < paramInfos.Length; i++) { if (!paramInfos[i].IsOut) { object o; if (Attribute.GetCustomAttribute(paramInfos[i], typeof(Ice.AsProxy)) != null) { o = pr.ReadObjectProxy(paramInfos[i].ParameterType); args.Add(o); } else if (!IceByValue(paramInfos[i].ParameterType)) { // add a placeholder that will get replaced by // patch call below. args.Add(null); pr.ReadClassInstanceParameterRef(args, readInParams); } else { o = pr.ReadObject(paramInfos[i].ParameterType); args.Add(o); } inParams++; readInParams++; } else { outParams++; } } pr.ReadClassInstancesAndPatch(); methodArgs = args.ToArray(); } if (readInParams != inParams) { // FIXME throw new InvalidOperationException("Wrong number of parameters for operation, expected " + inParams + " got " + readInParams); } // I need: uri, typeNAme, methodName, object[] args System.Runtime.Remoting.Messaging.Header[] hs = new System.Runtime.Remoting.Messaging.Header[4]; hs[0] = new Header("__TypeName", svrType.FullName); hs[1] = new Header("__MethodName", methodname); hs[2] = new Header("__Uri", uri); hs[3] = new Header("__Args", methodArgs); MethodCall mc = new MethodCall(hs); mc.Properties["__iceRequestId"] = requestId; mc.Properties["__iceIdentity"] = id; mc.Properties["__iceMode"] = mode; mc.Properties["__iceContext"] = context; return(mc); }
// ProtocolReplyToMessage // // Given a response message stream respStream, and the message that // originated to call msg, returns an IMethodReturnMessage describing // the return value of the function. // public static IMethodReturnMessage ProtocolReplyToMessage (Stream respStream, IMessage msg) { IMethodCallMessage mcall = msg as IMethodCallMessage; // set up some stuff that we'll need for parsing ParameterInfo[] paramInfos = mcall.MethodBase.GetParameters(); Type returnType = ((MethodInfo) mcall.MethodBase).ReturnType; // at this point, respStream should be pointing to the first byte after the requestId Ice.ProtocolReader pr = new Ice.ProtocolReader (respStream); // the first byte here is the MessageReplyType byte b = pr.ReadByte(); MessageReplyType replyType = (MessageReplyType) Enum.ToObject (typeof(MessageReplyType), b); if (replyType == MessageReplyType.Success) { // what follows is an encapsulation with return value and out params, if any. int encapsBytes = pr.ReadEncapsulationHeader(); if (encapsBytes == 0) { // no reply value(s) follow return new ReturnMessage (null, null, 0, mcall.LogicalCallContext, mcall); } else { // reply values follow: first the out-values in order of declaration, // then the return value object returnValue = null; ArrayList outArgs = new ArrayList(); int readOutArgs = 0; for (int i = 0; i < mcall.ArgCount; i++) { if (paramInfos[i].IsOut) { object o; if (Attribute.GetCustomAttribute (paramInfos[i], typeof(Ice.AsProxy)) != null) { o = pr.ReadObjectProxy (paramInfos[i].ParameterType); outArgs.Add (o); } else if (!IceByValue (paramInfos[i].ParameterType)) { // add placeholder for patch later outArgs.Add (null); pr.ReadClassInstanceParameterRef (outArgs, readOutArgs); } else { o = pr.ReadObject (paramInfos[i].ParameterType); outArgs.Add (o); } readOutArgs++; } } if (returnType != null && returnType != typeof(void)) { returnValue = pr.ReadObject (returnType); } pr.ReadClassInstancesAndPatch(); return new ReturnMessage (returnValue, outArgs.ToArray(), outArgs.Count, mcall.LogicalCallContext, mcall); } } else { // message was not a success; we ought to parse the exception. TODO FIXME Ice.UnknownException e = new Ice.UnknownException(); e.unknown = "Message reply type was " + replyType; return new ReturnMessage (e, mcall); } }
// ProtocolReplyToMessage // // Given a response message stream respStream, and the message that // originated to call msg, returns an IMethodReturnMessage describing // the return value of the function. // public static IMethodReturnMessage ProtocolReplyToMessage(Stream respStream, IMessage msg) { IMethodCallMessage mcall = msg as IMethodCallMessage; // set up some stuff that we'll need for parsing ParameterInfo[] paramInfos = mcall.MethodBase.GetParameters(); Type returnType = ((MethodInfo)mcall.MethodBase).ReturnType; // at this point, respStream should be pointing to the first byte after the requestId Ice.ProtocolReader pr = new Ice.ProtocolReader(respStream); // the first byte here is the MessageReplyType byte b = pr.ReadByte(); MessageReplyType replyType = (MessageReplyType)Enum.ToObject(typeof(MessageReplyType), b); if (replyType == MessageReplyType.Success) { // what follows is an encapsulation with return value and out params, if any. int encapsBytes = pr.ReadEncapsulationHeader(); if (encapsBytes == 0) { // no reply value(s) follow return(new ReturnMessage(null, null, 0, mcall.LogicalCallContext, mcall)); } else { // reply values follow: first the out-values in order of declaration, // then the return value object returnValue = null; ArrayList outArgs = new ArrayList(); int readOutArgs = 0; for (int i = 0; i < mcall.ArgCount; i++) { if (paramInfos[i].IsOut) { object o; if (Attribute.GetCustomAttribute(paramInfos[i], typeof(Ice.AsProxy)) != null) { o = pr.ReadObjectProxy(paramInfos[i].ParameterType); outArgs.Add(o); } else if (!IceByValue(paramInfos[i].ParameterType)) { // add placeholder for patch later outArgs.Add(null); pr.ReadClassInstanceParameterRef(outArgs, readOutArgs); } else { o = pr.ReadObject(paramInfos[i].ParameterType); outArgs.Add(o); } readOutArgs++; } } if (returnType != null && returnType != typeof(void)) { returnValue = pr.ReadObject(returnType); } pr.ReadClassInstancesAndPatch(); return(new ReturnMessage(returnValue, outArgs.ToArray(), outArgs.Count, mcall.LogicalCallContext, mcall)); } } else { // message was not a success; we ought to parse the exception. TODO FIXME Ice.UnknownException e = new Ice.UnknownException(); e.unknown = "Message reply type was " + replyType; return(new ReturnMessage(e, mcall)); } }
// ProtocolRequestToMessage // // Converts an incoming Ice Protocol Request stream from requestStream // into a new IMethodCallMessage. isBatched specifies if the request // is a batched request or not. public static IMessage ProtocolRequestToMessage (Stream requestStream, bool isBatched) { Ice.ProtocolReader pr = new Ice.ProtocolReader (requestStream); Ice.Identity id; string methodname; int requestId; Ice.OperationMode mode; Ice.Context context; if (!isBatched) { Ice.MessageRequest req = pr.ReadMessageRequest(); requestId = req.requestId; id = req.id; methodname = req.operation; mode = (Ice.OperationMode) Enum.ToObject (typeof(Ice.OperationMode), req.mode); context = req.context; } else { Ice.MessageBatchRequest req = pr.ReadMessageBatchRequest(); requestId = 0; id = req.id; methodname = req.operation; mode = (Ice.OperationMode) Enum.ToObject (typeof(Ice.OperationMode), req.mode); context = req.context; // FIXME -- if this is a batch, we really want to return multiple // messages. We need to extend both this function and the callee // to understand an array return. throw new NotImplementedException ("Batch execution detected"); } string uri = id.ToUri(); Type svrType = RemotingServices.GetServerTypeForUri (uri); if (svrType == null) throw new RemotingException ("No registered server for uri " + uri); MethodInfo mi = svrType.GetMethod (methodname); if (mi == null) throw new Ice.OperationNotExistException(); int encapsSize = pr.ReadEncapsulationHeader(); Trace.WriteLine ("ProtocolRequestToMessage method: " + methodname + " -> " + mi); ParameterInfo[] paramInfos = mi.GetParameters(); int inParams = 0, outParams = 0; int readInParams = 0; object[] methodArgs; if (encapsSize == 0) { for (int i = 0; i < paramInfos.Length; i++) { if (paramInfos[i].IsOut) outParams++; else inParams++; } methodArgs = new object[0]; } else { ArrayList args = new ArrayList(); for (int i = 0; i < paramInfos.Length; i++) { if (!paramInfos[i].IsOut) { object o; if (Attribute.GetCustomAttribute (paramInfos[i], typeof(Ice.AsProxy)) != null) { o = pr.ReadObjectProxy (paramInfos[i].ParameterType); args.Add (o); } else if (!IceByValue (paramInfos[i].ParameterType)) { // add a placeholder that will get replaced by // patch call below. args.Add (null); pr.ReadClassInstanceParameterRef (args, readInParams); } else { o = pr.ReadObject (paramInfos[i].ParameterType); args.Add (o); } inParams++; readInParams++; } else { outParams++; } } pr.ReadClassInstancesAndPatch(); methodArgs = args.ToArray(); } if (readInParams != inParams) { // FIXME throw new InvalidOperationException("Wrong number of parameters for operation, expected " + inParams + " got " + readInParams); } // I need: uri, typeNAme, methodName, object[] args System.Runtime.Remoting.Messaging.Header[] hs = new System.Runtime.Remoting.Messaging.Header[4]; hs[0] = new Header ("__TypeName", svrType.FullName); hs[1] = new Header ("__MethodName",methodname); hs[2] = new Header ("__Uri", uri); hs[3] = new Header ("__Args", methodArgs); MethodCall mc = new MethodCall (hs); mc.Properties["__iceRequestId"] = requestId; mc.Properties["__iceIdentity"] = id; mc.Properties["__iceMode"] = mode; mc.Properties["__iceContext"] = context; return mc; }