[runtime] Free rgctx_lazy_fetch_trampoline info
[mono.git] / mcs / class / System.Core / System.IO.Pipes / PipeStream.cs
1 //
2 // PipeStream.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2009 Novell, Inc.  http://www.novell.com
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 #if !BOOTSTRAP_BASIC
30
31 using Microsoft.Win32.SafeHandles;
32 using System;
33 using System.IO;
34 using System.Linq;
35 using System.Security.AccessControl;
36 using System.Security.Permissions;
37 using System.Security.Principal;
38 using System.Runtime.InteropServices;
39
40 namespace System.IO.Pipes
41 {
42         [PermissionSet (SecurityAction.InheritanceDemand, Name = "FullTrust")]
43         [HostProtection (SecurityAction.LinkDemand, MayLeakOnAbort = true)]
44         public abstract class PipeStream : Stream
45         {
46                 // FIXME: not precise.
47                 internal const int DefaultBufferSize = 0x400;
48
49                 internal static bool IsWindows {
50                         get { return Win32Marshal.IsWindows; }
51                 }
52
53                 internal Exception ThrowACLException ()
54                 {
55                         return new NotImplementedException ("ACL is not supported in Mono");
56                 }
57
58                 internal static PipeAccessRights ToAccessRights (PipeDirection direction)
59                 {
60                         switch (direction) {
61                         case PipeDirection.In:
62                                 return PipeAccessRights.ReadData;
63                         case PipeDirection.Out:
64                                 return PipeAccessRights.WriteData;
65                         case PipeDirection.InOut:
66                                 return PipeAccessRights.ReadData | PipeAccessRights.WriteData;
67                         default:
68                                 throw new ArgumentOutOfRangeException ();
69                         }
70                 }
71
72                 internal static PipeDirection ToDirection (PipeAccessRights rights)
73                 {
74                         bool r = (rights & PipeAccessRights.ReadData) != 0;
75                         bool w = (rights & PipeAccessRights.WriteData) != 0;
76                         if (r) {
77                                 if (w)
78                                         return PipeDirection.InOut;
79                                 else
80                                         return PipeDirection.In;
81                         } else {
82                                 if (w)
83                                         return PipeDirection.Out;
84                                 else
85                                         throw new ArgumentOutOfRangeException ();
86                         }
87                 }
88
89                 protected PipeStream (PipeDirection direction, int bufferSize)
90                         : this (direction, PipeTransmissionMode.Byte, bufferSize)
91                 {
92                 }
93
94                 protected PipeStream (PipeDirection direction, PipeTransmissionMode transmissionMode, int outBufferSize)
95                 {
96                         this.direction = direction;
97                         this.transmission_mode = transmissionMode;
98                         read_trans_mode = transmissionMode;
99                         if (outBufferSize <= 0)
100                                 throw new ArgumentOutOfRangeException ("bufferSize must be greater than 0");
101                         buffer_size = outBufferSize;
102                 }
103
104                 PipeDirection direction;
105                 PipeTransmissionMode transmission_mode, read_trans_mode;
106                 int buffer_size;
107                 SafePipeHandle handle;
108                 Stream stream;
109
110                 public override bool CanRead {
111                         get { return (direction & PipeDirection.In) != 0; }
112                 }
113
114                 public override bool CanSeek {
115                         get { return false; }
116                 }
117
118                 public override bool CanWrite {
119                         get { return (direction & PipeDirection.Out) != 0; }
120                 }
121
122                 public virtual int InBufferSize {
123                         get { return buffer_size; }
124                 }
125
126                 public bool IsAsync { get; private set; }
127
128                 public bool IsConnected { get; protected set; }
129
130                 internal Stream Stream {
131                         get {
132                                 if (!IsConnected)
133                                         throw new InvalidOperationException ("Pipe is not connected");
134                                 if (stream == null)
135                                         stream = new FileStream (handle.DangerousGetHandle (),
136                                                                  CanRead ? (CanWrite ? FileAccess.ReadWrite : FileAccess.Read)
137                                                                          : FileAccess.Write, true, buffer_size, IsAsync);
138                                 return stream;
139                         }
140                         set { stream = value; }
141                 }
142
143                 protected bool IsHandleExposed { get; private set; }
144
145                 [MonoTODO]
146                 public bool IsMessageComplete { get; private set; }
147
148                 [MonoTODO]
149                 public virtual int OutBufferSize {
150                         get { return buffer_size; }
151                 }
152
153                 public virtual PipeTransmissionMode ReadMode {
154                         get {
155                                 CheckPipePropertyOperations ();
156                                 return read_trans_mode;
157                         }
158                         set {
159                                 CheckPipePropertyOperations ();
160                                 read_trans_mode = value;
161                         }
162                 }
163
164                 public SafePipeHandle SafePipeHandle {
165                         get {
166                                 CheckPipePropertyOperations ();
167                                 return handle;
168                         }
169                 }
170
171                 public virtual PipeTransmissionMode TransmissionMode {
172                         get {
173                                 CheckPipePropertyOperations ();
174                                 return transmission_mode;
175                         }
176                 }
177
178                 // initialize/dispose/state check
179
180                 [MonoTODO]
181                 protected internal virtual void CheckPipePropertyOperations ()
182                 {
183                 }
184
185                 [MonoTODO]
186                 protected internal void CheckReadOperations ()
187                 {
188                         if (!IsConnected)
189                                 throw new InvalidOperationException ("Pipe is not connected");
190                         if (!CanRead)
191                                 throw new NotSupportedException ("The pipe stream does not support read operations");
192                 }
193
194                 [MonoTODO]
195                 protected internal void CheckWriteOperations ()
196                 {
197                         if (!IsConnected)
198                                 throw new InvalidOperationException ("Pipe is not connected");
199                         if (!CanWrite)
200                                 throw new NotSupportedException ("The pipe stream does not support write operations");
201                 }
202
203                 protected void InitializeHandle (SafePipeHandle handle, bool isExposed, bool isAsync)
204                 {
205                         this.handle = handle;
206                         this.IsHandleExposed = isExposed;
207                         this.IsAsync = isAsync;
208                 }
209
210                 protected override void Dispose (bool disposing)
211                 {
212                         if (handle != null && disposing)
213                                 handle.Dispose ();
214                 }
215
216                 // not supported
217
218                 public override long Length {
219                         get { throw new NotSupportedException (); }
220                 }
221
222                 public override long Position {
223                         get { return 0; }
224                         set { throw new NotSupportedException (); }
225                 }
226
227                 public override void SetLength (long value)
228                 {
229                         throw new NotSupportedException ();
230                 }
231
232                 public override long Seek (long offset, SeekOrigin origin)
233                 {
234                         throw new NotSupportedException ();
235                 }
236
237                 public PipeSecurity GetAccessControl ()
238                 {
239                         return new PipeSecurity (SafePipeHandle,
240                                                  AccessControlSections.Owner |
241                                                  AccessControlSections.Group |
242                                                  AccessControlSections.Access);
243                 }
244
245                 public void SetAccessControl (PipeSecurity pipeSecurity)
246                 {
247                         if (pipeSecurity == null)
248                                 throw new ArgumentNullException ("pipeSecurity");
249                                 
250                         pipeSecurity.Persist (SafePipeHandle);
251                 }
252
253                 // pipe I/O
254
255                 public void WaitForPipeDrain ()
256                 {
257                 }
258
259                 [MonoTODO]
260                 public override int Read ([In] byte [] buffer, int offset, int count)
261                 {
262                         CheckReadOperations ();
263
264                         return Stream.Read (buffer, offset, count);
265                 }
266
267                 [MonoTODO]
268                 public override int ReadByte ()
269                 {
270                         CheckReadOperations ();
271
272                         return Stream.ReadByte ();
273                 }
274
275                 [MonoTODO]
276                 public override void Write (byte [] buffer, int offset, int count)
277                 {
278                         CheckWriteOperations ();
279
280                         Stream.Write (buffer, offset, count);
281                 }
282
283                 [MonoTODO]
284                 public override void WriteByte (byte value)
285                 {
286                         CheckWriteOperations ();
287
288                         Stream.WriteByte (value);
289                 }
290
291                 [MonoTODO]
292                 public override void Flush ()
293                 {
294                         CheckWriteOperations ();
295
296                         Stream.Flush ();
297                 }
298
299                 // async
300
301                 Func<byte [],int,int,int> read_delegate;
302
303                 [HostProtection (SecurityAction.LinkDemand, ExternalThreading = true)]
304                 public override IAsyncResult BeginRead (byte [] buffer, int offset, int count, AsyncCallback callback, object state)
305                 {
306                         if (read_delegate == null)
307                                 read_delegate = new Func<byte[],int,int,int> (Read);
308                         return read_delegate.BeginInvoke (buffer, offset, count, callback, state);
309                 }
310
311                 Action<byte[],int,int> write_delegate;
312
313                 [HostProtection (SecurityAction.LinkDemand, ExternalThreading = true)]
314                 public override IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback callback, object state)
315                 {
316                         if (write_delegate == null)
317                                 write_delegate = new Action<byte[],int,int> (Write);
318                         return write_delegate.BeginInvoke (buffer, offset, count, callback, state);
319                 }
320
321                 public override int EndRead (IAsyncResult asyncResult)
322                 {
323                         return read_delegate.EndInvoke (asyncResult);
324                 }
325
326                 public override void EndWrite (IAsyncResult asyncResult)
327                 {
328                         write_delegate.EndInvoke (asyncResult);
329                 }
330         }
331 }
332
333 #endif