diff options
Diffstat (limited to 'UCoreWorkers.pas')
| -rw-r--r-- | UCoreWorkers.pas | 71 |
1 files changed, 39 insertions, 32 deletions
diff --git a/UCoreWorkers.pas b/UCoreWorkers.pas index 507e2b7..75a9453 100644 --- a/UCoreWorkers.pas +++ b/UCoreWorkers.pas @@ -1019,11 +1019,12 @@ var DefResponse: integer; // Global variables for this function var fsrc, fdst: TEngineFileDes; BSize: integer; Buffer: Pointer; - BytesDone, BytesRead, BytesWritten: Int64; + BytesDone, BytesRead, BytesWritten, BytesRemaining: Int64; LocalError: PGError; begin Result := False; LocalError := nil; + BytesDone := 0; DebugMsg(['ManualCopyFile: ', SourceFile, ' ---> ', DestFile]); fsrc := SrcEngine.OpenFile(SourceFile, omRead, @LocalError); if fsrc = nil then begin @@ -1042,7 +1043,6 @@ var DefResponse: integer; // Global variables for this function Exit; end; - BytesDone := 0; BSize := DestEngine.GetBlockSize; Buffer := malloc(BSize); if Buffer = nil then begin @@ -1050,60 +1050,66 @@ var DefResponse: integer; // Global variables for this function CopyFilesWorker_ProgressFunc(Self, 0, Error^); // Memory allocation failed Exit; end; - memset(Buffer, 0, BSize); - BytesWritten := 0; repeat + // Read block BytesRead := SrcEngine.ReadFile(fsrc, Buffer, BSize, @LocalError); - if (BytesRead = 0) and (Error^ <> nil) then begin + if BytesRead < 0 then begin g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_SOURCE_READ), LocalError^.message); g_error_free(LocalError); LocalError := nil; - Result := CopyFilesWorker_ProgressFunc(Self, BytesWritten, Error^); // Cannot read from source file + Result := CopyFilesWorker_ProgressFunc(Self, BytesDone, Error^); // Cannot read from source file if Result then begin g_error_free(Error^); Error^ := nil; Continue; end else Break; end; + + // Write block if BytesRead > 0 then begin - BytesWritten := DestEngine.WriteFile(fdst, Buffer, BytesRead, @LocalError); - if (BytesWritten < BytesRead) then begin + BytesRemaining := BytesRead; + repeat + BytesWritten := DestEngine.WriteFile(fdst, Buffer + (BytesRead - BytesRemaining), BytesRemaining, @LocalError); + if BytesWritten > 0 then + BytesRemaining := BytesRemaining - BytesWritten; + until (BytesRemaining = 0) or (BytesWritten <= 0); + if BytesWritten < 0 then begin g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_TARGET_WRITE), LocalError^.message); g_error_free(LocalError); LocalError := nil; - Result := CopyFilesWorker_ProgressFunc(Self, BytesWritten, Error^); // Cannot write to target file - if Result then begin - g_error_free(Error^); - Error^ := nil; - Continue; - end else Break; + Result := False; + CopyFilesWorker_ProgressFunc(Self, BytesDone, Error^); // Cannot write to target file + Break; end; end; + // BytesRead == 0 means EOF BytesDone := BytesDone + BytesRead; Result := CopyFilesWorker_ProgressFunc(Self, BytesDone, nil); if not Result then Break; - until (BytesRead = 0) or (BytesWritten < BytesRead); + until BytesRead <= 0; libc_free(Buffer); - if not DestEngine.CloseFile(fdst, @LocalError) then begin - g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_TARGET_CLOSE), LocalError^.message); - g_error_free(LocalError); - Result := False; - SrcEngine.CloseFile(fsrc, nil); - CopyFilesWorker_ProgressFunc(Self, BytesDone, Error^); // Cannot close target file - Exit; - end; - if not SrcEngine.CloseFile(fsrc, @LocalError) then begin - g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_SOURCE_CLOSE), LocalError^.message); - g_error_free(LocalError); - Result := CopyFilesWorker_ProgressFunc(Self, BytesDone, Error^); // Cannot close source file + if not DestEngine.CloseFile(fdst, @LocalError) then if Result then begin - // user has chosen to ignore the error - g_error_free(Error^); - Error^ := nil; - end else Exit; - end; + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_TARGET_CLOSE), LocalError^.message); + g_error_free(LocalError); + Result := False; + SrcEngine.CloseFile(fsrc, nil); + CopyFilesWorker_ProgressFunc(Self, BytesDone, Error^); // Cannot close target file + Exit; + end; + if not SrcEngine.CloseFile(fsrc, @LocalError) then + if Result then begin + g_set_error(Error, TUXCMD_ERROR, gint(TUXCMD_ERROR_SOURCE_CLOSE), LocalError^.message); + g_error_free(LocalError); + Result := CopyFilesWorker_ProgressFunc(Self, BytesDone, Error^); // Cannot close source file + if Result then begin + // user has chosen to ignore the error + g_error_free(Error^); + Error^ := nil; + end else Exit; + end; end; // Returns True if the file was successfully copied and will be deleted on move @@ -1120,6 +1126,7 @@ var DefResponse: integer; // Global variables for this function then Result := DestEngine.CopyFileIn(SourceFile, DestFile, Append, @CopyFilesWorker_ProgressFunc, Self, Error) else + // TODO: check for reported Append capability and fall back to manual copy if needed // from local engine to VFS engine if (SrcEngine is TLocalTreeEngine) and (DestEngine is TVFSEngine) then begin |
