flush
[mcs.git] / class / System.Core / System.IO.Pipes / PipeStream.cs
blob9b6dda2c4228addf88adbcec8f8fd4c4beb3b78e
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.
29 #if !BOOTSTRAP_BASIC
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;
39 namespace System.IO.Pipes
41 [PermissionSet (SecurityAction.InheritanceDemand, Name = "FullTrust")]
42 [HostProtection (SecurityAction.LinkDemand, MayLeakOnAbort = true)]
43 public abstract class PipeStream : Stream
45 // FIXME: not precise.
46 internal const int DefaultBufferSize = 0x400;
48 internal static bool IsWindows {
49 get { return Win32Marshal.IsWindows; }
52 internal Exception ThrowACLException ()
54 return new NotImplementedException ("ACL is not supported in Mono");
57 internal static PipeAccessRights ToAccessRights (PipeDirection direction)
59 switch (direction) {
60 case PipeDirection.In:
61 return PipeAccessRights.ReadData;
62 case PipeDirection.Out:
63 return PipeAccessRights.WriteData;
64 case PipeDirection.InOut:
65 return PipeAccessRights.ReadData | PipeAccessRights.WriteData;
66 default:
67 throw new ArgumentOutOfRangeException ();
71 internal static PipeDirection ToDirection (PipeAccessRights rights)
73 bool r = (rights & PipeAccessRights.ReadData) != 0;
74 bool w = (rights & PipeAccessRights.WriteData) != 0;
75 if (r) {
76 if (w)
77 return PipeDirection.InOut;
78 else
79 return PipeDirection.In;
80 } else {
81 if (w)
82 return PipeDirection.Out;
83 else
84 throw new ArgumentOutOfRangeException ();
88 protected PipeStream (PipeDirection direction, int bufferSize)
89 : this (direction, PipeTransmissionMode.Byte, bufferSize)
93 protected PipeStream (PipeDirection direction, PipeTransmissionMode transmissionMode, int outBufferSize)
95 this.direction = direction;
96 this.transmission_mode = transmissionMode;
97 read_trans_mode = transmissionMode;
98 if (outBufferSize <= 0)
99 throw new ArgumentOutOfRangeException ("bufferSize must be greater than 0");
100 buffer_size = outBufferSize;
103 PipeDirection direction;
104 PipeTransmissionMode transmission_mode, read_trans_mode;
105 int buffer_size;
106 SafePipeHandle handle;
107 Stream stream;
109 public override bool CanRead {
110 get { return (direction & PipeDirection.In) != 0; }
113 public override bool CanSeek {
114 get { return false; }
117 public override bool CanWrite {
118 get { return (direction & PipeDirection.Out) != 0; }
121 public virtual int InBufferSize {
122 get { return buffer_size; }
125 public bool IsAsync { get; private set; }
127 public bool IsConnected { get; protected set; }
129 internal Stream Stream {
130 get {
131 if (!IsConnected)
132 throw new InvalidOperationException ("Pipe is not connected");
133 if (stream == null)
134 stream = new FileStream (handle.DangerousGetHandle (), CanRead ? (CanWrite ? FileAccess.ReadWrite : FileAccess.Read) : FileAccess.Write, true, buffer_size, IsAsync);
135 return stream;
137 set { stream = value; }
140 protected bool IsHandleExposed { get; private set; }
142 [MonoTODO]
143 public bool IsMessageComplete { get; private set; }
145 [MonoTODO]
146 public virtual int OutBufferSize {
147 get { return buffer_size; }
150 public virtual PipeTransmissionMode ReadMode {
151 get {
152 CheckPipePropertyOperations ();
153 return read_trans_mode;
155 set {
156 CheckPipePropertyOperations ();
157 read_trans_mode = value;
161 public SafePipeHandle SafePipeHandle {
162 get {
163 CheckPipePropertyOperations ();
164 return handle;
168 public virtual PipeTransmissionMode TransmissionMode {
169 get {
170 CheckPipePropertyOperations ();
171 return transmission_mode;
175 // initialize/dispose/state check
177 [MonoTODO]
178 protected internal virtual void CheckPipePropertyOperations ()
182 [MonoTODO]
183 protected internal void CheckReadOperations ()
185 if (!IsConnected)
186 throw new InvalidOperationException ("Pipe is not connected");
187 if (!CanRead)
188 throw new NotSupportedException ("The pipe stream does not support read operations");
191 [MonoTODO]
192 protected internal void CheckWriteOperations ()
194 if (!IsConnected)
195 throw new InvalidOperationException ("Pipe us not connected");
196 if (!CanWrite)
197 throw new NotSupportedException ("The pipe stream does not support write operations");
200 protected void InitializeHandle (SafePipeHandle handle, bool isExposed, bool isAsync)
202 this.handle = handle;
203 this.IsHandleExposed = isExposed;
204 this.IsAsync = isAsync;
207 protected override void Dispose (bool disposing)
209 if (handle != null && disposing)
210 handle.Dispose ();
213 // not supported
215 public override long Length {
216 get { throw new NotSupportedException (); }
219 public override long Position {
220 get { return 0; }
221 set { throw new NotSupportedException (); }
224 public override void SetLength (long value)
226 throw new NotSupportedException ();
229 public override long Seek (long offset, SeekOrigin origin)
231 throw new NotSupportedException ();
234 [MonoNotSupported ("ACL is not supported in Mono")]
235 public PipeSecurity GetAccessControl ()
237 throw ThrowACLException ();
240 [MonoNotSupported ("ACL is not supported in Mono")]
241 public void SetAccessControl (PipeSecurity pipeSecurity)
243 throw ThrowACLException ();
246 // pipe I/O
248 public void WaitForPipeDrain ()
252 [MonoTODO]
253 public override int Read (byte [] buffer, int offset, int count)
255 CheckReadOperations ();
257 return Stream.Read (buffer, offset, count);
260 [MonoTODO]
261 public override int ReadByte ()
263 CheckReadOperations ();
265 return Stream.ReadByte ();
268 [MonoTODO]
269 public override void Write (byte [] buffer, int offset, int count)
271 CheckWriteOperations ();
273 Stream.Write (buffer, offset, count);
276 [MonoTODO]
277 public override void WriteByte (byte value)
279 CheckWriteOperations ();
281 Stream.WriteByte (value);
284 [MonoTODO]
285 public override void Flush ()
287 CheckWriteOperations ();
289 Stream.Flush ();
292 // async
294 Func<byte [],int,int,int> read_delegate;
296 [HostProtection (SecurityAction.LinkDemand, ExternalThreading = true)]
297 public override IAsyncResult BeginRead (byte [] buffer, int offset, int count, AsyncCallback callback, object state)
299 if (read_delegate == null)
300 read_delegate = new Func<byte[],int,int,int> (Read);
301 return read_delegate.BeginInvoke (buffer, offset, count, callback, state);
304 Action<byte[],int,int> write_delegate;
306 [HostProtection (SecurityAction.LinkDemand, ExternalThreading = true)]
307 public override IAsyncResult BeginWrite (byte[] buffer, int offset, int count, AsyncCallback callback, object state)
309 if (write_delegate == null)
310 write_delegate = new Action<byte[],int,int> (Write);
311 return write_delegate.BeginInvoke (buffer, offset, count, callback, state);
314 public override int EndRead (IAsyncResult asyncResult)
316 return read_delegate.EndInvoke (asyncResult);
319 public override void EndWrite (IAsyncResult asyncResult)
321 write_delegate.EndInvoke (asyncResult);
326 #endif