public async Task <byte[]> WaitAsync(int count, WaitMode mode, AsyncOperationInfo operationInfo)
            {
                throwIfDisposed();
                _responseReadTimeout.ThrowIfTimeout();
                operationInfo.CancellationToken.ThrowIfCancellationRequested();

                byte[] waitResult = null;
                try
                {
                    using (_waitTimeout.RestartMode)
                    {
                        switch (mode)
                        {
                        case WaitMode.EXACT:
                            var buffer = new List <byte>(count);
                            while (buffer.Count != count)
                            {
                                _responseReadTimeout.ThrowIfTimeout();

                                var result = await _pipe.ReadAsync(new PipeReadParameters(count - buffer.Count), _cancellation);

                                if (result.Status.IsOneOf(IOBase.ReadStatus.DONE, IOBase.ReadStatus.PATIALLY_DONE))
                                {
                                    buffer.AddRange(result.Data);
                                }
                                else
                                {
                                    throw new NotSupportedException();
                                }
                            }
                            waitResult = buffer.ToArray();
                            break;

                        case WaitMode.NO_MORE_THAN:
                        {
                            var result = await _pipe.ReadAsync(new PipeReadParameters(count), _cancellation);

                            if (result.Status.IsOneOf(IOBase.ReadStatus.DONE, IOBase.ReadStatus.PATIALLY_DONE))
                            {
                                waitResult = result.Data.ToArray();
                            }
                            else
                            {
                                throw new NotSupportedException();
                            }
                        }
                        break;

                        default:
                            throw new NotSupportedException();
                        }
                    }

                    return(waitResult);
                }
                finally
                {
                    await Logger.LogResponseAsync(waitResult ?? new byte[0], count);
                }
            }
Пример #2
0
        static async Task <byte[]> readExactAsync
            (int count, Func <byte[], int, int, object> readFunc, ReadExactInfo info)
        {
            var timeouter = new Timeouter(info.MethodTimeout);

            var buffer         = new byte[count];
            var offset         = 0;
            var totalBytesRead = 0;
            var remain         = count;

            while (totalBytesRead != count)
            {
                var bytesRead = 0;
                var readInfo  = readFunc(buffer, offset, remain);
                if (readInfo is Task <int> task)
                {
                    bytesRead = await task;
                }
                else if (readInfo is int read)
                {
                    bytesRead = read;
                }
                else
                {
                    throw new NotSupportedException();
                }
                totalBytesRead += bytesRead;
                offset          = totalBytesRead;
                remain          = count - totalBytesRead;

                if (bytesRead == 0 && info.ThrowIfZeroReceived)
                {
                    throw new ReadExactZeroReceivedException();
                }
                if (info.RetryDelay != 0)
                {
                    await Task.Delay(info.RetryDelay).ConfigureAwait(false);
                }
                if ((info.TimeoutOnlyIfNothingWasRead && totalBytesRead == 0) ||
                    (!info.TimeoutOnlyIfNothingWasRead))
                {
                    timeouter.ThrowIfTimeout(() => new ReadExactTimeoutException(buffer.Take(totalBytesRead), count));
                }
            }

            return(buffer);
        }
Пример #3
0
        protected override async Task <IResponse> deserializeResponseAsync(IResponseFuture inputStream, AsyncOperationInfo operationInfo)
        {
            IResponse result = null;
            Stream    stream = createReadBuffer();

            var dataRead = new StreamResponseData(stream);

            switch (_responseInfo.ReadMode)
            {
            case ResponseReadMode.TILL_TIMEOUT:
                try
                {
                    var readTimeout = new Timeouter(CHUNK_READ_TIMEOUT);
                    while (true)
                    {
                        var piece = await inputStream.WaitAsync(READ_CHUNK_SIZE, WaitMode.NO_MORE_THAN, operationInfo);

                        await stream.WriteAsync(piece, 0, piece.Length);

                        operationInfo.Progress.AddProgress(piece.Length);
                        if (piece.Length != 0)
                        {
                            readTimeout.Restart();
                        }
                        readTimeout.ThrowIfTimeout();
                    }
                }
                catch (TimeoutException)
                {
                }
                break;

            case ResponseReadMode.CONSTRAINED_BY_ANSWER:
                var max = _responseInfo.ResponseFullLength.IsUnknown
                        ? long.MaxValue
                        : _responseInfo.ResponseFullLength.Length;
                for (long i = 0; i < max; i++)
                {
                    var data = await inputStream.WaitAsync(1, WaitMode.EXACT, operationInfo);

                    stream.WriteByte(data.Single());
                    operationInfo.Progress.AddProgress(1D / max);
                }
                break;

            case ResponseReadMode.READ_BY_TARGET:
                result = await _deviceRequest.DeserializeResponseAsync(inputStream, operationInfo);

                break;

            default:
                throw new NotSupportedException();
            }

            if (result == null)
            {
                if (!_responseInfo.ResponseFullLength.IsUnknown &&
                    _responseInfo.ExpectedAnswer != null &&
                    !stream.AsEnumerable().Take((int)_responseInfo.ResponseFullLength.Length).SequenceEqual(_responseInfo.ExpectedAnswer))
                {
                    result = new FTDIBoxResponse(this, RequestStatus.NOT_EXPECTED_RESPONSE_BYTES, dataRead, null, null);
                }
                else
                {
                    await stream.FlushAsync(operationInfo.CancellationToken);

                    IResponseData serviceSection = null;
                    IResponseData bodySection    = null;
                    switch (Address)
                    {
                    case FTDIBoxRequestAddress.HS_SET_LOW_SPEED_MODE:
                    case FTDIBoxRequestAddress.LS_SET_HIGH_SPEED_MODE:
                    case FTDIBoxRequestAddress.HS_ACTIVATE_CHANNEL4:
                    case FTDIBoxRequestAddress.LS_ACTIVATE_CHANNEL4:
                        break;

                    case FTDIBoxRequestAddress.HS_GET_FLASH_LENGTH:
                    case FTDIBoxRequestAddress.HS_READ_ALL_FLASH:
                        serviceSection = new ResponseDataAreaProxy(dataRead, dataRead.Count - 6, dataRead.Count);
                        bodySection    = new ResponseDataAreaProxy(dataRead, 0, dataRead.Count - 6);
                        break;

                    case FTDIBoxRequestAddress.LS_DEVICE_REQUEST:
                        bodySection = dataRead;
                        break;

                    default:
                        throw new NotSupportedException();
                    }

                    result = new FTDIBoxResponse(this, RequestStatus.OK, dataRead, serviceSection, bodySection);
                }
            }

            return(result);

            Stream createReadBuffer()
            {
                Stream buffer = new MemoryStream();

                if (Address == FTDIBoxRequestAddress.HS_READ_ALL_FLASH)
                {
                    buffer = _scope.TryGetFirstParameter <FlashDumpStreamParameter>()?.Stream;
                    if (buffer == null)
                    {
                        var path = Path.GetTempFileName();
                        buffer = File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);

                        Logger.LogInfo(null, $"Создан буфер чтения по пути {path}");
                    }
                    else
                    {
                        Logger.LogInfo(null, $"Буфер чтения предоставлен через параметр");
                    }
                }

                return(buffer);
            }
        }