// Authors: Marcin Szczepanski (marcins@zipworld.com.au)
// Patrik Torstensson
// Gonzalo Paniagua Javier (gonzalo@ximian.com)
+// Marek Safar (marek.safar@gmail.com)
//
// (c) 2001,2002 Marcin Szczepanski, Patrik Torstensson
// (c) 2003 Ximian, Inc. (http://www.ximian.com)
-// Copyright (C) 2004 Novell (http://www.novell.com)
-//
-
-//
// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+// Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
using System.Globalization;
using System.Runtime.InteropServices;
+using System.Threading;
+#if NET_4_5
+using System.Threading.Tasks;
+#endif
namespace System.IO
{
bool streamClosed;
int position;
int dirty_bytes;
+#if NET_4_5
+ [NonSerialized]
+ Task<int> read_task;
+#endif
public MemoryStream () : this (0)
{
set {
CheckIfClosedThrowDisposed ();
- if (value == capacity)
- return; // LAMENESS: see MemoryStreamTest.ConstructorFive
if (!expandable)
throw new NotSupportedException ("Cannot expand this MemoryStream");
public override int Read ([In,Out] byte [] buffer, int offset, int count)
{
- CheckIfClosedThrowDisposed ();
-
if (buffer == null)
throw new ArgumentNullException ("buffer");
throw new ArgumentException ("offset+count",
"The size of the buffer is less than offset + count.");
+ CheckIfClosedThrowDisposed ();
+
if (position >= length || count == 0)
return 0;
public override void Write (byte [] buffer, int offset, int count)
{
- CheckIfClosedThrowDisposed ();
-
- if (!canWrite)
- throw new NotSupportedException ("Cannot write to this stream.");
-
if (buffer == null)
throw new ArgumentNullException ("buffer");
throw new ArgumentException ("offset+count",
"The size of the buffer is less than offset + count.");
+ CheckIfClosedThrowDisposed ();
+
+ if (!CanWrite)
+ throw new NotSupportedException ("Cannot write to this stream.");
+
// reordered to avoid possible integer overflow
if (position > length - count)
Expand (position + count);
stream.Write (internalBuffer, initialIndex, length - initialIndex);
}
-#if NET_4_0
- protected override void ObjectInvariant ()
+#if NET_4_5
+
+ public override Task CopyToAsync (Stream destination, int bufferSize, CancellationToken cancellationToken)
+ {
+ // TODO: Specialization but what for?
+ return base.CopyToAsync (destination, bufferSize, cancellationToken);
+ }
+
+ public override Task FlushAsync (CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ return TaskConstants.Canceled;
+
+ try {
+ Flush ();
+ return TaskConstants.Finished;
+ } catch (Exception ex) {
+ return Task<object>.FromException (ex);
+ }
+ }
+
+ public override Task<int> ReadAsync (byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
+ if (buffer == null)
+ throw new ArgumentNullException ("buffer");
+
+ if (offset < 0 || count < 0)
+ throw new ArgumentOutOfRangeException ("offset or count less than zero.");
+
+ if (buffer.Length - offset < count )
+ throw new ArgumentException ("offset+count",
+ "The size of the buffer is less than offset + count.");
+ if (cancellationToken.IsCancellationRequested)
+ return TaskConstants<int>.Canceled;
+
+ try {
+ count = Read (buffer, offset, count);
+
+ // Try not to allocate a new task for every buffer read
+ if (read_task == null || read_task.Result != count)
+ read_task = Task<int>.FromResult (count);
+
+ return read_task;
+ } catch (Exception ex) {
+ return Task<int>.FromException (ex);
+ }
+ }
+
+ public override Task WriteAsync (byte[] buffer, int offset, int count, CancellationToken cancellationToken)
+ {
+ if (buffer == null)
+ throw new ArgumentNullException ("buffer");
+
+ if (offset < 0 || count < 0)
+ throw new ArgumentOutOfRangeException ();
+
+ if (buffer.Length - offset < count)
+ throw new ArgumentException ("offset+count",
+ "The size of the buffer is less than offset + count.");
+
+ if (cancellationToken.IsCancellationRequested)
+ return TaskConstants.Canceled;
+
+ try {
+ Write (buffer, offset, count);
+ return TaskConstants.Finished;
+ } catch (Exception ex) {
+ return Task<object>.FromException (ex);
+ }
}
#endif
}