Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mcs / class / System.Runtime.Remoting / System.Runtime.Remoting.Channels.Ipc.Win32 / IpcTransport.cs
1 //
2 // System.Runtime.Remoting.Channels.Ipc.Win32.IpcTransport.cs
3 //
4 // Author: Robert Jordan (robertj@gmx.net)
5 //
6 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
7 //
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29
30 using System;
31 using System.IO;
32 using System.Runtime.Remoting;
33 using System.Runtime.Remoting.Channels;
34 using System.Runtime.Remoting.Messaging;
35 using System.Runtime.Serialization.Formatters.Binary;
36
37 namespace System.Runtime.Remoting.Channels.Ipc.Win32
38 {
39     /// <summary>
40     /// IPC transport helper
41     /// </summary>
42     internal class IpcTransport
43     {
44         readonly NamedPipeSocket socket;
45         readonly BinaryFormatter formatter = new BinaryFormatter();
46
47         /// <summary>
48         /// Creates a new object.
49         /// </summary>
50         /// <param name="socket">The named pipe.</param>
51         public IpcTransport(NamedPipeSocket socket)
52         {
53             this.socket = socket;
54         }
55
56         /// <summary>
57         /// Writes a request.
58         /// </summary>
59         /// <param name="header"></param>
60         /// <param name="requestStream"></param>
61         public void Write(ITransportHeaders header, Stream requestStream) 
62         {
63             Stream bs = socket.GetStream();
64
65             MemoryStream m = new MemoryStream();
66             formatter.Serialize(m, header);
67             m.Position = 0;
68             byte[] bytes = BitConverter.GetBytes((int)m.Length);
69             bs.Write(bytes, 0, bytes.Length);
70             m.WriteTo(bs);
71
72             try 
73             {
74                 bytes = BitConverter.GetBytes((int)requestStream.Length);
75                 bs.Write(bytes, 0, bytes.Length);
76                 IpcChannelHelper.Copy(requestStream, bs);
77             }
78             catch 
79             {
80                 bs.Write(bytes, 0, bytes.Length);
81             }
82
83             bs.Flush();
84         }
85
86         /// <summary>
87         /// Reads a response.
88         /// </summary>
89         /// <param name="headers"></param>
90         /// <param name="responseStream"></param>
91         public void Read(out ITransportHeaders headers, out Stream responseStream)
92         {
93             byte[] bytes;
94             long length;
95
96             bytes = BitConverter.GetBytes(int.MaxValue);
97             socket.Receive(bytes, 0, bytes.Length);
98             length = BitConverter.ToInt32(bytes, 0);
99
100             if (length != int.MaxValue && length > 0) 
101             {
102                 bytes = new byte[length];
103                 socket.Receive(bytes, 0, (int)length);
104
105                 MemoryStream m = new MemoryStream(bytes);
106                 headers = (ITransportHeaders) formatter.Deserialize(m);
107             }
108             else 
109             {
110                 headers = new TransportHeaders();
111             }
112
113             bytes = BitConverter.GetBytes(int.MaxValue);
114             socket.Receive(bytes, 0, bytes.Length);
115             length = BitConverter.ToInt32(bytes, 0);
116             if (length != int.MaxValue && length > 0) 
117             {
118                 bytes = new byte[length];
119                 socket.Receive(bytes, 0, (int)length);
120                 responseStream = new MemoryStream(bytes);
121             }
122             else 
123             {
124                 responseStream = new MemoryStream(new byte[0]);
125             }
126         }
127
128         /// <summary>
129         /// Closes the unterlying named pipe socket.
130         /// </summary>
131         public void Close() 
132         {
133             socket.Close();
134         }
135     }
136 }
137