Fix contradicting defines in Stream
[mono.git] / mcs / class / referencesource / mscorlib / system / io / stream.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 /*============================================================
7 **
8 ** Class:  Stream
9 ** 
10 ** <OWNER>gpaperin</OWNER>
11 **
12 **
13 ** Purpose: Abstract base class for all Streams.  Provides
14 ** default implementations of asynchronous reads & writes, in
15 ** terms of the synchronous reads & writes (and vice versa).
16 **
17 **
18 ===========================================================*/
19 using System;
20 using System.Threading;
21 #if FEATURE_ASYNC_IO
22 using System.Threading.Tasks;
23 #endif
24
25 using System.Runtime;
26 using System.Runtime.InteropServices;
27 #if NEW_EXPERIMENTAL_ASYNC_IO
28 using System.Runtime.CompilerServices;
29 #endif
30 using System.Runtime.ExceptionServices;
31 using System.Security;
32 using System.Security.Permissions;
33 using System.Diagnostics.Contracts;
34 using System.Reflection;
35
36 namespace System.IO {
37     [Serializable]
38     [ComVisible(true)]
39 #if CONTRACTS_FULL
40     [ContractClass(typeof(StreamContract))]
41 #endif
42 #if FEATURE_REMOTING
43     public abstract class Stream : MarshalByRefObject, IDisposable {
44 #else // FEATURE_REMOTING
45     public abstract class Stream : IDisposable {
46 #endif // FEATURE_REMOTING
47
48         public static readonly Stream Null = new NullStream();
49
50         //We pick a value that is the largest multiple of 4096 that is still smaller than the large object heap threshold (85K).
51         // The CopyTo/CopyToAsync buffer is short-lived and is likely to be collected at Gen0, and it offers a significant
52         // improvement in Copy performance.
53         private const int _DefaultCopyBufferSize = 81920;
54
55 #if NEW_EXPERIMENTAL_ASYNC_IO
56         // To implement Async IO operations on streams that don't support async IO
57
58         [NonSerialized]
59         private ReadWriteTask _activeReadWriteTask;
60         [NonSerialized]
61         private SemaphoreSlim _asyncActiveSemaphore;
62
63         internal SemaphoreSlim EnsureAsyncActiveSemaphoreInitialized()
64         {
65             // Lazily-initialize _asyncActiveSemaphore.  As we're never accessing the SemaphoreSlim's
66             // WaitHandle, we don't need to worry about Disposing it.
67             return LazyInitializer.EnsureInitialized(ref _asyncActiveSemaphore, () => new SemaphoreSlim(1, 1));
68         }
69 #endif
70
71         public abstract bool CanRead {
72             [Pure]
73             get;
74         }
75
76         // If CanSeek is false, Position, Seek, Length, and SetLength should throw.
77         public abstract bool CanSeek {
78             [Pure]
79             get;
80         }
81
82         [ComVisible(false)]
83         public virtual bool CanTimeout {
84             [Pure]
85             get {
86                 return false;
87             }
88         }
89         
90         public abstract bool CanWrite {
91             [Pure]
92             get;
93         }
94
95         public abstract long Length {
96             get;
97         }
98
99         public abstract long Position {
100             get;
101             set;
102         }
103
104         [ComVisible(false)]
105         public virtual int ReadTimeout {
106             get {
107                 Contract.Ensures(Contract.Result<int>() >= 0);
108                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_TimeoutsNotSupported"));
109             }
110             set {
111                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_TimeoutsNotSupported"));
112             }
113         }
114
115         [ComVisible(false)]
116         public virtual int WriteTimeout {
117             get {
118                 Contract.Ensures(Contract.Result<int>() >= 0);
119                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_TimeoutsNotSupported"));
120             }
121             set {
122                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_TimeoutsNotSupported"));
123             }
124         }
125
126 #if FEATURE_ASYNC_IO
127         [HostProtection(ExternalThreading = true)]
128         [ComVisible(false)]
129         public Task CopyToAsync(Stream destination)
130         {
131             return CopyToAsync(destination, _DefaultCopyBufferSize);
132         }
133
134         [HostProtection(ExternalThreading = true)]
135         [ComVisible(false)]
136         public Task CopyToAsync(Stream destination, Int32 bufferSize)
137         {
138             return CopyToAsync(destination, bufferSize, CancellationToken.None);
139         }
140
141         [HostProtection(ExternalThreading = true)]
142         [ComVisible(false)]
143         public virtual Task CopyToAsync(Stream destination, Int32 bufferSize, CancellationToken cancellationToken)
144         {
145             if (destination == null)
146                 throw new ArgumentNullException("destination");
147             if (bufferSize <= 0)
148                 throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
149             if (!CanRead && !CanWrite)
150                 throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_StreamClosed"));
151             if (!destination.CanRead && !destination.CanWrite)
152                 throw new ObjectDisposedException("destination", Environment.GetResourceString("ObjectDisposed_StreamClosed"));
153             if (!CanRead)
154                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnreadableStream"));
155             if (!destination.CanWrite)
156                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnwritableStream"));
157             Contract.EndContractBlock();
158
159             return CopyToAsyncInternal(destination, bufferSize, cancellationToken);
160         }
161
162         private async Task CopyToAsyncInternal(Stream destination, Int32 bufferSize, CancellationToken cancellationToken)
163         {
164             Contract.Requires(destination != null);
165             Contract.Requires(bufferSize > 0);
166             Contract.Requires(CanRead);
167             Contract.Requires(destination.CanWrite);
168
169             byte[] buffer = new byte[bufferSize];
170             int bytesRead;
171             while ((bytesRead = await ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) != 0)
172             {
173                 await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
174             }
175         }
176 #endif // FEATURE_ASYNC_IO
177
178         // Reads the bytes from the current stream and writes the bytes to
179         // the destination stream until all bytes are read, starting at
180         // the current position.
181         public void CopyTo(Stream destination)
182         {
183             if (destination == null)
184                 throw new ArgumentNullException("destination");
185             if (!CanRead && !CanWrite)
186                 throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_StreamClosed"));
187             if (!destination.CanRead && !destination.CanWrite)
188                 throw new ObjectDisposedException("destination", Environment.GetResourceString("ObjectDisposed_StreamClosed"));
189             if (!CanRead)
190                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnreadableStream"));
191             if (!destination.CanWrite)
192                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnwritableStream"));
193             Contract.EndContractBlock();
194
195             InternalCopyTo(destination, _DefaultCopyBufferSize);
196         }
197
198         public void CopyTo(Stream destination, int bufferSize)
199         {
200             if (destination == null)
201                 throw new ArgumentNullException("destination");
202             if (bufferSize <= 0)
203                 throw new ArgumentOutOfRangeException("bufferSize",
204                         Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
205             if (!CanRead && !CanWrite)
206                 throw new ObjectDisposedException(null, Environment.GetResourceString("ObjectDisposed_StreamClosed"));
207             if (!destination.CanRead && !destination.CanWrite)
208                 throw new ObjectDisposedException("destination", Environment.GetResourceString("ObjectDisposed_StreamClosed"));
209             if (!CanRead)
210                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnreadableStream"));
211             if (!destination.CanWrite)
212                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_UnwritableStream"));
213             Contract.EndContractBlock();
214
215             InternalCopyTo(destination, bufferSize);
216         }
217
218         private void InternalCopyTo(Stream destination, int bufferSize)
219         {
220             Contract.Requires(destination != null);
221             Contract.Requires(CanRead);
222             Contract.Requires(destination.CanWrite);
223             Contract.Requires(bufferSize > 0);
224             
225             byte[] buffer = new byte[bufferSize];
226             int read;
227             while ((read = Read(buffer, 0, buffer.Length)) != 0)
228                 destination.Write(buffer, 0, read);
229         }
230
231
232         // Stream used to require that all cleanup logic went into Close(),
233         // which was thought up before we invented IDisposable.  However, we
234         // need to follow the IDisposable pattern so that users can write 
235         // sensible subclasses without needing to inspect all their base 
236         // classes, and without worrying about version brittleness, from a
237         // base class switching to the Dispose pattern.  We're moving
238         // Stream to the Dispose(bool) pattern - that's where all subclasses 
239         // should put their cleanup starting in V2.
240         public virtual void Close()
241         {
242             /* These are correct, but we'd have to fix PipeStream & NetworkStream very carefully.
243             Contract.Ensures(CanRead == false);
244             Contract.Ensures(CanWrite == false);
245             Contract.Ensures(CanSeek == false);
246             */
247
248             Dispose(true);
249             GC.SuppressFinalize(this);
250         }
251
252         public void Dispose()
253         {
254             /* These are correct, but we'd have to fix PipeStream & NetworkStream very carefully.
255             Contract.Ensures(CanRead == false);
256             Contract.Ensures(CanWrite == false);
257             Contract.Ensures(CanSeek == false);
258             */
259
260             Close();
261         }
262
263
264         protected virtual void Dispose(bool disposing)
265         {
266             // Note: Never change this to call other virtual methods on Stream
267             // like Write, since the state on subclasses has already been 
268             // torn down.  This is the last code to run on cleanup for a stream.
269         }
270
271         public abstract void Flush();
272
273 #if FEATURE_ASYNC_IO
274         [HostProtection(ExternalThreading=true)]
275         [ComVisible(false)]
276         public Task FlushAsync()
277         {
278             return FlushAsync(CancellationToken.None);
279         }
280
281         [HostProtection(ExternalThreading=true)]
282         [ComVisible(false)]
283         public virtual Task FlushAsync(CancellationToken cancellationToken)
284         {
285             return Task.Factory.StartNew(state => ((Stream)state).Flush(), this,
286                 cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
287         }
288 #endif // FEATURE_ASYNC_IO
289
290         [Obsolete("CreateWaitHandle will be removed eventually.  Please use \"new ManualResetEvent(false)\" instead.")]
291         protected virtual WaitHandle CreateWaitHandle()
292         {
293             Contract.Ensures(Contract.Result<WaitHandle>() != null);
294             return new ManualResetEvent(false);
295         }
296
297         [HostProtection(ExternalThreading=true)]
298         public virtual IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
299         {
300             Contract.Ensures(Contract.Result<IAsyncResult>() != null);
301             return BeginReadInternal(buffer, offset, count, callback, state, serializeAsynchronously: false);
302         }
303
304         [HostProtection(ExternalThreading = true)]
305         internal IAsyncResult BeginReadInternal(byte[] buffer, int offset, int count, AsyncCallback callback, Object state, bool serializeAsynchronously)
306         {
307             Contract.Ensures(Contract.Result<IAsyncResult>() != null);
308             if (!CanRead) __Error.ReadNotSupported();
309
310 #if !NEW_EXPERIMENTAL_ASYNC_IO
311             return BlockingBeginRead(buffer, offset, count, callback, state);
312 #else
313
314             // Mango did not do Async IO.
315             if(CompatibilitySwitches.IsAppEarlierThanWindowsPhone8)
316             {
317                 return BlockingBeginRead(buffer, offset, count, callback, state);
318             }
319
320             // To avoid a race with a stream's position pointer & generating ---- 
321             // conditions with internal buffer indexes in our own streams that 
322             // don't natively support async IO operations when there are multiple 
323             // async requests outstanding, we will block the application's main
324             // thread if it does a second IO request until the first one completes.
325             var semaphore = EnsureAsyncActiveSemaphoreInitialized();
326             Task semaphoreTask = null;
327             if (serializeAsynchronously)
328             {
329                 semaphoreTask = semaphore.WaitAsync();
330             }
331             else
332             {
333                 semaphore.Wait();
334             }
335
336             // Create the task to asynchronously do a Read.  This task serves both
337             // as the asynchronous work item and as the IAsyncResult returned to the user.
338             var asyncResult = new ReadWriteTask(true /*isRead*/, delegate
339             {
340                 // The ReadWriteTask stores all of the parameters to pass to Read.
341                 // As we're currently inside of it, we can get the current task
342                 // and grab the parameters from it.
343                 var thisTask = Task.InternalCurrent as ReadWriteTask;
344                 Contract.Assert(thisTask != null, "Inside ReadWriteTask, InternalCurrent should be the ReadWriteTask");
345
346                 // Do the Read and return the number of bytes read
347                 var bytesRead = thisTask._stream.Read(thisTask._buffer, thisTask._offset, thisTask._count);
348                 thisTask.ClearBeginState(); // just to help alleviate some memory pressure
349                 return bytesRead;
350             }, state, this, buffer, offset, count, callback);
351
352             // Schedule it
353             if (semaphoreTask != null)
354                 RunReadWriteTaskWhenReady(semaphoreTask, asyncResult);
355             else
356                 RunReadWriteTask(asyncResult);
357
358             
359             return asyncResult; // return it
360 #endif
361         }
362
363         public virtual int EndRead(IAsyncResult asyncResult)
364         {
365             if (asyncResult == null)
366                 throw new ArgumentNullException("asyncResult");
367             Contract.Ensures(Contract.Result<int>() >= 0);
368             Contract.EndContractBlock();
369
370 #if !NEW_EXPERIMENTAL_ASYNC_IO
371             return BlockingEndRead(asyncResult);
372 #else
373             // Mango did not do async IO.
374             if(CompatibilitySwitches.IsAppEarlierThanWindowsPhone8)
375             {
376                 return BlockingEndRead(asyncResult);
377             }
378
379             var readTask = _activeReadWriteTask;
380
381             if (readTask == null)
382             {
383                 throw new ArgumentException(Environment.GetResourceString("InvalidOperation_WrongAsyncResultOrEndReadCalledMultiple"));
384             }
385             else if (readTask != asyncResult)
386             {
387                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WrongAsyncResultOrEndReadCalledMultiple"));
388             }
389             else if (!readTask._isRead)
390             {
391                 throw new ArgumentException(Environment.GetResourceString("InvalidOperation_WrongAsyncResultOrEndReadCalledMultiple"));
392             }
393             
394             try 
395             {
396                 return readTask.GetAwaiter().GetResult(); // block until completion, then get result / propagate any exception
397             }
398             finally
399             {
400                 _activeReadWriteTask = null;
401                 Contract.Assert(_asyncActiveSemaphore != null, "Must have been initialized in order to get here.");
402                 _asyncActiveSemaphore.Release();
403             }
404 #endif
405         }
406
407 #if FEATURE_ASYNC_IO
408         [HostProtection(ExternalThreading = true)]
409         [ComVisible(false)]
410         public Task<int> ReadAsync(Byte[] buffer, int offset, int count)
411         {
412             return ReadAsync(buffer, offset, count, CancellationToken.None);
413         }
414
415         [HostProtection(ExternalThreading = true)]
416         [ComVisible(false)]
417         public virtual Task<int> ReadAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken)
418         {
419             // If cancellation was requested, bail early with an already completed task.
420             // Otherwise, return a task that represents the Begin/End methods.
421             return cancellationToken.IsCancellationRequested
422                         ? Task.FromCancellation<int>(cancellationToken)
423                         : BeginEndReadAsync(buffer, offset, count);
424         }
425
426         private Task<Int32> BeginEndReadAsync(Byte[] buffer, Int32 offset, Int32 count)
427         {            
428             return TaskFactory<Int32>.FromAsyncTrim(
429                         this, new ReadWriteParameters { Buffer = buffer, Offset = offset, Count = count },
430                         (stream, args, callback, state) => stream.BeginRead(args.Buffer, args.Offset, args.Count, callback, state), // cached by compiler
431                         (stream, asyncResult) => stream.EndRead(asyncResult)); // cached by compiler
432         }
433
434         private struct ReadWriteParameters // struct for arguments to Read and Write calls
435         {
436             internal byte[] Buffer;
437             internal int Offset;
438             internal int Count;
439         }
440 #endif //FEATURE_ASYNC_IO
441
442
443
444         [HostProtection(ExternalThreading=true)]
445         public virtual IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
446         {
447             Contract.Ensures(Contract.Result<IAsyncResult>() != null);
448             return BeginWriteInternal(buffer, offset, count, callback, state, serializeAsynchronously: false);
449         }
450
451         [HostProtection(ExternalThreading = true)]
452         internal IAsyncResult BeginWriteInternal(byte[] buffer, int offset, int count, AsyncCallback callback, Object state, bool serializeAsynchronously)
453         {
454             Contract.Ensures(Contract.Result<IAsyncResult>() != null);
455             if (!CanWrite) __Error.WriteNotSupported();
456 #if !NEW_EXPERIMENTAL_ASYNC_IO
457             return BlockingBeginWrite(buffer, offset, count, callback, state);
458 #else
459
460             // Mango did not do Async IO.
461             if(CompatibilitySwitches.IsAppEarlierThanWindowsPhone8)
462             {
463                 return BlockingBeginWrite(buffer, offset, count, callback, state);
464             }
465
466             // To avoid a race with a stream's position pointer & generating ---- 
467             // conditions with internal buffer indexes in our own streams that 
468             // don't natively support async IO operations when there are multiple 
469             // async requests outstanding, we will block the application's main
470             // thread if it does a second IO request until the first one completes.
471             var semaphore = EnsureAsyncActiveSemaphoreInitialized();
472             Task semaphoreTask = null;
473             if (serializeAsynchronously)
474             {
475                 semaphoreTask = semaphore.WaitAsync(); // kick off the asynchronous wait, but don't block
476             }
477             else
478             {
479                 semaphore.Wait(); // synchronously wait here
480             }
481
482             // Create the task to asynchronously do a Write.  This task serves both
483             // as the asynchronous work item and as the IAsyncResult returned to the user.
484             var asyncResult = new ReadWriteTask(false /*isRead*/, delegate
485             {
486                 // The ReadWriteTask stores all of the parameters to pass to Write.
487                 // As we're currently inside of it, we can get the current task
488                 // and grab the parameters from it.
489                 var thisTask = Task.InternalCurrent as ReadWriteTask;
490                 Contract.Assert(thisTask != null, "Inside ReadWriteTask, InternalCurrent should be the ReadWriteTask");
491
492                 // Do the Write
493                 thisTask._stream.Write(thisTask._buffer, thisTask._offset, thisTask._count);  
494                 thisTask.ClearBeginState(); // just to help alleviate some memory pressure
495                 return 0; // not used, but signature requires a value be returned
496             }, state, this, buffer, offset, count, callback);
497
498             // Schedule it
499             if (semaphoreTask != null)
500                 RunReadWriteTaskWhenReady(semaphoreTask, asyncResult);
501             else
502                 RunReadWriteTask(asyncResult);
503
504             return asyncResult; // return it
505 #endif
506         }
507
508 #if NEW_EXPERIMENTAL_ASYNC_IO
509         private void RunReadWriteTaskWhenReady(Task asyncWaiter, ReadWriteTask readWriteTask)
510         {
511             Contract.Assert(readWriteTask != null);  // Should be Contract.Requires, but CCRewrite is doing a poor job with
512                                                      // preconditions in async methods that await.  Mike & Manuel are aware. (10/6/2011, bug 290222)
513             Contract.Assert(asyncWaiter != null);    // Ditto
514
515             // If the wait has already complete, run the task.
516             if (asyncWaiter.IsCompleted)
517             {
518                 Contract.Assert(asyncWaiter.IsRanToCompletion, "The semaphore wait should always complete successfully.");
519                 RunReadWriteTask(readWriteTask);
520             }                
521             else  // Otherwise, wait for our turn, and then run the task.
522             {
523                 asyncWaiter.ContinueWith((t, state) =>
524                     {
525                         Contract.Assert(t.IsRanToCompletion, "The semaphore wait should always complete successfully.");
526                         var tuple = (Tuple<Stream,ReadWriteTask>)state;
527                         tuple.Item1.RunReadWriteTask(tuple.Item2); // RunReadWriteTask(readWriteTask);
528                     }, Tuple.Create<Stream,ReadWriteTask>(this, readWriteTask),
529                 default(CancellationToken),
530                 TaskContinuationOptions.ExecuteSynchronously, 
531                 TaskScheduler.Default);
532             }
533         }
534
535         private void RunReadWriteTask(ReadWriteTask readWriteTask)
536         {
537             Contract.Requires(readWriteTask != null);
538             Contract.Assert(_activeReadWriteTask == null, "Expected no other readers or writers");
539
540             // Schedule the task.  ScheduleAndStart must happen after the write to _activeReadWriteTask to avoid a race.
541             // Internally, we're able to directly call ScheduleAndStart rather than Start, avoiding
542             // two interlocked operations.  However, if ReadWriteTask is ever changed to use
543             // a cancellation token, this should be changed to use Start.
544             _activeReadWriteTask = readWriteTask; // store the task so that EndXx can validate it's given the right one
545             readWriteTask.m_taskScheduler = TaskScheduler.Default;
546             readWriteTask.ScheduleAndStart(needsProtection: false);
547         }
548 #endif
549
550         public virtual void EndWrite(IAsyncResult asyncResult)
551         {
552             if (asyncResult==null)
553                 throw new ArgumentNullException("asyncResult");
554             Contract.EndContractBlock();
555
556 #if !NEW_EXPERIMENTAL_ASYNC_IO
557             BlockingEndWrite(asyncResult);
558 #else            
559
560             // Mango did not do Async IO.
561             if(CompatibilitySwitches.IsAppEarlierThanWindowsPhone8)
562             {
563                 BlockingEndWrite(asyncResult);
564                 return;
565             }            
566
567             var writeTask = _activeReadWriteTask;
568             if (writeTask == null)
569             {
570                 throw new ArgumentException(Environment.GetResourceString("InvalidOperation_WrongAsyncResultOrEndWriteCalledMultiple"));
571             }
572             else if (writeTask != asyncResult)
573             {
574                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WrongAsyncResultOrEndWriteCalledMultiple"));
575             }
576             else if (writeTask._isRead)
577             {
578                 throw new ArgumentException(Environment.GetResourceString("InvalidOperation_WrongAsyncResultOrEndWriteCalledMultiple"));
579             }
580
581             try 
582             {
583                 writeTask.GetAwaiter().GetResult(); // block until completion, then propagate any exceptions
584                 Contract.Assert(writeTask.Status == TaskStatus.RanToCompletion);
585             }
586             finally
587             {
588                 _activeReadWriteTask = null;
589                 Contract.Assert(_asyncActiveSemaphore != null, "Must have been initialized in order to get here.");
590                 _asyncActiveSemaphore.Release();
591             }
592 #endif
593         }
594
595 #if NEW_EXPERIMENTAL_ASYNC_IO
596         // Task used by BeginRead / BeginWrite to do Read / Write asynchronously.
597         // A single instance of this task serves four purposes:
598         // 1. The work item scheduled to run the Read / Write operation
599         // 2. The state holding the arguments to be passed to Read / Write
600         // 3. The IAsyncResult returned from BeginRead / BeginWrite
601         // 4. The completion action that runs to invoke the user-provided callback.
602         // This last item is a bit tricky.  Before the AsyncCallback is invoked, the
603         // IAsyncResult must have completed, so we can't just invoke the handler
604         // from within the task, since it is the IAsyncResult, and thus it's not
605         // yet completed.  Instead, we use AddCompletionAction to install this
606         // task as its own completion handler.  That saves the need to allocate
607         // a separate completion handler, it guarantees that the task will
608         // have completed by the time the handler is invoked, and it allows
609         // the handler to be invoked synchronously upon the completion of the
610         // task.  This all enables BeginRead / BeginWrite to be implemented
611         // with a single allocation.
612         private sealed class ReadWriteTask : Task<int>, ITaskCompletionAction
613         {
614             internal readonly bool _isRead;
615             internal Stream _stream;
616             internal byte [] _buffer;
617             internal int _offset;
618             internal int _count;
619             private AsyncCallback _callback;
620             private ExecutionContext _context;
621
622             internal void ClearBeginState() // Used to allow the args to Read/Write to be made available for GC
623             {
624                 _stream = null;
625                 _buffer = null;
626             }
627
628             [SecuritySafeCritical] // necessary for EC.Capture
629             [MethodImpl(MethodImplOptions.NoInlining)]
630             public ReadWriteTask(
631                 bool isRead,
632                 Func<object,int> function, object state,
633                 Stream stream, byte[] buffer, int offset, int count, AsyncCallback callback) :
634                 base(function, state, CancellationToken.None, TaskCreationOptions.DenyChildAttach)
635             {
636                 Contract.Requires(function != null);
637                 Contract.Requires(stream != null);
638                 Contract.Requires(buffer != null);
639                 Contract.EndContractBlock();
640
641                 StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
642
643                 // Store the arguments
644                 _isRead = isRead;
645                 _stream = stream;
646                 _buffer = buffer;
647                 _offset = offset;
648                 _count = count;
649
650                 // If a callback was provided, we need to:
651                 // - Store the user-provided handler
652                 // - Capture an ExecutionContext under which to invoke the handler
653                 // - Add this task as its own completion handler so that the Invoke method
654                 //   will run the callback when this task completes.
655                 if (callback != null)
656                 {
657                     _callback = callback;
658                     _context = ExecutionContext.Capture(ref stackMark, 
659                         ExecutionContext.CaptureOptions.OptimizeDefaultCase | ExecutionContext.CaptureOptions.IgnoreSyncCtx);
660                     base.AddCompletionAction(this);
661                 }
662             }
663
664             [SecurityCritical] // necessary for CoreCLR
665             private static void InvokeAsyncCallback(object completedTask)
666             {
667                 var rwc = (ReadWriteTask)completedTask;
668                 var callback = rwc._callback;
669                 rwc._callback = null;
670                 callback(rwc);
671             }
672
673             [SecurityCritical] // necessary for CoreCLR
674             private static ContextCallback s_invokeAsyncCallback;
675             
676             [SecuritySafeCritical] // necessary for ExecutionContext.Run
677             void ITaskCompletionAction.Invoke(Task completingTask)
678             {
679                 // Get the ExecutionContext.  If there is none, just run the callback
680                 // directly, passing in the completed task as the IAsyncResult.
681                 // If there is one, process it with ExecutionContext.Run.
682                 var context = _context;
683                 if (context == null) 
684                 {
685                     var callback = _callback;
686                     _callback = null;
687                     callback(completingTask);
688                 }
689                 else 
690                 {
691                     _context = null;
692         
693                     var invokeAsyncCallback = s_invokeAsyncCallback;
694                     if (invokeAsyncCallback == null) s_invokeAsyncCallback = invokeAsyncCallback = InvokeAsyncCallback; // benign ----
695
696                     using(context) ExecutionContext.Run(context, invokeAsyncCallback, this, true);
697                 }
698             }
699         }
700 #endif
701
702 #if FEATURE_ASYNC_IO
703         [HostProtection(ExternalThreading = true)]
704         [ComVisible(false)]
705         public Task WriteAsync(Byte[] buffer, int offset, int count)
706         {
707             return WriteAsync(buffer, offset, count, CancellationToken.None);
708         }
709
710         [HostProtection(ExternalThreading = true)]
711         [ComVisible(false)]
712         public virtual Task WriteAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken)
713         {
714             // If cancellation was requested, bail early with an already completed task.
715             // Otherwise, return a task that represents the Begin/End methods.
716             return cancellationToken.IsCancellationRequested
717                         ? Task.FromCancellation(cancellationToken)
718                         : BeginEndWriteAsync(buffer, offset, count);
719         }
720
721
722         private Task BeginEndWriteAsync(Byte[] buffer, Int32 offset, Int32 count)
723         {            
724             return TaskFactory<VoidTaskResult>.FromAsyncTrim(
725                         this, new ReadWriteParameters { Buffer=buffer, Offset=offset, Count=count },
726                         (stream, args, callback, state) => stream.BeginWrite(args.Buffer, args.Offset, args.Count, callback, state), // cached by compiler
727                         (stream, asyncResult) => // cached by compiler
728                         {
729                             stream.EndWrite(asyncResult);
730                             return default(VoidTaskResult);
731                         });
732         }        
733 #endif // FEATURE_ASYNC_IO
734
735         public abstract long Seek(long offset, SeekOrigin origin);
736
737         public abstract void SetLength(long value);
738
739         public abstract int Read([In, Out] byte[] buffer, int offset, int count);
740
741         // Reads one byte from the stream by calling Read(byte[], int, int). 
742         // Will return an unsigned byte cast to an int or -1 on end of stream.
743         // This implementation does not perform well because it allocates a new
744         // byte[] each time you call it, and should be overridden by any 
745         // subclass that maintains an internal buffer.  Then, it can help perf
746         // significantly for people who are reading one byte at a time.
747 #if !FEATURE_CORECLR
748         [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
749 #endif
750         public virtual int ReadByte()
751         {
752             Contract.Ensures(Contract.Result<int>() >= -1);
753             Contract.Ensures(Contract.Result<int>() < 256);
754
755             byte[] oneByteArray = new byte[1];
756             int r = Read(oneByteArray, 0, 1);
757             if (r==0)
758                 return -1;
759             return oneByteArray[0];
760         }
761
762         public abstract void Write(byte[] buffer, int offset, int count);
763
764         // Writes one byte from the stream by calling Write(byte[], int, int).
765         // This implementation does not perform well because it allocates a new
766         // byte[] each time you call it, and should be overridden by any 
767         // subclass that maintains an internal buffer.  Then, it can help perf
768         // significantly for people who are writing one byte at a time.
769         public virtual void WriteByte(byte value)
770         {
771             byte[] oneByteArray = new byte[1];
772             oneByteArray[0] = value;
773             Write(oneByteArray, 0, 1);
774         }
775
776         [HostProtection(Synchronization=true)]
777         public static Stream Synchronized(Stream stream) 
778         {
779             if (stream==null)
780                 throw new ArgumentNullException("stream");
781             Contract.Ensures(Contract.Result<Stream>() != null);
782             Contract.EndContractBlock();
783             if (stream is SyncStream)
784                 return stream;
785             
786             return new SyncStream(stream);
787         }
788
789 #if !FEATURE_PAL  // This method shouldn't have been exposed in Dev10 (we revised object invariants after locking down).
790         [Obsolete("Do not call or override this method.")]
791         protected virtual void ObjectInvariant() 
792         {
793         }
794 #endif
795
796         internal IAsyncResult BlockingBeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
797         {
798             Contract.Ensures(Contract.Result<IAsyncResult>() != null);
799
800             // To avoid a race with a stream's position pointer & generating ---- 
801             // conditions with internal buffer indexes in our own streams that 
802             // don't natively support async IO operations when there are multiple 
803             // async requests outstanding, we will block the application's main
804             // thread and do the IO synchronously.  
805             // This can't perform well - use a different approach.
806             SynchronousAsyncResult asyncResult; 
807             try {
808                 int numRead = Read(buffer, offset, count);
809                 asyncResult = new SynchronousAsyncResult(numRead, state);
810             }
811             catch (IOException ex) {
812                 asyncResult = new SynchronousAsyncResult(ex, state, isWrite: false);
813             }
814             
815             if (callback != null) {
816                 callback(asyncResult);
817             }
818
819             return asyncResult;
820         }
821
822         internal static int BlockingEndRead(IAsyncResult asyncResult)
823         {
824             Contract.Ensures(Contract.Result<int>() >= 0);
825
826             return SynchronousAsyncResult.EndRead(asyncResult);
827         }
828
829         internal IAsyncResult BlockingBeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
830         {
831             Contract.Ensures(Contract.Result<IAsyncResult>() != null);
832
833             // To avoid a race with a stream's position pointer & generating ---- 
834             // conditions with internal buffer indexes in our own streams that 
835             // don't natively support async IO operations when there are multiple 
836             // async requests outstanding, we will block the application's main
837             // thread and do the IO synchronously.  
838             // This can't perform well - use a different approach.
839             SynchronousAsyncResult asyncResult;
840             try {
841                 Write(buffer, offset, count);
842                 asyncResult = new SynchronousAsyncResult(state);
843             }
844             catch (IOException ex) {
845                 asyncResult = new SynchronousAsyncResult(ex, state, isWrite: true);
846             }
847
848             if (callback != null) {
849                 callback(asyncResult);
850             }
851
852             return asyncResult;
853         }
854
855         internal static void BlockingEndWrite(IAsyncResult asyncResult)
856         {
857             SynchronousAsyncResult.EndWrite(asyncResult);
858         }
859
860         [Serializable]
861         private sealed class NullStream : Stream
862         {
863             internal NullStream() {}
864
865             public override bool CanRead {
866                 [Pure]
867                 get { return true; }
868             }
869
870             public override bool CanWrite {
871                 [Pure]
872                 get { return true; }
873             }
874
875             public override bool CanSeek {
876                 [Pure]
877                 get { return true; }
878             }
879
880             public override long Length {
881                 get { return 0; }
882             }
883
884             public override long Position {
885                 get { return 0; }
886                 set {}
887             }
888
889             protected override void Dispose(bool disposing)
890             {
891                 // Do nothing - we don't want NullStream singleton (static) to be closable
892             }
893
894             public override void Flush()
895             {
896             }
897
898 #if FEATURE_ASYNC_IO
899             [ComVisible(false)]
900             public override Task FlushAsync(CancellationToken cancellationToken)
901             {
902                 return cancellationToken.IsCancellationRequested ?
903                     Task.FromCancellation(cancellationToken) :
904                     Task.CompletedTask;
905             }
906 #endif // FEATURE_ASYNC_IO
907
908             [HostProtection(ExternalThreading = true)]
909             public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
910             {
911                 if (!CanRead) __Error.ReadNotSupported();
912
913                 return BlockingBeginRead(buffer, offset, count, callback, state);
914             }
915
916             public override int EndRead(IAsyncResult asyncResult)
917             {
918                 if (asyncResult == null)
919                     throw new ArgumentNullException("asyncResult");
920                 Contract.EndContractBlock();
921
922                 return BlockingEndRead(asyncResult);
923             }
924
925             [HostProtection(ExternalThreading = true)]
926             public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
927             {
928                 if (!CanWrite) __Error.WriteNotSupported();
929
930                 return BlockingBeginWrite(buffer, offset, count, callback, state);
931             }
932
933             public override void EndWrite(IAsyncResult asyncResult)
934             {
935                 if (asyncResult == null)
936                     throw new ArgumentNullException("asyncResult");
937                 Contract.EndContractBlock();
938
939                 BlockingEndWrite(asyncResult);
940             }
941
942             public override int Read([In, Out] byte[] buffer, int offset, int count)
943             {
944                 return 0;
945             }
946
947 #if FEATURE_ASYNC_IO
948             [ComVisible(false)]
949             public override Task<int> ReadAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken)
950             {
951                 var nullReadTask = s_nullReadTask;
952                 if (nullReadTask == null) 
953                     s_nullReadTask = nullReadTask = new Task<int>(false, 0, (TaskCreationOptions)InternalTaskOptions.DoNotDispose, CancellationToken.None); // benign ----
954                 return nullReadTask;
955             }
956             private static Task<int> s_nullReadTask;
957 #endif //FEATURE_ASYNC_IO
958
959             public override int ReadByte()
960             {
961                 return -1;
962             }
963
964             public override void Write(byte[] buffer, int offset, int count)
965             {
966             }
967
968 #if FEATURE_ASYNC_IO
969             [ComVisible(false)]
970             public override Task WriteAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken)
971             {
972                 return cancellationToken.IsCancellationRequested ?
973                     Task.FromCancellation(cancellationToken) :
974                     Task.CompletedTask;
975             }
976 #endif // FEATURE_ASYNC_IO
977
978             public override void WriteByte(byte value)
979             {
980             }
981
982             public override long Seek(long offset, SeekOrigin origin)
983             {
984                 return 0;
985             }
986
987             public override void SetLength(long length)
988             {
989             }
990         }
991
992         
993         /// <summary>Used as the IAsyncResult object when using asynchronous IO methods on the base Stream class.</summary>
994         internal sealed class SynchronousAsyncResult : IAsyncResult {
995             
996             private readonly Object _stateObject;            
997             private readonly bool _isWrite;
998             private ManualResetEvent _waitHandle;
999             private ExceptionDispatchInfo _exceptionInfo;
1000
1001             private bool _endXxxCalled;
1002             private Int32 _bytesRead;
1003
1004             internal SynchronousAsyncResult(Int32 bytesRead, Object asyncStateObject) {
1005                 _bytesRead = bytesRead;
1006                 _stateObject = asyncStateObject;
1007                 //_isWrite = false;
1008             }
1009
1010             internal SynchronousAsyncResult(Object asyncStateObject) {
1011                 _stateObject = asyncStateObject;
1012                 _isWrite = true;
1013             }
1014
1015             internal SynchronousAsyncResult(Exception ex, Object asyncStateObject, bool isWrite) {
1016                 _exceptionInfo = ExceptionDispatchInfo.Capture(ex);
1017                 _stateObject = asyncStateObject;
1018                 _isWrite = isWrite;                
1019             }
1020
1021             public bool IsCompleted {
1022                 // We never hand out objects of this type to the user before the synchronous IO completed:
1023                 get { return true; }
1024             }
1025
1026             public WaitHandle AsyncWaitHandle {
1027                 get {
1028                     return LazyInitializer.EnsureInitialized(ref _waitHandle, () => new ManualResetEvent(true));                    
1029                 }
1030             }
1031
1032             public Object AsyncState {
1033                 get { return _stateObject; }
1034             }
1035
1036             public bool CompletedSynchronously {
1037                 get { return true; }
1038             }
1039
1040             internal void ThrowIfError() {
1041                 if (_exceptionInfo != null)
1042                     _exceptionInfo.Throw();
1043             }                        
1044
1045             internal static Int32 EndRead(IAsyncResult asyncResult) {
1046
1047                 SynchronousAsyncResult ar = asyncResult as SynchronousAsyncResult;
1048                 if (ar == null || ar._isWrite)
1049                     __Error.WrongAsyncResult();
1050
1051                 if (ar._endXxxCalled)
1052                     __Error.EndReadCalledTwice();
1053
1054                 ar._endXxxCalled = true;
1055
1056                 ar.ThrowIfError();
1057                 return ar._bytesRead;
1058             }
1059
1060             internal static void EndWrite(IAsyncResult asyncResult) {
1061
1062                 SynchronousAsyncResult ar = asyncResult as SynchronousAsyncResult;
1063                 if (ar == null || !ar._isWrite)
1064                     __Error.WrongAsyncResult();
1065
1066                 if (ar._endXxxCalled)
1067                     __Error.EndWriteCalledTwice();
1068
1069                 ar._endXxxCalled = true;
1070
1071                 ar.ThrowIfError();
1072             }
1073         }   // class SynchronousAsyncResult
1074
1075
1076         // SyncStream is a wrapper around a stream that takes 
1077         // a lock for every operation making it thread safe.
1078         [Serializable]
1079         internal sealed class SyncStream : Stream, IDisposable
1080         {
1081             private Stream _stream;
1082             [NonSerialized]
1083             private bool? _overridesBeginRead;
1084             [NonSerialized]
1085             private bool? _overridesBeginWrite;
1086
1087             internal SyncStream(Stream stream)
1088             {
1089                 if (stream == null)
1090                     throw new ArgumentNullException("stream");
1091                 Contract.EndContractBlock();
1092                 _stream = stream;
1093             }
1094         
1095             public override bool CanRead {
1096                 [Pure]
1097                 get { return _stream.CanRead; }
1098             }
1099         
1100             public override bool CanWrite {
1101                 [Pure]
1102                 get { return _stream.CanWrite; }
1103             }
1104         
1105             public override bool CanSeek {
1106                 [Pure]
1107                 get { return _stream.CanSeek; }
1108             }
1109         
1110             [ComVisible(false)]
1111             public override bool CanTimeout {
1112                 [Pure]
1113                 get {
1114                     return _stream.CanTimeout;
1115                 }
1116             }
1117
1118             public override long Length {
1119                 get {
1120                     lock(_stream) {
1121                         return _stream.Length;
1122                     }
1123                 }
1124             }
1125         
1126             public override long Position {
1127                 get {
1128                     lock(_stream) {
1129                         return _stream.Position;
1130                     }
1131                 }
1132                 set {
1133                     lock(_stream) {
1134                         _stream.Position = value;
1135                     }
1136                 }
1137             }
1138
1139             [ComVisible(false)]
1140             public override int ReadTimeout {
1141                 get {
1142                     return _stream.ReadTimeout;
1143                 }
1144                 set {
1145                     _stream.ReadTimeout = value;
1146                 }
1147             }
1148
1149             [ComVisible(false)]
1150             public override int WriteTimeout {
1151                 get {
1152                     return _stream.WriteTimeout;
1153                 }
1154                 set {
1155                     _stream.WriteTimeout = value;
1156                 }
1157             }
1158
1159             // In the off chance that some wrapped stream has different 
1160             // semantics for Close vs. Dispose, let's preserve that.
1161             public override void Close()
1162             {
1163                 lock(_stream) {
1164                     try {
1165                         _stream.Close();
1166                     }
1167                     finally {
1168                         base.Dispose(true);
1169                     }
1170                 }
1171             }
1172         
1173             protected override void Dispose(bool disposing)
1174             {
1175                 lock(_stream) {
1176                     try {
1177                         // Explicitly pick up a potentially methodimpl'ed Dispose
1178                         if (disposing)
1179                             ((IDisposable)_stream).Dispose();
1180                     }
1181                     finally {
1182                         base.Dispose(disposing);
1183                     }
1184                 }
1185             }
1186         
1187             public override void Flush()
1188             {
1189                 lock(_stream)
1190                     _stream.Flush();
1191             }
1192         
1193             public override int Read([In, Out]byte[] bytes, int offset, int count)
1194             {
1195                 lock(_stream)
1196                     return _stream.Read(bytes, offset, count);
1197             }
1198         
1199             public override int ReadByte()
1200             {
1201                 lock(_stream)
1202                     return _stream.ReadByte();
1203             }
1204
1205             private static bool OverridesBeginMethod(Stream stream, string methodName)
1206             {
1207                 Contract.Requires(stream != null, "Expected a non-null stream.");
1208                 Contract.Requires(methodName == "BeginRead" || methodName == "BeginWrite",
1209                     "Expected BeginRead or BeginWrite as the method name to check.");
1210
1211                 // Get all of the methods on the underlying stream
1212                 var methods = stream.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance);
1213
1214                 // If any of the methods have the desired name and are defined on the base Stream
1215                 // Type, then the method was not overridden.  If none of them were defined on the
1216                 // base Stream, then it must have been overridden.
1217                 foreach (var method in methods)
1218                 {
1219                     if (method.DeclaringType == typeof(Stream) &&
1220                         method.Name == methodName)
1221                     {
1222                         return false;
1223                     }
1224                 }
1225                 return true;
1226             }
1227         
1228             [HostProtection(ExternalThreading=true)]
1229             public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
1230             {
1231                 // Lazily-initialize whether the wrapped stream overrides BeginRead
1232                 if (_overridesBeginRead == null)
1233                 {
1234                     _overridesBeginRead = OverridesBeginMethod(_stream, "BeginRead");
1235                 }
1236
1237                 lock (_stream)
1238                 {
1239                     // If the Stream does have its own BeginRead implementation, then we must use that override.
1240                     // If it doesn't, then we'll use the base implementation, but we'll make sure that the logic
1241                     // which ensures only one asynchronous operation does so with an asynchronous wait rather
1242                     // than a synchronous wait.  A synchronous wait will result in a deadlock condition, because
1243                     // the EndXx method for the outstanding async operation won't be able to acquire the lock on
1244                     // _stream due to this call blocked while holding the lock.
1245                     return _overridesBeginRead.Value ?
1246                         _stream.BeginRead(buffer, offset, count, callback, state) :
1247                         _stream.BeginReadInternal(buffer, offset, count, callback, state, serializeAsynchronously: true);
1248                 }
1249             }
1250         
1251             public override int EndRead(IAsyncResult asyncResult)
1252             {
1253                 if (asyncResult == null)
1254                     throw new ArgumentNullException("asyncResult");
1255                 Contract.Ensures(Contract.Result<int>() >= 0);
1256                 Contract.EndContractBlock();
1257
1258                 lock(_stream)
1259                     return _stream.EndRead(asyncResult);
1260             }
1261         
1262             public override long Seek(long offset, SeekOrigin origin)
1263             {
1264                 lock(_stream)
1265                     return _stream.Seek(offset, origin);
1266             }
1267         
1268             public override void SetLength(long length)
1269             {
1270                 lock(_stream)
1271                     _stream.SetLength(length);
1272             }
1273         
1274             public override void Write(byte[] bytes, int offset, int count)
1275             {
1276                 lock(_stream)
1277                     _stream.Write(bytes, offset, count);
1278             }
1279         
1280             public override void WriteByte(byte b)
1281             {
1282                 lock(_stream)
1283                     _stream.WriteByte(b);
1284             }
1285         
1286             [HostProtection(ExternalThreading=true)]
1287             public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, Object state)
1288             {
1289                 // Lazily-initialize whether the wrapped stream overrides BeginWrite
1290                 if (_overridesBeginWrite == null)
1291                 {
1292                     _overridesBeginWrite = OverridesBeginMethod(_stream, "BeginWrite");
1293                 }
1294
1295                 lock (_stream)
1296                 {
1297                     // If the Stream does have its own BeginWrite implementation, then we must use that override.
1298                     // If it doesn't, then we'll use the base implementation, but we'll make sure that the logic
1299                     // which ensures only one asynchronous operation does so with an asynchronous wait rather
1300                     // than a synchronous wait.  A synchronous wait will result in a deadlock condition, because
1301                     // the EndXx method for the outstanding async operation won't be able to acquire the lock on
1302                     // _stream due to this call blocked while holding the lock.
1303                     return _overridesBeginWrite.Value ?
1304                         _stream.BeginWrite(buffer, offset, count, callback, state) :
1305                         _stream.BeginWriteInternal(buffer, offset, count, callback, state, serializeAsynchronously: true);
1306                 }
1307             }
1308             
1309             public override void EndWrite(IAsyncResult asyncResult)
1310             {
1311                 if (asyncResult == null)
1312                     throw new ArgumentNullException("asyncResult");
1313                 Contract.EndContractBlock();
1314
1315                 lock(_stream)
1316                     _stream.EndWrite(asyncResult);
1317             }
1318         }
1319     }
1320
1321 #if CONTRACTS_FULL
1322     [ContractClassFor(typeof(Stream))]
1323     internal abstract class StreamContract : Stream
1324     {
1325         public override long Seek(long offset, SeekOrigin origin)
1326         {
1327             Contract.Ensures(Contract.Result<long>() >= 0);
1328             throw new NotImplementedException();
1329         }
1330
1331         public override void SetLength(long value)
1332         {
1333             throw new NotImplementedException();
1334         }
1335
1336         public override int Read(byte[] buffer, int offset, int count)
1337         {
1338             Contract.Ensures(Contract.Result<int>() >= 0);
1339             Contract.Ensures(Contract.Result<int>() <= count);
1340             throw new NotImplementedException();
1341         }
1342
1343         public override void Write(byte[] buffer, int offset, int count)
1344         {
1345             throw new NotImplementedException();
1346         }
1347
1348         public override long Position {
1349             get {
1350                 Contract.Ensures(Contract.Result<long>() >= 0);
1351                 throw new NotImplementedException();
1352             }
1353             set {
1354                 throw new NotImplementedException();
1355             }
1356         }
1357
1358         public override void Flush()
1359         {
1360             throw new NotImplementedException();
1361         }
1362
1363         public override bool CanRead {
1364             get { throw new NotImplementedException(); }
1365         }
1366
1367         public override bool CanWrite {
1368             get { throw new NotImplementedException(); }
1369         }
1370
1371         public override bool CanSeek {
1372             get { throw new NotImplementedException(); }
1373         }
1374
1375         public override long Length
1376         {
1377             get {
1378                 Contract.Ensures(Contract.Result<long>() >= 0);
1379                 throw new NotImplementedException();
1380             }
1381         }
1382     }
1383 #endif  // CONTRACTS_FULL
1384 }