Merge pull request #1626 from iainx/add-coverage-to-log-profiler
[mono.git] / mcs / class / corlib / System.Runtime.Remoting / ObjRef.cs
1 //
2 // System.Runtime.Remoting.ObjRef.cs
3 //
4 // Author:
5 //   Miguel de Icaza (miguel@ximian.com)
6 //   Dietmar Maurer (dietmar@ximian.com)
7 //   Lluis Sanchez Gual (lluis@ideary.com)
8 //   Patrik Torstensson
9 //
10 // (C) Ximian, Inc.  http://www.ximian.com
11 //
12
13 //
14 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
15 //
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
23 // 
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
26 // 
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 //
35
36 using System;
37 using System.IO;
38 using System.Runtime.Serialization;
39 using System.Runtime.Remoting.Channels;
40 using System.Runtime.Remoting.Messaging;
41 using System.Runtime.Remoting.Proxies;
42
43 using System.Runtime.ConstrainedExecution;
44
45 namespace System.Runtime.Remoting {
46
47         [Serializable]
48         [System.Runtime.InteropServices.ComVisible (true)]
49         public class ObjRef : IObjectReference, ISerializable 
50         {
51                 IChannelInfo channel_info;
52                 string uri;
53                 IRemotingTypeInfo typeInfo;
54                 IEnvoyInfo envoyInfo;
55                 int flags;
56                 Type _serverType;
57
58                 static int MarshalledObjectRef = 1;
59                 static int WellKnowObjectRef = 2;
60                 
61                 public ObjRef ()
62                 {
63                         // no idea why this needs to be public
64
65                         UpdateChannelInfo();
66                 }
67
68                 internal ObjRef (string uri, IChannelInfo cinfo)
69                 {
70                         this.uri = uri;
71                         this.channel_info = cinfo;
72                 }
73
74                 internal ObjRef DeserializeInTheCurrentDomain (int domainId, byte[] tInfo)
75                 {
76                                 string local_uri = string.Copy (this.uri);
77                                 ChannelInfo cinfo = new ChannelInfo (new CrossAppDomainData (domainId));
78                                 ObjRef res = new ObjRef (local_uri, cinfo);
79                                 IRemotingTypeInfo typeInfo = (IRemotingTypeInfo)CADSerializer.DeserializeObjectSafe (tInfo);
80                                 res.typeInfo = typeInfo;
81                                 return res;
82                 }
83
84                 internal byte[] SerializeType ()
85                 {
86                         // FIXME: Assert self and typeinfo in same domain
87                         if (typeInfo == null)
88                                 throw new Exception ("Attempt to serialize a null TypeInfo.");
89
90                         MemoryStream stm = CADSerializer.SerializeObject (typeInfo);
91                         return stm.GetBuffer ();
92                 }
93
94                 internal ObjRef (ObjRef o, bool unmarshalAsProxy)
95                 {
96                         channel_info = o.channel_info;
97                         uri = o.uri;
98         
99                         typeInfo = o.typeInfo;
100                         envoyInfo = o.envoyInfo;
101                         flags = o.flags;
102                         if (unmarshalAsProxy) flags |= MarshalledObjectRef;
103                 }
104
105                 public ObjRef (MarshalByRefObject o, Type requestedType)
106                 {
107                         if (o == null)
108                                 throw new ArgumentNullException ("o");
109                         
110                         if (requestedType == null)
111                                 throw new ArgumentNullException ("requestedType");
112
113                         // The ObjRef can only be constructed if the given o
114                         // has already been marshalled using RemotingServices.Marshall
115
116                         uri = RemotingServices.GetObjectUri (o);
117                         typeInfo = new TypeInfo (requestedType);
118
119                         if (!requestedType.IsInstanceOfType (o))
120                                 throw new RemotingException ("The server object type cannot be cast to the requested type " + requestedType.FullName);
121
122                         UpdateChannelInfo();
123                 }
124
125                 internal ObjRef (Type type, string url, object remoteChannelData)
126                 {
127                         uri = url;
128                         typeInfo = new TypeInfo(type);
129
130                         if (remoteChannelData != null)
131                                 channel_info = new ChannelInfo (remoteChannelData);
132
133                         flags |= WellKnowObjectRef;
134                 }
135
136                 protected ObjRef (SerializationInfo info, StreamingContext context)
137                 {
138                         SerializationInfoEnumerator en = info.GetEnumerator();
139                         // Info to serialize: uri, objrefFlags, typeInfo, envoyInfo, channelInfo
140
141                         bool marshalledValue = true;
142
143                         while (en.MoveNext ()) {
144                                 switch (en.Name) {
145                                 case "uri":
146                                         uri = (string)en.Value;
147                                         break;
148                                 case "typeInfo":
149                                         typeInfo = (IRemotingTypeInfo)en.Value;
150                                         break;
151                                 case "channelInfo":
152                                         channel_info = (IChannelInfo)en.Value;
153                                         break;
154                                 case "envoyInfo":
155                                         envoyInfo = (IEnvoyInfo)en.Value;
156                                         break;
157                                 case "fIsMarshalled":
158                                         int status;
159                                         Object o = en.Value;
160                                         if (o is string)
161                                                 status = ((IConvertible) o).ToInt32(null);
162                                         else
163                                                 status = (int) o;
164
165                                         if (status == 0)
166                                                 marshalledValue = false;
167                                         break;
168                                 case "objrefFlags":
169                                         flags = Convert.ToInt32 (en.Value);
170                                         break;
171                                 default:
172                                         throw new NotSupportedException ();
173                                 }
174                         }
175                         if (marshalledValue) flags |= MarshalledObjectRef;
176                 }
177
178                 internal bool IsPossibleToCAD () 
179                 {
180                         // we should check if this obj ref belongs to a cross app context.
181
182                         // Return false. If not, serialization of this ObjRef will not work
183                         // on the target AD.
184                         return false;
185                 }
186
187                 internal bool IsReferenceToWellKnow
188                 {
189                         get { return (flags & WellKnowObjectRef) > 0; }
190                 }
191
192                 public virtual IChannelInfo ChannelInfo {
193                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
194                         get {
195                                 return channel_info;
196                         }
197                         
198                         set {
199                                 channel_info = value;
200                         }
201                 }
202                 
203                 public virtual IEnvoyInfo EnvoyInfo {
204                         get {
205                                 return envoyInfo;
206                         }
207                         set {
208                                 envoyInfo = value;
209                         }
210                 }
211                 
212                 public virtual IRemotingTypeInfo TypeInfo {
213                         get {
214                                 return typeInfo;
215                         }
216                         set {
217                                 typeInfo = value;
218                         }
219                 }
220                 
221                 public virtual string URI {
222                         get {
223                                 return uri;
224                         }
225                         set {
226                                 uri = value;
227                         }
228                 }
229
230                 public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
231                 {
232                         info.SetType (GetType());
233                         info.AddValue ("uri", uri);
234                         info.AddValue ("typeInfo", typeInfo, typeof (IRemotingTypeInfo));
235                         info.AddValue ("envoyInfo", envoyInfo, typeof (IEnvoyInfo));
236                         info.AddValue ("channelInfo", channel_info, typeof(IChannelInfo));
237                         info.AddValue ("objrefFlags", flags);
238                 }
239
240                 public virtual object GetRealObject (StreamingContext context)
241                 {
242                         if ((flags & MarshalledObjectRef) > 0)
243                                 return RemotingServices.Unmarshal (this);
244                         else
245                                 return this;
246                 }
247
248                 public bool IsFromThisAppDomain ()
249                 {
250                         Identity identity = RemotingServices.GetIdentityForUri (uri);
251                         if (identity == null) return false;             // URI not registered in this domain
252
253                         return identity.IsFromThisAppDomain;
254                 }
255
256                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
257                 public bool IsFromThisProcess ()
258                 {
259                         foreach (object data in channel_info.ChannelData)
260                         {
261                                 if (data is CrossAppDomainData)
262                                 {
263                                         string refProcId = ((CrossAppDomainData)data).ProcessID;
264                                         return (refProcId == RemotingConfiguration.ProcessId);
265                                 }
266                         }
267                         
268                         return true;
269                 }
270
271                 internal void UpdateChannelInfo()
272                 {
273                         channel_info = new ChannelInfo ();
274                 }
275
276                 internal Type ServerType
277                 {
278                         get
279                         {
280                                 if (_serverType == null) _serverType = Type.GetType (typeInfo.TypeName);
281                                 return _serverType;
282                         }
283                 }
284
285                 internal void SetDomainID (int id)
286                 {
287                 }
288         }
289 }