2003-10-22 Todd Berman <tberman@gentoo.org>
[mono.git] / mcs / class / Microsoft.Web.Services / Microsoft.Web.Services.Messaging / SoapChannel.cs
1 //
2 // Microsoft.Web.Services.Messaging.SoapChannel.cs
3 //
4 // Author: Todd Berman <tberman@gentoo.org>
5 //
6 // (C) 2003 Todd Berman
7
8 using System;
9 using System.IO;
10 using Microsoft.Web.Services;
11
12 namespace Microsoft.Web.Services.Messaging
13 {
14         public abstract class SoapChannel
15         {
16                 
17                 private ISoapFormatter _formatter;
18                 private object _sync_obj = new object ();
19
20                 public SoapChannel (ISoapFormatter format)
21                 {
22                         if(format == null) {
23                                 throw new ArgumentNullException ("formatter");
24                         }
25                         _formatter = format;
26                 }
27
28                 public abstract void Close ();
29
30                 public SoapEnvelope DeserializeMessage (Stream stream)
31                 {
32                         return _formatter.Deserialize (stream);
33                 }
34
35                 public void SerializeMessage (SoapEnvelope envelope, Stream stream)
36                 {
37                         _formatter.Serialize (envelope, stream);
38                 }
39
40                 public abstract SoapEnvelope Receive ();
41                 public abstract void Send (SoapEnvelope envelope);
42
43                 public abstract bool Active {
44                         get;
45                 }
46                 
47                 public abstract string Scheme {
48                         get;
49                 }
50
51                 public object SyncRoot {
52                         get { return _sync_obj; }
53                 }
54                 
55                 public IAsyncResult BeginReceive (AsyncCallback callback, object state)
56                 {
57                         return new ReceiveAsyncResult (this, callback, state);
58                 }
59
60                 public SoapEnvelope EndReceive (IAsyncResult result)
61                 {
62                         if(result == null) {
63                                 throw new ArgumentNullException ("result");
64                         }
65
66                         ReceiveAsyncResult res = result as ReceiveAsyncResult;
67                         
68                         if(res != null) {
69                                 ReceiveAsyncResult.End (result);
70                                 return res.Envelope;
71                         }
72                         
73                         throw new InvalidOperationException ("Invalid IAsyncResult type");
74                 }
75
76                 public IAsyncResult BeginSend (SoapEnvelope env, AsyncCallback callback, object state)
77                 {
78                         if(env == null) {
79                                 throw new ArgumentNullException ("envelope");
80                         }
81                         return new SendAsyncResult (this, env, callback, state);
82                 }
83
84                 public void EndSend (IAsyncResult result)
85                 {
86                         if(result == null) {
87                                 throw new ArgumentNullException ("result");
88                         }
89                         SendAsyncResult a_res = result as SendAsyncResult;
90
91                         if(a_res != null) {
92                                 AsyncResult.End (result);
93                         }
94                         throw new InvalidOperationException ("Invalid IAsyncResult type");
95                 }
96                 
97                 protected class ReceiveAsyncResult : AsyncResult
98                 {
99                         private SoapEnvelope _envelope;
100
101                         private delegate SoapEnvelope Receive ();
102
103                         public ReceiveAsyncResult (SoapChannel channel,
104                                                    AsyncCallback callback,
105                                                    object state) : base (callback, state)
106                         {
107                                 Receive rec = new Receive (channel.Receive);
108                                 
109                                 rec.BeginInvoke (new AsyncCallback (OnReceiveComplete), rec);
110                         }
111
112                         private void OnReceiveComplete (IAsyncResult result)
113                         {
114                                 Receive rec = (Receive) result.AsyncState;
115
116                                 try {
117                                         _envelope = rec.EndInvoke (result);
118                                         Complete (result.CompletedSynchronously);
119                                 } catch (Exception e) {
120                                         Complete (result.CompletedSynchronously, e);
121                                 }
122                         }
123
124                         public SoapEnvelope Envelope {
125                                 get { return _envelope; }
126                         }
127                 }
128
129                 protected class SendAsyncResult : AsyncResult
130                 {
131                         private delegate void Send (SoapEnvelope e);
132                         
133                         public SendAsyncResult (SoapChannel channel,
134                                                 SoapEnvelope env,
135                                                 AsyncCallback callback,
136                                                 object state) : base (callback, state)
137                         {
138                                 Send send_delegate = new Send (channel.Send);
139                                 send_delegate.BeginInvoke (env, new AsyncCallback (OnSendComplete), send_delegate);
140                         }
141
142                         private void OnSendComplete (IAsyncResult result)
143                         {
144                                 Send s_del = result.AsyncState as Send;
145
146                                 try {
147                                         s_del.EndInvoke (result);
148                                         this.Complete (result.CompletedSynchronously);
149                                 } catch (Exception e) {
150                                         Complete (result.CompletedSynchronously, e);
151                                 }
152                         }
153                 }
154         }
155 }