2 // System.Runtime.Remoting.Channels.BinaryClientFormatterSink.cs
4 // Author: Rodrigo Moya (rodrigo@ximian.com)
5 // Dietmar Maurer (dietmar@ximian.com)
6 // Lluis Sanchez Gual (lluis@ideary.com)
8 // 2002 (C) Copyright, Ximian, Inc.
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System
.Collections
;
34 using System
.Runtime
.Remoting
.Messaging
;
35 using System
.Runtime
.Serialization
;
36 using System
.Runtime
.Serialization
.Formatters
.Binary
;
38 namespace System
.Runtime
.Remoting
.Channels
40 public class BinaryClientFormatterSink
: IClientFormatterSink
,
41 IMessageSink
, IClientChannelSink
, IChannelSinkBase
43 BinaryCore _binaryCore
= BinaryCore
.DefaultInstance
;
44 IClientChannelSink _nextInChain
;
46 public BinaryClientFormatterSink (IClientChannelSink nextSink
)
48 _nextInChain
= nextSink
;
51 internal BinaryCore BinaryCore
53 get { return _binaryCore; }
54 set { _binaryCore = value; }
57 public IClientChannelSink NextChannelSink
64 public IMessageSink NextSink
67 // This is the last sink in the IMessageSink sink chain
72 public IDictionary Properties
79 public void AsyncProcessRequest (IClientChannelSinkStack sinkStack
,
81 ITransportHeaders headers
,
84 // never called because the formatter sink is
85 // always the first in the chain
86 throw new NotSupportedException("BinaryClientFormatterSink must be the first sink in the IClientChannelSink chain");
89 public void AsyncProcessResponse (IClientResponseChannelSinkStack sinkStack
,
91 ITransportHeaders headers
,
94 IMessage replyMessage
= (IMessage
)_binaryCore
.Deserializer
.DeserializeMethodResponse (stream
, null, (IMethodCallMessage
)state
);
95 sinkStack
.DispatchReplyMessage (replyMessage
);
98 public Stream
GetRequestStream (IMessage msg
,
99 ITransportHeaders headers
)
102 throw new NotSupportedException ();
105 public void ProcessMessage (IMessage msg
,
106 ITransportHeaders requestHeaders
,
107 Stream requestStream
,
108 out ITransportHeaders responseHeaders
,
109 out Stream responseStream
)
111 // never called because the formatter sink is
112 // always the first in the chain
113 throw new NotSupportedException ();
116 public IMessageCtrl
AsyncProcessMessage (IMessage msg
,
117 IMessageSink replySink
)
119 ITransportHeaders transportHeaders
= new TransportHeaders();
120 Stream stream
= _nextInChain
.GetRequestStream(msg
, transportHeaders
);
121 if (stream
== null) stream
= new MemoryStream ();
123 _binaryCore
.Serializer
.Serialize (stream
, msg
, null);
124 if (stream
is MemoryStream
) stream
.Position
= 0;
126 ClientChannelSinkStack stack
= new ClientChannelSinkStack(replySink
);
127 stack
.Push (this, msg
);
129 _nextInChain
.AsyncProcessRequest (stack
, msg
, transportHeaders
, stream
);
131 // FIXME: No idea about how to implement IMessageCtrl
135 public IMessage
SyncProcessMessage (IMessage msg
)
139 ITransportHeaders call_headers
= new TransportHeaders();
140 call_headers
[CommonTransportKeys
.RequestUri
] = ((IMethodCallMessage
)msg
).Uri
;
141 call_headers
["Content-Type"] = "application/octet-stream";
143 Stream call_stream
= _nextInChain
.GetRequestStream(msg
, call_headers
);
144 if (call_stream
== null) call_stream
= new MemoryStream ();
146 // Serialize msg to the stream
148 _binaryCore
.Serializer
.Serialize (call_stream
, msg
, null);
149 if (call_stream
is MemoryStream
) call_stream
.Position
= 0;
151 Stream response_stream
;
152 ITransportHeaders response_headers
;
154 _nextInChain
.ProcessMessage (msg
, call_headers
, call_stream
, out response_headers
,
155 out response_stream
);
157 // Deserialize response_stream
159 return (IMessage
) _binaryCore
.Deserializer
.DeserializeMethodResponse (response_stream
, null, (IMethodCallMessage
)msg
);
161 } catch (Exception e
) {
162 return new ReturnMessage (e
, (IMethodCallMessage
)msg
);