dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Dotgnu-pnet-commits] CVS: pnetlib/runtime/System/IO FileStream.cs,1.10


From: Rhys Weatherley <address@hidden>
Subject: [Dotgnu-pnet-commits] CVS: pnetlib/runtime/System/IO FileStream.cs,1.10,1.11 Stream.cs,1.5,1.6
Date: Tue, 01 Apr 2003 18:56:53 -0500

Update of /cvsroot/dotgnu-pnet/pnetlib/runtime/System/IO
In directory subversions:/tmp/cvs-serv13519/runtime/System/IO

Modified Files:
        FileStream.cs Stream.cs 
Log Message:


Implement asynchronous methods for "Stream" and "FileStream";
protect "FileStream" operations with a lock to prevent invalid
states in threaded applications.


Index: FileStream.cs
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnetlib/runtime/System/IO/FileStream.cs,v
retrieving revision 1.10
retrieving revision 1.11
diff -C2 -r1.10 -r1.11
*** FileStream.cs       22 Nov 2002 15:37:32 -0000      1.10
--- FileStream.cs       1 Apr 2003 23:56:51 -0000       1.11
***************
*** 151,155 ****
                                this.access = access;
                                this.ownsHandle = true;
!                               this.isAsync = (useAsync && 
FileMethods.HasAsync());
                                this.bufferSize = bufferSize;
                                this.buffer = new byte [bufferSize];
--- 151,155 ----
                                this.access = access;
                                this.ownsHandle = true;
!                               this.isAsync = useAsync;
                                this.bufferSize = bufferSize;
                                this.buffer = new byte [bufferSize];
***************
*** 209,213 ****
                                this.access = access;
                                this.ownsHandle = ownsHandle;
!                               this.isAsync = (isAsync && 
FileMethods.HasAsync());
                                this.bufferSize = bufferSize;
                                this.buffer = new byte [bufferSize];
--- 209,213 ----
                                this.access = access;
                                this.ownsHandle = ownsHandle;
!                               this.isAsync = isAsync;
                                this.bufferSize = bufferSize;
                                this.buffer = new byte [bufferSize];
***************
*** 236,274 ****
                        }
  
!       // Begin an asynchronous read operation.
!       [TODO]
        public override IAsyncResult BeginRead
                                (byte[] buffer, int offset, int count,
                                 AsyncCallback callback, Object state)
                        {
!                               ValidateBuffer(buffer, offset, count);
!                               // TODO
!                               return null;
                        }
- 
-       // Wait for an asynchronous read operation to end.
-       [TODO]
        public override int EndRead(IAsyncResult asyncResult)
                        {
!                               // TODO
!                               return 0;
                        }
- 
-       // Begin an asychronous write operation.
-       [TODO]
        public override IAsyncResult BeginWrite
                                (byte[] buffer, int offset, int count,
                                 AsyncCallback callback, Object state)
                        {
!                               ValidateBuffer(buffer, offset, count);
!                               // TODO
!                               return null;
                        }
- 
-       // Wait for an asynchronous write operation to end.
-       [TODO]
        public override void EndWrite(IAsyncResult asyncResult)
                        {
!                               // TODO
                        }
  
--- 236,259 ----
                        }
  
!       // Asynchronous operations - let the base class do the work.
        public override IAsyncResult BeginRead
                                (byte[] buffer, int offset, int count,
                                 AsyncCallback callback, Object state)
                        {
!                               return base.BeginRead(buffer, offset, count, 
callback, state);
                        }
        public override int EndRead(IAsyncResult asyncResult)
                        {
!                               return base.EndRead(asyncResult);
                        }
        public override IAsyncResult BeginWrite
                                (byte[] buffer, int offset, int count,
                                 AsyncCallback callback, Object state)
                        {
!                               return base.BeginWrite(buffer, offset, count, 
callback, state);
                        }
        public override void EndWrite(IAsyncResult asyncResult)
                        {
!                               base.EndWrite(asyncResult);
                        }
  
***************
*** 368,379 ****
  #endif        // !ECMA_COMPAT
  
-       // Create a wait handle for asynchronous operations.
-       [TODO]
-       protected override WaitHandle CreateWaitHandle()
-                       {
-                               // TODO
-                               return null;
-                       }
- 
  #if !ECMA_COMPAT
        // Dispose of this stream.
