diff options
| author | Tomas Bzatek <tbzatek@redhat.com> | 2024-10-23 21:14:22 +0200 |
|---|---|---|
| committer | Tomas Bzatek <tbzatek@redhat.com> | 2024-10-23 21:14:22 +0200 |
| commit | 40a71ffb604413c41b429dbbe4dfaf4520a03061 (patch) | |
| tree | ea2abc1839cca441e4242667c35acee461515033 | |
| parent | af25c37af9cd3fd62b70ef2f238cbb900dd480e3 (diff) | |
| download | tuxcmd-40a71ffb604413c41b429dbbe4dfaf4520a03061.tar.xz | |
Sort global filelist in case of a streaming type archive
Before this change sorting was done on each panel item separately.
Streaming type archives (e.g. tar) needs strict sequential order
as indicated by the inode_no and the global filelist to copy
needs to be sorted once more.
Tested on 7z2301-extra.7z
| -rw-r--r-- | UCore.pas | 42 | ||||
| -rw-r--r-- | UCoreWorkers.pas | 6 |
2 files changed, 30 insertions, 18 deletions
@@ -29,6 +29,7 @@ procedure FindNextSelected(ListView: TGTKListView; DataList: TList; var Item1, I procedure UnselectAll(ListView: TGTKListView; DataList: TList); procedure FillDirFiles(Engine: TPanelEngine; DestList: TList; InputFiles: TStringList; DoNotRecurse: boolean; InaccessiblePaths: TStringList; CancelFlag: Pboolean); +procedure FillDirFiles_sort(FList: TList); function GetFileInfoSL(Engine: TPanelEngine; const APath: string): PDataItemSL; procedure DebugWriteListSL(List: TList); @@ -348,8 +349,7 @@ end; (********************************************************************************************************************************) (********************************************************************************************************************************) -procedure FillDirFiles(Engine: TPanelEngine; DestList: TList; InputFiles: TStringList; DoNotRecurse: boolean; InaccessiblePaths: TStringList; CancelFlag: Pboolean); -var DirStage1List, FilesList, DirStage2List: TList; +procedure FillDirFiles_sort(FList: TList); function FillDirFiles_compare_func(Item1, Item2: Pointer): integer; var DataItem1, DataItem2: PDataItem; @@ -357,12 +357,16 @@ var DirStage1List, FilesList, DirStage2List: TList; DataItem1 := PDataItemSL(Item1)^.DataItem; DataItem2 := PDataItemSL(Item2)^.DataItem; // sort by inode number - // also, we want to have directories at the bottom of the list - if DataItem1^.IsDir and (not DataItem2^.IsDir) then Result := 1 else - if (not DataItem1^.IsDir) and DataItem2^.IsDir then Result := -1 else + // also, we want to have directories at the top of the list + if PDataItemSL(Item1)^.Stage1 and (not PDataItemSL(Item2)^.Stage1) then Result := -1 else + if (not PDataItemSL(Item1)^.Stage1) and PDataItemSL(Item2)^.Stage1 then Result := 1 else + if DataItem1^.IsDir and (not DataItem2^.IsDir) then Result := -1 else + if (not DataItem1^.IsDir) and DataItem2^.IsDir then Result := 1 else if DataItem1^.inode_no > DataItem2^.inode_no then Result := 1 else if DataItem1^.inode_no < DataItem2^.inode_no then Result := -1 else - Result := 0; + // sort by name, in inverse order for Stage2 + if PDataItemSL(Item1)^.Stage1 then Result := strcmp(DataItem1^.FName, DataItem2^.FName) + else Result := -strcmp(DataItem1^.FName, DataItem2^.FName); end; procedure QuickSort(FList: TList; L, R : Longint); @@ -392,18 +396,20 @@ var DirStage1List, FilesList, DirStage2List: TList; until I >= R; end; - procedure FillDirFiles_sort(FList: TList); - var i: integer; - begin - if FList.Count < 2 then Exit; - DebugMsg(['before sorting:']); - for i := 0 to FList.Count - 1 do - DebugMsg([' ', i, ' [', PDataItemSL(FList[i])^.DataItem^.inode_no, '] ', PDataItemSL(FList[i])^.DataItem^.FName]); - QuickSort(Flist, 0, FList.Count - 1); - DebugMsg(['after sorting:']); - for i := 0 to FList.Count - 1 do - DebugMsg([' ', i, ' [', PDataItemSL(FList[i])^.DataItem^.inode_no, '] ', PDataItemSL(FList[i])^.DataItem^.FName]); - end; +var i: integer; +begin + if FList.Count < 2 then Exit; + DebugMsg(['before sorting:']); + for i := 0 to FList.Count - 1 do + DebugMsg([' ', i, ' [', PDataItemSL(FList[i])^.DataItem^.inode_no, '] ', PDataItemSL(FList[i])^.DataItem^.FName]); + QuickSort(Flist, 0, FList.Count - 1); + DebugMsg(['after sorting:']); + for i := 0 to FList.Count - 1 do + DebugMsg([' ', i, ' [', PDataItemSL(FList[i])^.DataItem^.inode_no, '] ', PDataItemSL(FList[i])^.DataItem^.FName]); +end; + +procedure FillDirFiles(Engine: TPanelEngine; DestList: TList; InputFiles: TStringList; DoNotRecurse: boolean; InaccessiblePaths: TStringList; CancelFlag: Pboolean); +var DirStage1List, FilesList, DirStage2List: TList; procedure FillDirFiles_Recurse(const LocalPath: string; ALevel: integer); var LocalList: TList; diff --git a/UCoreWorkers.pas b/UCoreWorkers.pas index 6ea4268..507e2b7 100644 --- a/UCoreWorkers.pas +++ b/UCoreWorkers.pas @@ -1501,6 +1501,12 @@ begin { if DestEngine.ChangeDir(CurrPath) <> 0 then DebugMsg(['*** WARNING: Cannot change to the origin location, strange behaviour may occur.']); if SrcEngine.ChangeDir(CurrPath) <> 0 then DebugMsg(['*** WARNING: Cannot change to the origin location, strange behaviour may occur.']); } + + // For streaming type archives the list of files to copy strictly needs to be sorted globally according to inode_no + if (SrcEngine is TVFSEngine) and (SrcEngine as TVFSEngine).ArchiveMode and (SrcEngine as TVFSEngine).ArchiveStreamingType then begin + DebugMsg(['Archive type is streaming, performing global filelist sort...']); + FillDirFiles_sort(List); + end; DebugWriteListSL(List); SkipInaccessible := False; |
