2010-01-07 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Channels / DuplexChannelBase.cs
1 // 
2 // DuplexSessionChannelBase.cs
3 // 
4 // Author:
5 //     Marcos Cobena (marcoscobena@gmail.com)
6 //      Atsushi Enomoto  <atsushi@ximian.com>
7 // 
8 // Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
9 // 
10 // Copyright (C) 2009 Novell, Inc.  http://www.novell.com
11 //
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:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
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.
30 //
31
32 using System;
33 using System.ServiceModel.Channels;
34
35 namespace System.ServiceModel.Channels
36 {
37         internal abstract class DuplexChannelBase : ChannelBase, IDuplexChannel
38         {
39                 ChannelFactoryBase channel_factory_base;
40                 ChannelListenerBase channel_listener_base;
41                 EndpointAddress local_address;
42                 EndpointAddress remote_address;
43                 Uri via;
44                 
45                 public DuplexChannelBase (ChannelFactoryBase factory, EndpointAddress remoteAddress, Uri via) : base (factory)
46                 {
47                         channel_factory_base = factory;
48                         remote_address = remoteAddress;
49                         this.via = via;
50                         SetupDelegates ();
51                 }
52                 
53                 public DuplexChannelBase (ChannelListenerBase listener) : base (listener)
54                 {
55                         channel_listener_base = listener;
56                         local_address = new EndpointAddress (listener.Uri);
57                         SetupDelegates ();
58                 }
59
60                 public virtual EndpointAddress LocalAddress {
61                         get { return local_address; }
62                 }
63
64                 public virtual EndpointAddress RemoteAddress {
65                         get { return remote_address; }
66                 }
67
68                 public Uri Via {
69                         get { return via ?? RemoteAddress.Uri; }
70                 }
71
72                 void SetupDelegates ()
73                 {
74                         open_handler = new Action<TimeSpan> (Open);
75                         close_handler = new Action<TimeSpan> (Close);
76                         send_handler = new AsyncSendHandler (Send);
77                         receive_handler = new AsyncReceiveHandler (Receive);
78                         wait_handler = new AsyncWaitForMessageHandler (WaitForMessage);
79                         try_receive_handler = new TryReceiveHandler (TryReceive);
80                 }
81
82                 public override T GetProperty<T> ()
83                 {
84                         if (typeof (T) == typeof (IChannelFactory))
85                                 return (T) (object) channel_factory_base;
86                         if (typeof (T) == typeof (IChannelListener))
87                                 return (T) (object) channel_listener_base;
88                         return base.GetProperty<T> ();
89                 }
90
91                 // Open
92                 Action<TimeSpan> open_handler;
93
94                 protected override IAsyncResult OnBeginOpen (TimeSpan timeout, AsyncCallback callback, object state)
95                 {
96                         return open_handler.BeginInvoke (timeout, callback, state);
97                 }
98
99                 protected override void OnEndOpen (IAsyncResult result)
100                 {
101                         open_handler.EndInvoke (result);
102                 }
103
104                 // Close
105                 Action<TimeSpan> close_handler;
106
107                 protected override IAsyncResult OnBeginClose (TimeSpan timeout, AsyncCallback callback, object state)
108                 {
109                         return close_handler.BeginInvoke (timeout, callback, state);
110                 }
111
112                 protected override void OnEndClose (IAsyncResult result)
113                 {
114                         close_handler.EndInvoke (result);
115                 }
116
117                 // Send
118
119                 delegate void AsyncSendHandler (Message message, TimeSpan timeout);
120                 AsyncSendHandler send_handler;
121
122                 public virtual IAsyncResult BeginSend (Message message, AsyncCallback callback, object state)
123                 {
124                         return BeginSend (message, DefaultSendTimeout, callback, state);
125                 }
126
127                 public virtual IAsyncResult BeginSend (Message message, TimeSpan timeout, AsyncCallback callback, object state)
128                 {
129                         return send_handler.BeginInvoke (message, timeout, callback, state);
130                 }
131
132                 public virtual void EndSend (IAsyncResult result)
133                 {
134                         send_handler.EndInvoke (result);
135                 }
136
137                 public virtual void Send (Message message)
138                 {
139                         Send (message, this.DefaultSendTimeout);
140                 }
141
142                 public abstract void Send (Message message, TimeSpan timeout);
143
144                 // Receive
145
146                 delegate Message AsyncReceiveHandler (TimeSpan timeout);
147                 AsyncReceiveHandler receive_handler;
148
149                 public virtual IAsyncResult BeginReceive (AsyncCallback callback, object state)
150                 {
151                         return BeginReceive (this.DefaultReceiveTimeout, callback, state);
152                 }
153
154                 public virtual IAsyncResult BeginReceive (TimeSpan timeout, AsyncCallback callback, object state)
155                 {
156                         return receive_handler.BeginInvoke (timeout, callback, state);
157                 }
158
159                 public virtual Message EndReceive (IAsyncResult result)
160                 {
161                         return receive_handler.EndInvoke (result);
162                 }
163
164                 public virtual Message Receive ()
165                 {
166                         return Receive (this.DefaultReceiveTimeout);
167                 }
168
169                 public abstract Message Receive (TimeSpan timeout);
170
171                 // TryReceive
172
173                 delegate bool TryReceiveHandler (TimeSpan timeout, out Message msg);
174                 TryReceiveHandler try_receive_handler;
175
176                 public virtual IAsyncResult BeginTryReceive (TimeSpan timeout, AsyncCallback callback, object state)
177                 {
178                         Message dummy;
179                         return try_receive_handler.BeginInvoke (timeout, out dummy, callback, state);
180                 }
181                 
182                 public virtual bool EndTryReceive (IAsyncResult result, out Message message)
183                 {
184                         return try_receive_handler.EndInvoke (out message, result);
185                 }
186                 
187                 public virtual bool TryReceive (TimeSpan timeout, out Message message)
188                 {
189                         try {
190                                 message = Receive (timeout);
191                                 return true;
192                         } catch (TimeoutException) {
193                                 message = null;
194                                 return false;
195                         }
196                 }
197
198                 // WaitForMessage
199
200                 delegate bool AsyncWaitForMessageHandler (TimeSpan timeout);
201                 AsyncWaitForMessageHandler wait_handler;
202
203                 public virtual IAsyncResult BeginWaitForMessage (TimeSpan timeout, AsyncCallback callback, object state)
204                 {
205                         return wait_handler.BeginInvoke (timeout, callback, state);
206                 }
207                 
208                 public virtual bool EndWaitForMessage (IAsyncResult result)
209                 {
210                         return wait_handler.EndInvoke (result);
211                 }
212                 
213                 public abstract bool WaitForMessage (TimeSpan timeout);
214         }
215 }