--- 353,356 ----
***************
*** 401,424 ****
        public override void Flush()
                        {
!                               if(handle != invalidHandle)
                                {
!                                       if(bufferOwnedByWrite)
                                        {
!                                               FlushWriteBuffer();
!                                               
if(!FileMethods.FlushWrite(handle))
                                                {
!                                                       throw new IOException
!                                                               
(FileMethods.GetErrno(), _("IO_FlushFailed"));
                                                }
                                        }
                                        else
                                        {
!                                               FlushReadBuffer();
                                        }
                                }
-                               else
-                               {
-                                       throw new 
ObjectDisposedException(_("IO_StreamClosed"));
-                               }
                        }
  
--- 378,406 ----
        public override void Flush()
                        {
!                               lock(this)
                                {
!                                       if(handle != invalidHandle)
                                        {
!                                               if(bufferOwnedByWrite)
                                                {
!                                                       FlushWriteBuffer();
!                                                       
if(!FileMethods.FlushWrite(handle))
!                                                       {
!                                                               throw new 
IOException
!                                                                       
(FileMethods.GetErrno(),
!                                                                       
_("IO_FlushFailed"));
!                                                       }
!                                               }
!                                               else
!                                               {
!                                                       FlushReadBuffer();
                                                }
                                        }
                                        else
                                        {
!                                               throw new 
ObjectDisposedException
!                                                       (_("IO_StreamClosed"));
                                        }
                                }
                        }
  
***************
*** 431,478 ****
                                // Validate the parameters and setup the object 
for reading.
                                ValidateBuffer(buffer, offset, count);
-                               SetupRead();
  
!                               // Read data into the caller's buffer.
!                               while(count > 0)
                                {
!                                       // How much data do we have available 
in the buffer?
!                                       tempLen = bufferLen - bufferPosn;
!                                       if(tempLen <= 0)
!                                       {
!                                               bufferPosn = 0;
!                                               bufferLen = FileMethods.Read
!                                                       (handle, this.buffer, 
0, bufferSize);
!                                               if(bufferLen < 0)
!                                               {
!                                                       bufferLen = 0;
!                                                       throw new IOException
!                                                               
(FileMethods.GetErrno(), _("IO_ReadFailed"));
!                                               }
!                                               else if(bufferLen == 0)
!                                               {
!                                                       break;
!                                               }
!                                               else
!                                               {
!                                                       tempLen = bufferLen;
!                                               }
!                                       }
  
!                                       // Don't read more than the caller 
wants.
!                                       if(tempLen > count)
                                        {
!                                               tempLen = count;
                                        }
- 
-                                       // Copy stream data to the caller's 
buffer.
-                                       Array.Copy(this.buffer, bufferPosn,
-                                                          buffer, offset, 
tempLen);
- 
-                                       // Advance to the next buffer positions.
-                                       readLen += tempLen;
-                                       offset += tempLen;
-                                       count -= tempLen;
-                                       bufferPosn += tempLen;
-                                       position += tempLen;
                                }
  
--- 413,467 ----
                                // Validate the parameters and setup the object 
for reading.
                                ValidateBuffer(buffer, offset, count);
  
!                               // Lock down the file stream while we do this.
!                               lock(this)
                                {
!                                       // Set up for the read operation.
!                                       SetupRead();
  
!                                       // Read data into the caller's buffer.
!                                       while(count > 0)
                                        {
!                                               // How much data do we have 
available in the buffer?
!                                               tempLen = bufferLen - 
bufferPosn;
!                                               if(tempLen <= 0)
!                                               {
!                                                       bufferPosn = 0;
!                                                       bufferLen = 
FileMethods.Read
!                                                               (handle, 
this.buffer, 0, bufferSize);
!                                                       if(bufferLen < 0)
!                                                       {
!                                                               bufferLen = 0;
!                                                               throw new 
IOException
!                                                                       
(FileMethods.GetErrno(),
!                                                                        
_("IO_ReadFailed"));
!                                                       }
!                                                       else if(bufferLen == 0)
!                                                       {
!                                                               break;
!                                                       }
!                                                       else
!                                                       {
!                                                               tempLen = 
bufferLen;
!                                                       }
!                                               }
! 
!                                               // Don't read more than the 
caller wants.
!                                               if(tempLen > count)
!                                               {
!                                                       tempLen = count;
!                                               }
! 
!                                               // Copy stream data to the 
caller's buffer.
!                                               Array.Copy(this.buffer, 
bufferPosn,
!                                                                  buffer, 
offset, tempLen);
! 
!                                               // Advance to the next buffer 
positions.
!                                               readLen += tempLen;
!                                               offset += tempLen;
!                                               count -= tempLen;
!                                               bufferPosn += tempLen;
!                                               position += tempLen;
                                        }
                                }
  
