[runtime] Updates comments.
[mono.git] / mcs / class / corlib / System.Runtime.Remoting.Messaging / MonoMethodMessage.cs
1 //
2 // System.Runtime.Remoting.Messaging.MonoMethodMessage.cs
3 //
4 // Author:
5 //   Dietmar Maurer (dietmar@ximian.com)
6 //   Patrik Torstensson
7 //
8 // (C) Ximian, Inc.  http://www.ximian.com
9 //
10
11 //
12 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 //
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:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
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.
32 //
33
34 using System;
35 using System.Collections;
36 using System.Reflection;
37 using System.Runtime.CompilerServices;
38 using System.Runtime.InteropServices;
39
40 namespace System.Runtime.Remoting.Messaging {
41         
42         [Serializable]
43         [StructLayout (LayoutKind.Sequential)]
44         internal class MonoMethodMessage : IMethodCallMessage, IMethodReturnMessage, IInternalMessage {
45
46 #pragma warning disable 649
47                 #region keep in sync with MonoMessage in object-internals.h
48                 MonoMethod method;
49                 object []  args;
50                 string []  names;
51                 byte [] arg_types; /* 1 == IN; 2 == OUT; 3 == INOUT; 4 == COPY OUT */
52                 public LogicalCallContext ctx;
53                 public object rval;
54                 public Exception exc;
55                 AsyncResult asyncResult;
56                 CallType call_type;
57                 #endregion
58 #pragma warning restore 649
59
60                 string uri;
61
62                 MethodCallDictionary properties;
63
64                 Type[] methodSignature;
65
66                 Identity identity;
67
68
69                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
70                 internal extern void InitMessage (MonoMethod method, object [] out_args);
71
72                 public MonoMethodMessage (MethodBase method, object [] out_args)
73                 {
74                         if (method != null)
75                                 InitMessage ((MonoMethod)method, out_args);
76                         else
77                                 args = null;
78                 }
79
80                 public MonoMethodMessage (Type type, string method_name, object [] in_args)
81                 {
82                         // fixme: consider arg types
83                         MethodInfo minfo = type.GetMethod (method_name);
84                         
85                         InitMessage ((MonoMethod)minfo, null);
86
87                         int len = in_args.Length;
88                         for (int i = 0; i < len; i++) {
89                                 args [i] = in_args [i];
90                         }
91                 }
92                 
93                 public IDictionary Properties {
94                         get {
95                                 if (properties == null) properties = new MethodCallDictionary (this);
96                                 return properties;
97                         }
98                 }
99
100                 public int ArgCount {
101                         get {
102                                 if (CallType == CallType.EndInvoke)
103                                         return -1;
104                                         
105                                 if (null == args)
106                                         return 0;
107
108                                 return args.Length;
109                         }
110                 }
111                 
112                 public object [] Args {
113                         get {
114                                 return args;
115                         }
116                 }
117                 
118                 public bool HasVarArgs {
119                         get {
120                                 return false;
121                         }
122                 }
123
124                 public LogicalCallContext LogicalCallContext {
125                         get {
126                                 return ctx;
127                         }
128
129                         set {
130                                 ctx = value;
131                         }
132                 }
133
134                 public MethodBase MethodBase {
135                         get {
136                                 return method;
137                         }
138                 }
139
140                 public string MethodName {
141                         get {
142                                 if (null == method)
143                                         return String.Empty;
144
145                                 return method.Name;
146                         }
147                 }
148
149                 public object MethodSignature {
150                         get {
151                                 if (methodSignature == null) {
152                                         ParameterInfo[] parameters = method.GetParameters();
153                                         methodSignature = new Type[parameters.Length];
154                                         for (int n=0; n<parameters.Length; n++)
155                                                 methodSignature[n] = parameters[n].ParameterType;
156                                 }
157                                 return methodSignature;
158                         }
159                 }
160
161                 public string TypeName {
162                         get {
163                                 if (null == method)
164                                         return String.Empty;
165
166                                 return method.DeclaringType.AssemblyQualifiedName;
167                         }
168                 }
169
170                 public string Uri {
171                         get {
172                                 return uri;
173                         }
174
175                         set {
176                                 uri = value;
177                         }
178                 }
179
180                 public object GetArg (int arg_num)
181                 {
182                         if (null == args)
183                                 return null;
184
185                         return args [arg_num];
186                 }
187                 
188                 public string GetArgName (int arg_num)
189                 {
190                         if (null == args)
191                                 return String.Empty;
192
193                         return names [arg_num];
194                 }
195
196                 public int InArgCount {
197                         get {
198                                 if (CallType == CallType.EndInvoke)
199                                         return -1;
200
201                                 if (null == args)
202                                         return 0;
203
204                                 int count = 0;
205
206                                 foreach (byte t in arg_types) {
207                                         if ((t & 1) != 0) count++;
208                                                 
209                                 }
210                                 return count;
211                         }
212                 }
213                 
214                 public object [] InArgs {
215                         get {                
216                                 int i, j, count = InArgCount;
217                                 object [] inargs = new object [count];
218
219                                 i = j = 0;
220                                 foreach (byte t in arg_types) {
221                                         if ((t & 1) != 0)
222                                                 inargs [j++] = args [i];
223                                         i++;
224                                 }
225                                 
226                                 return inargs;
227                         }
228                 }
229                 
230                 public object GetInArg (int arg_num)
231                 {
232                         int i = 0, j = 0;
233                         foreach (byte t in arg_types) {
234                                 if ((t & 1) != 0) {
235                                         if (j++ == arg_num)
236                                                 return args [i]; 
237                                 }
238                                 i++;
239                         }
240                         return null;
241                 }
242                 
243                 public string GetInArgName (int arg_num)
244                 {
245                         int i = 0, j = 0;
246                         foreach (byte t in arg_types) {
247                                 if ((t & 1) != 0) {
248                                         if (j++ == arg_num)
249                                                 return names [i]; 
250                                 }
251                                 i++;
252                         }
253                         return null;
254                 }
255
256                 public Exception Exception {
257                         get {
258                                 return exc;
259                         }
260                 }
261                 
262                 public int OutArgCount {
263                         get {
264                                 if (null == args)
265                                         return 0;
266                                 
267                                 int count = 0;
268
269                                 foreach (byte t in arg_types) {
270                                         if ((t & 2) != 0) count++;
271                                                 
272                                 }
273                                 return count;
274                         }
275                 }
276                 
277                 public object [] OutArgs {
278                         get {
279                                 if (null == args)
280                                         return null;
281
282                                 int i, j, count = OutArgCount;
283                                 object [] outargs = new object [count];
284
285                                 i = j = 0;
286                                 foreach (byte t in arg_types) {
287                                         if ((t & 2) != 0)
288                                                 outargs [j++] = args [i];
289                                         i++;
290                                 }
291                                 
292                                 return outargs;
293                         }
294                 }
295                 
296                 public object ReturnValue {
297                         get {
298                                 return rval;
299                         }
300                 }
301
302                 public object GetOutArg (int arg_num)
303                 {
304                         int i = 0, j = 0;
305                         foreach (byte t in arg_types) {
306                                 if ((t & 2) != 0) {
307                                         if (j++ == arg_num)
308                                                 return args [i]; 
309                                 }
310                                 i++;
311                         }
312                         return null;
313                 }
314                 
315                 public string GetOutArgName (int arg_num)
316                 {
317                         int i = 0, j = 0;
318                         foreach (byte t in arg_types) {
319                                 if ((t & 2) != 0) {
320                                         if (j++ == arg_num)
321                                                 return names [i]; 
322                                 }
323                                 i++;
324                         }
325                         return null;
326                 }
327
328                 Identity IInternalMessage.TargetIdentity
329                 {
330                         get { return identity; }
331                         set { identity = value; }
332                 }
333
334                 public bool IsAsync
335                 {
336                         get { return asyncResult != null; }
337                 }
338
339                 public AsyncResult AsyncResult
340                 {
341                         get { return asyncResult; }
342                 }
343
344                 internal CallType CallType
345                 {
346                         get
347                         {
348                                 // FIXME: ideally, the OneWay type would be set by the runtime
349                                 
350                                 if (call_type == CallType.Sync && RemotingServices.IsOneWay (method))
351                                         call_type = CallType.OneWay;
352                                 return call_type;
353                         }
354                 }
355                 
356                 public bool NeedsOutProcessing (out int outCount) {
357                         bool res = false;
358                         outCount = 0;
359                         foreach (byte t in arg_types) {
360                                 if ((t & 2) != 0)
361                                         outCount++;
362                                 else if ((t & 4) != 0)
363                                         res = true;
364                         }
365                         return outCount > 0 || res;
366                 }
367                 
368         }
369
370         internal enum CallType: int
371         {
372                 Sync = 0,
373                 BeginInvoke = 1,
374                 EndInvoke = 2,
375                 OneWay = 3
376         }
377 }
378