예제 #1
0
        public override IAsyncResult BeginWrite(byte[] array, int offset, int numBytes, AsyncCallback userCallback, Object stateObject)
        {
            if (array == null)
            {
                throw new ArgumentNullException("array");
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset", Helper.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            }
            if (numBytes < 0)
            {
                throw new ArgumentOutOfRangeException("numBytes", Helper.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            }
            if (array.Length - offset < numBytes)
            {
                throw new ArgumentException(Helper.GetResourceString("Argument_InvalidOffLen"));
            }

            if (!CanWrite)
            {
                __Error.WriteNotSupported();
            }

            Debug.Assert((_readPos == 0 && _readLen == 0 && _writePos >= 0) || (_writePos == 0 && _readPos <= _readLen), "We're either reading or writing, but not both.");

            if (_writePos == 0)
            {
                if (_readPos < _readLen)
                {
                    FlushRead();
                }
                _readPos = 0;
                _readLen = 0;
            }

            int n = bufferSize - _writePos;

            if (numBytes <= n)
            {
                if (_buffer == null)
                {
                    _buffer = new byte[bufferSize];
                }
                Buffer.BlockCopy(array, offset, _buffer, _writePos, numBytes);
                _writePos += numBytes;

                return(BufferedStreamAsyncResult.Complete(numBytes, userCallback, stateObject, true));
            }

            if (_writePos > 0)
            {
                FlushWrite(false);
            }
            return(BeginWriteCore(array, offset, numBytes, userCallback, stateObject));
        }
예제 #2
0
        public unsafe override void EndWrite(IAsyncResult asyncResult)
        {
            if (asyncResult == null)
            {
                throw new ArgumentNullException("asyncResult");
            }

            BufferedStreamAsyncResult bsar = asyncResult as BufferedStreamAsyncResult;

            if (bsar == null)
            {
                EndWriteCore(asyncResult);
            }
        }
예제 #3
0
        internal static IAsyncResult Complete(int numBufferedBytes, AsyncCallback userCallback, Object userStateObject, bool isWrite)
        {
            // Fake async
            BufferedStreamAsyncResult asyncResult = new BufferedStreamAsyncResult();

            asyncResult._numBytes        = numBufferedBytes;
            asyncResult._userCallback    = userCallback;
            asyncResult._userStateObject = userStateObject;
            asyncResult._isWrite         = isWrite;
            if (userCallback != null)
            {
                userCallback(asyncResult);
            }
            return(asyncResult);
        }
예제 #4
0
        public unsafe override int EndRead(IAsyncResult asyncResult)
        {
            if (asyncResult == null)
            {
                throw new ArgumentNullException("asyncResult");
            }

            BufferedStreamAsyncResult bsar = asyncResult as BufferedStreamAsyncResult;

            if (bsar != null)
            {
                if (bsar._isWrite)
                {
                    __Error.WrongAsyncResult();
                }
                return(bsar._numBytes);
            }
            else
            {
                return(EndReadCore(asyncResult));
            }
        }
 internal static IAsyncResult Complete(int numBufferedBytes, AsyncCallback userCallback, Object userStateObject, bool isWrite)
 {
     // Fake async
     BufferedStreamAsyncResult asyncResult = new BufferedStreamAsyncResult();
     asyncResult._numBytes = numBufferedBytes;
     asyncResult._userCallback = userCallback;
     asyncResult._userStateObject = userStateObject;
     asyncResult._isWrite = isWrite;
     if (userCallback != null) {
         userCallback(asyncResult);
     }
     return asyncResult;
 }
예제 #6
0
        public override IAsyncResult BeginRead(byte[] array, int offset, int numBytes, AsyncCallback userCallback, Object stateObject)
        {
            if (array == null)
            {
                throw new ArgumentNullException("array");
            }
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException("offset", Helper.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            }
            if (numBytes < 0)
            {
                throw new ArgumentOutOfRangeException("numBytes", Helper.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
            }
            if (array.Length - offset < numBytes)
            {
                throw new ArgumentException(Helper.GetResourceString("Argument_InvalidOffLen"));
            }

            if (!CanRead)
            {
                __Error.ReadNotSupported();
            }

            Debug.Assert((_readPos == 0 && _readLen == 0 && _writePos >= 0) || (_writePos == 0 && _readPos <= _readLen), "We're either reading or writing, but not both.");

            if (_writePos > 0)
            {
                FlushWrite(false);
            }
            if (_readPos == _readLen)
            {
                // I can't see how to handle buffering of async requests when
                // filling the buffer asynchronously, without a lot of complexity.
                // The problems I see are issuing an async read, we do an async
                // read to fill the buffer, then someone issues another read
                // (either synchronously or asynchronously) before the first one
                // returns.  This would involve some sort of complex buffer locking
                // that we probably don't want to get into, at least not in V1.
                // If we did a sync read to fill the buffer, we could avoid the
                // problem, and any async read less than 64K gets turned into a
                // synchronous read by NT anyways...       --

                if (numBytes < bufferSize)
                {
                    if (_buffer == null)
                    {
                        _buffer = new byte[bufferSize];
                    }
                    IAsyncResult bufferRead = BeginReadCore(_buffer, 0, bufferSize, null, null, 0);
                    _readLen = EndRead(bufferRead);
                    int n = _readLen;
                    if (n > numBytes)
                    {
                        n = numBytes;
                    }
                    Buffer.BlockCopy(_buffer, 0, array, offset, n);
                    _readPos = n;

                    // Fake async
                    return(BufferedStreamAsyncResult.Complete(n, userCallback, stateObject, false));
                }

                // Here we're making our position pointer inconsistent
                // with our read buffer.  Throw away the read buffer's contents.
                _readPos = 0;
                _readLen = 0;
                return(BeginReadCore(array, offset, numBytes, userCallback, stateObject, 0));
            }
            else
            {
                int n = _readLen - _readPos;
                if (n > numBytes)
                {
                    n = numBytes;
                }
                Buffer.BlockCopy(_buffer, _readPos, array, offset, n);
                _readPos += n;

                if (n >= numBytes)
                {
                    return(BufferedStreamAsyncResult.Complete(n, userCallback, stateObject, false));
                }

                // For streams with no clear EOF like serial ports or pipes
                // we cannot read more data without causing an app to block
                // incorrectly.  Pipes don't go down this path
                // though.  This code needs to be fixed.
                // Throw away read buffer.
                _readPos = 0;
                _readLen = 0;

                // WARNING: all state on asyncResult objects must be set before
                // we call ReadFile in BeginReadCore, since the OS can run our
                // callback & the user's callback before ReadFile returns.
                return(BeginReadCore(array, offset + n, numBytes - n, userCallback, stateObject, n));
            }
        }