***************
*** 484,511 ****
        public override int ReadByte()
                        {
!                               // Setup the object for reading.
!                               SetupRead();
! 
!                               // Read more data into the internal buffer if 
necessary.
!                               if(bufferPosn >= bufferLen)
                                {
!                                       bufferPosn = 0;
!                                       bufferLen = FileMethods.Read(handle, 
buffer, 0, bufferSize);
!                                       if(bufferLen < 0)
!                                       {
!                                               bufferLen = 0;
!                                               throw new IOException
!                                                       
(FileMethods.GetErrno(), _("IO_ReadFailed"));
!                                       }
!                                       else if(bufferLen == 0)
                                        {
!                                               // We've reached EOF.
!                                               return -1;
                                        }
-                               }
  
!                               // Extract the next byte from the buffer.
!                               ++position;
!                               return buffer[bufferPosn++];
                        }
  
--- 473,505 ----
        public override int ReadByte()
                        {
!                               // Lock down the file stream while we do this.
!                               lock(this)
                                {
!                                       // Setup the object for reading.
!                                       SetupRead();
! 
!                                       // Read more data into the internal 
buffer if necessary.
!                                       if(bufferPosn >= bufferLen)
                                        {
!                                               bufferPosn = 0;
!                                               bufferLen = FileMethods.Read
!                                                       (handle, buffer, 0, 
bufferSize);
!                                               if(bufferLen < 0)
!                                               {
!                                                       bufferLen = 0;
!                                                       throw new IOException
!                                                               
(FileMethods.GetErrno(), _("IO_ReadFailed"));
!                                               }
!                                               else if(bufferLen == 0)
!                                               {
!                                                       // We've reached EOF.
!                                                       return -1;
!                                               }
                                        }
  
!                                       // Extract the next byte from the 
buffer.
!                                       ++position;
!                                       return buffer[bufferPosn++];
!                               }
                        }
  
***************
*** 521,592 ****
                                }
  
!                               // Bail out if the handle is invalid.
!                               if(handle == invalidHandle)
!                               {
!                                       throw new 
ObjectDisposedException(_("IO_StreamClosed"));
!                               }
! 
!                               // Don't do anything if the position won't be 
moving.
!                               if(origin == SeekOrigin.Begin && offset == 
position)
!                               {
!                                       return offset;
!                               }
!                               else if(origin == SeekOrigin.Current && offset 
== 0)
                                {
!                                       return position;
!                               }
  
!                               // The behaviour depends upon the read/write 
mode.
!                               if(bufferOwnedByWrite)
!                               {
!                                       // Flush the write buffer and then seek.
!                                       FlushWriteBuffer();
!                                       newPosn = FileMethods.Seek(handle, 
offset, origin);
!                                       if(newPosn == -1)
                                        {
!                                               throw new 
EndOfStreamException(_("IO_EndOfStream"));
                                        }
!                                       position = newPosn;
!                               }
!                               else
!                               {
!                                       // Determine if the seek is to 
somewhere inside
!                                       // the current read buffer bounds.
!                                       if(origin == SeekOrigin.Begin)
                                        {
!                                               newPosn = position - bufferPosn;
!                                               if(offset >= newPosn && offset 
< (newPosn + bufferLen))
!                                               {
!                                                       bufferPosn = 
(int)(offset - newPosn);
!                                                       position = newPosn;
!                                                       return position;
!                                               }
                                        }
!                                       else if(origin == SeekOrigin.Current)
                                        {
!                                               newPosn = position + offset;
!                                               if(newPosn >= (position - 
bufferPosn) &&
!                                                  newPosn < (position - 
bufferPosn + bufferLen))
                                                {
!                                                       bufferPosn =
!                                                               (int)(newPosn - 
(position - bufferPosn));
!                                                       position = newPosn;
!                                                       return position;
                                                }
                                        }
  
!                                       // Abandon the read buffer.
!                                       bufferPosn = 0;
!                                       bufferLen = 0;
  
!                                       // Seek to the new position.
!                                       newPosn = FileMethods.Seek(handle, 
offset, origin);
!                                       if(newPosn == -1)
!                                       {
!                                               throw new 
EndOfStreamException(_("IO_EndOfStream"));
                                        }
!                                       position = newPosn;
                                }
