2008-01-15 Stephane Delcroix <sdelcroix@novell.com>
[mono.git] / mcs / class / corlib / System.Runtime.Remoting.Messaging / ReturnMessage.cs
index aecd0a730cb90b967febdf1fc04dc8899fb0fdc5..aee39f5bb81103129491a363a4e1641fd44a3d56 100644 (file)
 // (C) Ximian, Inc.  http://www.ximian.com
 //
 
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
 using System;
 using System.Collections;
 using System.Reflection;
+using System.IO;
 
-namespace System.Runtime.Remoting.Messaging {
-
-       internal class ReturnMessage : IMethodReturnMessage, IMethodMessage {
+namespace System.Runtime.Remoting.Messaging 
+{
+#if NET_2_0
+       [System.Runtime.InteropServices.ComVisible (true)]
+#endif
+       public class ReturnMessage : IMethodReturnMessage, IMethodMessage, IMessage, IInternalMessage 
+       {
+               object[] _outArgs;
+               object[] _args;
+               int _outArgsCount;
+               LogicalCallContext _callCtx;
+               object _returnValue;
+               string _uri;
+               Exception _exception;
+               MethodBase _methodBase;
+               string _methodName;
+               Type [] _methodSignature;
+               string _typeName;
+               MethodReturnDictionary _properties;
+               Identity _targetIdentity;
+               ArgInfo _inArgInfo;
 
-               MonoMethodMessage msg;
-               IMethodCallMessage request;
-               
                public ReturnMessage (object returnValue, object [] outArgs,
                               int outArgCount, LogicalCallContext callCtx,
                               IMethodCallMessage request)
                {
-                       // fixme: why do we need outArgCount?
-                       msg = new MonoMethodMessage ((MonoMethod)request.MethodBase, outArgs);
-                       this.request = request;
-                       msg.rval = returnValue;
-                       msg.ctx = callCtx;
+                       // outArgCount tells how many values of outArgs are valid
+
+                       _returnValue = returnValue;
+                       _args = outArgs;
+                       _outArgsCount = outArgCount;
+                       _callCtx = callCtx;
+                       if (request != null) {
+                               _uri = request.Uri;
+                               _methodBase = request.MethodBase;
+                       }
+                       if (_args == null) _args = new object [outArgCount];
                }
 
                public ReturnMessage (Exception exc, IMethodCallMessage request)
                {
-                       msg = new MonoMethodMessage ((MonoMethod)request.MethodBase, null);
-                       this.request = request;
-                       msg.exc = exc;
-                       msg.ctx = request.LogicalCallContext;
+                       _exception = exc;
+                       
+                       if (request != null) {
+                               _methodBase = request.MethodBase;
+                               _callCtx = request.LogicalCallContext;
+                       }
+                       _args = new object[0];  // .NET does this
                }
                
                public int ArgCount {
                        get {
-                               return msg.ArgCount;
+                               return _args.Length;
                        }
                }
                
                public object [] Args {
                        get {
-                               return msg.Args;
+                               return _args;
                        }
                }
                
                public bool HasVarArgs {
                        get {
-                               return msg.HasVarArgs;
+                               if (_methodBase == null) return false;
+                               else return (_methodBase.CallingConvention | CallingConventions.VarArgs) != 0;
                        }
                }
 
                public LogicalCallContext LogicalCallContext {
                        get {
-                               return msg.ctx;
+                               if (_callCtx == null)
+                                       _callCtx = new LogicalCallContext ();
+                               return _callCtx;
                        }
                }
 
                public MethodBase MethodBase {
                        get {
-                               return msg.MethodBase;
+                               return _methodBase;
                        }
                }
 
                public string MethodName {
                        get {
-                               return msg.MethodName;
+                               if (_methodBase != null && _methodName == null)
+                                       _methodName = _methodBase.Name;
+                               return _methodName;
                        }
                }
 
                public object MethodSignature {
                        get {
-                               return msg.MethodSignature;
+                               if (_methodBase != null && _methodSignature == null) {
+                                       ParameterInfo[] parameters = _methodBase.GetParameters();
+                                       _methodSignature = new Type [parameters.Length];
+                                       for (int n=0; n<parameters.Length; n++)
+                                               _methodSignature[n] = parameters[n].ParameterType;
+                               }
+                               return _methodSignature;
                        }
                }
 
-               [MonoTODO]
                public virtual IDictionary Properties {
                        get {
-                               return null;
+                               if (_properties == null) _properties = new MethodReturnDictionary (this);
+                               return _properties;
                        }
                }
 
                public string TypeName {
                        get {
-                               return msg.TypeName;
+
+                               // lazily fill in _typeName from _methodBase
+                               if (_methodBase != null && _typeName == null)
+                                       _typeName = _methodBase.DeclaringType.AssemblyQualifiedName;
+                               return _typeName;
+
                        }
                }
 
                public string Uri {
                        get {
-                               return msg.Uri;
+                               return _uri;
                        }
+
+                       set {
+                               _uri = value;
+                       }
+               }
+
+               string IInternalMessage.Uri {
+                       get { return Uri; }
+                       set { Uri = value; }
                }
 
                public object GetArg (int arg_num)
                {
-                       return msg.GetArg (arg_num);
+                       return _args [arg_num];
                }
                
                public string GetArgName (int arg_num)
                {
-                       return msg.GetArgName (arg_num);
+                       return _methodBase.GetParameters()[arg_num].Name;
                }
 
                public Exception Exception {
                        get {
-                               return msg.exc;
+                               return _exception;
                        }
                }
 
                public int OutArgCount {
                        get {
-                               return msg.OutArgCount;
+                               if (_args == null || _args.Length == 0) return 0;
+                               if (_inArgInfo == null) _inArgInfo = new ArgInfo (MethodBase, ArgInfoType.Out);
+                               return _inArgInfo.GetInOutArgCount ();
                        }
                }
 
                public object [] OutArgs {
                        get {
-                               return msg.OutArgs;
+                               if (_outArgs == null && _args != null) {
+                                       if (_inArgInfo == null) _inArgInfo = new ArgInfo (MethodBase, ArgInfoType.Out);
+                                       _outArgs = _inArgInfo.GetInOutArgs (_args);
+                               }                                       
+                               return _outArgs;
                        }
                }
 
                public virtual object ReturnValue {
                        get {
-                               return msg.rval;
+                               return _returnValue;
                        }
                }
 
                public object GetOutArg (int arg_num)
                {
-                       return msg.GetOutArg (arg_num);
+                       if (_inArgInfo == null) _inArgInfo = new ArgInfo (MethodBase, ArgInfoType.Out);
+                       return _args[_inArgInfo.GetInOutArgIndex (arg_num)];
                }
 
                public string GetOutArgName (int arg_num)
                {
-                       return msg.GetOutArgName (arg_num);
+                       if (_inArgInfo == null) _inArgInfo = new ArgInfo (MethodBase, ArgInfoType.Out);
+                       return _inArgInfo.GetInOutArgName(arg_num);
                }
 
+               Identity IInternalMessage.TargetIdentity
+               {
+                       get { return _targetIdentity; }
+                       set { _targetIdentity = value; }
+               }
+
+#if !NET_2_0
+               public override string ToString ()
+               {
+                       string s = TypeName.Split(',')[0] + "." + MethodName + " (";
+                       if (_exception != null)
+                       {
+                               s += "Exception)\n" + _exception;
+                       }
+                       else
+                       {
+                               for (int n=0; n<OutArgs.Length; n++)
+                               {
+                                       if (n>0) s+= ", ";
+                                       if (OutArgs[n] != null) s += OutArgs[n].GetType().Name + " ";
+                                       s += GetOutArgName (n);
+                                       if (OutArgs[n] != null) s += " = {" + OutArgs[n] + "}";
+                                       else s+=" = {null}";
+                               }
+                               s += ")";
+                       }
+                       return s;
+               }
+#endif
        }
 }