private async Task <string> FetchFilePartAsync(ICommunicationChannel channel, int groupIndex, int groupSize, int nGroups, bool fetchWholeFile) { GetRequestedFilePart(groupIndex, groupSize, nGroups, fetchWholeFile, out var waveOffset, out var waveCount); if (IsFilePartFetched(waveOffset, waveCount)) { return(null); } var waveDataSize = _laneDataSize * WaveSize; var requestedByteOffset = waveOffset * waveDataSize * 4; var requestedByteCount = Math.Min(waveCount * waveDataSize, _outputFile.DwordCount) * 4; var response = await channel.SendWithReplyAsync <DebugServer.IPC.Responses.ResultRangeFetched>( new DebugServer.IPC.Commands.FetchResultRange { FilePath = new[] { _outputFile.Path }, BinaryOutput = _outputFile.BinaryOutput, ByteOffset = requestedByteOffset, ByteCount = requestedByteCount, OutputOffset = _outputFile.Offset }, CancellationToken.None).ConfigureAwait(false); if (response.Status != DebugServer.IPC.Responses.FetchStatus.Successful) { return("Output file could not be opened."); } Buffer.BlockCopy(response.Data, 0, _data, requestedByteOffset, response.Data.Length); var fetchedWaveCount = response.Data.Length / waveDataSize / 4; MarkFilePartAsFetched(waveOffset, fetchedWaveCount); if (response.Timestamp != _outputFile.Timestamp) { return("Output file has changed since the last debugger execution."); } if (response.Data.Length < requestedByteCount) { return($"Group #{groupIndex} is incomplete: expected to read {requestedByteCount} bytes but the output file contains {response.Data.Length}."); } if (_data.Length < nGroups * groupSize * _laneDataSize) { return($"Output file has fewer groups than requested (NGroups = {nGroups}, but the file contains only {GetGroupCount(groupSize, WaveSize, nGroups)})"); } return(null); }
private async Task <StepResult> DoCopyFileAsync(CopyFileStep step) { IList <FileMetadata> sourceFiles, targetFiles; // List all source files if (step.Direction == FileCopyDirection.RemoteToLocal) { var command = new ListFilesCommand { Path = step.SourcePath, IncludeSubdirectories = step.IncludeSubdirectories }; var response = await _channel.SendWithReplyAsync <ListFilesResponse>(command, _controller.CancellationToken); sourceFiles = response.Files; } else { if (!TryGetLocalMetadata(step.SourcePath, step.IncludeSubdirectories, out sourceFiles, out var error)) { return(new StepResult(false, error, "")); } } if (sourceFiles.Count == 0) { return(new StepResult(false, $"Path \"{step.SourcePath}\" does not exist", "")); } // List all target files if (step.Direction == FileCopyDirection.LocalToRemote) { var command = new ListFilesCommand { Path = step.TargetPath, IncludeSubdirectories = step.IncludeSubdirectories }; var response = await _channel.SendWithReplyAsync <ListFilesResponse>(command, _controller.CancellationToken); targetFiles = response.Files; } else { if (!TryGetLocalMetadata(step.TargetPath, step.IncludeSubdirectories, out targetFiles, out var error)) { return(new StepResult(false, error, "")); } } // Copying one file? if (sourceFiles.Count == 1 && !sourceFiles[0].IsDirectory) { if (targetFiles.Count > 0 && targetFiles[0].IsDirectory) { return(new StepResult(false, $"File \"{step.SourcePath}\" cannot be copied: the target path is a directory.", "")); } if (step.FailIfNotModified && sourceFiles[0].LastWriteTimeUtc == GetInitialFileTimestamp(step.SourcePath)) { return(new StepResult(false, "File was not changed after executing the previous steps. Disable Check Timestamp in step options to skip the modification date check.", "")); } if (step.SkipIfNotModified && targetFiles.Count == 1 && sourceFiles[0].Size == targetFiles[0].Size && sourceFiles[0].LastWriteTimeUtc == targetFiles[0].LastWriteTimeUtc) { return(new StepResult(true, "", "No files were copied. Sizes and modification times are identical on the source and target sides.\r\n")); } return(await DoCopySingleFileAsync(step)); } // Copying a directory? return(await DoCopyDirectoryAsync(step, sourceFiles, targetFiles)); }