-                               return position;
                        }
  
--- 515,594 ----
                                }
  
!                               // Lock down the file stream while we do this.
!                               lock(this)
                                {
!                                       // Bail out if the handle is invalid.
!                                       if(handle == invalidHandle)
!                                       {
!                                               throw new 
ObjectDisposedException
!                                                       (_("IO_StreamClosed"));
!                                       }
  
!                                       // Don't do anything if the position 
won't be moving.
!                                       if(origin == SeekOrigin.Begin && offset 
== position)
                                        {
!                                               return offset;
                                        }
!                                       else if(origin == SeekOrigin.Current && 
offset == 0)
                                        {
!                                               return position;
                                        }
! 
!                                       // The behaviour depends upon the 
read/write mode.
!                                       if(bufferOwnedByWrite)
                                        {
!                                               // Flush the write buffer and 
then seek.
!                                               FlushWriteBuffer();
!                                               newPosn = 
FileMethods.Seek(handle, offset, origin);
!                                               if(newPosn == -1)
                                                {
!                                                       throw new 
EndOfStreamException
!                                                               
(_("IO_EndOfStream"));
                                                }
+                                               position = newPosn;
                                        }
+                                       else
+                                       {
+                                               // Determine if the seek is to 
somewhere inside
+                                               // the current read buffer 
bounds.
+                                               if(origin == SeekOrigin.Begin)
+                                               {
+                                                       newPosn = position - 
bufferPosn;
+                                                       if(offset >= newPosn && 
offset <
+                                                                       
(newPosn + bufferLen))
+                                                       {
+                                                               bufferPosn = 
(int)(offset - newPosn);
+                                                               position = 
newPosn;
+                                                               return position;
+                                                       }
+                                               }
+                                               else if(origin == 
SeekOrigin.Current)
+                                               {
+                                                       newPosn = position + 
offset;
+                                                       if(newPosn >= (position 
- bufferPosn) &&
+                                                          newPosn < (position 
- bufferPosn + bufferLen))
+                                                       {
+                                                               bufferPosn =
+                                                                       
(int)(newPosn - (position - bufferPosn));
+                                                               position = 
newPosn;
+                                                               return position;
+                                                       }
+                                               }
  
!                                               // Abandon the read buffer.
!                                               bufferPosn = 0;
!                                               bufferLen = 0;
  
!                                               // Seek to the new position.
!                                               newPosn = 
FileMethods.Seek(handle, offset, origin);
!                                               if(newPosn == -1)
!                                               {
!                                                       throw new 
EndOfStreamException
!                                                               
(_("IO_EndOfStream"));
!                                               }
!                                               position = newPosn;
                                        }
!                                       return position;
                                }
                        }
  
***************
*** 604,614 ****
                                        throw new 
NotSupportedException(_("IO_NotSupp_Seek"));
                                }
-                               SetupWrite();
  
!                               // Call the underlying platform's "SetLength" 
method.
!                               if(!FileMethods.SetLength(handle, value))
                                {
!                                       throw new IOException
!                                               (FileMethods.GetErrno(), 
_("IO_SetLengthFailed"));
                                }
                        }
--- 606,622 ----
                                        throw new 
NotSupportedException(_("IO_NotSupp_Seek"));
                                }
  
!                               // Lock down the file stream while we do this.
!                               lock(this)
                                {
!                                       // Setup this object for writing.
!                                       SetupWrite();
! 
!                                       // Call the underlying platform's 
"SetLength" method.
!                                       if(!FileMethods.SetLength(handle, 
value))
!                                       {
!                                               throw new IOException
!                                                       
(FileMethods.GetErrno(), _("IO_SetLengthFailed"));
!                                       }
                                }
                        }
***************
*** 621,682 ****
                                // Validate the parameters and setup the object 
for writing.
                                ValidateBuffer(buffer, offset, count);
-                               SetupWrite();
  
