// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-using System;
using System.Collections;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Messaging;
+using System.Security.Permissions;
using System.Threading;
#if NET_2_0
public FileStream (IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize, bool isAsync)
: this (handle, access, ownsHandle, bufferSize, isAsync, false) {}
+ [SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
internal FileStream (IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize, bool isAsync, bool noBuffering)
{
this.handle = MonoIO.InvalidHandle;
this.canseek = true;
} else {
this.canseek = false;
+ noBuffering = true;
+ bufferSize = 0;
}
this.handle = handle;
this.async = isAsync;
this.anonymous = false;
- if (isAsync && MonoIO.SupportsAsync)
- ThreadPool.BindHandle (handle);
-
InitBuffer (bufferSize, noBuffering);
/* Can't set append mode */
MonoIOError error;
- bool openAsync = (isAsync && MonoIO.SupportsAsync);
- this.handle = MonoIO.Open (name, mode, access, share, openAsync, out error);
+ this.handle = MonoIO.Open (name, mode, access, share, false, out error);
if (handle == MonoIO.InvalidHandle) {
// don't leak the path information for isolated storage
string fname = (anonymous) ? Path.GetFileName (name) : name;
if (MonoIO.GetFileType (handle, out error) == MonoFileType.Disk) {
this.canseek = true;
this.async = isAsync;
- if (openAsync)
- ThreadPool.BindHandle (handle);
} else {
this.canseek = false;
this.async = false;
if (handle == MonoIO.InvalidHandle)
throw new ObjectDisposedException ("Stream has been closed");
- if (!canseek)
+ if (!CanSeek)
throw new NotSupportedException ("The stream does not support seeking");
// Buffered data might change the length of the stream
}
public virtual IntPtr Handle {
+ [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
+ [SecurityPermission (SecurityAction.InheritanceDemand, UnmanagedCode = true)]
get {
return handle;
}
#if NET_2_0
public virtual SafeFileHandle SafeFileHandle {
+ [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
+ [SecurityPermission (SecurityAction.InheritanceDemand, UnmanagedCode = true)]
get { throw new NotImplementedException (); }
}
#endif
if (buf_offset == buf_size)
FlushBuffer ();
+ if (buf_size == 0) { // No buffering
+ buf [0] = value;
+ buf_dirty = true;
+ buf_length = 1;
+ FlushBuffer ();
+ return;
+ }
+
buf [buf_offset ++] = value;
if (buf_offset > buf_length)
buf_length = buf_offset;
if (!async)
return base.BeginRead (buffer, offset, count, cback, state);
- if (!MonoIO.SupportsAsync) {
- ReadDelegate r = new ReadDelegate (ReadInternal);
- return r.BeginInvoke (buffer, offset, count, cback, state);
- }
-
- FileStreamAsyncResult result = new FileStreamAsyncResult (cback, state);
- result.Count = count;
- result.OriginalCount = count;
- int buffered = ReadSegment (buffer, offset, count);
- if (buffered >= count) {
- result.SetComplete (null, buffered, true);
- return result;
- }
-
- result.Buffer = buffer;
- result.Offset = offset + buffered;
- result.Count -= buffered;
-
- KeepReference (result);
- MonoIO.BeginRead (handle, result);
-
- return result;
+ ReadDelegate r = new ReadDelegate (ReadInternal);
+ return r.BeginInvoke (buffer, offset, count, cback, state);
}
public override int EndRead (IAsyncResult async_result)
if (!async)
return base.EndRead (async_result);
- if (!MonoIO.SupportsAsync) {
- AsyncResult ares = async_result as AsyncResult;
- if (ares == null)
- throw new ArgumentException ("Invalid IAsyncResult", "async_result");
-
- ReadDelegate r = ares.AsyncDelegate as ReadDelegate;
- if (r == null)
- throw new ArgumentException ("Invalid IAsyncResult", "async_result");
-
- return r.EndInvoke (async_result);
- }
-
- FileStreamAsyncResult result = async_result as FileStreamAsyncResult;
- if (result == null || result.BytesRead == -1)
+ AsyncResult ares = async_result as AsyncResult;
+ if (ares == null)
throw new ArgumentException ("Invalid IAsyncResult", "async_result");
- RemoveReference (result);
- if (result.Done)
- throw new InvalidOperationException ("EndRead already called.");
-
- result.Done = true;
- if (!result.IsCompleted)
- result.AsyncWaitHandle.WaitOne ();
-
- if (result.Exception != null)
- throw result.Exception;
+ ReadDelegate r = ares.AsyncDelegate as ReadDelegate;
+ if (r == null)
+ throw new ArgumentException ("Invalid IAsyncResult", "async_result");
- buf_start += result.BytesRead;
- return result.OriginalCount - result.Count + result.BytesRead;
+ return r.EndInvoke (async_result);
}
public override void Write (byte[] src, int src_offset, int count)
if (!async)
return base.BeginWrite (buffer, offset, count, cback, state);
- byte [] bytes;
- int buffered = 0;
FileStreamAsyncResult result = new FileStreamAsyncResult (cback, state);
result.BytesRead = -1;
result.Count = count;
if (buf_dirty) {
MemoryStream ms = new MemoryStream ();
FlushBufferToStream (ms);
- buffered = (int) ms.Length;
ms.Write (buffer, offset, count);
- bytes = ms.GetBuffer ();
offset = 0;
count = (int) ms.Length;
- } else {
- bytes = buffer;
- }
-
- if (!MonoIO.SupportsAsync) {
- WriteDelegate w = new WriteDelegate (WriteInternal);
- return w.BeginInvoke (buffer, offset, count, cback, state);
}
- if (buffered >= count) {
- result.SetComplete (null, buffered, true);
- return result;
- }
-
- result.Buffer = buffer;
- result.Offset = offset;
- result.Count = count;
-
- KeepReference (result);
- MonoIO.BeginWrite (handle, result);
-
- return result;
+ WriteDelegate w = new WriteDelegate (WriteInternal);
+ return w.BeginInvoke (buffer, offset, count, cback, state);
}
public override void EndWrite (IAsyncResult async_result)
return;
}
- if (!MonoIO.SupportsAsync) {
- AsyncResult ares = async_result as AsyncResult;
- if (ares == null)
- throw new ArgumentException ("Invalid IAsyncResult", "async_result");
-
- WriteDelegate w = ares.AsyncDelegate as WriteDelegate;
- if (w == null)
- throw new ArgumentException ("Invalid IAsyncResult", "async_result");
-
- w.EndInvoke (async_result);
- return;
- }
-
- FileStreamAsyncResult result = async_result as FileStreamAsyncResult;
- if (result == null || result.BytesRead != -1)
+ AsyncResult ares = async_result as AsyncResult;
+ if (ares == null)
throw new ArgumentException ("Invalid IAsyncResult", "async_result");
- RemoveReference (result);
- if (result.Done)
- throw new InvalidOperationException ("EndWrite already called.");
-
- result.Done = true;
- if (!result.IsCompleted)
- result.AsyncWaitHandle.WaitOne ();
-
- if (result.Exception != null)
- throw result.Exception;
+ WriteDelegate w = ares.AsyncDelegate as WriteDelegate;
+ if (w == null)
+ throw new ArgumentException ("Invalid IAsyncResult", "async_result");
- buf_start += result.Count;
- buf_offset = buf_length = 0;
+ w.EndInvoke (async_result);
+ return;
}
public override long Seek (long offset, SeekOrigin origin)
buf_dirty = false;
}
- static void KeepReference (object o)
- {
- lock (typeof (FileStream)) {
- if (asyncObjects == null)
- asyncObjects = new Hashtable ();
-
- asyncObjects [o] = o;
- }
- }
-
- static void RemoveReference (object o)
- {
- lock (typeof (FileStream)) {
- if (asyncObjects == null)
- return;
-
- asyncObjects.Remove (o);
- }
- }
-
// fields
internal const int DefaultBufferSize = 8192;
- private static Hashtable asyncObjects;
private FileAccess access;
private bool owner;