5 // Dietmar Maurer (dietmar@ximian.com)
6 // Miguel de Icaza (miguel@ximian.com)
7 // Gonzalo Paniagua Javier (gonzalo@ximian.com)
9 // (C) 2001, 2002 Ximian, Inc. http://www.ximian.com
10 // (c) 2004 Novell, Inc. (http://www.novell.com)
14 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 using System
.Threading
;
37 using System
.Runtime
.Remoting
.Messaging
;
38 using System
.Runtime
.InteropServices
;
45 public abstract class Stream
: IDisposable
47 public abstract class Stream
: MarshalByRefObject
, IDisposable
50 public static readonly Stream Null
= new NullStream ();
56 public abstract bool CanRead
61 public abstract bool CanSeek
66 public abstract bool CanWrite
72 public virtual bool CanTimeout
{
78 public abstract long Length
83 public abstract long Position
90 // 2.0 version of Dispose.
91 public void Dispose ()
96 // 2.0 version of Dispose.
97 protected virtual void Dispose (bool disposing
)
103 // 2.0 version of Close (): calls Dispose (true)
105 public virtual void Close ()
111 public virtual int ReadTimeout
{
113 throw new InvalidOperationException ("Timeouts are not supported on this stream.");
116 throw new InvalidOperationException ("Timeouts are not supported on this stream.");
121 public virtual int WriteTimeout
{
123 throw new InvalidOperationException ("Timeouts are not supported on this stream.");
126 throw new InvalidOperationException ("Timeouts are not supported on this stream.");
130 public static Stream
Synchronized (Stream stream
)
132 return new SynchronizedStream (stream
);
135 [Obsolete ("CreateWaitHandle is due for removal. Use \"new ManualResetEvent(false)\" instead.")]
136 protected virtual WaitHandle
CreateWaitHandle()
138 return new ManualResetEvent (false);
141 public abstract void Flush ();
143 public abstract int Read ([In
,Out
] byte[] buffer
, int offset
, int count
);
145 public virtual int ReadByte ()
147 byte[] buffer
= new byte [1];
149 if (Read (buffer
, 0, 1) == 1)
155 public abstract long Seek (long offset
, SeekOrigin origin
);
157 public abstract void SetLength (long value);
159 public abstract void Write (byte[] buffer
, int offset
, int count
);
161 public virtual void WriteByte (byte value)
163 byte[] buffer
= new byte [1];
167 Write (buffer
, 0, 1);
170 public virtual IAsyncResult
171 BeginRead (byte [] buffer
, int offset
, int count
, AsyncCallback callback
, object state
)
174 throw new NotSupportedException ("This stream does not support reading");
176 // Creating a class derived from Stream that doesn't override BeginRead
177 // shows that it actually calls Read and does everything synchronously.
178 // Just put this in the Read override:
179 // Console.WriteLine ("Read");
180 // Console.WriteLine (Environment.StackTrace);
181 // Thread.Sleep (10000);
184 StreamAsyncResult result
= new StreamAsyncResult (state
);
186 int nbytes
= Read (buffer
, offset
, count
);
187 result
.SetComplete (null, nbytes
);
188 } catch (Exception e
) {
189 result
.SetComplete (e
, 0);
192 if (callback
!= null)
198 // delegate void WriteDelegate (byte [] buffer, int offset, int count);
200 public virtual IAsyncResult
201 BeginWrite (byte [] buffer
, int offset
, int count
, AsyncCallback callback
, object state
)
204 throw new NotSupportedException ("This stream does not support writing");
206 // Creating a class derived from Stream that doesn't override BeginWrite
207 // shows that it actually calls Write and does everything synchronously except
208 // when invoking the callback, which is done from the ThreadPool.
209 // Just put this in the Write override:
210 // Console.WriteLine ("Write");
211 // Console.WriteLine (Environment.StackTrace);
212 // Thread.Sleep (10000);
214 StreamAsyncResult result
= new StreamAsyncResult (state
);
216 Write (buffer
, offset
, count
);
217 result
.SetComplete (null);
218 } catch (Exception e
) {
219 result
.SetComplete (e
);
222 if (callback
!= null)
223 callback
.BeginInvoke (result
, null, null);
228 public virtual int EndRead (IAsyncResult asyncResult
)
230 if (asyncResult
== null)
231 throw new ArgumentNullException ("asyncResult");
233 StreamAsyncResult result
= asyncResult
as StreamAsyncResult
;
234 if (result
== null || result
.NBytes
== -1)
235 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
238 throw new InvalidOperationException ("EndRead already called.");
241 if (result
.Exception
!= null)
242 throw result
.Exception
;
244 return result
.NBytes
;
247 public virtual void EndWrite (IAsyncResult asyncResult
)
249 if (asyncResult
== null)
250 throw new ArgumentNullException ("asyncResult");
252 StreamAsyncResult result
= asyncResult
as StreamAsyncResult
;
253 if (result
== null || result
.NBytes
!= -1)
254 throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
257 throw new InvalidOperationException ("EndWrite already called.");
260 if (result
.Exception
!= null)
261 throw result
.Exception
;
264 #if MOONLIGHT || NET_4_0
265 public void CopyTo (Stream destination
)
267 CopyTo (destination
, 16*1024);
270 public void CopyTo (Stream destination
, int bufferSize
)
272 if (destination
== null)
273 throw new ArgumentNullException ("destination");
275 throw new NotSupportedException ("This stream does not support reading");
276 if (!destination
.CanWrite
)
277 throw new NotSupportedException ("This destination stream does not support writing");
279 throw new ArgumentOutOfRangeException ("bufferSize");
281 var buffer
= new byte [bufferSize
];
283 while ((nread
= Read (buffer
, 0, bufferSize
)) != 0)
284 destination
.Write (buffer
, 0, nread
);
287 protected virtual void ObjectInvariant ()
293 class NullStream
: Stream
295 public override bool CanRead
302 public override bool CanSeek
309 public override bool CanWrite
316 public override long Length
323 public override long Position
332 public override void Flush ()
336 public override int Read (byte[] buffer
, int offset
, int count
)
341 public override int ReadByte ()
346 public override long Seek (long offset
, SeekOrigin origin
)
351 public override void SetLength (long value)
355 public override void Write (byte[] buffer
, int offset
, int count
)
359 public override void WriteByte (byte value)
364 class SynchronizedStream
: Stream
{
368 internal SynchronizedStream (Stream source
)
370 this.source
= source
;
371 slock
= new object ();
374 public override bool CanRead
378 return source
.CanRead
;
382 public override bool CanSeek
386 return source
.CanSeek
;
390 public override bool CanWrite
394 return source
.CanWrite
;
398 public override long Length
402 return source
.Length
;
406 public override long Position
410 return source
.Position
;
414 source
.Position
= value;
418 public override void Flush ()
424 public override int Read (byte[] buffer
, int offset
, int count
)
427 return source
.Read (buffer
, offset
, count
);
430 public override int ReadByte ()
433 return source
.ReadByte ();
436 public override long Seek (long offset
, SeekOrigin origin
)
439 return source
.Seek (offset
, origin
);
442 public override void SetLength (long value)
445 source
.SetLength (value);
448 public override void Write (byte[] buffer
, int offset
, int count
)
451 source
.Write (buffer
, offset
, count
);
454 public override void WriteByte (byte value)
457 source
.WriteByte (value);