!                               // Write data to the file stream.
!                               while(count > 0)
                                {
!                                       // Determine how many bytes we can 
write to the buffer.
!                                       tempLen = bufferSize - bufferPosn;
!                                       if(tempLen <= 0)
                                        {
!                                               // Flush the current buffer 
contents.
!                                               if(!FileMethods.Write
!                                                               (handle, 
this.buffer, 0, bufferPosn))
                                                {
!                                                       throw new IOException
!                                                               
(FileMethods.GetErrno(), _("IO_WriteFailed"));
                                                }
!                                               bufferPosn = 0;
!                                               tempLen = bufferSize;
!                                       }
!                                       if(tempLen > count)
!                                       {
!                                               tempLen = count;
                                        }
  
!                                       // Can we short-cut the internal buffer?
!                                       if(bufferPosn == 0 && tempLen == 
bufferSize)
                                        {
!                                               // Yes: write the data directly 
to the platform file.
!                                               if(!FileMethods.Write(handle, 
buffer, offset, tempLen))
                                                {
                                                        throw new IOException
                                                                
(FileMethods.GetErrno(), _("IO_WriteFailed"));
                                                }
                                        }
-                                       else
-                                       {
-                                               // No: copy the data to the 
write buffer first.
-                                               Array.Copy(buffer, offset, 
this.buffer,
-                                                                  bufferPosn, 
tempLen);
-                                               bufferPosn += tempLen;
-                                       }
- 
-                                       // Advance the buffer and stream 
positions.
-                                       position += tempLen;
-                                       offset += tempLen;
-                                       count -= tempLen;
-                               }
- 
-                               // If the buffer is full, then do a speculative 
flush now,
-                               // rather than waiting for the next call to 
this method.
-                               if(bufferPosn >= bufferSize)
-                               {
-                                       if(!FileMethods.Write(handle, 
this.buffer, 0, bufferPosn))
-                                       {
-                                               throw new IOException
-                                                       
(FileMethods.GetErrno(), _("IO_WriteFailed"));
-                                       }
-                                       bufferPosn = 0;
                                }
                        }
--- 629,700 ----
                                // Validate the parameters and setup the object 
for writing.
                                ValidateBuffer(buffer, offset, count);
  
!                               // Lock down the file stream while we do this.
!                               lock(this)
                                {
!                                       // Setup this object for writing.
!                                       SetupWrite();
! 
!                                       // Write data to the file stream.
!                                       while(count > 0)
                                        {
!                                               // Determine how many bytes we 
can write to the buffer.
!                                               tempLen = bufferSize - 
bufferPosn;
!                                               if(tempLen <= 0)
!                                               {
!                                                       // Flush the current 
buffer contents.
!                                                       if(!FileMethods.Write
!                                                                       
(handle, this.buffer, 0, bufferPosn))
!                                                       {
!                                                               throw new 
IOException
!                                                                       
(FileMethods.GetErrno(),
!                                                                        
_("IO_WriteFailed"));
!                                                       }
!                                                       bufferPosn = 0;
!                                                       tempLen = bufferSize;
!                                               }
!                                               if(tempLen > count)
!                                               {
!                                                       tempLen = count;
!                                               }
! 
!                                               // Can we short-cut the 
internal buffer?
!                                               if(bufferPosn == 0 && tempLen 
== bufferSize)
!                                               {
!                                                       // Yes: write the data 
directly to the file.
!                                                       if(!FileMethods.Write
!                                                                       
(handle, buffer, offset, tempLen))
!                                                       {
!                                                               throw new 
IOException
!                                                                       
(FileMethods.GetErrno(),
!                                                                        
_("IO_WriteFailed"));
!                                                       }
!                                               }
!                                               else
                                                {
!                                                       // No: copy the data to 
the write buffer first.
!                                                       Array.Copy(buffer, 
offset, this.buffer,
!                                                                          
bufferPosn, tempLen);
!                                                       bufferPosn += tempLen;
                                                }
! 
!                                               // Advance the buffer and 
stream positions.
!                                               position += tempLen;
!                                               offset += tempLen;
!                                               count -= tempLen;
                                        }
  
!                                       // If the buffer is full, then do a 
speculative flush now,
!                                       // rather than waiting for the next 
call to this method.
!                                       if(bufferPosn >= bufferSize)
                                        {
!                                               if(!FileMethods.Write
!                                                       (handle, this.buffer, 
0, bufferPosn))
                                                {
                                                        throw new IOException
                                                                
(FileMethods.GetErrno(), _("IO_WriteFailed"));
                                                }
+                                               bufferPosn = 0;
                                        }
                                }
                        }
