mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
parent
78467ea00d
commit
df447bf704
2 changed files with 144 additions and 0 deletions
|
|
@ -806,6 +806,46 @@ begin
|
|||
TargetFileStream.Seek(0, fsFromBeginning);
|
||||
end;
|
||||
end else
|
||||
{$ELSEIF DEFINED(DARWIN)}
|
||||
if (Mode = fsohcmDefault) then
|
||||
begin
|
||||
FReserveSpace:= False;
|
||||
|
||||
OpenTargetFile;
|
||||
if not Assigned(TargetFileStream) then
|
||||
Exit;
|
||||
|
||||
Result:= CopyFileF(SourceFileStream.Handle, TargetFileStream.Handle, Options, @FileCopyProgress, Self);
|
||||
|
||||
if Result then
|
||||
begin
|
||||
FreeAndNil(SourceFileStream);
|
||||
FreeAndNil(TargetFileStream);
|
||||
|
||||
if FVerify then
|
||||
begin
|
||||
Result:= CompareFiles(SourceFile.FullPath, TargetFileName, SourceFile.Size);
|
||||
end;
|
||||
if Result then begin
|
||||
CopyProperties(SourceFile, TargetFileName);
|
||||
end;
|
||||
end
|
||||
else begin
|
||||
bDeleteFile := True;
|
||||
if FSkipCopyError then Exit;
|
||||
case AskQuestion('',
|
||||
Format(rsMsgErrCannotCopyFile, [WrapTextSimple(SourceFile.FullPath, 64), WrapTextSimple(TargetFileName, 64)]) +
|
||||
LineEnding + LineEnding + mbSysErrorMessage,
|
||||
[fsourSkip, fsourSkipAll, fsourAbort],
|
||||
fsourSkip, fsourAbort) of
|
||||
fsourAbort:
|
||||
AbortOperation;
|
||||
fsourSkipAll:
|
||||
FSkipCopyError := True;
|
||||
end; // case
|
||||
end;
|
||||
Exit;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
OpenTargetFile;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@ var
|
|||
FileCopyEx: TFileCopyEx = nil;
|
||||
CopyAttributesOptionEx: TCopyAttributesOptions = [];
|
||||
|
||||
{$IF DEFINED(DARWIN)}
|
||||
function CopyFileF(Source, Target: THandle; Options: UInt32; UpdateProgress: TFileCopyProgress; UserData: Pointer): LongBool;
|
||||
{$ENDIF}
|
||||
|
||||
implementation
|
||||
|
||||
{$IF DEFINED(MSWINDOWS)}
|
||||
|
|
@ -63,6 +67,106 @@ end;
|
|||
initialization
|
||||
FileCopyEx:= @CopyFile;
|
||||
CopyAttributesOptionEx:= [caoCopyTimeEx, caoCopyAttrEx];
|
||||
{$ELSEIF DEFINED(DARWIN)}
|
||||
uses
|
||||
InitC, CTypes;
|
||||
|
||||
const
|
||||
// copyfile_state_t values
|
||||
COPYFILE_STATE_STATUS_CB = 6;
|
||||
COPYFILE_STATE_STATUS_CTX = 7;
|
||||
COPYFILE_STATE_COPIED = 8;
|
||||
|
||||
const
|
||||
// flags for copyfile
|
||||
COPYFILE_DATA = (1 << 3);
|
||||
|
||||
// progress function what
|
||||
COPYFILE_COPY_DATA = 4;
|
||||
|
||||
// progress function stages
|
||||
COPYFILE_START = 1;
|
||||
COPYFILE_FINISH = 2;
|
||||
COPYFILE_ERR = 3;
|
||||
COPYFILE_PROGRESS = 4;
|
||||
|
||||
// callback function return values
|
||||
COPYFILE_CONTINUE = 0;
|
||||
COPYFILE_SKIP = 1;
|
||||
COPYFILE_QUIT = 2;
|
||||
|
||||
type
|
||||
TCopyInfo = class
|
||||
FileSize: Int64;
|
||||
UserData: Pointer;
|
||||
UpdateProgress: TFileCopyProgress;
|
||||
end;
|
||||
|
||||
type
|
||||
copyfile_flags_t = type cuint32;
|
||||
copyfile_state_t = type pointer;
|
||||
|
||||
function copyfile_state_free(s: copyfile_state_t): cint; cdecl; external clib;
|
||||
function copyfile_state_alloc(): copyfile_state_t; cdecl; external clib;
|
||||
|
||||
function copyfile_state_get(s: copyfile_state_t; flag: cuint32; dst: pointer): cint; cdecl; external clib;
|
||||
function copyfile_state_set(s: copyfile_state_t; flag: cuint32; const src: pointer): cint; cdecl; external clib;
|
||||
|
||||
function fcopyfile(from_fd, to_fd: cint; s: copyfile_state_t; flags: copyfile_flags_t): cint; cdecl; external clib;
|
||||
|
||||
function Callback(what, stage: cint; state: copyfile_state_t; src, dst: pansichar; ctx: pointer): cint; cdecl;
|
||||
var
|
||||
BytesTransferred: coff_t;
|
||||
ACopyInfo: TCopyInfo absolute ctx;
|
||||
begin
|
||||
if (what = COPYFILE_COPY_DATA) and (stage = COPYFILE_PROGRESS) then
|
||||
begin
|
||||
if (copyfile_state_get(state, COPYFILE_STATE_COPIED, @BytesTransferred) = 0) then
|
||||
begin
|
||||
if ACopyInfo.UpdateProgress(ACopyInfo.FileSize, BytesTransferred, ACopyInfo.UserData) then
|
||||
Result:= COPYFILE_CONTINUE
|
||||
else begin
|
||||
Result:= COPYFILE_QUIT;
|
||||
end;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
Result:= COPYFILE_CONTINUE;
|
||||
end;
|
||||
|
||||
function CopyFileF(Source, Target: THandle; Options: UInt32; UpdateProgress: TFileCopyProgress; UserData: Pointer): LongBool;
|
||||
var
|
||||
ACopyInfo: TCopyInfo;
|
||||
LastError: Integer = 0;
|
||||
AState: copyfile_state_t;
|
||||
begin
|
||||
Result:= False;
|
||||
|
||||
AState:= copyfile_state_alloc();
|
||||
|
||||
if Assigned(AState) then
|
||||
begin
|
||||
ACopyInfo:= TCopyInfo.Create;
|
||||
ACopyInfo.UserData:= UserData;
|
||||
ACopyInfo.FileSize:= FileGetSize(Source);
|
||||
ACopyInfo.UpdateProgress:= UpdateProgress;
|
||||
|
||||
copyfile_state_set(AState, COPYFILE_STATE_STATUS_CB, @Callback);
|
||||
copyfile_state_set(AState, COPYFILE_STATE_STATUS_CTX, ACopyInfo);
|
||||
|
||||
Result:= fcopyfile(Source, Target, AState, COPYFILE_DATA) = 0;
|
||||
|
||||
if not Result then LastError:= cerrno;
|
||||
|
||||
copyfile_state_free(AState);
|
||||
ACopyInfo.Free;
|
||||
|
||||
if (LastError <> 0) then
|
||||
begin
|
||||
SetLastOSError(LastError);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
end.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue