2009-05-21 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Channels / DuplexSessionChannelBase.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                         SetupDelegates ();
57                 }
58
59                 public abstract EndpointAddress LocalAddress { get; }
60                 
61                 public EndpointAddress RemoteAddress {
62                         get { return remote_address; }
63                 }
64
65                 public Uri Via {
66                         get { return via; }
67                 }
68
69                 void SetupDelegates ()
70                 {
71                         send_handler = new AsyncSendHandler (Send);
72                         receive_handler = new AsyncReceiveHandler (Receive);
73                         wait_handler = new AsyncWaitForMessageHandler (WaitForMessage);
74                 }
75
76                 // Send
77
78                 delegate void AsyncSendHandler (Message message, TimeSpan timeout);
79                 AsyncSendHandler send_handler;
80
81                 public virtual IAsyncResult BeginSend (Message message, AsyncCallback callback, object state)
82                 {
83                         return BeginSend (message, DefaultSendTimeout, callback, state);
84                 }
85
86                 public virtual IAsyncResult BeginSend (Message message, TimeSpan timeout, AsyncCallback callback, object state)
87                 {
88                         return send_handler.BeginInvoke (message, timeout, callback, state);
89                 }
90
91                 public virtual void EndSend (IAsyncResult result)
92                 {
93                         send_handler.EndInvoke (result);
94                 }
95
96                 public virtual void Send (Message message)
97                 {
98                         Send (message, this.DefaultSendTimeout);
99                 }
100
101                 public abstract void Send (Message message, TimeSpan timeout);
102
103                 // Receive
104
105                 delegate Message AsyncReceiveHandler (TimeSpan timeout);
106                 AsyncReceiveHandler receive_handler;
107
108                 public virtual IAsyncResult BeginReceive (AsyncCallback callback, object state)
109                 {
110                         return BeginReceive (this.DefaultReceiveTimeout, callback, state);
111                 }
112
113                 public virtual IAsyncResult BeginReceive (TimeSpan timeout, AsyncCallback callback, object state)
114                 {
115                         return receive_handler.BeginInvoke (timeout, callback, state);
116                 }
117
118                 public virtual Message EndReceive (IAsyncResult result)
119                 {
120                         return receive_handler.EndInvoke (result);
121                 }
122
123                 public virtual Message Receive ()
124                 {
125                         return Receive (this.DefaultReceiveTimeout);
126                 }
127
128                 public abstract Message Receive (TimeSpan timeout);
129
130                 // TryReceive
131                 // FIXME: apply those "async to call sync" pattern too (but how?)
132
133                 public abstract IAsyncResult BeginTryReceive (TimeSpan timeout, AsyncCallback callback, object state);
134                 
135                 public abstract bool EndTryReceive (IAsyncResult result, out Message message);
136                 
137                 public virtual bool TryReceive (TimeSpan timeout, out Message message)
138                 {
139                         return EndTryReceive (BeginTryReceive (timeout, null, null), out message);
140                 }
141
142                 // WaitForMessage
143
144                 delegate bool AsyncWaitForMessageHandler (TimeSpan timeout);
145                 AsyncWaitForMessageHandler wait_handler;
146
147                 public virtual IAsyncResult BeginWaitForMessage (TimeSpan timeout, AsyncCallback callback, object state)
148                 {
149                         return wait_handler.BeginInvoke (timeout, callback, state);
150                 }
151                 
152                 public virtual bool EndWaitForMessage (IAsyncResult result)
153                 {
154                         return wait_handler.EndInvoke (result);
155                 }
156                 
157                 public abstract bool WaitForMessage (TimeSpan timeout);
158         }
159 }