***************
*** 685,705 ****
        public override void WriteByte(byte value)
                        {
!                               // Setup the object for writing.
!                               SetupWrite();
! 
!                               // Flush the current buffer if it is full.
!                               if(bufferPosn >= bufferSize)
                                {
!                                       if(!FileMethods.Write(handle, 
this.buffer, 0, bufferPosn))
                                        {
!                                               throw new IOException
!                                                       
(FileMethods.GetErrno(), _("IO_WriteFailed"));
                                        }
-                                       bufferPosn = 0;
-                               }
  
!                               // Write the byte into the buffer and advance 
the file posn.
!                               buffer[bufferPosn++] = value;
!                               ++position;
                        }
  
--- 703,728 ----
        public override void WriteByte(byte value)
                        {
!                               // Lock down the file stream while we do this.
!                               lock(this)
                                {
!                                       // Setup the object for writing.
!                                       SetupWrite();
! 
!                                       // Flush the current buffer if it is 
full.
!                                       if(bufferPosn >= bufferSize)
                                        {
!                                               if(!FileMethods.Write
!                                                               (handle, 
this.buffer, 0, bufferPosn))
!                                               {
!                                                       throw new IOException
!                                                               
(FileMethods.GetErrno(), _("IO_WriteFailed"));
!                                               }
!                                               bufferPosn = 0;
                                        }
  
!                                       // Write the byte into the buffer and 
advance the posn.
!                                       buffer[bufferPosn++] = value;
!                                       ++position;
!                               }
                        }
  
***************
*** 741,782 ****
                                                throw new NotSupportedException 
(_("IO_NotSupp_Seek"));
                                        }
-                                       if(handle == invalidHandle)
-                                       {
-                                               // ECMA says this should be 
IOException even though
-                                               // everywhere else uses 
ObjectDisposedException.
-                                               throw new IOException
-                                                       
(FileMethods.GetErrno(), _("IO_StreamClosed"));
-                                       }
  
!                                       // Flush the write buffer, because it 
may
!                                       // affect the length of the stream.
!                                       if(bufferOwnedByWrite)
                                        {
!                                               FlushWriteBuffer();
!                                       }
  
!                                       // Seek to the end to get the stream 
length.
!                                       long posn = FileMethods.Seek(handle, 0, 
SeekOrigin.End);
  
!                                       // Seek back to where we used to be.
!                                       if(bufferOwnedByWrite)
!                                       {
!                                               FileMethods.Seek
!                                                       (handle, position - 
bufferPosn, SeekOrigin.Begin);
!                                       }
!                                       else
!                                       {
!                                               FileMethods.Seek
!                                                       (handle, position - 
bufferPosn + bufferLen,
!                                                        SeekOrigin.Begin);
!                                       }
  
!                                       // Decode the result.
!                                       if(posn == -1)
!                                       {
!                                               throw new IOException
!                                                       
(FileMethods.GetErrno(), _("IO_SeekFailed"));
                                        }
-                                       return posn;
                                }
                        }
--- 764,812 ----
                                                throw new NotSupportedException 
(_("IO_NotSupp_Seek"));
                                        }
  
!                                       // Lock down the file stream while we 
do this.
!                                       lock(this)
                                        {
!                                               if(handle == invalidHandle)
!                                               {
!                                                       // ECMA says this 
should be IOException even though
!                                                       // everywhere else uses 
ObjectDisposedException.
!                                                       throw new IOException
!                                                               
(FileMethods.GetErrno(), _("IO_StreamClosed"));
!                                               }
  
!                                               // Flush the write buffer, 
because it may
!                                               // affect the length of the 
stream.
!                                               if(bufferOwnedByWrite)
!                                               {
!                                                       FlushWriteBuffer();
!                                               }
  
!                                               // Seek to the end to get the 
stream length.
!                                               long posn = FileMethods.Seek
!                                                       (handle, 0, 
SeekOrigin.End);
  
!                                               // Seek back to where we used 
to be.
!                                               if(bufferOwnedByWrite)
!                                               {
!                                                       FileMethods.Seek
!                                                               (handle, 
position - bufferPosn,
!                                                                
SeekOrigin.Begin);
!                                               }
!                                               else
!                                               {
!                                                       FileMethods.Seek
!                                                               (handle, 
position - bufferPosn + bufferLen,
!                                                                
SeekOrigin.Begin);
!                                               }
!       
!                                               // Decode the result.
!                                               if(posn == -1)
!                                               {
!                                                       throw new IOException
!                                                               
(FileMethods.GetErrno(), _("IO_SeekFailed"));
!                                               }
!                                               return posn;
                                        }
                                }
                        }

