* ArgInfo.cs, ClientContextTerminatorSink.cs, ErrorMessage.cs, MethodCall.cs,
[mono.git] / mcs / class / corlib / System.Runtime.Remoting.Messaging / MethodResponse.cs
1 //
2 // System.Runtime.Remoting.Messaging.MethodResponse.cs
3 //
4 // Author:      Duncan Mak (duncan@ximian.com)
5 //              Patrik Torstensson
6 //
7 // 2002 (C) Copyright, Ximian, Inc.
8 //
9
10 using System;
11 using System.Collections;
12 using System.Reflection;
13 using System.Runtime.Remoting;
14 using System.Runtime.Serialization;
15
16 namespace System.Runtime.Remoting.Messaging {
17
18         [Serializable] [CLSCompliant (false)]
19         public class MethodResponse : IMethodReturnMessage, ISerializable, IInternalMessage, ISerializationRootObject
20         {
21                 string _methodName;
22                 string _uri;
23                 string _typeName;
24                 MethodBase _methodBase;
25
26                 object _returnValue;
27                 Exception _exception;
28                 Type [] _methodSignature;
29                 ArgInfo _inArgInfo;
30
31                 object []  _args;
32                 object []  _outArgs;
33                 IMethodCallMessage _callMsg;
34                 LogicalCallContext _callContext;
35                 Identity _targetIdentity;
36
37                 protected IDictionary ExternalProperties;
38                 protected IDictionary InternalProperties;
39
40                 public MethodResponse (Header[] headers, IMethodCallMessage mcm)
41                 {
42                         if (mcm != null)
43                         {
44                                 _methodName = mcm.MethodName;
45                                 _uri = mcm.Uri;
46                                 _typeName = mcm.TypeName;
47                                 _methodBase = mcm.MethodBase;
48                                 _methodSignature = (Type[]) mcm.MethodSignature;
49                                 _args = mcm.Args;
50                         }
51
52                         if (headers != null)
53                         {
54                                 foreach (Header header in headers)
55                                         InitMethodProperty (header.Name, header.Value);
56                         }
57                 }
58
59                 internal MethodResponse (Exception e, IMethodCallMessage msg) {
60                         _callMsg = msg;
61
62                         if (null != msg)
63                                 _uri = msg.Uri;
64                         else
65                                 _uri = String.Empty;
66                         
67                         _exception = e;
68                         _returnValue = null;
69                         _outArgs = new object[0];       // .NET does this
70                 }
71
72                 internal MethodResponse (object returnValue, object [] outArgs, LogicalCallContext callCtx, IMethodCallMessage msg) {
73                         _callMsg = msg;
74
75                         _uri = msg.Uri;
76                         
77                         _exception = null;
78                         _returnValue = returnValue;
79                         _outArgs = outArgs;
80                 }
81
82                 internal MethodResponse (IMethodCallMessage msg, CADMethodReturnMessage retmsg) {
83                         _callMsg = msg;
84
85                         _methodBase = msg.MethodBase;
86                         //_typeName = msg.TypeName;
87                         _uri = msg.Uri;
88                         _methodName = msg.MethodName;
89                         
90                         // Get unmarshalled arguments
91                         ArrayList args = retmsg.GetArguments ();
92
93                         _exception = retmsg.GetException (args);
94                         _returnValue = retmsg.GetReturnValue (args);
95                         _outArgs = retmsg.GetArgs (args);
96
97                         _callContext = retmsg.GetLogicalCallContext (args);
98                         if (_callContext == null) _callContext = new LogicalCallContext ();
99                         
100                         if (retmsg.PropertiesCount > 0)
101                                 CADMessageBase.UnmarshalProperties (Properties, retmsg.PropertiesCount, args);
102                 }
103
104                 internal MethodResponse (SerializationInfo info, StreamingContext context) 
105                 {
106                         foreach (SerializationEntry entry in info)
107                                 InitMethodProperty (entry.Name, entry.Value);
108                 }
109
110                 internal void InitMethodProperty (string key, object value) 
111                 {
112                         switch (key) 
113                         {
114                                 case "__TypeName": _typeName = (string) value; break;
115                                 case "__MethodName": _methodName = (string) value; break;
116                                 case "__MethodSignature": _methodSignature = (Type[]) value; break;
117                                 case "__Uri": _uri = (string) value; break;
118                                 case "__Return": _returnValue = value; break;
119                                 case "__OutArgs": _outArgs = (object[]) value; break;
120                                 case "__fault": _exception = (Exception) value; break;
121                                 case "__CallContext": _callContext = (LogicalCallContext) value; break;
122                                 default: Properties [key] = value; break;
123                         }
124                 }
125
126                 public int ArgCount {
127                         get { 
128                                 if (null == _args)
129                                         return 0;
130
131                                 return _args.Length;
132                         }
133                 }
134
135                 public object[] Args {
136                         get { 
137                                 return _args; 
138                         }
139                 }
140
141                 public Exception Exception {
142                         get { 
143                                 return _exception; 
144                         }
145                 }
146                 
147                 public bool HasVarArgs {
148                         get { 
149                                 return false;   // TODO: implement var args
150                         }
151                 }
152                 
153                 public LogicalCallContext LogicalCallContext {
154                         get { 
155                                 return _callContext;
156                         }
157                 }
158                 
159                 public MethodBase MethodBase {
160                         get { 
161                                 if (null == _methodBase && null != _callMsg)
162                                         _methodBase = _callMsg.MethodBase;
163
164                                 return _methodBase;
165                         }
166                 }
167
168                 public string MethodName {
169                         get { 
170                                 if (null == _methodName && null != _callMsg)
171                                         _methodName = _callMsg.MethodName;
172
173                                 return _methodName;
174                         }
175                 }
176
177                 public object MethodSignature {
178                         get { 
179                                 if (null == _methodSignature && null != _callMsg)
180                                         _methodSignature = (Type []) _callMsg.MethodSignature;
181
182                                 return _methodSignature;
183                         }
184                 }
185
186                 public int OutArgCount {
187                         get { 
188                                 if (null == _outArgs)
189                                         return 0;
190
191                                 return _outArgs.Length;
192                         }
193                 }
194
195                 public object[] OutArgs {
196                         get { 
197                                 if (null == _outArgs)
198                                         return new object[0];
199
200                                 return _outArgs;
201                         }
202                 }
203
204                 public virtual IDictionary Properties {
205                         get { 
206                                 if (null == ExternalProperties) {
207                                         MethodReturnDictionary properties = new MethodReturnDictionary (this);
208                                         ExternalProperties = properties;
209                                         InternalProperties = properties.GetInternalProperties();
210                                 }
211                                 
212                                 return ExternalProperties;
213                         }
214                 }
215
216                 public object ReturnValue {
217                         get { 
218                                 return _returnValue;
219                         }
220                 }
221
222                 public string TypeName {
223                         get { 
224                                 if (null == _typeName && null != _callMsg)
225                                         _typeName = _callMsg.TypeName;
226
227                                 return _typeName;
228                         }
229                 }
230
231                 public string Uri {
232                         get { 
233                                 if (null == _uri && null != _callMsg)
234                                         _uri = _callMsg.Uri;
235                                 
236                                 return _uri;
237                         }
238
239                         set { 
240                                 _uri = value;
241                         }
242                 }
243
244                 public object GetArg (int argNum)
245                 {
246                         if (null == _outArgs)
247                                 return null;
248
249                         return _outArgs [argNum];
250                 }
251
252                 public string GetArgName (int index)
253                 {
254                         throw new NotSupportedException ();
255                 }
256
257                 public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
258                 {
259                         if (_exception == null)
260                         {
261                                 info.AddValue ("__TypeName", _typeName);
262                                 info.AddValue ("__MethodName", _methodName);
263                                 info.AddValue ("__MethodSignature", _methodSignature);
264                                 info.AddValue ("__Uri", _uri);
265                                 info.AddValue ("__Return", _returnValue);
266                                 info.AddValue ("__OutArgs", _outArgs);
267                         }
268                         else
269                                 info.AddValue ("__fault", _exception);
270
271                         info.AddValue ("__CallContext", _callContext);
272
273                         if (InternalProperties != null) {
274                                 foreach (DictionaryEntry entry in InternalProperties)
275                                         info.AddValue ((string) entry.Key, entry.Value);
276                         }
277                 } 
278
279                 public object GetOutArg (int argNum)
280                 {
281                         if (null == _methodBase)
282                                 return null;
283
284                         return _outArgs [argNum];
285                 }
286
287                 public string GetOutArgName (int index)
288                 {
289                         if (null == _methodBase)
290                                 return "__method_" + index;
291
292                         if (_inArgInfo == null) _inArgInfo = new ArgInfo (MethodBase, ArgInfoType.Out);
293                         return _inArgInfo.GetInOutArgName(index);
294                 }
295
296                 [MonoTODO]
297                 public virtual object HeaderHandler (Header[] h)
298                 {
299                         throw new NotImplementedException ();
300                 }
301
302                 [MonoTODO]
303                 public void RootSetObjectData (SerializationInfo info, StreamingContext context)
304                 {
305                         throw new NotImplementedException ();
306                 } 
307
308                 Identity IInternalMessage.TargetIdentity
309                 {
310                         get { return _targetIdentity; }
311                         set { _targetIdentity = value; }
312                 }
313
314                 public override string ToString ()
315                 {
316                         string s = _typeName.Split(',')[0] + "." + _methodName + " (";
317                         if (_exception != null)
318                         {
319                                 s += "Exception\n)" + _exception;
320                         }
321                         else
322                         {
323                                 if (_outArgs != null)
324                                 {
325                                         for (int n=0; n<_outArgs.Length; n++)
326                                         {
327                                                 if (n>0) s+= ", ";
328                                                 if (_outArgs[n] != null) s += _outArgs[n].GetType().Name + " ";
329                                                 s += GetOutArgName (n);
330                                                 if (_outArgs[n] != null) s += " = {" + _outArgs[n] + "}";
331                                                 else s+=" = {null}";
332                                         }
333                                 }
334                                 s += ")";
335                         }
336                         return s;
337                 }
338
339         }
340 }