2 // System.Runtime.Remoting.Messaging.MonoMethodMessage.cs
5 // Dietmar Maurer (dietmar@ximian.com)
8 // (C) Ximian, Inc. http://www.ximian.com
12 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 using System.Collections;
36 using System.Reflection;
37 using System.Runtime.CompilerServices;
38 using System.Runtime.InteropServices;
40 namespace System.Runtime.Remoting.Messaging {
43 [StructLayout (LayoutKind.Sequential)]
44 internal class MonoMethodMessage : IMethodCallMessage, IMethodReturnMessage, IInternalMessage {
46 #pragma warning disable 649
47 #region keep in sync with MonoMessage in object-internals.h
51 byte [] arg_types; /* 1 == IN; 2 == OUT; 3 == INOUT; 4 == COPY OUT */
52 public LogicalCallContext ctx;
55 AsyncResult asyncResult;
58 #pragma warning restore 649
62 MCMDictionary properties;
64 Type[] methodSignature;
68 internal static String CallContextKey = "__CallContext";
69 internal static String UriKey = "__Uri";
71 internal void InitMessage (MonoMethod method, object [] out_args)
74 ParameterInfo[] paramInfo = method.GetParametersInternal ();
75 int param_count = paramInfo.Length;
76 args = new object[param_count];
77 arg_types = new byte[param_count];
79 call_type = CallType.Sync;
80 names = new string[param_count];
81 for (int i = 0; i < param_count; i++) {
82 names[i] = paramInfo[i].Name;
84 bool hasOutArgs = out_args != null;
86 for (int i = 0; i < param_count; i++) {
88 bool isOut = paramInfo[i].IsOut;
89 if (paramInfo[i].ParameterType.IsByRef) {
91 args[i] = out_args[j++];
94 arg_type |= 1; // INOUT
98 arg_type |= 4; // IN, COPY OUT
100 arg_types[i] = arg_type;
104 public MonoMethodMessage (MethodBase method, object [] out_args)
107 InitMessage ((MonoMethod)method, out_args);
112 public MonoMethodMessage (Type type, string method_name, object [] in_args)
114 // fixme: consider arg types
115 MethodInfo minfo = type.GetMethod (method_name);
117 InitMessage ((MonoMethod)minfo, null);
119 int len = in_args.Length;
120 for (int i = 0; i < len; i++) {
121 args [i] = in_args [i];
125 public IDictionary Properties {
127 if (properties == null) properties = new MCMDictionary (this);
132 public int ArgCount {
134 if (CallType == CallType.EndInvoke)
144 public object [] Args {
150 public bool HasVarArgs {
156 public LogicalCallContext LogicalCallContext {
166 public MethodBase MethodBase {
172 public string MethodName {
181 public object MethodSignature {
183 if (methodSignature == null) {
184 ParameterInfo[] parameters = method.GetParameters();
185 methodSignature = new Type[parameters.Length];
186 for (int n=0; n<parameters.Length; n++)
187 methodSignature[n] = parameters[n].ParameterType;
189 return methodSignature;
193 public string TypeName {
198 return method.DeclaringType.AssemblyQualifiedName;
212 public object GetArg (int arg_num)
217 return args [arg_num];
220 public string GetArgName (int arg_num)
225 return names [arg_num];
228 public int InArgCount {
230 if (CallType == CallType.EndInvoke)
238 foreach (byte t in arg_types) {
239 if ((t & 1) != 0) count++;
246 public object [] InArgs {
248 int i, j, count = InArgCount;
249 object [] inargs = new object [count];
252 foreach (byte t in arg_types) {
254 inargs [j++] = args [i];
262 public object GetInArg (int arg_num)
265 foreach (byte t in arg_types) {
275 public string GetInArgName (int arg_num)
278 foreach (byte t in arg_types) {
288 public Exception Exception {
294 public int OutArgCount {
301 foreach (byte t in arg_types) {
302 if ((t & 2) != 0) count++;
309 public object [] OutArgs {
314 int i, j, count = OutArgCount;
315 object [] outargs = new object [count];
318 foreach (byte t in arg_types) {
320 outargs [j++] = args [i];
328 public object ReturnValue {
334 public object GetOutArg (int arg_num)
337 foreach (byte t in arg_types) {
347 public string GetOutArgName (int arg_num)
350 foreach (byte t in arg_types) {
360 Identity IInternalMessage.TargetIdentity
362 get { return identity; }
363 set { identity = value; }
366 bool IInternalMessage.HasProperties()
368 return properties != null;
373 get { return asyncResult != null; }
376 public AsyncResult AsyncResult
378 get { return asyncResult; }
381 internal CallType CallType
385 // FIXME: ideally, the OneWay type would be set by the runtime
387 if (call_type == CallType.Sync && RemotingServices.IsOneWay (method))
388 call_type = CallType.OneWay;
393 public bool NeedsOutProcessing (out int outCount) {
396 foreach (byte t in arg_types) {
399 else if ((t & 4) != 0)
402 return outCount > 0 || res;
407 internal enum CallType: int