예제 #1
0
        public AsyncCompletionResult BeginRead(int offset, int size, TimeSpan timeout, Action <object> callback, object state)
        {
            ConnectionUtilities.ValidateBufferBounds(AsyncReadBufferSize, offset, size);
            readCallback = callback;

            try
            {
                SetReadTimeout(timeout);
                Task <int> localTask = stream.ReadAsync(AsyncReadBuffer, offset, size);

                if (!localTask.IsCompleted)
                {
                    localTask.ContinueWith(onRead, state);
                    return(AsyncCompletionResult.Queued);
                }

                bytesRead = localTask.GetAwaiter().GetResult();
            }
            catch (IOException ioException)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(ConvertIOException(ioException));
            }

            return(AsyncCompletionResult.Completed);
        }
예제 #2
0
        public override int Read(byte[] buffer, int offset, int size, TimeSpan timeout)
        {
            ConnectionUtilities.ValidateBufferBounds(buffer, offset, size);

            if (preReadCount > 0)
            {
                int bytesToCopy = Math.Min(size, preReadCount);
                Buffer.BlockCopy(base.Connection.AsyncReadBuffer, preReadOffset, buffer, offset, bytesToCopy);
                preReadOffset += bytesToCopy;
                preReadCount  -= bytesToCopy;
                return(bytesToCopy);
            }

            return(base.Read(buffer, offset, size, timeout));
        }
예제 #3
0
        public static async Task DecodeFramingFaultAsync(ClientFramingDecoder decoder, IConnection connection,
                                                         Uri via, string contentType, TimeoutHelper timeoutHelper)
        {
            ValidateReadingFaultString(decoder);

            int offset = 0;

            byte[] faultBuffer = Fx.AllocateByteArray(FaultStringDecoder.FaultSizeQuota);
            int    size        = await connection.ReadAsync(0, Math.Min(FaultStringDecoder.FaultSizeQuota, connection.AsyncReadBufferSize),
                                                            timeoutHelper.RemainingTime());

            while (size > 0)
            {
                int bytesDecoded = decoder.Decode(connection.AsyncReadBuffer, offset, size);
                offset += bytesDecoded;
                size   -= bytesDecoded;

                if (decoder.CurrentState == ClientFramingDecoderState.Fault)
                {
                    ConnectionUtilities.CloseNoThrow(connection, timeoutHelper.RemainingTime());
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                              FaultStringDecoder.GetFaultException(decoder.Fault, via.ToString(), contentType));
                }
                else
                {
                    if (decoder.CurrentState != ClientFramingDecoderState.ReadingFaultString)
                    {
                        throw Fx.AssertAndThrow("invalid framing client state machine");
                    }
                    if (size == 0)
                    {
                        offset = 0;
                        size   = await connection.ReadAsync(0, Math.Min(FaultStringDecoder.FaultSizeQuota, connection.AsyncReadBufferSize),
                                                            timeoutHelper.RemainingTime());
                    }
                }
            }

            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(decoder.CreatePrematureEOFException());
        }
예제 #4
0
        public override AsyncCompletionResult BeginRead(int offset, int size, TimeSpan timeout, Action <object> callback, object state)
        {
            ConnectionUtilities.ValidateBufferBounds(AsyncReadBufferSize, offset, size);

            if (preReadCount > 0)
            {
                int bytesToCopy = Math.Min(size, preReadCount);
                if (preReadData == null)
                {
                    if (offset != preReadOffset)
                    {
                        preReadData = Fx.AllocateByteArray(preReadCount);
                        Buffer.BlockCopy(base.Connection.AsyncReadBuffer, preReadOffset, preReadData, 0, preReadCount);
                        preReadOffset = 0;
                        Buffer.BlockCopy(preReadData, 0, base.Connection.AsyncReadBuffer, offset, bytesToCopy);
                        preReadOffset += bytesToCopy;
                        preReadCount  -= bytesToCopy;
                        asyncBytesRead = bytesToCopy;
                        return(AsyncCompletionResult.Completed);
                    }

                    // Requested offset and preReadOffset are the same so no copy needed
                    preReadOffset += bytesToCopy;
                    preReadCount  -= bytesToCopy;
                    asyncBytesRead = bytesToCopy;
                    return(AsyncCompletionResult.Completed);
                }

                Buffer.BlockCopy(preReadData, preReadOffset, AsyncReadBuffer, offset, bytesToCopy);
                preReadOffset += bytesToCopy;
                preReadCount  -= bytesToCopy;
                asyncBytesRead = bytesToCopy;
                return(AsyncCompletionResult.Completed);
            }

            return(base.BeginRead(offset, size, timeout, callback, state));
        }
        internal static void SendFault(IConnection connection, string faultString, byte[] drainBuffer, TimeSpan sendTimeout, int maxRead)
        {
            EncodedFault  encodedFault  = new EncodedFault(faultString);
            TimeoutHelper timeoutHelper = new TimeoutHelper(sendTimeout);

            try
            {
                connection.Write(encodedFault.EncodedBytes, 0, encodedFault.EncodedBytes.Length, true, timeoutHelper.RemainingTime());
                connection.Shutdown(timeoutHelper.RemainingTime());
            }
            catch (CommunicationException e)
            {
                DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                connection.Abort();
                return;
            }
            catch (TimeoutException e)
            {
                DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                connection.Abort();
                return;
            }

            // make sure we read until EOF or a quota is hit
            int read      = 0;
            int readTotal = 0;

            for (;;)
            {
                try
                {
                    read = connection.Read(drainBuffer, 0, drainBuffer.Length, timeoutHelper.RemainingTime());
                }
                catch (CommunicationException e)
                {
                    DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                    connection.Abort();
                    return;
                }
                catch (TimeoutException e)
                {
                    DiagnosticUtility.TraceHandledException(e, TraceEventType.Information);
                    connection.Abort();
                    return;
                }

                if (read == 0)
                {
                    break;
                }

                readTotal += read;
                if (readTotal > maxRead || timeoutHelper.RemainingTime() <= TimeSpan.Zero)
                {
                    connection.Abort();
                    return;
                }
            }

            ConnectionUtilities.CloseNoThrow(connection, timeoutHelper.RemainingTime());
        }