Index: Stream.cs
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnetlib/runtime/System/IO/Stream.cs,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -r1.5 -r1.6
*** Stream.cs   20 Dec 2001 10:11:39 -0000      1.5
--- Stream.cs   1 Apr 2003 23:56:51 -0000       1.6
***************
*** 43,81 ****
                        }
  
        // Begin an asynchronous read operation.
-       [TODO]
        public virtual IAsyncResult BeginRead
                                (byte[] buffer, int offset, int count,
                                 AsyncCallback callback, Object state)
                        {
                                ValidateBuffer(buffer, offset, count);
!                               // TODO
!                               return null;
                        }
  
        // Wait for an asynchronous read operation to end.
-       [TODO]
        public virtual int EndRead(IAsyncResult asyncResult)
                        {
!                               // TODO
!                               return 0;
                        }
  
        // Begin an asychronous write operation.
-       [TODO]
        public virtual IAsyncResult BeginWrite
                                (byte[] buffer, int offset, int count,
                                 AsyncCallback callback, Object state)
                        {
                                ValidateBuffer(buffer, offset, count);
!                               // TODO
!                               return null;
                        }
  
        // Wait for an asynchronous write operation to end.
-       [TODO]
        public virtual void EndWrite(IAsyncResult asyncResult)
                        {
!                               // TODO
                        }
  
--- 43,281 ----
                        }
  
