Merge pull request #1659 from alexanderkyte/stringbuilder-referencesource
[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.Runtime.Serialization;
38 using System.Runtime.Remoting.Channels;
39 using System.Runtime.Remoting.Messaging;
40 using System.Runtime.Remoting.Proxies;
41
42 using System.Runtime.ConstrainedExecution;
43
44 namespace System.Runtime.Remoting {
45
46         [Serializable]
47         [System.Runtime.InteropServices.ComVisible (true)]
48         public class ObjRef : IObjectReference, ISerializable 
49         {
50                 IChannelInfo channel_info;
51                 string uri;
52                 IRemotingTypeInfo typeInfo;
53                 IEnvoyInfo envoyInfo;
54                 int flags;
55                 Type _serverType;
56
57                 static int MarshalledObjectRef = 1;
58                 static int WellKnowObjectRef = 2;
59                 
60                 public ObjRef ()
61                 {
62                         // no idea why this needs to be public
63
64                         UpdateChannelInfo();
65                 }
66
67                 internal ObjRef (string typeName, string uri, IChannelInfo cinfo) 
68                 {
69                         this.uri = uri;
70                         channel_info = cinfo;
71                         typeInfo = new TypeInfo (Type.GetType (typeName, true));
72                 }
73
74                 internal ObjRef (ObjRef o, bool unmarshalAsProxy) {
75                         channel_info = o.channel_info;
76                         uri = o.uri;
77         
78                         typeInfo = o.typeInfo;
79                         envoyInfo = o.envoyInfo;
80                         flags = o.flags;
81                         if (unmarshalAsProxy) flags |= MarshalledObjectRef;
82                 }
83
84                 public ObjRef (MarshalByRefObject o, Type requestedType)
85                 {
86                         if (o == null)
87                                 throw new ArgumentNullException ("o");
88                         
89                         if (requestedType == null)
90                                 throw new ArgumentNullException ("requestedType");
91
92                         // The ObjRef can only be constructed if the given o
93                         // has already been marshalled using RemotingServices.Marshall
94
95                         uri = RemotingServices.GetObjectUri (o);
96                         typeInfo = new TypeInfo (requestedType);
97
98                         if (!requestedType.IsInstanceOfType (o))
99                                 throw new RemotingException ("The server object type cannot be cast to the requested type " + requestedType.FullName);
100
101                         UpdateChannelInfo();
102                 }
103
104                 internal ObjRef (Type type, string url, object remoteChannelData)
105                 {
106                         uri = url;
107                         typeInfo = new TypeInfo(type);
108
109                         if (remoteChannelData != null)
110                                 channel_info = new ChannelInfo (remoteChannelData);
111
112                         flags |= WellKnowObjectRef;
113                 }
114
115                 protected ObjRef (SerializationInfo info, StreamingContext context)
116                 {
117                         SerializationInfoEnumerator en = info.GetEnumerator();
118                         // Info to serialize: uri, objrefFlags, typeInfo, envoyInfo, channelInfo
119
120                         bool marshalledValue = true;
121
122                         while (en.MoveNext ()) {
123                                 switch (en.Name) {
124                                 case "uri":
125                                         uri = (string)en.Value;
126                                         break;
127                                 case "typeInfo":
128                                         typeInfo = (IRemotingTypeInfo)en.Value;
129                                         break;
130                                 case "channelInfo":
131                                         channel_info = (IChannelInfo)en.Value;
132                                         break;
133                                 case "envoyInfo":
134                                         envoyInfo = (IEnvoyInfo)en.Value;
135                                         break;
136                                 case "fIsMarshalled":
137                                         int status;
138                                         Object o = en.Value;
139                                         if (o is string)
140                                                 status = ((IConvertible) o).ToInt32(null);
141                                         else
142                                                 status = (int) o;
143
144                                         if (status == 0)
145                                                 marshalledValue = false;
146                                         break;
147                                 case "objrefFlags":
148                                         flags = Convert.ToInt32 (en.Value);
149                                         break;
150                                 default:
151                                         throw new NotSupportedException ();
152                                 }
153                         }
154                         if (marshalledValue) flags |= MarshalledObjectRef;
155                 }
156
157                 internal bool IsPossibleToCAD () 
158                 {
159                         // we should check if this obj ref belongs to a cross app context.
160
161                         // Return false. If not, serialization of this ObjRef will not work
162                         // on the target AD.
163                         return false;
164                 }
165
166                 internal bool IsReferenceToWellKnow
167                 {
168                         get { return (flags & WellKnowObjectRef) > 0; }
169                 }
170
171                 public virtual IChannelInfo ChannelInfo {
172                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
173                         get {
174                                 return channel_info;
175                         }
176                         
177                         set {
178                                 channel_info = value;
179                         }
180                 }
181                 
182                 public virtual IEnvoyInfo EnvoyInfo {
183                         get {
184                                 return envoyInfo;
185                         }
186                         set {
187                                 envoyInfo = value;
188                         }
189                 }
190                 
191                 public virtual IRemotingTypeInfo TypeInfo {
192                         get {
193                                 return typeInfo;
194                         }
195                         set {
196                                 typeInfo = value;
197                         }
198                 }
199                 
200                 public virtual string URI {
201                         get {
202                                 return uri;
203                         }
204                         set {
205                                 uri = value;
206                         }
207                 }
208
209                 public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
210                 {
211                         info.SetType (GetType());
212                         info.AddValue ("uri", uri);
213                         info.AddValue ("typeInfo", typeInfo, typeof (IRemotingTypeInfo));
214                         info.AddValue ("envoyInfo", envoyInfo, typeof (IEnvoyInfo));
215                         info.AddValue ("channelInfo", channel_info, typeof(IChannelInfo));
216                         info.AddValue ("objrefFlags", flags);
217                 }
218
219                 public virtual object GetRealObject (StreamingContext context)
220                 {
221                         if ((flags & MarshalledObjectRef) > 0)
222                                 return RemotingServices.Unmarshal (this);
223                         else
224                                 return this;
225                 }
226
227                 public bool IsFromThisAppDomain ()
228                 {
229                         Identity identity = RemotingServices.GetIdentityForUri (uri);
230                         if (identity == null) return false;             // URI not registered in this domain
231
232                         return identity.IsFromThisAppDomain;
233                 }
234
235                 [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
236                 public bool IsFromThisProcess ()
237                 {
238                         foreach (object data in channel_info.ChannelData)
239                         {
240                                 if (data is CrossAppDomainData)
241                                 {
242                                         string refProcId = ((CrossAppDomainData)data).ProcessID;
243                                         return (refProcId == RemotingConfiguration.ProcessId);
244                                 }
245                         }
246                         
247                         return true;
248                 }
249
250                 internal void UpdateChannelInfo()
251                 {
252                         channel_info = new ChannelInfo ();
253                 }
254
255                 internal Type ServerType
256                 {
257                         get
258                         {
259                                 if (_serverType == null) _serverType = Type.GetType (typeInfo.TypeName);
260                                 return _serverType;
261                         }
262                 }
263
264                 internal void SetDomainID (int id)
265                 {
266                 }
267         }
268 }