+       // Asynchronous read/write control class.
+       private sealed class AsyncControl : IAsyncResult
+       {
+               // Internal state.
+               private ManualResetEvent waitHandle;
+               private bool completedSynchronously;
+               private bool completed;
+               private bool reading;
+               private AsyncCallback callback;
+               private Object state;
+               private Stream stream;
+               private byte[] buffer;
+               private int offset;
+               private int count;
+               private int result;
+               private Exception exception;
+ 
+               // Constructor.
+               public AsyncControl(AsyncCallback callback, Object state,
+                                                       Stream stream, byte[] 
buffer, int offset,
+                                                       int count, bool reading)
+                               {
+                                       this.waitHandle = new 
ManualResetEvent(false);
+                                       this.completedSynchronously = false;
+                                       this.completed = false;
+                                       this.reading = reading;
+                                       this.callback = callback;
+                                       this.state = state;
+                                       this.stream = stream;
+                                       this.buffer = buffer;
+                                       this.offset = offset;
+                                       this.count = count;
+                                       this.result = -1;
+                                       this.exception = null;
+                               }
+ 
+               // Run the operation thread.
+               private void Run()
+                               {
+                                       try
+                                       {
+                                               if(reading)
+                                               {
+                                                       result = 
stream.Read(buffer, offset, count);
+                                               }
+                                               else
+                                               {
+                                                       stream.Write(buffer, 
offset, count);
+                                               }
+                                       }
+                                       catch(Exception e)
+                                       {
+                                               // Save the exception to be 
thrown in EndRead/EndWrite.
+                                               exception = e;
+                                       }
+                                       completed = true;
+                                       if(callback != null)
+                                       {
+                                               callback(this);
+                                       }
+                                       waitHandle.Set();
+                               }
+ 
+               // Start the async thread, or perform the operation 
synchronously.
+               public void Start()
+                               {
+                                       if(Thread.CanStartThreads())
+                                       {
+                                               Thread thread = new Thread(new 
ThreadStart(Run));
+                                               thread.IsBackground = true;
+                                               thread.Start();
+                                       }
+                                       else
+                                       {
+                                               completedSynchronously = true;
+                                               Run();
+                                       }
+                               }
+ 
+               // End an asynchronous read operation.
+               public int EndRead(Stream check)
+                               {
+                                       if(stream != check || !reading)
+                                       {
+                                               throw new 
ArgumentException(_("Arg_InvalidAsync"));
+                                       }
+                                       WaitHandle handle = waitHandle;
+                                       if(handle != null)
+                                       {
+                                               if(!completed)
+                                               {
+                                                       handle.WaitOne();
+                                               }
+                                               ((IDisposable)handle).Dispose();
+                                       }
+                                       waitHandle = null;
+                                       if(exception != null)
+                                       {
+                                               throw exception;
+                                       }
+                                       else
+                                       {
+                                               return result;
+                                       }
+                               }
+ 
+               // End an asynchronous write operation.
+               public void EndWrite(Stream check)
+                               {
+                                       if(stream != check || reading)
+                                       {
+                                               throw new 
ArgumentException(_("Arg_InvalidAsync"));
+                                       }
+                                       WaitHandle handle = waitHandle;
+                                       if(handle != null)
+                                       {
+                                               if(!completed)
+                                               {
+                                                       handle.WaitOne();
+                                               }
+                                               ((IDisposable)handle).Dispose();
+                                       }
+                                       waitHandle = null;
+                                       if(exception != null)
+                                       {
+                                               throw exception;
+                                       }
+                               }
+ 
+               // Implement the IAsyncResult interface.
+               public Object AsyncState
+                               {
+                                       get
+                                       {
+                                               return state;
+                                       }
+                               }
+               public WaitHandle AsyncWaitHandle
+                               {
+                                       get
+                                       {
+                                               return waitHandle;
+                                       }
+                               }
+               public bool CompletedSynchronously
+                               {
+                                       get
+                                       {
+                                               return completedSynchronously;
+                                       }
+                               }
+               public bool IsCompleted
+                               {
+                                       get
+                                       {
+                                               return completed;
+                                       }
+                               }
+ 
+       }; // class AsyncControl
+ 
        // Begin an asynchronous read operation.
        public virtual IAsyncResult BeginRead
                                (byte[] buffer, int offset, int count,
                                 AsyncCallback callback, Object state)
                        {
+                               // Validate the parameters and the stream.
                                ValidateBuffer(buffer, offset, count);
!                               if(!CanRead)
!                               {
!                                       throw new 
NotSupportedException(_("IO_NotSupp_Read"));
!                               }
! 
!                               // Create the result object.
!                               AsyncControl async = new AsyncControl
!                                       (callback, state, this, buffer, offset, 
count, true);
! 
!                               // Start the background read.
!                               async.Start();
!                               return async;
                        }
  
        // Wait for an asynchronous read operation to end.
        public virtual int EndRead(IAsyncResult asyncResult)
                        {
!                               if(asyncResult == null)
!                               {
!                                       throw new 
ArgumentNullException("asyncResult");
!                               }
!                               else if(!(asyncResult is AsyncControl))
!                               {
!                                       throw new 
ArgumentException(_("Arg_InvalidAsync"));
!                               }
!                               else
!                               {
!                                       return 
((AsyncControl)asyncResult).EndRead(this);
!                               }
                        }
  
        // Begin an asychronous write operation.
        public virtual IAsyncResult BeginWrite
                                (byte[] buffer, int offset, int count,
                                 AsyncCallback callback, Object state)
                        {
+                               // Validate the parameters and the stream.
                                ValidateBuffer(buffer, offset, count);
!                               if(!CanWrite)
!                               {
!                                       throw new 
NotSupportedException(_("IO_NotSupp_Write"));
!                               }
! 
!                               // Create the result object.
!                               AsyncControl async = new AsyncControl
!                                       (callback, state, this, buffer, offset, 
count, false);
! 
!                               // Start the background write.
!                               async.Start();
!                               return async;
                        }
  
        // Wait for an asynchronous write operation to end.
        public virtual void EndWrite(IAsyncResult asyncResult)
                        {
!                               if(asyncResult == null)
!                               {
!                                       throw new 
ArgumentNullException("asyncResult");
!                               }
!                               else if(!(asyncResult is AsyncControl))
!                               {
!                                       throw new 
ArgumentException(_("Arg_InvalidAsync"));
!                               }
!                               else
!                               {
!                                       
((AsyncControl)asyncResult).EndWrite(this);
!                               }
                        }
  
***************
*** 89,97 ****
  
        // Create a wait handle for asynchronous operations.
-       [TODO]
        protected virtual WaitHandle CreateWaitHandle()
                        {
!                               // TODO
!                               return null;
                        }
  
--- 289,295 ----
  
        // Create a wait handle for asynchronous operations.
        protected virtual WaitHandle CreateWaitHandle()
                        {
!                               return new ManualResetEvent(false);
                        }
  





reply via email to

[Prev in Thread] Current Thread [Next in Thread]