From 8ceccef9284064f4f75fdf445f82eac723a7f951 Mon Sep 17 00:00:00 2001 From: Razor12911 Date: Fri, 13 May 2022 13:03:25 +0200 Subject: [PATCH] update to 0.5.1 --- io/__history/IODecode.pas.~101~ | 198 --------------- io/__history/IODecode.pas.~102~ | 198 --------------- io/__history/IODecode.pas.~103~ | 198 --------------- io/__history/IODecode.pas.~104~ | 202 --------------- io/__history/IODecode.pas.~105~ | 202 --------------- io/__history/IODecode.pas.~106~ | 198 --------------- io/__history/IODecode.pas.~107~ | 198 --------------- io/__history/IODecode.pas.~108~ | 198 --------------- io/__history/IODecode.pas.~109~ | 198 --------------- io/__history/IODecode.pas.~110~ | 198 --------------- io/__history/IOErase.pas.~100~ | 340 ------------------------- io/__history/IOErase.pas.~101~ | 341 ------------------------- io/__history/IOErase.pas.~102~ | 341 ------------------------- io/__history/IOErase.pas.~103~ | 341 ------------------------- io/__history/IOErase.pas.~104~ | 341 ------------------------- io/__history/IOErase.pas.~105~ | 341 ------------------------- io/__history/IOErase.pas.~106~ | 342 ------------------------- io/__history/IOErase.pas.~107~ | 342 ------------------------- io/__history/IOErase.pas.~108~ | 342 ------------------------- io/__history/IOErase.pas.~99~ | 338 ------------------------- io/__history/IOFind.pas.~1~ | 7 - io/__history/IOFind.pas.~2~ | 341 ------------------------- io/__history/IOFind.pas.~3~ | 324 ------------------------ io/__history/IOFind.pas.~4~ | 324 ------------------------ io/__history/IOFind.pas.~5~ | 325 ------------------------ io/__history/IOFind.pas.~6~ | 325 ------------------------ io/__history/IOPatch.pas.~302~ | 429 ------------------------------- io/__history/IOPatch.pas.~303~ | 429 ------------------------------- io/__history/IOPatch.pas.~304~ | 430 ------------------------------- io/__history/IOPatch.pas.~305~ | 431 -------------------------------- io/__history/IOPatch.pas.~306~ | 430 ------------------------------- io/__history/IOPatch.pas.~307~ | 431 -------------------------------- io/__history/IOPatch.pas.~308~ | 430 ------------------------------- io/__history/IOPatch.pas.~309~ | 430 ------------------------------- io/__history/IOPatch.pas.~310~ | 431 -------------------------------- io/__history/IOPatch.pas.~311~ | 430 ------------------------------- io/__history/IOReplace.pas.~50~ | 360 -------------------------- io/__history/IOReplace.pas.~51~ | 363 --------------------------- io/__history/IOReplace.pas.~52~ | 363 --------------------------- io/__history/IOReplace.pas.~53~ | 363 --------------------------- io/__history/IOReplace.pas.~54~ | 363 --------------------------- io/__history/IOReplace.pas.~55~ | 363 --------------------------- io/__history/IOReplace.pas.~56~ | 364 --------------------------- io/__history/IOReplace.pas.~57~ | 364 --------------------------- io/__history/IOReplace.pas.~58~ | 364 --------------------------- io/__history/IOReplace.pas.~59~ | 364 --------------------------- io/__history/IOUtils.pas.~31~ | 54 ---- io/__history/IOUtils.pas.~32~ | 54 ---- io/__history/IOUtils.pas.~33~ | 54 ---- io/__history/IOUtils.pas.~34~ | 55 ---- io/__history/IOUtils.pas.~35~ | 55 ---- io/__history/IOUtils.pas.~36~ | 56 ----- io/__history/IOUtils.pas.~37~ | 55 ---- io/__history/IOUtils.pas.~38~ | 55 ---- io/__history/IOUtils.pas.~39~ | 55 ---- io/__history/IOUtils.pas.~40~ | 56 ----- 56 files changed, 15524 deletions(-) delete mode 100644 io/__history/IODecode.pas.~101~ delete mode 100644 io/__history/IODecode.pas.~102~ delete mode 100644 io/__history/IODecode.pas.~103~ delete mode 100644 io/__history/IODecode.pas.~104~ delete mode 100644 io/__history/IODecode.pas.~105~ delete mode 100644 io/__history/IODecode.pas.~106~ delete mode 100644 io/__history/IODecode.pas.~107~ delete mode 100644 io/__history/IODecode.pas.~108~ delete mode 100644 io/__history/IODecode.pas.~109~ delete mode 100644 io/__history/IODecode.pas.~110~ delete mode 100644 io/__history/IOErase.pas.~100~ delete mode 100644 io/__history/IOErase.pas.~101~ delete mode 100644 io/__history/IOErase.pas.~102~ delete mode 100644 io/__history/IOErase.pas.~103~ delete mode 100644 io/__history/IOErase.pas.~104~ delete mode 100644 io/__history/IOErase.pas.~105~ delete mode 100644 io/__history/IOErase.pas.~106~ delete mode 100644 io/__history/IOErase.pas.~107~ delete mode 100644 io/__history/IOErase.pas.~108~ delete mode 100644 io/__history/IOErase.pas.~99~ delete mode 100644 io/__history/IOFind.pas.~1~ delete mode 100644 io/__history/IOFind.pas.~2~ delete mode 100644 io/__history/IOFind.pas.~3~ delete mode 100644 io/__history/IOFind.pas.~4~ delete mode 100644 io/__history/IOFind.pas.~5~ delete mode 100644 io/__history/IOFind.pas.~6~ delete mode 100644 io/__history/IOPatch.pas.~302~ delete mode 100644 io/__history/IOPatch.pas.~303~ delete mode 100644 io/__history/IOPatch.pas.~304~ delete mode 100644 io/__history/IOPatch.pas.~305~ delete mode 100644 io/__history/IOPatch.pas.~306~ delete mode 100644 io/__history/IOPatch.pas.~307~ delete mode 100644 io/__history/IOPatch.pas.~308~ delete mode 100644 io/__history/IOPatch.pas.~309~ delete mode 100644 io/__history/IOPatch.pas.~310~ delete mode 100644 io/__history/IOPatch.pas.~311~ delete mode 100644 io/__history/IOReplace.pas.~50~ delete mode 100644 io/__history/IOReplace.pas.~51~ delete mode 100644 io/__history/IOReplace.pas.~52~ delete mode 100644 io/__history/IOReplace.pas.~53~ delete mode 100644 io/__history/IOReplace.pas.~54~ delete mode 100644 io/__history/IOReplace.pas.~55~ delete mode 100644 io/__history/IOReplace.pas.~56~ delete mode 100644 io/__history/IOReplace.pas.~57~ delete mode 100644 io/__history/IOReplace.pas.~58~ delete mode 100644 io/__history/IOReplace.pas.~59~ delete mode 100644 io/__history/IOUtils.pas.~31~ delete mode 100644 io/__history/IOUtils.pas.~32~ delete mode 100644 io/__history/IOUtils.pas.~33~ delete mode 100644 io/__history/IOUtils.pas.~34~ delete mode 100644 io/__history/IOUtils.pas.~35~ delete mode 100644 io/__history/IOUtils.pas.~36~ delete mode 100644 io/__history/IOUtils.pas.~37~ delete mode 100644 io/__history/IOUtils.pas.~38~ delete mode 100644 io/__history/IOUtils.pas.~39~ delete mode 100644 io/__history/IOUtils.pas.~40~ diff --git a/io/__history/IODecode.pas.~101~ b/io/__history/IODecode.pas.~101~ deleted file mode 100644 index 794757d..0000000 --- a/io/__history/IODecode.pas.~101~ +++ /dev/null @@ -1,198 +0,0 @@ -unit IODecode; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PDecodeOptions = ^TDecodeOptions; - - TDecodeOptions = record - - end; - - PExtractOptions = ^TExtractOptions; - - TExtractOptions = record - - end; - -procedure PrintHelpExtract; -procedure ParseDecode(ParamArg: TArray; out Options: TDecodeOptions); -procedure ParseExtract(ParamArg: TArray; out Options: TExtractOptions); -procedure Decode(Input1: TStream; Input2, Output: String; - Options: TDecodeOptions); -procedure Extract(Input1: TStream; Input2, Output: String; - Options: TExtractOptions); - -implementation - -procedure PrintHelpExtract; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'extract - extract sectors from files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool extract decode_data original_data extracted_streams '); - WriteLn(ErrOutput, ''); -end; - -procedure ParseDecode(ParamArg: TArray; out Options: TDecodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ''; - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure ParseExtract(ParamArg: TArray; out Options: TExtractOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ''; - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Decode(Input1: TStream; Input2, Output: String; - Options: TDecodeOptions); -var - I, J: Integer; - LEntry: TEntryStruct; - LBytes: TBytes; - LFilename: String; - BaseDir1, BaseDir2: String; - SS1, SS2: TSharedMemoryStream; -begin - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Output) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)); - while true do - begin - try - Input1.ReadBuffer(I, I.Size); - except - break; - end; - SetLength(LBytes, I); - Input1.ReadBuffer(LBytes[0], I); - SS1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), - BaseDir2 + StringOf(LBytes)); - try - Input1.ReadBuffer(I, I.Size); - for J := 0 to I - 1 do - begin - Input1.ReadBuffer(LEntry, SizeOf(TEntryStruct)); - LFilename := BaseDir1 + LEntry.Filename; - if FileExists(LFilename) then - begin - SS2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LFilename); - try - Move(SS2.Memory^, (PByte(SS1.Memory) + LEntry.Position)^, - LEntry.Size); - finally - SS2.Free; - end; - WriteLn(ErrOutput, Format('Extracted %s', [LEntry.Filename])); - end; - end; - finally - SS1.Free; - end; - end; -end; - -procedure Extract(Input1: TStream; Input2, Output: String; - Options: TExtractOptions); -var - I, J: Integer; - LEntry: TEntryStruct; - LBytes: TBytes; - LFilename: String; - BaseDir1, BaseDir2: String; - FS1, FS2: TFileStream; -begin - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Output) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)); - while true do - begin - try - Input1.ReadBuffer(I, I.Size); - except - break; - end; - SetLength(LBytes, I); - Input1.ReadBuffer(LBytes[0], I); - FS1 := TFileStream.Create(BaseDir1 + StringOf(LBytes), fmShareDenyNone); - try - Input1.ReadBuffer(I, I.Size); - for J := 0 to I - 1 do - begin - Input1.ReadBuffer(LEntry, SizeOf(TEntryStruct)); - LFilename := BaseDir2 + LEntry.Filename; - ForceDirectories(ExtractFilePath(LFilename)); - FS2 := TFileStream.Create(LFilename, fmCreate); - try - FS1.Position := LEntry.Position; - CopyStreamEx(FS1, FS2, LEntry.Size); - finally - FS2.Free; - end; - WriteLn(ErrOutput, Format('Extracted %s', [LEntry.Filename])); - end; - finally - FS1.Free; - end; - end; -end; - -end. diff --git a/io/__history/IODecode.pas.~102~ b/io/__history/IODecode.pas.~102~ deleted file mode 100644 index 794757d..0000000 --- a/io/__history/IODecode.pas.~102~ +++ /dev/null @@ -1,198 +0,0 @@ -unit IODecode; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PDecodeOptions = ^TDecodeOptions; - - TDecodeOptions = record - - end; - - PExtractOptions = ^TExtractOptions; - - TExtractOptions = record - - end; - -procedure PrintHelpExtract; -procedure ParseDecode(ParamArg: TArray; out Options: TDecodeOptions); -procedure ParseExtract(ParamArg: TArray; out Options: TExtractOptions); -procedure Decode(Input1: TStream; Input2, Output: String; - Options: TDecodeOptions); -procedure Extract(Input1: TStream; Input2, Output: String; - Options: TExtractOptions); - -implementation - -procedure PrintHelpExtract; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'extract - extract sectors from files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool extract decode_data original_data extracted_streams '); - WriteLn(ErrOutput, ''); -end; - -procedure ParseDecode(ParamArg: TArray; out Options: TDecodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ''; - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure ParseExtract(ParamArg: TArray; out Options: TExtractOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ''; - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Decode(Input1: TStream; Input2, Output: String; - Options: TDecodeOptions); -var - I, J: Integer; - LEntry: TEntryStruct; - LBytes: TBytes; - LFilename: String; - BaseDir1, BaseDir2: String; - SS1, SS2: TSharedMemoryStream; -begin - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Output) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)); - while true do - begin - try - Input1.ReadBuffer(I, I.Size); - except - break; - end; - SetLength(LBytes, I); - Input1.ReadBuffer(LBytes[0], I); - SS1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), - BaseDir2 + StringOf(LBytes)); - try - Input1.ReadBuffer(I, I.Size); - for J := 0 to I - 1 do - begin - Input1.ReadBuffer(LEntry, SizeOf(TEntryStruct)); - LFilename := BaseDir1 + LEntry.Filename; - if FileExists(LFilename) then - begin - SS2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LFilename); - try - Move(SS2.Memory^, (PByte(SS1.Memory) + LEntry.Position)^, - LEntry.Size); - finally - SS2.Free; - end; - WriteLn(ErrOutput, Format('Extracted %s', [LEntry.Filename])); - end; - end; - finally - SS1.Free; - end; - end; -end; - -procedure Extract(Input1: TStream; Input2, Output: String; - Options: TExtractOptions); -var - I, J: Integer; - LEntry: TEntryStruct; - LBytes: TBytes; - LFilename: String; - BaseDir1, BaseDir2: String; - FS1, FS2: TFileStream; -begin - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Output) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)); - while true do - begin - try - Input1.ReadBuffer(I, I.Size); - except - break; - end; - SetLength(LBytes, I); - Input1.ReadBuffer(LBytes[0], I); - FS1 := TFileStream.Create(BaseDir1 + StringOf(LBytes), fmShareDenyNone); - try - Input1.ReadBuffer(I, I.Size); - for J := 0 to I - 1 do - begin - Input1.ReadBuffer(LEntry, SizeOf(TEntryStruct)); - LFilename := BaseDir2 + LEntry.Filename; - ForceDirectories(ExtractFilePath(LFilename)); - FS2 := TFileStream.Create(LFilename, fmCreate); - try - FS1.Position := LEntry.Position; - CopyStreamEx(FS1, FS2, LEntry.Size); - finally - FS2.Free; - end; - WriteLn(ErrOutput, Format('Extracted %s', [LEntry.Filename])); - end; - finally - FS1.Free; - end; - end; -end; - -end. diff --git a/io/__history/IODecode.pas.~103~ b/io/__history/IODecode.pas.~103~ deleted file mode 100644 index 7bde09c..0000000 --- a/io/__history/IODecode.pas.~103~ +++ /dev/null @@ -1,198 +0,0 @@ -unit IODecode; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PDecodeOptions = ^TDecodeOptions; - - TDecodeOptions = record - - end; - - PExtractOptions = ^TExtractOptions; - - TExtractOptions = record - - end; - -procedure PrintHelpExtract; -procedure ParseDecode(ParamArg: TArray; out Options: TDecodeOptions); -procedure ParseExtract(ParamArg: TArray; out Options: TExtractOptions); -procedure Decode(Input1: TStream; Input2, Output: String; - Options: TDecodeOptions); -procedure Extract(Input1: TStream; Input2, Output: String; - Options: TExtractOptions); - -implementation - -procedure PrintHelpExtract; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'extract - extract sectors from files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool extract decode_data original_data extracted_streams '); - WriteLn(ErrOutput, ''); -end; - -procedure ParseDecode(ParamArg: TArray; out Options: TDecodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ''; - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure ParseExtract(ParamArg: TArray; out Options: TExtractOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ''; - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Decode(Input1: TStream; Input2, Output: String; - Options: TDecodeOptions); -var - I, J: Integer; - LEntry: TEntryStruct; - LBytes: TBytes; - LFilename: String; - BaseDir1, BaseDir2: String; - SS1, SS2: TSharedMemoryStream; -begin - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Output) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)); - while true do - begin - try - Input1.ReadBuffer(I, I.Size); - except - break; - end; - SetLength(LBytes, I); - Input1.ReadBuffer(LBytes[0], I); - SS1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), - BaseDir2 + StringOf(LBytes)); - try - Input1.ReadBuffer(I, I.Size); - for J := 0 to I - 1 do - begin - Input1.ReadBuffer(LEntry, SizeOf(TEntryStruct)); - LFilename := BaseDir1 + LEntry.Filename; - if FileExists(LFilename) then - begin - SS2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LFilename); - try - Move(SS2.Memory^, (PByte(SS1.Memory) + LEntry.Position)^, - LEntry.Size); - finally - SS2.Free; - end; - WriteLn(ErrOutput, Format('Restored %s', [LEntry.Filename])); - end; - end; - finally - SS1.Free; - end; - end; -end; - -procedure Extract(Input1: TStream; Input2, Output: String; - Options: TExtractOptions); -var - I, J: Integer; - LEntry: TEntryStruct; - LBytes: TBytes; - LFilename: String; - BaseDir1, BaseDir2: String; - FS1, FS2: TFileStream; -begin - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Output) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)); - while true do - begin - try - Input1.ReadBuffer(I, I.Size); - except - break; - end; - SetLength(LBytes, I); - Input1.ReadBuffer(LBytes[0], I); - FS1 := TFileStream.Create(BaseDir1 + StringOf(LBytes), fmShareDenyNone); - try - Input1.ReadBuffer(I, I.Size); - for J := 0 to I - 1 do - begin - Input1.ReadBuffer(LEntry, SizeOf(TEntryStruct)); - LFilename := BaseDir2 + LEntry.Filename; - ForceDirectories(ExtractFilePath(LFilename)); - FS2 := TFileStream.Create(LFilename, fmCreate); - try - FS1.Position := LEntry.Position; - CopyStreamEx(FS1, FS2, LEntry.Size); - finally - FS2.Free; - end; - WriteLn(ErrOutput, Format('Extracted %s', [LEntry.Filename])); - end; - finally - FS1.Free; - end; - end; -end; - -end. diff --git a/io/__history/IODecode.pas.~104~ b/io/__history/IODecode.pas.~104~ deleted file mode 100644 index 8879635..0000000 --- a/io/__history/IODecode.pas.~104~ +++ /dev/null @@ -1,202 +0,0 @@ -unit IODecode; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PDecodeOptions = ^TDecodeOptions; - - TDecodeOptions = record - - end; - - PExtractOptions = ^TExtractOptions; - - TExtractOptions = record - - end; - -procedure PrintHelpExtract; -procedure ParseDecode(ParamArg: TArray; out Options: TDecodeOptions); -procedure ParseExtract(ParamArg: TArray; out Options: TExtractOptions); -procedure Decode(Input1: TStream; Input2, Output: String; - Options: TDecodeOptions); -procedure Extract(Input1: TStream; Input2, Output: String; - Options: TExtractOptions); - -implementation - -procedure PrintHelpExtract; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'extract - extract sectors from files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool extract decode_data original_data extracted_streams '); - WriteLn(ErrOutput, ''); -end; - -procedure ParseDecode(ParamArg: TArray; out Options: TDecodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ''; - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure ParseExtract(ParamArg: TArray; out Options: TExtractOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ''; - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Decode(Input1: TStream; Input2, Output: String; - Options: TDecodeOptions); -var - I, J: Integer; - LEntry: TEntryStruct; - LBytes: TBytes; - LFilename: String; - BaseDir1, BaseDir2: String; - SS1, SS2: TSharedMemoryStream; -begin - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Output) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)); - while true do - begin - try - Input1.ReadBuffer(I, I.Size); - except - break; - end; - SetLength(LBytes, I); - Input1.ReadBuffer(LBytes[0], I); - SS1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), - BaseDir2 + StringOf(LBytes)); - try - Input1.ReadBuffer(I, I.Size); - for J := 0 to I - 1 do - begin - Input1.ReadBuffer(LEntry, SizeOf(TEntryStruct)); - LFilename := BaseDir1 + LEntry.Filename; - if FileExists(LFilename) then - begin - SS2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LFilename); - try - Move(SS2.Memory^, (PByte(SS1.Memory) + LEntry.Position)^, - LEntry.Size); - finally - SS2.Free; - end; - WriteLn(ErrOutput, Format('Restored %s', [LEntry.Filename])); - end; - end; - finally - SS1.Free; - end; - end; -end; - -procedure Extract(Input1: TStream; Input2, Output: String; - Options: TExtractOptions); -var - I, J: Integer; - LEntry: TEntryStruct; - LBytes: TBytes; - LFilename: String; - BaseDir1, BaseDir2: String; - FS1, FS2: TFileStream; -begin - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Output) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)); - while true do - begin - try - Input1.ReadBuffer(I, I.Size); - except - break; - end; - SetLength(LBytes, I); - Input1.ReadBuffer(LBytes[0], I); - if FileExists(Input2) then - LFilename := Input2 - else - LFilename := BaseDir1 + PEntry^.Filename; - FS1 := TFileStream.Create(BaseDir1 + StringOf(LBytes), fmShareDenyNone); - try - Input1.ReadBuffer(I, I.Size); - for J := 0 to I - 1 do - begin - Input1.ReadBuffer(LEntry, SizeOf(TEntryStruct)); - LFilename := BaseDir2 + LEntry.Filename; - ForceDirectories(ExtractFilePath(LFilename)); - FS2 := TFileStream.Create(LFilename, fmCreate); - try - FS1.Position := LEntry.Position; - CopyStreamEx(FS1, FS2, LEntry.Size); - finally - FS2.Free; - end; - WriteLn(ErrOutput, Format('Extracted %s', [LEntry.Filename])); - end; - finally - FS1.Free; - end; - end; -end; - -end. diff --git a/io/__history/IODecode.pas.~105~ b/io/__history/IODecode.pas.~105~ deleted file mode 100644 index 8879635..0000000 --- a/io/__history/IODecode.pas.~105~ +++ /dev/null @@ -1,202 +0,0 @@ -unit IODecode; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PDecodeOptions = ^TDecodeOptions; - - TDecodeOptions = record - - end; - - PExtractOptions = ^TExtractOptions; - - TExtractOptions = record - - end; - -procedure PrintHelpExtract; -procedure ParseDecode(ParamArg: TArray; out Options: TDecodeOptions); -procedure ParseExtract(ParamArg: TArray; out Options: TExtractOptions); -procedure Decode(Input1: TStream; Input2, Output: String; - Options: TDecodeOptions); -procedure Extract(Input1: TStream; Input2, Output: String; - Options: TExtractOptions); - -implementation - -procedure PrintHelpExtract; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'extract - extract sectors from files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool extract decode_data original_data extracted_streams '); - WriteLn(ErrOutput, ''); -end; - -procedure ParseDecode(ParamArg: TArray; out Options: TDecodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ''; - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure ParseExtract(ParamArg: TArray; out Options: TExtractOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ''; - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Decode(Input1: TStream; Input2, Output: String; - Options: TDecodeOptions); -var - I, J: Integer; - LEntry: TEntryStruct; - LBytes: TBytes; - LFilename: String; - BaseDir1, BaseDir2: String; - SS1, SS2: TSharedMemoryStream; -begin - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Output) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)); - while true do - begin - try - Input1.ReadBuffer(I, I.Size); - except - break; - end; - SetLength(LBytes, I); - Input1.ReadBuffer(LBytes[0], I); - SS1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), - BaseDir2 + StringOf(LBytes)); - try - Input1.ReadBuffer(I, I.Size); - for J := 0 to I - 1 do - begin - Input1.ReadBuffer(LEntry, SizeOf(TEntryStruct)); - LFilename := BaseDir1 + LEntry.Filename; - if FileExists(LFilename) then - begin - SS2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LFilename); - try - Move(SS2.Memory^, (PByte(SS1.Memory) + LEntry.Position)^, - LEntry.Size); - finally - SS2.Free; - end; - WriteLn(ErrOutput, Format('Restored %s', [LEntry.Filename])); - end; - end; - finally - SS1.Free; - end; - end; -end; - -procedure Extract(Input1: TStream; Input2, Output: String; - Options: TExtractOptions); -var - I, J: Integer; - LEntry: TEntryStruct; - LBytes: TBytes; - LFilename: String; - BaseDir1, BaseDir2: String; - FS1, FS2: TFileStream; -begin - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Output) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)); - while true do - begin - try - Input1.ReadBuffer(I, I.Size); - except - break; - end; - SetLength(LBytes, I); - Input1.ReadBuffer(LBytes[0], I); - if FileExists(Input2) then - LFilename := Input2 - else - LFilename := BaseDir1 + PEntry^.Filename; - FS1 := TFileStream.Create(BaseDir1 + StringOf(LBytes), fmShareDenyNone); - try - Input1.ReadBuffer(I, I.Size); - for J := 0 to I - 1 do - begin - Input1.ReadBuffer(LEntry, SizeOf(TEntryStruct)); - LFilename := BaseDir2 + LEntry.Filename; - ForceDirectories(ExtractFilePath(LFilename)); - FS2 := TFileStream.Create(LFilename, fmCreate); - try - FS1.Position := LEntry.Position; - CopyStreamEx(FS1, FS2, LEntry.Size); - finally - FS2.Free; - end; - WriteLn(ErrOutput, Format('Extracted %s', [LEntry.Filename])); - end; - finally - FS1.Free; - end; - end; -end; - -end. diff --git a/io/__history/IODecode.pas.~106~ b/io/__history/IODecode.pas.~106~ deleted file mode 100644 index 7bde09c..0000000 --- a/io/__history/IODecode.pas.~106~ +++ /dev/null @@ -1,198 +0,0 @@ -unit IODecode; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PDecodeOptions = ^TDecodeOptions; - - TDecodeOptions = record - - end; - - PExtractOptions = ^TExtractOptions; - - TExtractOptions = record - - end; - -procedure PrintHelpExtract; -procedure ParseDecode(ParamArg: TArray; out Options: TDecodeOptions); -procedure ParseExtract(ParamArg: TArray; out Options: TExtractOptions); -procedure Decode(Input1: TStream; Input2, Output: String; - Options: TDecodeOptions); -procedure Extract(Input1: TStream; Input2, Output: String; - Options: TExtractOptions); - -implementation - -procedure PrintHelpExtract; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'extract - extract sectors from files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool extract decode_data original_data extracted_streams '); - WriteLn(ErrOutput, ''); -end; - -procedure ParseDecode(ParamArg: TArray; out Options: TDecodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ''; - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure ParseExtract(ParamArg: TArray; out Options: TExtractOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ''; - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Decode(Input1: TStream; Input2, Output: String; - Options: TDecodeOptions); -var - I, J: Integer; - LEntry: TEntryStruct; - LBytes: TBytes; - LFilename: String; - BaseDir1, BaseDir2: String; - SS1, SS2: TSharedMemoryStream; -begin - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Output) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)); - while true do - begin - try - Input1.ReadBuffer(I, I.Size); - except - break; - end; - SetLength(LBytes, I); - Input1.ReadBuffer(LBytes[0], I); - SS1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), - BaseDir2 + StringOf(LBytes)); - try - Input1.ReadBuffer(I, I.Size); - for J := 0 to I - 1 do - begin - Input1.ReadBuffer(LEntry, SizeOf(TEntryStruct)); - LFilename := BaseDir1 + LEntry.Filename; - if FileExists(LFilename) then - begin - SS2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LFilename); - try - Move(SS2.Memory^, (PByte(SS1.Memory) + LEntry.Position)^, - LEntry.Size); - finally - SS2.Free; - end; - WriteLn(ErrOutput, Format('Restored %s', [LEntry.Filename])); - end; - end; - finally - SS1.Free; - end; - end; -end; - -procedure Extract(Input1: TStream; Input2, Output: String; - Options: TExtractOptions); -var - I, J: Integer; - LEntry: TEntryStruct; - LBytes: TBytes; - LFilename: String; - BaseDir1, BaseDir2: String; - FS1, FS2: TFileStream; -begin - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Output) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)); - while true do - begin - try - Input1.ReadBuffer(I, I.Size); - except - break; - end; - SetLength(LBytes, I); - Input1.ReadBuffer(LBytes[0], I); - FS1 := TFileStream.Create(BaseDir1 + StringOf(LBytes), fmShareDenyNone); - try - Input1.ReadBuffer(I, I.Size); - for J := 0 to I - 1 do - begin - Input1.ReadBuffer(LEntry, SizeOf(TEntryStruct)); - LFilename := BaseDir2 + LEntry.Filename; - ForceDirectories(ExtractFilePath(LFilename)); - FS2 := TFileStream.Create(LFilename, fmCreate); - try - FS1.Position := LEntry.Position; - CopyStreamEx(FS1, FS2, LEntry.Size); - finally - FS2.Free; - end; - WriteLn(ErrOutput, Format('Extracted %s', [LEntry.Filename])); - end; - finally - FS1.Free; - end; - end; -end; - -end. diff --git a/io/__history/IODecode.pas.~107~ b/io/__history/IODecode.pas.~107~ deleted file mode 100644 index 7bde09c..0000000 --- a/io/__history/IODecode.pas.~107~ +++ /dev/null @@ -1,198 +0,0 @@ -unit IODecode; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PDecodeOptions = ^TDecodeOptions; - - TDecodeOptions = record - - end; - - PExtractOptions = ^TExtractOptions; - - TExtractOptions = record - - end; - -procedure PrintHelpExtract; -procedure ParseDecode(ParamArg: TArray; out Options: TDecodeOptions); -procedure ParseExtract(ParamArg: TArray; out Options: TExtractOptions); -procedure Decode(Input1: TStream; Input2, Output: String; - Options: TDecodeOptions); -procedure Extract(Input1: TStream; Input2, Output: String; - Options: TExtractOptions); - -implementation - -procedure PrintHelpExtract; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'extract - extract sectors from files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool extract decode_data original_data extracted_streams '); - WriteLn(ErrOutput, ''); -end; - -procedure ParseDecode(ParamArg: TArray; out Options: TDecodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ''; - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure ParseExtract(ParamArg: TArray; out Options: TExtractOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ''; - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Decode(Input1: TStream; Input2, Output: String; - Options: TDecodeOptions); -var - I, J: Integer; - LEntry: TEntryStruct; - LBytes: TBytes; - LFilename: String; - BaseDir1, BaseDir2: String; - SS1, SS2: TSharedMemoryStream; -begin - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Output) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)); - while true do - begin - try - Input1.ReadBuffer(I, I.Size); - except - break; - end; - SetLength(LBytes, I); - Input1.ReadBuffer(LBytes[0], I); - SS1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), - BaseDir2 + StringOf(LBytes)); - try - Input1.ReadBuffer(I, I.Size); - for J := 0 to I - 1 do - begin - Input1.ReadBuffer(LEntry, SizeOf(TEntryStruct)); - LFilename := BaseDir1 + LEntry.Filename; - if FileExists(LFilename) then - begin - SS2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LFilename); - try - Move(SS2.Memory^, (PByte(SS1.Memory) + LEntry.Position)^, - LEntry.Size); - finally - SS2.Free; - end; - WriteLn(ErrOutput, Format('Restored %s', [LEntry.Filename])); - end; - end; - finally - SS1.Free; - end; - end; -end; - -procedure Extract(Input1: TStream; Input2, Output: String; - Options: TExtractOptions); -var - I, J: Integer; - LEntry: TEntryStruct; - LBytes: TBytes; - LFilename: String; - BaseDir1, BaseDir2: String; - FS1, FS2: TFileStream; -begin - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Output) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)); - while true do - begin - try - Input1.ReadBuffer(I, I.Size); - except - break; - end; - SetLength(LBytes, I); - Input1.ReadBuffer(LBytes[0], I); - FS1 := TFileStream.Create(BaseDir1 + StringOf(LBytes), fmShareDenyNone); - try - Input1.ReadBuffer(I, I.Size); - for J := 0 to I - 1 do - begin - Input1.ReadBuffer(LEntry, SizeOf(TEntryStruct)); - LFilename := BaseDir2 + LEntry.Filename; - ForceDirectories(ExtractFilePath(LFilename)); - FS2 := TFileStream.Create(LFilename, fmCreate); - try - FS1.Position := LEntry.Position; - CopyStreamEx(FS1, FS2, LEntry.Size); - finally - FS2.Free; - end; - WriteLn(ErrOutput, Format('Extracted %s', [LEntry.Filename])); - end; - finally - FS1.Free; - end; - end; -end; - -end. diff --git a/io/__history/IODecode.pas.~108~ b/io/__history/IODecode.pas.~108~ deleted file mode 100644 index 33d09a1..0000000 --- a/io/__history/IODecode.pas.~108~ +++ /dev/null @@ -1,198 +0,0 @@ -unit IODecode; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PDecodeOptions = ^TDecodeOptions; - - TDecodeOptions = record - - end; - - PExtractOptions = ^TExtractOptions; - - TExtractOptions = record - - end; - -procedure PrintHelpExtract; -procedure ParseDecode(ParamArg: TArray; out Options: TDecodeOptions); -procedure ParseExtract(ParamArg: TArray; out Options: TExtractOptions); -procedure Decode(Input1: TStream; Input2, Output: String; - Options: TDecodeOptions); -procedure Extract(Input1: TStream; Input2, Output: String; - Options: TExtractOptions); - -implementation - -procedure PrintHelpExtract; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'extract - extract sectors from files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool extract decode_data original_data extracted_streams '); - WriteLn(ErrOutput, ''); -end; - -procedure ParseDecode(ParamArg: TArray; out Options: TDecodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ''; - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure ParseExtract(ParamArg: TArray; out Options: TExtractOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ''; - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Decode(Input1: TStream; Input2, Output: String; - Options: TDecodeOptions); -var - I, J: Integer; - LEntry: TEntryStruct1; - LBytes: TBytes; - LFilename: String; - BaseDir1, BaseDir2: String; - SS1, SS2: TSharedMemoryStream; -begin - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Output) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)); - while true do - begin - try - Input1.ReadBuffer(I, I.Size); - except - break; - end; - SetLength(LBytes, I); - Input1.ReadBuffer(LBytes[0], I); - SS1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), - BaseDir2 + StringOf(LBytes)); - try - Input1.ReadBuffer(I, I.Size); - for J := 0 to I - 1 do - begin - Input1.ReadBuffer(LEntry, SizeOf(TEntryStruct1)); - LFilename := BaseDir1 + LEntry.Filename; - if FileExists(LFilename) then - begin - SS2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LFilename); - try - Move(SS2.Memory^, (PByte(SS1.Memory) + LEntry.Position)^, - LEntry.Size); - finally - SS2.Free; - end; - WriteLn(ErrOutput, Format('Restored %s', [LEntry.Filename])); - end; - end; - finally - SS1.Free; - end; - end; -end; - -procedure Extract(Input1: TStream; Input2, Output: String; - Options: TExtractOptions); -var - I, J: Integer; - LEntry: TEntryStruct1; - LBytes: TBytes; - LFilename: String; - BaseDir1, BaseDir2: String; - FS1, FS2: TFileStream; -begin - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Output) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)); - while true do - begin - try - Input1.ReadBuffer(I, I.Size); - except - break; - end; - SetLength(LBytes, I); - Input1.ReadBuffer(LBytes[0], I); - FS1 := TFileStream.Create(BaseDir1 + StringOf(LBytes), fmShareDenyNone); - try - Input1.ReadBuffer(I, I.Size); - for J := 0 to I - 1 do - begin - Input1.ReadBuffer(LEntry, SizeOf(TEntryStruct)); - LFilename := BaseDir2 + LEntry.Filename; - ForceDirectories(ExtractFilePath(LFilename)); - FS2 := TFileStream.Create(LFilename, fmCreate); - try - FS1.Position := LEntry.Position; - CopyStreamEx(FS1, FS2, LEntry.Size); - finally - FS2.Free; - end; - WriteLn(ErrOutput, Format('Extracted %s', [LEntry.Filename])); - end; - finally - FS1.Free; - end; - end; -end; - -end. diff --git a/io/__history/IODecode.pas.~109~ b/io/__history/IODecode.pas.~109~ deleted file mode 100644 index 2299ec2..0000000 --- a/io/__history/IODecode.pas.~109~ +++ /dev/null @@ -1,198 +0,0 @@ -unit IODecode; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PDecodeOptions = ^TDecodeOptions; - - TDecodeOptions = record - - end; - - PExtractOptions = ^TExtractOptions; - - TExtractOptions = record - - end; - -procedure PrintHelpExtract; -procedure ParseDecode(ParamArg: TArray; out Options: TDecodeOptions); -procedure ParseExtract(ParamArg: TArray; out Options: TExtractOptions); -procedure Decode(Input1: TStream; Input2, Output: String; - Options: TDecodeOptions); -procedure Extract(Input1: TStream; Input2, Output: String; - Options: TExtractOptions); - -implementation - -procedure PrintHelpExtract; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'extract - extract sectors from files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool extract decode_data original_data extracted_streams '); - WriteLn(ErrOutput, ''); -end; - -procedure ParseDecode(ParamArg: TArray; out Options: TDecodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ''; - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure ParseExtract(ParamArg: TArray; out Options: TExtractOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ''; - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Decode(Input1: TStream; Input2, Output: String; - Options: TDecodeOptions); -var - I, J: Integer; - LEntry: TEntryStruct1; - LBytes: TBytes; - LFilename: String; - BaseDir1, BaseDir2: String; - SS1, SS2: TSharedMemoryStream; -begin - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Output) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)); - while true do - begin - try - Input1.ReadBuffer(I, I.Size); - except - break; - end; - SetLength(LBytes, I); - Input1.ReadBuffer(LBytes[0], I); - SS1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), - BaseDir2 + StringOf(LBytes)); - try - Input1.ReadBuffer(I, I.Size); - for J := 0 to I - 1 do - begin - Input1.ReadBuffer(LEntry, SizeOf(TEntryStruct1)); - LFilename := BaseDir1 + LEntry.Filename; - if FileExists(LFilename) then - begin - SS2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LFilename); - try - Move(SS2.Memory^, (PByte(SS1.Memory) + LEntry.Position)^, - LEntry.Size); - finally - SS2.Free; - end; - WriteLn(ErrOutput, Format('Restored %s', [LEntry.Filename])); - end; - end; - finally - SS1.Free; - end; - end; -end; - -procedure Extract(Input1: TStream; Input2, Output: String; - Options: TExtractOptions); -var - I, J: Integer; - LEntry: TEntryStruct1; - LBytes: TBytes; - LFilename: String; - BaseDir1, BaseDir2: String; - FS1, FS2: TFileStream; -begin - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Output) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)); - while true do - begin - try - Input1.ReadBuffer(I, I.Size); - except - break; - end; - SetLength(LBytes, I); - Input1.ReadBuffer(LBytes[0], I); - FS1 := TFileStream.Create(BaseDir1 + StringOf(LBytes), fmShareDenyNone); - try - Input1.ReadBuffer(I, I.Size); - for J := 0 to I - 1 do - begin - Input1.ReadBuffer(LEntry, SizeOf(TEntryStruct1)); - LFilename := BaseDir2 + LEntry.Filename; - ForceDirectories(ExtractFilePath(LFilename)); - FS2 := TFileStream.Create(LFilename, fmCreate); - try - FS1.Position := LEntry.Position; - CopyStreamEx(FS1, FS2, LEntry.Size); - finally - FS2.Free; - end; - WriteLn(ErrOutput, Format('Extracted %s', [LEntry.Filename])); - end; - finally - FS1.Free; - end; - end; -end; - -end. diff --git a/io/__history/IODecode.pas.~110~ b/io/__history/IODecode.pas.~110~ deleted file mode 100644 index 4ee9769..0000000 --- a/io/__history/IODecode.pas.~110~ +++ /dev/null @@ -1,198 +0,0 @@ -unit IODecode; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PDecodeOptions = ^TDecodeOptions; - - TDecodeOptions = record - - end; - - PExtractOptions = ^TExtractOptions; - - TExtractOptions = record - - end; - -procedure PrintHelpExtract; -procedure ParseDecode(ParamArg: TArray; out Options: TDecodeOptions); -procedure ParseExtract(ParamArg: TArray; out Options: TExtractOptions); -procedure Decode(Input1: TStream; Input2, Output: String; - Options: TDecodeOptions); -procedure Extract(Input1: TStream; Input2, Output: String; - Options: TExtractOptions); - -implementation - -procedure PrintHelpExtract; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'extract - extract sectors from files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool extract decode_data original_data extracted_streams '); - WriteLn(ErrOutput, ''); -end; - -procedure ParseDecode(ParamArg: TArray; out Options: TDecodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ''; - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure ParseExtract(ParamArg: TArray; out Options: TExtractOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ''; - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Decode(Input1: TStream; Input2, Output: String; - Options: TDecodeOptions); -var - I, J: Integer; - LEntry: TEntryStruct1; - LBytes: TBytes; - LFilename: String; - BaseDir1, BaseDir2: String; - SS1, SS2: TSharedMemoryStream; -begin - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Output) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)); - while true do - begin - try - Input1.ReadBuffer(I, I.Size); - except - break; - end; - SetLength(LBytes, I); - Input1.ReadBuffer(LBytes[0], I); - SS1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + StringOf(LBytes)); - try - Input1.ReadBuffer(I, I.Size); - for J := 0 to I - 1 do - begin - Input1.ReadBuffer(LEntry, SizeOf(TEntryStruct1)); - LFilename := BaseDir1 + LEntry.Filename; - if FileExists(LFilename) then - begin - SS2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - try - Move(SS2.Memory^, (PByte(SS1.Memory) + LEntry.Position)^, - LEntry.Size); - finally - SS2.Free; - end; - WriteLn(ErrOutput, Format('Restored %s', [LEntry.Filename])); - end; - end; - finally - SS1.Free; - end; - end; -end; - -procedure Extract(Input1: TStream; Input2, Output: String; - Options: TExtractOptions); -var - I, J: Integer; - LEntry: TEntryStruct1; - LBytes: TBytes; - LFilename: String; - BaseDir1, BaseDir2: String; - FS1, FS2: TFileStream; -begin - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Output) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Output)); - while true do - begin - try - Input1.ReadBuffer(I, I.Size); - except - break; - end; - SetLength(LBytes, I); - Input1.ReadBuffer(LBytes[0], I); - FS1 := TFileStream.Create(BaseDir1 + StringOf(LBytes), fmShareDenyNone); - try - Input1.ReadBuffer(I, I.Size); - for J := 0 to I - 1 do - begin - Input1.ReadBuffer(LEntry, SizeOf(TEntryStruct1)); - LFilename := BaseDir2 + LEntry.Filename; - ForceDirectories(ExtractFilePath(LFilename)); - FS2 := TFileStream.Create(LFilename, fmCreate); - try - FS1.Position := LEntry.Position; - CopyStreamEx(FS1, FS2, LEntry.Size); - finally - FS2.Free; - end; - WriteLn(ErrOutput, Format('Extracted %s', [LEntry.Filename])); - end; - finally - FS1.Free; - end; - end; -end; - -end. diff --git a/io/__history/IOErase.pas.~100~ b/io/__history/IOErase.pas.~100~ deleted file mode 100644 index d1c286d..0000000 --- a/io/__history/IOErase.pas.~100~ +++ /dev/null @@ -1,340 +0,0 @@ -unit IOErase; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'erase - blank out sectors within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool erase [parameters] extracted_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - BaseDir: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('%s is smaller than %d', [LList[I], MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('%s is larger than %d', - [LList[I], Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].ActualSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)); - LList := GetFileList([Input2], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - WriteLn(ErrOutput, Format('%s is smaller than %d', - [LList[I], MinSize2])); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - FillChar((PByte(SStream.Memory) + PEntry.Position)^, - PEntry.Size, 0); - end; - finally - SStream.Free; - end; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('%s is smaller than %d', - [LList[I], MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOErase.pas.~101~ b/io/__history/IOErase.pas.~101~ deleted file mode 100644 index 3484d63..0000000 --- a/io/__history/IOErase.pas.~101~ +++ /dev/null @@ -1,341 +0,0 @@ -unit IOErase; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'erase - blank out sectors within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool erase [parameters] extracted_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - BaseDir: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('%s is smaller than %d', [LList[I], MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('%s is larger than %d', - [LList[I], Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].ActualSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)); - LList := GetFileList([Input2], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - WriteLn(ErrOutput, Format('Found %s in %s at %d', - [LEntry.Filename, ReplaceText(LList[I], BaseDir, ''), - MinSize2])); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - FillChar((PByte(SStream.Memory) + PEntry.Position)^, - PEntry.Size, 0); - end; - finally - SStream.Free; - end; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('%s is smaller than %d', - [LList[I], MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOErase.pas.~102~ b/io/__history/IOErase.pas.~102~ deleted file mode 100644 index 5dc95f9..0000000 --- a/io/__history/IOErase.pas.~102~ +++ /dev/null @@ -1,341 +0,0 @@ -unit IOErase; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'erase - blank out sectors within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool erase [parameters] extracted_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - BaseDir: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('%s is smaller than %d', [LList[I], MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('%s is larger than %d', - [LList[I], Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].ActualSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)); - LList := GetFileList([Input2], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - WriteLn(ErrOutput, Format('Found %s in %s at %s', - [LEntry.Filename, ReplaceText(LList[I], BaseDir, ''), - MinSize2])); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - FillChar((PByte(SStream.Memory) + PEntry.Position)^, - PEntry.Size, 0); - end; - finally - SStream.Free; - end; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('%s is smaller than %d', - [LList[I], MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOErase.pas.~103~ b/io/__history/IOErase.pas.~103~ deleted file mode 100644 index cbcc539..0000000 --- a/io/__history/IOErase.pas.~103~ +++ /dev/null @@ -1,341 +0,0 @@ -unit IOErase; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'erase - blank out sectors within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool erase [parameters] extracted_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - BaseDir: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('%s is smaller than %d', [LList[I], MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('%s is larger than %d', - [LList[I], Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].ActualSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)); - LList := GetFileList([Input2], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - WriteLn(ErrOutput, Format('Found %s in %s at %s', - [LEntry.Filename, ReplaceText(LList[I], BaseDir, ''), - LEntry.Position.ToHexString])); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - FillChar((PByte(SStream.Memory) + PEntry.Position)^, - PEntry.Size, 0); - end; - finally - SStream.Free; - end; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('%s is smaller than %d', - [LList[I], MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOErase.pas.~104~ b/io/__history/IOErase.pas.~104~ deleted file mode 100644 index 1eba2fd..0000000 --- a/io/__history/IOErase.pas.~104~ +++ /dev/null @@ -1,341 +0,0 @@ -unit IOErase; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'erase - blank out sectors within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool erase [parameters] extracted_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - BaseDir: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('%s is smaller than %d', [LList[I], MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('%s is larger than %d', - [LList[I], Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].ActualSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)); - LList := GetFileList([Input2], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - WriteLn(ErrOutput, Format('Found %s in %s at %s', - [LEntry.Filename, ReplaceText(LList[I], BaseDir, ''), - LEntry.Position.ToHexString])); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - FillChar((PByte(SStream.Memory) + PEntry.Position)^, - PEntry.Size, 0); - end; - finally - SStream.Free; - end; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [LList[I], MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOErase.pas.~105~ b/io/__history/IOErase.pas.~105~ deleted file mode 100644 index d101288..0000000 --- a/io/__history/IOErase.pas.~105~ +++ /dev/null @@ -1,341 +0,0 @@ -unit IOErase; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'erase - blank out sectors within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool erase [parameters] extracted_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - BaseDir: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('%s is smaller than %d', [LList[I], MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('%s is larger than %d', - [LList[I], Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].ActualSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)); - LList := GetFileList([Input2], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - WriteLn(ErrOutput, Format('Found %s in %s at %s', - [LEntry.Filename, ReplaceText(LList[I], BaseDir, ''), - LEntry.Position.ToHexString])); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - FillChar((PByte(SStream.Memory) + PEntry.Position)^, - PEntry.Size, 0); - end; - finally - SStream.Free; - end; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir, ''), MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOErase.pas.~106~ b/io/__history/IOErase.pas.~106~ deleted file mode 100644 index 7a7b066..0000000 --- a/io/__history/IOErase.pas.~106~ +++ /dev/null @@ -1,342 +0,0 @@ -unit IOErase; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'erase - blank out sectors within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool erase [parameters] extracted_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - BaseDir: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('%s is smaller than %d', - [ReplaceText(LList[I], BaseDir, ''), MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('%s is larger than %d', - [ReplaceText(LList[I], BaseDir, ''), Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].ActualSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)); - LList := GetFileList([Input2], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - WriteLn(ErrOutput, Format('Found %s in %s at %s', - [LEntry.Filename, ReplaceText(LList[I], BaseDir, ''), - LEntry.Position.ToHexString])); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - FillChar((PByte(SStream.Memory) + PEntry.Position)^, - PEntry.Size, 0); - end; - finally - SStream.Free; - end; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir, ''), MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOErase.pas.~107~ b/io/__history/IOErase.pas.~107~ deleted file mode 100644 index bdd5d32..0000000 --- a/io/__history/IOErase.pas.~107~ +++ /dev/null @@ -1,342 +0,0 @@ -unit IOErase; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'erase - blank out sectors within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool erase [parameters] extracted_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - BaseDir: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir, ''), MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('Skipped %s (Larger than %d)', - [ReplaceText(LList[I], BaseDir, ''), Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].ActualSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)); - LList := GetFileList([Input2], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - WriteLn(ErrOutput, Format('Found %s in %s at %s', - [LEntry.Filename, ReplaceText(LList[I], BaseDir, ''), - LEntry.Position.ToHexString])); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - FillChar((PByte(SStream.Memory) + PEntry.Position)^, - PEntry.Size, 0); - end; - finally - SStream.Free; - end; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir, ''), MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOErase.pas.~108~ b/io/__history/IOErase.pas.~108~ deleted file mode 100644 index 385b714..0000000 --- a/io/__history/IOErase.pas.~108~ +++ /dev/null @@ -1,342 +0,0 @@ -unit IOErase; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'erase - blank out sectors within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool erase [parameters] extracted_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - BaseDir: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct1; - PEntry: PEntryStruct1; - LBytes: TBytes; - FStream: TFileStream; - SStream: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir, ''), MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('Skipped %s (Larger than %d)', - [ReplaceText(LList[I], BaseDir, ''), Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct1; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].ActualSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)); - LList := GetFileList([Input2], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct1)); - WriteLn(ErrOutput, Format('Found %s in %s at %s', - [LEntry.Filename, ReplaceText(LList[I], BaseDir, ''), - LEntry.Position.ToHexString])); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct1(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - FillChar((PByte(SStream.Memory) + PEntry.Position)^, - PEntry.Size, 0); - end; - finally - SStream.Free; - end; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir, ''), MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOErase.pas.~99~ b/io/__history/IOErase.pas.~99~ deleted file mode 100644 index 880e620..0000000 --- a/io/__history/IOErase.pas.~99~ +++ /dev/null @@ -1,338 +0,0 @@ -unit IOErase; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'erase - blank out sectors within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool erase [parameters] extracted_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - BaseDir: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('%s is smaller than %d', [LList[I], MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('%s is larger than %d', - [LList[I], Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].ActualSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)); - LList := GetFileList([Input2], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - FillChar((PByte(SStream.Memory) + PEntry.Position)^, - PEntry.Size, 0); - end; - finally - SStream.Free; - end; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('%s is smaller than %d', - [LList[I], MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOFind.pas.~1~ b/io/__history/IOFind.pas.~1~ deleted file mode 100644 index 72901ed..0000000 --- a/io/__history/IOFind.pas.~1~ +++ /dev/null @@ -1,7 +0,0 @@ -unit IOFind; - -interface - -implementation - -end. diff --git a/io/__history/IOFind.pas.~2~ b/io/__history/IOFind.pas.~2~ deleted file mode 100644 index f799d1f..0000000 --- a/io/__history/IOFind.pas.~2~ +++ /dev/null @@ -1,341 +0,0 @@ -unit IOFind; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'find - search for sectors within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool find [parameters] extracted_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - BaseDir: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('%s is smaller than %d', [LList[I], MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('%s is larger than %d', - [LList[I], Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].ActualSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)); - LList := GetFileList([Input2], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - WriteLn(ErrOutput, Format('Found %s in %s at %s', - [LEntry.Filename, ReplaceText(LList[I], BaseDir, ''), - LEntry.Position.ToHexString])); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - FillChar((PByte(SStream.Memory) + PEntry.Position)^, - PEntry.Size, 0); - end; - finally - SStream.Free; - end; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir, ''), MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOFind.pas.~3~ b/io/__history/IOFind.pas.~3~ deleted file mode 100644 index e95e4ac..0000000 --- a/io/__history/IOFind.pas.~3~ +++ /dev/null @@ -1,324 +0,0 @@ -unit IOFind; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'find - search for sectors within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool find [parameters] extracted_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - BaseDir: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('%s is smaller than %d', [LList[I], MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('%s is larger than %d', - [LList[I], Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].ActualSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)); - LList := GetFileList([Input2], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - WriteLn(ErrOutput, Format('Found %s in %s at %s', - [LEntry.Filename, ReplaceText(LList[I], BaseDir, ''), - LEntry.Position.ToHexString])); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir, ''), MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOFind.pas.~4~ b/io/__history/IOFind.pas.~4~ deleted file mode 100644 index e95e4ac..0000000 --- a/io/__history/IOFind.pas.~4~ +++ /dev/null @@ -1,324 +0,0 @@ -unit IOFind; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'find - search for sectors within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool find [parameters] extracted_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - BaseDir: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('%s is smaller than %d', [LList[I], MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('%s is larger than %d', - [LList[I], Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].ActualSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)); - LList := GetFileList([Input2], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - WriteLn(ErrOutput, Format('Found %s in %s at %s', - [LEntry.Filename, ReplaceText(LList[I], BaseDir, ''), - LEntry.Position.ToHexString])); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir, ''), MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOFind.pas.~5~ b/io/__history/IOFind.pas.~5~ deleted file mode 100644 index 1732ad3..0000000 --- a/io/__history/IOFind.pas.~5~ +++ /dev/null @@ -1,325 +0,0 @@ -unit IOFind; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'find - search for sectors within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool find [parameters] extracted_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - BaseDir: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('%s is smaller than %d', - [ReplaceText(LList[I], BaseDir, ''), MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('%s is larger than %d', - [ReplaceText(LList[I], BaseDir, ''), Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].ActualSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)); - LList := GetFileList([Input2], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - WriteLn(ErrOutput, Format('Found %s in %s at %s', - [LEntry.Filename, ReplaceText(LList[I], BaseDir, ''), - LEntry.Position.ToHexString])); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir, ''), MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOFind.pas.~6~ b/io/__history/IOFind.pas.~6~ deleted file mode 100644 index c5692e3..0000000 --- a/io/__history/IOFind.pas.~6~ +++ /dev/null @@ -1,325 +0,0 @@ -unit IOFind; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'find - search for sectors within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool find [parameters] extracted_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Output: String; Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - BaseDir: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir, ''), MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('Skipped %s (Larger than %d)', - [ReplaceText(LList[I], BaseDir, ''), Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].ActualSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Input2)); - LList := GetFileList([Input2], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - WriteLn(ErrOutput, Format('Found %s in %s at %s', - [LEntry.Filename, ReplaceText(LList[I], BaseDir, ''), - LEntry.Position.ToHexString])); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir, ''), MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOPatch.pas.~302~ b/io/__history/IOPatch.pas.~302~ deleted file mode 100644 index 60d1cac..0000000 --- a/io/__history/IOPatch.pas.~302~ +++ /dev/null @@ -1,429 +0,0 @@ -unit IOPatch; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - Threads: Integer; - MinSize, MaxSize: Int64; - end; - - PDecodeOptions = ^TDecodeOptions; - - TDecodeOptions = record - Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); - overload; -procedure Parse(ParamArg: TArray; out Options: TDecodeOptions); - overload; -procedure Encode(Input1, Input2: String; Output: TStream; - Options: TEncodeOptions); -procedure Decode(Input: TStream; Output: String; Options: TDecodeOptions); - -implementation - -uses - XDeltaDLL; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'patch - creates patches between two data sets'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, ' xtool patch [parameters] old_data new_data patch_data'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('--min=', 0, '64k'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.MinSize := Max(0, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('--max=', 0, '16g'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.MaxSize := Max(0, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Parse(ParamArg: TArray; out Options: TDecodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2: String; Output: TStream; - Options: TEncodeOptions); -var - I, J, K: Integer; - I64: Int64; - B, C: Boolean; - LFilename: String; - BaseDir1, BaseDir2: String; - LList1, LList2: TArray; - LBytes: TBytes; - LEntry: TEntryStruct2; - FStream: TFileStream; - SStream1, SStream2: TSharedMemoryStream; - Tasks: TArray; - CS: TCriticalSection; - TempDir: String; -begin - C := FileExists(Input1) and FileExists(Input2); - if FileExists(Input1) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)); - LList1 := GetFileList([Input1], True); - for I := Low(LList1) to High(LList1) do - LList1[I] := ReplaceText(LList1[I], BaseDir1, ''); - if FileExists(Input2) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input2)); - LList2 := GetFileList([Input2], True); - for I := Low(LList2) to High(LList2) do - LList2[I] := ReplaceText(LList2[I], BaseDir2, ''); - K := XTOOL_PATCH; - Output.WriteBuffer(K, K.Size); - if not C then - for I := High(LList1) downto Low(LList1) do - begin - if IndexText(LList1[I], LList2) < 0 then - begin - LEntry.Op := TPatchOp.opDelete; - LEntry.Filename := LList1[I]; - LEntry.Size := FileSize(BaseDir1 + LList1[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - Delete(LList1, I, 1); - end; - end; - if not C then - for I := High(LList2) downto Low(LList2) do - begin - if IndexText(LList2[I], LList1) < 0 then - begin - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir2 + LList2[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - Delete(LList2, I, 1); - end; - end; - for I := High(LList2) downto Low(LList2) do - begin - if C then - LFilename := Input1 - else - LFilename := BaseDir1 + LList2[I]; - if FileSize(LFilename) <> FileSize(BaseDir2 + LList2[I]) then - begin - if InRange(FileSize(BaseDir2 + LList2[I]), Options.MinSize, - Options.MaxSize) then - continue; - end - else - begin - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + LList2[I]); - try - B := SynCommons.CompareMem(SStream1.Memory, SStream2.Memory, - SStream1.Size); - finally - SStream1.Free; - SStream2.Free; - end; - if B then - if InRange(FileSize(BaseDir2 + LList2[I]), Options.MinSize, - Options.MaxSize) then - continue; - end; - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir2 + LList2[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - Delete(LList2, I, 1); - end; - TempDir := IncludeTrailingBackSlash(GetCurrentDir) + - LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF1)); - if not DirectoryExists(TempDir) then - CreateDir(TempDir); - SetLength(LList1, 0); - CS := TCriticalSection.Create; - SetLength(Tasks, Options.Threads); - J := -1; - K := 0; - try - for I := Low(Tasks) to High(Tasks) do - begin - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Y, Z: Integer; - S1, S2: String; - A: Boolean; - SS0, SS1, SS2: TSharedMemoryStream; - Res: NativeUInt; - begin - Z := Length(LList2); - Y := AtomicIncrement(J); - while Y < Z do - begin - S1 := IncludeTrailingBackSlash(TempDir) + Y.ToHexString + - XTOOL_MAPSUF3; - if C then - S2 := Input1 - else - S2 := BaseDir1 + LList2[Y]; - SS0 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S1); - SS1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S2); - SS2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + LList2[Y]); - try - SS0.Size := Max(SS1.Size, SS2.Size); - A := xd3_encode(SS1.Memory, SS1.Size, SS1.Memory, SS1.Size, - SS0.Memory, @Res, SS0.Size, 0) = 0; - if A then - SS0.Size := Res; - finally - SS0.Free; - SS1.Free; - SS2.Free; - end; - if not A then - DeleteFile(S1); - CS.Acquire; - try - Insert(S1, LList1, Length(LList1)); - Inc(K); - finally - CS.Release; - end; - Y := AtomicIncrement(J); - end; - end); - Tasks[I].Start; - end; - I := 0; - while I < Length(LList2) do - begin - while I >= K do - Sleep(10); - LFilename := IncludeTrailingBackSlash(TempDir) + I.ToHexString + - XTOOL_MAPSUF3; - if FileExists(LFilename) then - begin - LEntry.Op := TPatchOp.opDifferent; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - I64 := FileSize(LFilename); - Output.WriteBuffer(I64, I64.Size); - FStream := TFileStream.Create(LFilename, fmShareDenyNone); - try - CopyStreamEx(FStream, Output, I64); - finally - FStream.Free; - end; - TFile.Delete(LFilename); - end - else - begin - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList1[I]; - LEntry.Size := FileSize(BaseDir1 + LList1[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir1 + LList1[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - end; - Inc(I); - end; - WaitForAll(Tasks); - finally - for I := Low(Tasks) to High(Tasks) do - Tasks[I].Free; - CS.Free; - if DirectoryExists(TempDir) then - TDirectory.Delete(TempDir); - end; - FillChar(LEntry, SizeOf(TEntryStruct2), 0); - LEntry.Op := TPatchOp.opNone; - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); -end; - -procedure Decode(Input: TStream; Output: String; Options: TDecodeOptions); -var - I64: Int64; - B: Boolean; - S1, S2: String; - LFilename: String; - BaseDir: String; - LEntry: TEntryStruct2; - FStream: TFileStream; - SStream0, SStream1, SStream2: TSharedMemoryStream; - Res: NativeUInt; -begin - if FileExists(Output) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Output)); - S1 := IncludeTrailingBackSlash(GetCurrentDir) + - LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF3)); - SStream0 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S1); - try - Input.ReadBuffer(LEntry, SizeOf(TEntryStruct2)); - while LEntry.Op <> TPatchOp.opNone do - begin - if FileExists(Output) then - LFilename := Output - else - LFilename := BaseDir + LEntry.Filename; - case LEntry.Op of - TPatchOp.opDelete: - TFile.Delete(LFilename); - TPatchOp.opMissing: - begin - ForceDirectories(ExtractFilePath(LFilename)); - with TFileStream.Create(LFilename, fmCreate) do - try - CopyFrom(Input, LEntry.Size); - finally - Free; - end; - end; - TPatchOp.opDifferent: - begin - Input.ReadBuffer(I64, I64.Size); - SStream0.Size := Max(SStream0.Size, I64); - S2 := ChangeFileExt(LFilename, '_' + Random($7FFFFFFF).ToHexString + - XTOOL_MAPSUF3); - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S2); - B := False; - try - SStream2.Size := LEntry.Size; - B := xd3_decode(SStream0.Memory, I64, SStream1.Memory, - SStream1.Size, SStream2.Memory, @Res, SStream2.Size, 0) = 0; - finally - SStream1.Free; - SStream2.Free; - end; - if B then - begin - TFile.Delete(LFilename); - TFile.Move(S2, LFilename); - end - else if FileExists(S2) then - TFile.Delete(S2); - end; - end; - Input.ReadBuffer(LEntry, SizeOf(TEntryStruct2)); - end; - finally - SStream0.Free; - if FileExists(S1) then - TFile.Delete(S1); - end; -end; - -end. diff --git a/io/__history/IOPatch.pas.~303~ b/io/__history/IOPatch.pas.~303~ deleted file mode 100644 index 60d1cac..0000000 --- a/io/__history/IOPatch.pas.~303~ +++ /dev/null @@ -1,429 +0,0 @@ -unit IOPatch; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - Threads: Integer; - MinSize, MaxSize: Int64; - end; - - PDecodeOptions = ^TDecodeOptions; - - TDecodeOptions = record - Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); - overload; -procedure Parse(ParamArg: TArray; out Options: TDecodeOptions); - overload; -procedure Encode(Input1, Input2: String; Output: TStream; - Options: TEncodeOptions); -procedure Decode(Input: TStream; Output: String; Options: TDecodeOptions); - -implementation - -uses - XDeltaDLL; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'patch - creates patches between two data sets'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, ' xtool patch [parameters] old_data new_data patch_data'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('--min=', 0, '64k'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.MinSize := Max(0, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('--max=', 0, '16g'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.MaxSize := Max(0, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Parse(ParamArg: TArray; out Options: TDecodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2: String; Output: TStream; - Options: TEncodeOptions); -var - I, J, K: Integer; - I64: Int64; - B, C: Boolean; - LFilename: String; - BaseDir1, BaseDir2: String; - LList1, LList2: TArray; - LBytes: TBytes; - LEntry: TEntryStruct2; - FStream: TFileStream; - SStream1, SStream2: TSharedMemoryStream; - Tasks: TArray; - CS: TCriticalSection; - TempDir: String; -begin - C := FileExists(Input1) and FileExists(Input2); - if FileExists(Input1) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)); - LList1 := GetFileList([Input1], True); - for I := Low(LList1) to High(LList1) do - LList1[I] := ReplaceText(LList1[I], BaseDir1, ''); - if FileExists(Input2) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input2)); - LList2 := GetFileList([Input2], True); - for I := Low(LList2) to High(LList2) do - LList2[I] := ReplaceText(LList2[I], BaseDir2, ''); - K := XTOOL_PATCH; - Output.WriteBuffer(K, K.Size); - if not C then - for I := High(LList1) downto Low(LList1) do - begin - if IndexText(LList1[I], LList2) < 0 then - begin - LEntry.Op := TPatchOp.opDelete; - LEntry.Filename := LList1[I]; - LEntry.Size := FileSize(BaseDir1 + LList1[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - Delete(LList1, I, 1); - end; - end; - if not C then - for I := High(LList2) downto Low(LList2) do - begin - if IndexText(LList2[I], LList1) < 0 then - begin - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir2 + LList2[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - Delete(LList2, I, 1); - end; - end; - for I := High(LList2) downto Low(LList2) do - begin - if C then - LFilename := Input1 - else - LFilename := BaseDir1 + LList2[I]; - if FileSize(LFilename) <> FileSize(BaseDir2 + LList2[I]) then - begin - if InRange(FileSize(BaseDir2 + LList2[I]), Options.MinSize, - Options.MaxSize) then - continue; - end - else - begin - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + LList2[I]); - try - B := SynCommons.CompareMem(SStream1.Memory, SStream2.Memory, - SStream1.Size); - finally - SStream1.Free; - SStream2.Free; - end; - if B then - if InRange(FileSize(BaseDir2 + LList2[I]), Options.MinSize, - Options.MaxSize) then - continue; - end; - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir2 + LList2[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - Delete(LList2, I, 1); - end; - TempDir := IncludeTrailingBackSlash(GetCurrentDir) + - LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF1)); - if not DirectoryExists(TempDir) then - CreateDir(TempDir); - SetLength(LList1, 0); - CS := TCriticalSection.Create; - SetLength(Tasks, Options.Threads); - J := -1; - K := 0; - try - for I := Low(Tasks) to High(Tasks) do - begin - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Y, Z: Integer; - S1, S2: String; - A: Boolean; - SS0, SS1, SS2: TSharedMemoryStream; - Res: NativeUInt; - begin - Z := Length(LList2); - Y := AtomicIncrement(J); - while Y < Z do - begin - S1 := IncludeTrailingBackSlash(TempDir) + Y.ToHexString + - XTOOL_MAPSUF3; - if C then - S2 := Input1 - else - S2 := BaseDir1 + LList2[Y]; - SS0 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S1); - SS1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S2); - SS2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + LList2[Y]); - try - SS0.Size := Max(SS1.Size, SS2.Size); - A := xd3_encode(SS1.Memory, SS1.Size, SS1.Memory, SS1.Size, - SS0.Memory, @Res, SS0.Size, 0) = 0; - if A then - SS0.Size := Res; - finally - SS0.Free; - SS1.Free; - SS2.Free; - end; - if not A then - DeleteFile(S1); - CS.Acquire; - try - Insert(S1, LList1, Length(LList1)); - Inc(K); - finally - CS.Release; - end; - Y := AtomicIncrement(J); - end; - end); - Tasks[I].Start; - end; - I := 0; - while I < Length(LList2) do - begin - while I >= K do - Sleep(10); - LFilename := IncludeTrailingBackSlash(TempDir) + I.ToHexString + - XTOOL_MAPSUF3; - if FileExists(LFilename) then - begin - LEntry.Op := TPatchOp.opDifferent; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - I64 := FileSize(LFilename); - Output.WriteBuffer(I64, I64.Size); - FStream := TFileStream.Create(LFilename, fmShareDenyNone); - try - CopyStreamEx(FStream, Output, I64); - finally - FStream.Free; - end; - TFile.Delete(LFilename); - end - else - begin - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList1[I]; - LEntry.Size := FileSize(BaseDir1 + LList1[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir1 + LList1[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - end; - Inc(I); - end; - WaitForAll(Tasks); - finally - for I := Low(Tasks) to High(Tasks) do - Tasks[I].Free; - CS.Free; - if DirectoryExists(TempDir) then - TDirectory.Delete(TempDir); - end; - FillChar(LEntry, SizeOf(TEntryStruct2), 0); - LEntry.Op := TPatchOp.opNone; - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); -end; - -procedure Decode(Input: TStream; Output: String; Options: TDecodeOptions); -var - I64: Int64; - B: Boolean; - S1, S2: String; - LFilename: String; - BaseDir: String; - LEntry: TEntryStruct2; - FStream: TFileStream; - SStream0, SStream1, SStream2: TSharedMemoryStream; - Res: NativeUInt; -begin - if FileExists(Output) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Output)); - S1 := IncludeTrailingBackSlash(GetCurrentDir) + - LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF3)); - SStream0 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S1); - try - Input.ReadBuffer(LEntry, SizeOf(TEntryStruct2)); - while LEntry.Op <> TPatchOp.opNone do - begin - if FileExists(Output) then - LFilename := Output - else - LFilename := BaseDir + LEntry.Filename; - case LEntry.Op of - TPatchOp.opDelete: - TFile.Delete(LFilename); - TPatchOp.opMissing: - begin - ForceDirectories(ExtractFilePath(LFilename)); - with TFileStream.Create(LFilename, fmCreate) do - try - CopyFrom(Input, LEntry.Size); - finally - Free; - end; - end; - TPatchOp.opDifferent: - begin - Input.ReadBuffer(I64, I64.Size); - SStream0.Size := Max(SStream0.Size, I64); - S2 := ChangeFileExt(LFilename, '_' + Random($7FFFFFFF).ToHexString + - XTOOL_MAPSUF3); - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S2); - B := False; - try - SStream2.Size := LEntry.Size; - B := xd3_decode(SStream0.Memory, I64, SStream1.Memory, - SStream1.Size, SStream2.Memory, @Res, SStream2.Size, 0) = 0; - finally - SStream1.Free; - SStream2.Free; - end; - if B then - begin - TFile.Delete(LFilename); - TFile.Move(S2, LFilename); - end - else if FileExists(S2) then - TFile.Delete(S2); - end; - end; - Input.ReadBuffer(LEntry, SizeOf(TEntryStruct2)); - end; - finally - SStream0.Free; - if FileExists(S1) then - TFile.Delete(S1); - end; -end; - -end. diff --git a/io/__history/IOPatch.pas.~304~ b/io/__history/IOPatch.pas.~304~ deleted file mode 100644 index 07c477c..0000000 --- a/io/__history/IOPatch.pas.~304~ +++ /dev/null @@ -1,430 +0,0 @@ -unit IOPatch; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - Threads: Integer; - MinSize, MaxSize: Int64; - end; - - PDecodeOptions = ^TDecodeOptions; - - TDecodeOptions = record - Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); - overload; -procedure Parse(ParamArg: TArray; out Options: TDecodeOptions); - overload; -procedure Encode(Input1, Input2: String; Output: TStream; - Options: TEncodeOptions); -procedure Decode(Input: TStream; Output: String; Options: TDecodeOptions); - -implementation - -uses - XDeltaDLL; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'patch - creates patches between two data sets'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, ' xtool patch [parameters] old_data new_data patch_data'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('--min=', 0, '64k'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.MinSize := Max(0, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('--max=', 0, '16g'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.MaxSize := Max(0, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Parse(ParamArg: TArray; out Options: TDecodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2: String; Output: TStream; - Options: TEncodeOptions); -var - I, J, K: Integer; - I64: Int64; - B, C: Boolean; - LFilename: String; - BaseDir1, BaseDir2: String; - LList1, LList2: TArray; - LBytes: TBytes; - LEntry: TEntryStruct2; - FStream: TFileStream; - SStream1, SStream2: TSharedMemoryStream; - Tasks: TArray; - CS: TCriticalSection; - TempDir: String; -begin - C := FileExists(Input1) and FileExists(Input2); - if FileExists(Input1) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)); - LList1 := GetFileList([Input1], True); - for I := Low(LList1) to High(LList1) do - LList1[I] := ReplaceText(LList1[I], BaseDir1, ''); - if FileExists(Input2) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input2)); - LList2 := GetFileList([Input2], True); - for I := Low(LList2) to High(LList2) do - LList2[I] := ReplaceText(LList2[I], BaseDir2, ''); - K := XTOOL_PATCH; - Output.WriteBuffer(K, K.Size); - if not C then - for I := High(LList1) downto Low(LList1) do - begin - if IndexText(LList1[I], LList2) < 0 then - begin - LEntry.Op := TPatchOp.opDelete; - LEntry.Filename := LList1[I]; - LEntry.Size := FileSize(BaseDir1 + LList1[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - Delete(LList1, I, 1); - end; - end; - if not C then - for I := High(LList2) downto Low(LList2) do - begin - if IndexText(LList2[I], LList1) < 0 then - begin - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir2 + LList2[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - Delete(LList2, I, 1); - end; - end; - for I := High(LList2) downto Low(LList2) do - begin - if C then - LFilename := Input1 - else - LFilename := BaseDir1 + LList2[I]; - if FileSize(LFilename) <> FileSize(BaseDir2 + LList2[I]) then - begin - if InRange(FileSize(BaseDir2 + LList2[I]), Options.MinSize, - Options.MaxSize) then - continue; - end - else - begin - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + LList2[I]); - try - B := SynCommons.CompareMem(SStream1.Memory, SStream2.Memory, - SStream1.Size); - finally - SStream1.Free; - SStream2.Free; - end; - if B then - if InRange(FileSize(BaseDir2 + LList2[I]), Options.MinSize, - Options.MaxSize) then - continue; - end; - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir2 + LList2[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - Delete(LList2, I, 1); - end; - TempDir := IncludeTrailingBackSlash(GetCurrentDir) + - LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF1)); - if not DirectoryExists(TempDir) then - CreateDir(TempDir); - SetLength(LList1, 0); - CS := TCriticalSection.Create; - SetLength(Tasks, Options.Threads); - J := -1; - K := 0; - try - for I := Low(Tasks) to High(Tasks) do - begin - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Y, Z: Integer; - S1, S2: String; - A: Boolean; - SS0, SS1, SS2: TSharedMemoryStream; - Res: NativeUInt; - begin - Z := Length(LList2); - Y := AtomicIncrement(J); - while Y < Z do - begin - S1 := IncludeTrailingBackSlash(TempDir) + Y.ToHexString + - XTOOL_MAPSUF3; - if C then - S2 := Input1 - else - S2 := BaseDir1 + LList2[Y]; - SS0 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S1); - SS1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S2); - SS2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + LList2[Y]); - try - SS0.Size := Max(SS1.Size, SS2.Size); - A := xd3_encode(SS1.Memory, SS1.Size, SS1.Memory, SS1.Size, - SS0.Memory, @Res, SS0.Size, 0) = 0; - if A then - SS0.Size := Res; - finally - SS0.Free; - SS1.Free; - SS2.Free; - end; - if not A then - DeleteFile(S1); - CS.Acquire; - try - Insert(S1, LList1, Length(LList1)); - Inc(K); - finally - CS.Release; - end; - Y := AtomicIncrement(J); - end; - end); - Tasks[I].Start; - end; - I := 0; - while I < Length(LList2) do - begin - while I >= K do - Sleep(10); - LFilename := IncludeTrailingBackSlash(TempDir) + I.ToHexString + - XTOOL_MAPSUF3; - if FileExists(LFilename) then - begin - LEntry.Op := TPatchOp.opDifferent; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - I64 := FileSize(LFilename); - Output.WriteBuffer(I64, I64.Size); - FStream := TFileStream.Create(LFilename, fmShareDenyNone); - try - CopyStreamEx(FStream, Output, I64); - finally - FStream.Free; - end; - TFile.Delete(LFilename); - end - else - begin - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList1[I]; - LEntry.Size := FileSize(BaseDir1 + LList1[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir1 + LList1[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - end; - Inc(I); - end; - WaitForAll(Tasks); - finally - for I := Low(Tasks) to High(Tasks) do - Tasks[I].Free; - CS.Free; - if DirectoryExists(TempDir) then - TDirectory.Delete(TempDir); - end; - FillChar(LEntry, SizeOf(TEntryStruct2), 0); - LEntry.Op := TPatchOp.opNone; - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); -end; - -procedure Decode(Input: TStream; Output: String; Options: TDecodeOptions); -var - I64: Int64; - B: Boolean; - S1, S2: String; - LFilename: String; - BaseDir: String; - LEntry: TEntryStruct2; - FStream: TFileStream; - SStream0, SStream1, SStream2: TSharedMemoryStream; - Res: NativeUInt; -begin - if FileExists(Output) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Output)); - S1 := IncludeTrailingBackSlash(GetCurrentDir) + - LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF3)); - SStream0 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S1); - try - Input.ReadBuffer(LEntry, SizeOf(TEntryStruct2)); - while LEntry.Op <> TPatchOp.opNone do - begin - if FileExists(Output) then - LFilename := Output - else - LFilename := BaseDir + LEntry.Filename; - case LEntry.Op of - TPatchOp.opDelete: - TFile.Delete(LFilename); - TPatchOp.opMissing: - begin - ForceDirectories(ExtractFilePath(LFilename)); - with TFileStream.Create(LFilename, fmCreate) do - try - CopyFrom(Input, LEntry.Size); - finally - Free; - end; - end; - TPatchOp.opDifferent: - begin - Input.ReadBuffer(I64, I64.Size); - SStream0.Size := Max(SStream0.Size, I64); - S2 := ChangeFileExt(LFilename, '_' + Random($7FFFFFFF).ToHexString + - XTOOL_MAPSUF3); - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S2); - B := False; - try - SStream2.Size := LEntry.Size; - B := xd3_decode(SStream0.Memory, I64, SStream1.Memory, - SStream1.Size, SStream2.Memory, @Res, SStream2.Size, 0) = 0; - ShowMessage(Res.ToString); - finally - SStream1.Free; - SStream2.Free; - end; - if B then - begin - TFile.Delete(LFilename); - TFile.Move(S2, LFilename); - end - else if FileExists(S2) then - TFile.Delete(S2); - end; - end; - Input.ReadBuffer(LEntry, SizeOf(TEntryStruct2)); - end; - finally - SStream0.Free; - if FileExists(S1) then - TFile.Delete(S1); - end; -end; - -end. diff --git a/io/__history/IOPatch.pas.~305~ b/io/__history/IOPatch.pas.~305~ deleted file mode 100644 index 585dfdd..0000000 --- a/io/__history/IOPatch.pas.~305~ +++ /dev/null @@ -1,431 +0,0 @@ -unit IOPatch; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - Threads: Integer; - MinSize, MaxSize: Int64; - end; - - PDecodeOptions = ^TDecodeOptions; - - TDecodeOptions = record - Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); - overload; -procedure Parse(ParamArg: TArray; out Options: TDecodeOptions); - overload; -procedure Encode(Input1, Input2: String; Output: TStream; - Options: TEncodeOptions); -procedure Decode(Input: TStream; Output: String; Options: TDecodeOptions); - -implementation - -uses - XDeltaDLL; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'patch - creates patches between two data sets'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, ' xtool patch [parameters] old_data new_data patch_data'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('--min=', 0, '64k'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.MinSize := Max(0, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('--max=', 0, '16g'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.MaxSize := Max(0, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Parse(ParamArg: TArray; out Options: TDecodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2: String; Output: TStream; - Options: TEncodeOptions); -var - I, J, K: Integer; - I64: Int64; - B, C: Boolean; - LFilename: String; - BaseDir1, BaseDir2: String; - LList1, LList2: TArray; - LBytes: TBytes; - LEntry: TEntryStruct2; - FStream: TFileStream; - SStream1, SStream2: TSharedMemoryStream; - Tasks: TArray; - CS: TCriticalSection; - TempDir: String; -begin - C := FileExists(Input1) and FileExists(Input2); - if FileExists(Input1) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)); - LList1 := GetFileList([Input1], True); - for I := Low(LList1) to High(LList1) do - LList1[I] := ReplaceText(LList1[I], BaseDir1, ''); - if FileExists(Input2) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input2)); - LList2 := GetFileList([Input2], True); - for I := Low(LList2) to High(LList2) do - LList2[I] := ReplaceText(LList2[I], BaseDir2, ''); - K := XTOOL_PATCH; - Output.WriteBuffer(K, K.Size); - if not C then - for I := High(LList1) downto Low(LList1) do - begin - if IndexText(LList1[I], LList2) < 0 then - begin - LEntry.Op := TPatchOp.opDelete; - LEntry.Filename := LList1[I]; - LEntry.Size := FileSize(BaseDir1 + LList1[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - Delete(LList1, I, 1); - end; - end; - if not C then - for I := High(LList2) downto Low(LList2) do - begin - if IndexText(LList2[I], LList1) < 0 then - begin - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir2 + LList2[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - Delete(LList2, I, 1); - end; - end; - for I := High(LList2) downto Low(LList2) do - begin - if C then - LFilename := Input1 - else - LFilename := BaseDir1 + LList2[I]; - if FileSize(LFilename) <> FileSize(BaseDir2 + LList2[I]) then - begin - if InRange(FileSize(BaseDir2 + LList2[I]), Options.MinSize, - Options.MaxSize) then - continue; - end - else - begin - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + LList2[I]); - try - B := SynCommons.CompareMem(SStream1.Memory, SStream2.Memory, - SStream1.Size); - finally - SStream1.Free; - SStream2.Free; - end; - if B then - if InRange(FileSize(BaseDir2 + LList2[I]), Options.MinSize, - Options.MaxSize) then - continue; - end; - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir2 + LList2[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - Delete(LList2, I, 1); - end; - TempDir := IncludeTrailingBackSlash(GetCurrentDir) + - LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF1)); - if not DirectoryExists(TempDir) then - CreateDir(TempDir); - SetLength(LList1, 0); - CS := TCriticalSection.Create; - SetLength(Tasks, Options.Threads); - J := -1; - K := 0; - try - for I := Low(Tasks) to High(Tasks) do - begin - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Y, Z: Integer; - S1, S2: String; - A: Boolean; - SS0, SS1, SS2: TSharedMemoryStream; - Res: NativeUInt; - begin - Z := Length(LList2); - Y := AtomicIncrement(J); - while Y < Z do - begin - S1 := IncludeTrailingBackSlash(TempDir) + Y.ToHexString + - XTOOL_MAPSUF3; - if C then - S2 := Input1 - else - S2 := BaseDir1 + LList2[Y]; - SS0 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S1); - SS1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S2); - SS2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + LList2[Y]); - try - SS0.Size := Max(SS1.Size, SS2.Size); - A := xd3_encode(SS1.Memory, SS1.Size, SS1.Memory, SS1.Size, - SS0.Memory, @Res, SS0.Size, 0) = 0; - if A then - SS0.Size := Res; - finally - SS0.Free; - SS1.Free; - SS2.Free; - end; - if not A then - DeleteFile(S1); - CS.Acquire; - try - Insert(S1, LList1, Length(LList1)); - Inc(K); - finally - CS.Release; - end; - Y := AtomicIncrement(J); - end; - end); - Tasks[I].Start; - end; - I := 0; - while I < Length(LList2) do - begin - while I >= K do - Sleep(10); - LFilename := IncludeTrailingBackSlash(TempDir) + I.ToHexString + - XTOOL_MAPSUF3; - if FileExists(LFilename) then - begin - LEntry.Op := TPatchOp.opDifferent; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - I64 := FileSize(LFilename); - Output.WriteBuffer(I64, I64.Size); - FStream := TFileStream.Create(LFilename, fmShareDenyNone); - try - CopyStreamEx(FStream, Output, I64); - finally - FStream.Free; - end; - TFile.Delete(LFilename); - end - else - begin - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList1[I]; - LEntry.Size := FileSize(BaseDir1 + LList1[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir1 + LList1[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - end; - Inc(I); - end; - WaitForAll(Tasks); - finally - for I := Low(Tasks) to High(Tasks) do - Tasks[I].Free; - CS.Free; - if DirectoryExists(TempDir) then - TDirectory.Delete(TempDir); - end; - FillChar(LEntry, SizeOf(TEntryStruct2), 0); - LEntry.Op := TPatchOp.opNone; - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); -end; - -procedure Decode(Input: TStream; Output: String; Options: TDecodeOptions); -var - I64: Int64; - B: Boolean; - S1, S2: String; - LFilename: String; - BaseDir: String; - LEntry: TEntryStruct2; - FStream: TFileStream; - SStream0, SStream1, SStream2: TSharedMemoryStream; - Res: NativeUInt; -begin - if FileExists(Output) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Output)); - S1 := IncludeTrailingBackSlash(GetCurrentDir) + - LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF3)); - SStream0 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S1); - try - Input.ReadBuffer(LEntry, SizeOf(TEntryStruct2)); - while LEntry.Op <> TPatchOp.opNone do - begin - if FileExists(Output) then - LFilename := Output - else - LFilename := BaseDir + LEntry.Filename; - case LEntry.Op of - TPatchOp.opDelete: - TFile.Delete(LFilename); - TPatchOp.opMissing: - begin - ForceDirectories(ExtractFilePath(LFilename)); - with TFileStream.Create(LFilename, fmCreate) do - try - CopyFrom(Input, LEntry.Size); - finally - Free; - end; - end; - TPatchOp.opDifferent: - begin - Input.ReadBuffer(I64, I64.Size); - SStream0.Position := 0; - CopyStreamEx(Input, SStream0, I64); - S2 := ChangeFileExt(LFilename, '_' + Random($7FFFFFFF).ToHexString + - XTOOL_MAPSUF3); - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S2); - B := False; - try - SStream2.Size := LEntry.Size; - B := xd3_decode(SStream0.Memory, I64, SStream1.Memory, - SStream1.Size, SStream2.Memory, @Res, SStream2.Size, 0) = 0; - ShowMessage(Res.ToString); - finally - SStream1.Free; - SStream2.Free; - end; - if B then - begin - TFile.Delete(LFilename); - TFile.Move(S2, LFilename); - end - else if FileExists(S2) then - TFile.Delete(S2); - end; - end; - Input.ReadBuffer(LEntry, SizeOf(TEntryStruct2)); - end; - finally - SStream0.Free; - if FileExists(S1) then - TFile.Delete(S1); - end; -end; - -end. diff --git a/io/__history/IOPatch.pas.~306~ b/io/__history/IOPatch.pas.~306~ deleted file mode 100644 index 58a353f..0000000 --- a/io/__history/IOPatch.pas.~306~ +++ /dev/null @@ -1,430 +0,0 @@ -unit IOPatch; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - Threads: Integer; - MinSize, MaxSize: Int64; - end; - - PDecodeOptions = ^TDecodeOptions; - - TDecodeOptions = record - Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); - overload; -procedure Parse(ParamArg: TArray; out Options: TDecodeOptions); - overload; -procedure Encode(Input1, Input2: String; Output: TStream; - Options: TEncodeOptions); -procedure Decode(Input: TStream; Output: String; Options: TDecodeOptions); - -implementation - -uses - XDeltaDLL; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'patch - creates patches between two data sets'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, ' xtool patch [parameters] old_data new_data patch_data'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('--min=', 0, '64k'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.MinSize := Max(0, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('--max=', 0, '16g'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.MaxSize := Max(0, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Parse(ParamArg: TArray; out Options: TDecodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2: String; Output: TStream; - Options: TEncodeOptions); -var - I, J, K: Integer; - I64: Int64; - B, C: Boolean; - LFilename: String; - BaseDir1, BaseDir2: String; - LList1, LList2: TArray; - LBytes: TBytes; - LEntry: TEntryStruct2; - FStream: TFileStream; - SStream1, SStream2: TSharedMemoryStream; - Tasks: TArray; - CS: TCriticalSection; - TempDir: String; -begin - C := FileExists(Input1) and FileExists(Input2); - if FileExists(Input1) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)); - LList1 := GetFileList([Input1], True); - for I := Low(LList1) to High(LList1) do - LList1[I] := ReplaceText(LList1[I], BaseDir1, ''); - if FileExists(Input2) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input2)); - LList2 := GetFileList([Input2], True); - for I := Low(LList2) to High(LList2) do - LList2[I] := ReplaceText(LList2[I], BaseDir2, ''); - K := XTOOL_PATCH; - Output.WriteBuffer(K, K.Size); - if not C then - for I := High(LList1) downto Low(LList1) do - begin - if IndexText(LList1[I], LList2) < 0 then - begin - LEntry.Op := TPatchOp.opDelete; - LEntry.Filename := LList1[I]; - LEntry.Size := FileSize(BaseDir1 + LList1[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - Delete(LList1, I, 1); - end; - end; - if not C then - for I := High(LList2) downto Low(LList2) do - begin - if IndexText(LList2[I], LList1) < 0 then - begin - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir2 + LList2[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - Delete(LList2, I, 1); - end; - end; - for I := High(LList2) downto Low(LList2) do - begin - if C then - LFilename := Input1 - else - LFilename := BaseDir1 + LList2[I]; - if FileSize(LFilename) <> FileSize(BaseDir2 + LList2[I]) then - begin - if InRange(FileSize(BaseDir2 + LList2[I]), Options.MinSize, - Options.MaxSize) then - continue; - end - else - begin - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + LList2[I]); - try - B := SynCommons.CompareMem(SStream1.Memory, SStream2.Memory, - SStream1.Size); - finally - SStream1.Free; - SStream2.Free; - end; - if B then - if InRange(FileSize(BaseDir2 + LList2[I]), Options.MinSize, - Options.MaxSize) then - continue; - end; - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir2 + LList2[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - Delete(LList2, I, 1); - end; - TempDir := IncludeTrailingBackSlash(GetCurrentDir) + - LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF1)); - if not DirectoryExists(TempDir) then - CreateDir(TempDir); - SetLength(LList1, 0); - CS := TCriticalSection.Create; - SetLength(Tasks, Options.Threads); - J := -1; - K := 0; - try - for I := Low(Tasks) to High(Tasks) do - begin - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Y, Z: Integer; - S1, S2: String; - A: Boolean; - SS0, SS1, SS2: TSharedMemoryStream; - Res: NativeUInt; - begin - Z := Length(LList2); - Y := AtomicIncrement(J); - while Y < Z do - begin - S1 := IncludeTrailingBackSlash(TempDir) + Y.ToHexString + - XTOOL_MAPSUF3; - if C then - S2 := Input1 - else - S2 := BaseDir1 + LList2[Y]; - SS0 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S1); - SS1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S2); - SS2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + LList2[Y]); - try - SS0.Size := Max(SS1.Size, SS2.Size); - A := xd3_encode(SS1.Memory, SS1.Size, SS1.Memory, SS1.Size, - SS0.Memory, @Res, SS0.Size, 0) = 0; - if A then - SS0.Size := Res; - finally - SS0.Free; - SS1.Free; - SS2.Free; - end; - if not A then - DeleteFile(S1); - CS.Acquire; - try - Insert(S1, LList1, Length(LList1)); - Inc(K); - finally - CS.Release; - end; - Y := AtomicIncrement(J); - end; - end); - Tasks[I].Start; - end; - I := 0; - while I < Length(LList2) do - begin - while I >= K do - Sleep(10); - LFilename := IncludeTrailingBackSlash(TempDir) + I.ToHexString + - XTOOL_MAPSUF3; - if FileExists(LFilename) then - begin - LEntry.Op := TPatchOp.opDifferent; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - I64 := FileSize(LFilename); - Output.WriteBuffer(I64, I64.Size); - FStream := TFileStream.Create(LFilename, fmShareDenyNone); - try - CopyStreamEx(FStream, Output, I64); - finally - FStream.Free; - end; - TFile.Delete(LFilename); - end - else - begin - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList1[I]; - LEntry.Size := FileSize(BaseDir1 + LList1[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir1 + LList1[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - end; - Inc(I); - end; - WaitForAll(Tasks); - finally - for I := Low(Tasks) to High(Tasks) do - Tasks[I].Free; - CS.Free; - if DirectoryExists(TempDir) then - TDirectory.Delete(TempDir); - end; - FillChar(LEntry, SizeOf(TEntryStruct2), 0); - LEntry.Op := TPatchOp.opNone; - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); -end; - -procedure Decode(Input: TStream; Output: String; Options: TDecodeOptions); -var - I64: Int64; - B: Boolean; - S1, S2: String; - LFilename: String; - BaseDir: String; - LEntry: TEntryStruct2; - FStream: TFileStream; - SStream0, SStream1, SStream2: TSharedMemoryStream; - Res: NativeUInt; -begin - if FileExists(Output) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Output)); - S1 := IncludeTrailingBackSlash(GetCurrentDir) + - LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF3)); - SStream0 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S1); - try - Input.ReadBuffer(LEntry, SizeOf(TEntryStruct2)); - while LEntry.Op <> TPatchOp.opNone do - begin - if FileExists(Output) then - LFilename := Output - else - LFilename := BaseDir + LEntry.Filename; - case LEntry.Op of - TPatchOp.opDelete: - TFile.Delete(LFilename); - TPatchOp.opMissing: - begin - ForceDirectories(ExtractFilePath(LFilename)); - with TFileStream.Create(LFilename, fmCreate) do - try - CopyFrom(Input, LEntry.Size); - finally - Free; - end; - end; - TPatchOp.opDifferent: - begin - Input.ReadBuffer(I64, I64.Size); - SStream0.Position := 0; - CopyStreamEx(Input, SStream0, I64); - S2 := ChangeFileExt(LFilename, '_' + Random($7FFFFFFF).ToHexString + - XTOOL_MAPSUF3); - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S2); - B := False; - try - SStream2.Size := LEntry.Size; - B := xd3_decode(SStream0.Memory, I64, SStream1.Memory, - SStream1.Size, SStream2.Memory, @Res, SStream2.Size, 0) = 0; - finally - SStream1.Free; - SStream2.Free; - end; - if B then - begin - TFile.Delete(LFilename); - TFile.Move(S2, LFilename); - end - else if FileExists(S2) then - TFile.Delete(S2); - end; - end; - Input.ReadBuffer(LEntry, SizeOf(TEntryStruct2)); - end; - finally - SStream0.Free; - if FileExists(S1) then - TFile.Delete(S1); - end; -end; - -end. diff --git a/io/__history/IOPatch.pas.~307~ b/io/__history/IOPatch.pas.~307~ deleted file mode 100644 index 16a90e7..0000000 --- a/io/__history/IOPatch.pas.~307~ +++ /dev/null @@ -1,431 +0,0 @@ -unit IOPatch; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - Threads: Integer; - MinSize, MaxSize: Int64; - end; - - PDecodeOptions = ^TDecodeOptions; - - TDecodeOptions = record - Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); - overload; -procedure Parse(ParamArg: TArray; out Options: TDecodeOptions); - overload; -procedure Encode(Input1, Input2: String; Output: TStream; - Options: TEncodeOptions); -procedure Decode(Input: TStream; Output: String; Options: TDecodeOptions); - -implementation - -uses - XDeltaDLL; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'patch - creates patches between two data sets'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, ' xtool patch [parameters] old_data new_data patch_data'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('--min=', 0, '64k'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.MinSize := Max(0, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('--max=', 0, '16g'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.MaxSize := Max(0, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Parse(ParamArg: TArray; out Options: TDecodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2: String; Output: TStream; - Options: TEncodeOptions); -var - I, J, K: Integer; - I64: Int64; - B, C: Boolean; - LFilename: String; - BaseDir1, BaseDir2: String; - LList1, LList2: TArray; - LBytes: TBytes; - LEntry: TEntryStruct2; - FStream: TFileStream; - SStream1, SStream2: TSharedMemoryStream; - Tasks: TArray; - CS: TCriticalSection; - TempDir: String; -begin - C := FileExists(Input1) and FileExists(Input2); - if FileExists(Input1) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)); - LList1 := GetFileList([Input1], True); - for I := Low(LList1) to High(LList1) do - LList1[I] := ReplaceText(LList1[I], BaseDir1, ''); - if FileExists(Input2) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input2)); - LList2 := GetFileList([Input2], True); - for I := Low(LList2) to High(LList2) do - LList2[I] := ReplaceText(LList2[I], BaseDir2, ''); - K := XTOOL_PATCH; - Output.WriteBuffer(K, K.Size); - if not C then - for I := High(LList1) downto Low(LList1) do - begin - if IndexText(LList1[I], LList2) < 0 then - begin - LEntry.Op := TPatchOp.opDelete; - LEntry.Filename := LList1[I]; - LEntry.Size := FileSize(BaseDir1 + LList1[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - Delete(LList1, I, 1); - end; - end; - if not C then - for I := High(LList2) downto Low(LList2) do - begin - if IndexText(LList2[I], LList1) < 0 then - begin - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir2 + LList2[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - Delete(LList2, I, 1); - end; - end; - for I := High(LList2) downto Low(LList2) do - begin - if C then - LFilename := Input1 - else - LFilename := BaseDir1 + LList2[I]; - if FileSize(LFilename) <> FileSize(BaseDir2 + LList2[I]) then - begin - if InRange(FileSize(BaseDir2 + LList2[I]), Options.MinSize, - Options.MaxSize) then - continue; - end - else - begin - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + LList2[I]); - try - B := SynCommons.CompareMem(SStream1.Memory, SStream2.Memory, - SStream1.Size); - finally - SStream1.Free; - SStream2.Free; - end; - if B then - if InRange(FileSize(BaseDir2 + LList2[I]), Options.MinSize, - Options.MaxSize) then - continue; - end; - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir2 + LList2[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - Delete(LList2, I, 1); - end; - TempDir := IncludeTrailingBackSlash(GetCurrentDir) + - LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF1)); - if not DirectoryExists(TempDir) then - CreateDir(TempDir); - SetLength(LList1, 0); - CS := TCriticalSection.Create; - SetLength(Tasks, Options.Threads); - J := -1; - K := 0; - try - for I := Low(Tasks) to High(Tasks) do - begin - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Y, Z: Integer; - S1, S2: String; - A: Boolean; - SS0, SS1, SS2: TSharedMemoryStream; - Res: NativeUInt; - begin - Z := Length(LList2); - Y := AtomicIncrement(J); - while Y < Z do - begin - S1 := IncludeTrailingBackSlash(TempDir) + Y.ToHexString + - XTOOL_MAPSUF3; - if C then - S2 := Input1 - else - S2 := BaseDir1 + LList2[Y]; - SS0 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S1); - SS1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S2); - SS2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + LList2[Y]); - try - SS0.Size := Max(SS1.Size, SS2.Size); - A := xd3_encode(SS1.Memory, SS1.Size, SS1.Memory, SS1.Size, - SS0.Memory, @Res, SS0.Size, 0) = 0; - if A then - SS0.Size := Res; - finally - SS0.Free; - SS1.Free; - SS2.Free; - end; - if not A then - DeleteFile(S1); - CS.Acquire; - try - Insert(S1, LList1, Length(LList1)); - Inc(K); - finally - CS.Release; - end; - Y := AtomicIncrement(J); - end; - end); - Tasks[I].Start; - end; - I := 0; - while I < Length(LList2) do - begin - while I >= K do - Sleep(10); - LFilename := IncludeTrailingBackSlash(TempDir) + I.ToHexString + - XTOOL_MAPSUF3; - if FileExists(LFilename) then - begin - LEntry.Op := TPatchOp.opDifferent; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - I64 := FileSize(LFilename); - Output.WriteBuffer(I64, I64.Size); - FStream := TFileStream.Create(LFilename, fmShareDenyNone); - try - CopyStreamEx(FStream, Output, I64); - finally - FStream.Free; - end; - TFile.Delete(LFilename); - end - else - begin - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList1[I]; - LEntry.Size := FileSize(BaseDir1 + LList1[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir1 + LList1[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - end; - Inc(I); - end; - WaitForAll(Tasks); - finally - for I := Low(Tasks) to High(Tasks) do - Tasks[I].Free; - CS.Free; - if DirectoryExists(TempDir) then - TDirectory.Delete(TempDir); - end; - FillChar(LEntry, SizeOf(TEntryStruct2), 0); - LEntry.Op := TPatchOp.opNone; - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); -end; - -procedure Decode(Input: TStream; Output: String; Options: TDecodeOptions); -var - I64: Int64; - B: Boolean; - S1, S2: String; - LFilename: String; - BaseDir: String; - LEntry: TEntryStruct2; - FStream: TFileStream; - SStream0, SStream1, SStream2: TSharedMemoryStream; - Res: NativeUInt; -begin - if FileExists(Output) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Output)); - S1 := IncludeTrailingBackSlash(GetCurrentDir) + - LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF3)); - SStream0 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S1); - try - Input.ReadBuffer(LEntry, SizeOf(TEntryStruct2)); - while LEntry.Op <> TPatchOp.opNone do - begin - if FileExists(Output) then - LFilename := Output - else - LFilename := BaseDir + LEntry.Filename; - case LEntry.Op of - TPatchOp.opDelete: - TFile.Delete(LFilename); - TPatchOp.opMissing: - begin - ForceDirectories(ExtractFilePath(LFilename)); - with TFileStream.Create(LFilename, fmCreate) do - try - CopyFrom(Input, LEntry.Size); - finally - Free; - end; - end; - TPatchOp.opDifferent: - begin - Input.ReadBuffer(I64, I64.Size); - SStream0.Position := 0; - CopyStreamEx(Input, SStream0, I64); - S2 := ChangeFileExt(LFilename, '_' + Random($7FFFFFFF).ToHexString + - XTOOL_MAPSUF3); - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S2); - B := False; - try - SStream2.Size := LEntry.Size; - B := xd3_decode(SStream0.Memory, I64, SStream1.Memory, - SStream1.Size, SStream2.Memory, @Res, SStream2.Size, 0) = 0; - finally - SStream1.Free; - SStream2.Free; - end; - if B then - begin - ShowMessage(''); - TFile.Delete(LFilename); - TFile.Move(S2, LFilename); - end - else if FileExists(S2) then - TFile.Delete(S2); - end; - end; - Input.ReadBuffer(LEntry, SizeOf(TEntryStruct2)); - end; - finally - SStream0.Free; - if FileExists(S1) then - TFile.Delete(S1); - end; -end; - -end. diff --git a/io/__history/IOPatch.pas.~308~ b/io/__history/IOPatch.pas.~308~ deleted file mode 100644 index 58a353f..0000000 --- a/io/__history/IOPatch.pas.~308~ +++ /dev/null @@ -1,430 +0,0 @@ -unit IOPatch; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - Threads: Integer; - MinSize, MaxSize: Int64; - end; - - PDecodeOptions = ^TDecodeOptions; - - TDecodeOptions = record - Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); - overload; -procedure Parse(ParamArg: TArray; out Options: TDecodeOptions); - overload; -procedure Encode(Input1, Input2: String; Output: TStream; - Options: TEncodeOptions); -procedure Decode(Input: TStream; Output: String; Options: TDecodeOptions); - -implementation - -uses - XDeltaDLL; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'patch - creates patches between two data sets'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, ' xtool patch [parameters] old_data new_data patch_data'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('--min=', 0, '64k'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.MinSize := Max(0, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('--max=', 0, '16g'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.MaxSize := Max(0, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Parse(ParamArg: TArray; out Options: TDecodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2: String; Output: TStream; - Options: TEncodeOptions); -var - I, J, K: Integer; - I64: Int64; - B, C: Boolean; - LFilename: String; - BaseDir1, BaseDir2: String; - LList1, LList2: TArray; - LBytes: TBytes; - LEntry: TEntryStruct2; - FStream: TFileStream; - SStream1, SStream2: TSharedMemoryStream; - Tasks: TArray; - CS: TCriticalSection; - TempDir: String; -begin - C := FileExists(Input1) and FileExists(Input2); - if FileExists(Input1) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)); - LList1 := GetFileList([Input1], True); - for I := Low(LList1) to High(LList1) do - LList1[I] := ReplaceText(LList1[I], BaseDir1, ''); - if FileExists(Input2) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input2)); - LList2 := GetFileList([Input2], True); - for I := Low(LList2) to High(LList2) do - LList2[I] := ReplaceText(LList2[I], BaseDir2, ''); - K := XTOOL_PATCH; - Output.WriteBuffer(K, K.Size); - if not C then - for I := High(LList1) downto Low(LList1) do - begin - if IndexText(LList1[I], LList2) < 0 then - begin - LEntry.Op := TPatchOp.opDelete; - LEntry.Filename := LList1[I]; - LEntry.Size := FileSize(BaseDir1 + LList1[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - Delete(LList1, I, 1); - end; - end; - if not C then - for I := High(LList2) downto Low(LList2) do - begin - if IndexText(LList2[I], LList1) < 0 then - begin - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir2 + LList2[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - Delete(LList2, I, 1); - end; - end; - for I := High(LList2) downto Low(LList2) do - begin - if C then - LFilename := Input1 - else - LFilename := BaseDir1 + LList2[I]; - if FileSize(LFilename) <> FileSize(BaseDir2 + LList2[I]) then - begin - if InRange(FileSize(BaseDir2 + LList2[I]), Options.MinSize, - Options.MaxSize) then - continue; - end - else - begin - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + LList2[I]); - try - B := SynCommons.CompareMem(SStream1.Memory, SStream2.Memory, - SStream1.Size); - finally - SStream1.Free; - SStream2.Free; - end; - if B then - if InRange(FileSize(BaseDir2 + LList2[I]), Options.MinSize, - Options.MaxSize) then - continue; - end; - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir2 + LList2[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - Delete(LList2, I, 1); - end; - TempDir := IncludeTrailingBackSlash(GetCurrentDir) + - LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF1)); - if not DirectoryExists(TempDir) then - CreateDir(TempDir); - SetLength(LList1, 0); - CS := TCriticalSection.Create; - SetLength(Tasks, Options.Threads); - J := -1; - K := 0; - try - for I := Low(Tasks) to High(Tasks) do - begin - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Y, Z: Integer; - S1, S2: String; - A: Boolean; - SS0, SS1, SS2: TSharedMemoryStream; - Res: NativeUInt; - begin - Z := Length(LList2); - Y := AtomicIncrement(J); - while Y < Z do - begin - S1 := IncludeTrailingBackSlash(TempDir) + Y.ToHexString + - XTOOL_MAPSUF3; - if C then - S2 := Input1 - else - S2 := BaseDir1 + LList2[Y]; - SS0 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S1); - SS1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S2); - SS2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + LList2[Y]); - try - SS0.Size := Max(SS1.Size, SS2.Size); - A := xd3_encode(SS1.Memory, SS1.Size, SS1.Memory, SS1.Size, - SS0.Memory, @Res, SS0.Size, 0) = 0; - if A then - SS0.Size := Res; - finally - SS0.Free; - SS1.Free; - SS2.Free; - end; - if not A then - DeleteFile(S1); - CS.Acquire; - try - Insert(S1, LList1, Length(LList1)); - Inc(K); - finally - CS.Release; - end; - Y := AtomicIncrement(J); - end; - end); - Tasks[I].Start; - end; - I := 0; - while I < Length(LList2) do - begin - while I >= K do - Sleep(10); - LFilename := IncludeTrailingBackSlash(TempDir) + I.ToHexString + - XTOOL_MAPSUF3; - if FileExists(LFilename) then - begin - LEntry.Op := TPatchOp.opDifferent; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - I64 := FileSize(LFilename); - Output.WriteBuffer(I64, I64.Size); - FStream := TFileStream.Create(LFilename, fmShareDenyNone); - try - CopyStreamEx(FStream, Output, I64); - finally - FStream.Free; - end; - TFile.Delete(LFilename); - end - else - begin - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList1[I]; - LEntry.Size := FileSize(BaseDir1 + LList1[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir1 + LList1[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - end; - Inc(I); - end; - WaitForAll(Tasks); - finally - for I := Low(Tasks) to High(Tasks) do - Tasks[I].Free; - CS.Free; - if DirectoryExists(TempDir) then - TDirectory.Delete(TempDir); - end; - FillChar(LEntry, SizeOf(TEntryStruct2), 0); - LEntry.Op := TPatchOp.opNone; - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); -end; - -procedure Decode(Input: TStream; Output: String; Options: TDecodeOptions); -var - I64: Int64; - B: Boolean; - S1, S2: String; - LFilename: String; - BaseDir: String; - LEntry: TEntryStruct2; - FStream: TFileStream; - SStream0, SStream1, SStream2: TSharedMemoryStream; - Res: NativeUInt; -begin - if FileExists(Output) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Output)); - S1 := IncludeTrailingBackSlash(GetCurrentDir) + - LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF3)); - SStream0 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S1); - try - Input.ReadBuffer(LEntry, SizeOf(TEntryStruct2)); - while LEntry.Op <> TPatchOp.opNone do - begin - if FileExists(Output) then - LFilename := Output - else - LFilename := BaseDir + LEntry.Filename; - case LEntry.Op of - TPatchOp.opDelete: - TFile.Delete(LFilename); - TPatchOp.opMissing: - begin - ForceDirectories(ExtractFilePath(LFilename)); - with TFileStream.Create(LFilename, fmCreate) do - try - CopyFrom(Input, LEntry.Size); - finally - Free; - end; - end; - TPatchOp.opDifferent: - begin - Input.ReadBuffer(I64, I64.Size); - SStream0.Position := 0; - CopyStreamEx(Input, SStream0, I64); - S2 := ChangeFileExt(LFilename, '_' + Random($7FFFFFFF).ToHexString + - XTOOL_MAPSUF3); - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S2); - B := False; - try - SStream2.Size := LEntry.Size; - B := xd3_decode(SStream0.Memory, I64, SStream1.Memory, - SStream1.Size, SStream2.Memory, @Res, SStream2.Size, 0) = 0; - finally - SStream1.Free; - SStream2.Free; - end; - if B then - begin - TFile.Delete(LFilename); - TFile.Move(S2, LFilename); - end - else if FileExists(S2) then - TFile.Delete(S2); - end; - end; - Input.ReadBuffer(LEntry, SizeOf(TEntryStruct2)); - end; - finally - SStream0.Free; - if FileExists(S1) then - TFile.Delete(S1); - end; -end; - -end. diff --git a/io/__history/IOPatch.pas.~309~ b/io/__history/IOPatch.pas.~309~ deleted file mode 100644 index 2c5b100..0000000 --- a/io/__history/IOPatch.pas.~309~ +++ /dev/null @@ -1,430 +0,0 @@ -unit IOPatch; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - Threads: Integer; - MinSize, MaxSize: Int64; - end; - - PDecodeOptions = ^TDecodeOptions; - - TDecodeOptions = record - Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); - overload; -procedure Parse(ParamArg: TArray; out Options: TDecodeOptions); - overload; -procedure Encode(Input1, Input2: String; Output: TStream; - Options: TEncodeOptions); -procedure Decode(Input: TStream; Output: String; Options: TDecodeOptions); - -implementation - -uses - XDeltaDLL; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'patch - creates patches between two data sets'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, ' xtool patch [parameters] old_data new_data patch_data'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('--min=', 0, '64k'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.MinSize := Max(0, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('--max=', 0, '16g'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.MaxSize := Max(0, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Parse(ParamArg: TArray; out Options: TDecodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2: String; Output: TStream; - Options: TEncodeOptions); -var - I, J, K: Integer; - I64: Int64; - B, C: Boolean; - LFilename: String; - BaseDir1, BaseDir2: String; - LList1, LList2: TArray; - LBytes: TBytes; - LEntry: TEntryStruct2; - FStream: TFileStream; - SStream1, SStream2: TSharedMemoryStream; - Tasks: TArray; - CS: TCriticalSection; - TempDir: String; -begin - C := FileExists(Input1) and FileExists(Input2); - if FileExists(Input1) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)); - LList1 := GetFileList([Input1], True); - for I := Low(LList1) to High(LList1) do - LList1[I] := ReplaceText(LList1[I], BaseDir1, ''); - if FileExists(Input2) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input2)); - LList2 := GetFileList([Input2], True); - for I := Low(LList2) to High(LList2) do - LList2[I] := ReplaceText(LList2[I], BaseDir2, ''); - K := XTOOL_PATCH; - Output.WriteBuffer(K, K.Size); - if not C then - for I := High(LList1) downto Low(LList1) do - begin - if IndexText(LList1[I], LList2) < 0 then - begin - LEntry.Op := TPatchOp.opDelete; - LEntry.Filename := LList1[I]; - LEntry.Size := FileSize(BaseDir1 + LList1[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - Delete(LList1, I, 1); - end; - end; - if not C then - for I := High(LList2) downto Low(LList2) do - begin - if IndexText(LList2[I], LList1) < 0 then - begin - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir2 + LList2[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - Delete(LList2, I, 1); - end; - end; - for I := High(LList2) downto Low(LList2) do - begin - if C then - LFilename := Input1 - else - LFilename := BaseDir1 + LList2[I]; - if FileSize(LFilename) <> FileSize(BaseDir2 + LList2[I]) then - begin - if InRange(FileSize(BaseDir2 + LList2[I]), Options.MinSize, - Options.MaxSize) then - continue; - end - else - begin - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + LList2[I]); - try - B := SynCommons.CompareMem(SStream1.Memory, SStream2.Memory, - SStream1.Size); - finally - SStream1.Free; - SStream2.Free; - end; - if B then - if InRange(FileSize(BaseDir2 + LList2[I]), Options.MinSize, - Options.MaxSize) then - continue; - end; - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir2 + LList2[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - Delete(LList2, I, 1); - end; - TempDir := IncludeTrailingBackSlash(GetCurrentDir) + - LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF1)); - if not DirectoryExists(TempDir) then - CreateDir(TempDir); - SetLength(LList1, 0); - CS := TCriticalSection.Create; - SetLength(Tasks, Options.Threads); - J := -1; - K := 0; - try - for I := Low(Tasks) to High(Tasks) do - begin - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Y, Z: Integer; - S1, S2: String; - A: Boolean; - SS0, SS1, SS2: TSharedMemoryStream; - Res: NativeUInt; - begin - Z := Length(LList2); - Y := AtomicIncrement(J); - while Y < Z do - begin - S1 := IncludeTrailingBackSlash(TempDir) + Y.ToHexString + - XTOOL_MAPSUF3; - if C then - S2 := Input1 - else - S2 := BaseDir1 + LList2[Y]; - SS0 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S1); - SS1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S2); - SS2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + LList2[Y]); - try - SS0.Size := Max(SS1.Size, SS2.Size); - A := xd3_encode(SS1.Memory, SS1.Size, SS2.Memory, SS2.Size, - SS0.Memory, @Res, SS0.Size, 0) = 0; - if A then - SS0.Size := Res; - finally - SS0.Free; - SS1.Free; - SS2.Free; - end; - if not A then - DeleteFile(S1); - CS.Acquire; - try - Insert(S1, LList1, Length(LList1)); - Inc(K); - finally - CS.Release; - end; - Y := AtomicIncrement(J); - end; - end); - Tasks[I].Start; - end; - I := 0; - while I < Length(LList2) do - begin - while I >= K do - Sleep(10); - LFilename := IncludeTrailingBackSlash(TempDir) + I.ToHexString + - XTOOL_MAPSUF3; - if FileExists(LFilename) then - begin - LEntry.Op := TPatchOp.opDifferent; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - I64 := FileSize(LFilename); - Output.WriteBuffer(I64, I64.Size); - FStream := TFileStream.Create(LFilename, fmShareDenyNone); - try - CopyStreamEx(FStream, Output, I64); - finally - FStream.Free; - end; - TFile.Delete(LFilename); - end - else - begin - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList1[I]; - LEntry.Size := FileSize(BaseDir1 + LList1[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir1 + LList1[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - end; - Inc(I); - end; - WaitForAll(Tasks); - finally - for I := Low(Tasks) to High(Tasks) do - Tasks[I].Free; - CS.Free; - if DirectoryExists(TempDir) then - TDirectory.Delete(TempDir); - end; - FillChar(LEntry, SizeOf(TEntryStruct2), 0); - LEntry.Op := TPatchOp.opNone; - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); -end; - -procedure Decode(Input: TStream; Output: String; Options: TDecodeOptions); -var - I64: Int64; - B: Boolean; - S1, S2: String; - LFilename: String; - BaseDir: String; - LEntry: TEntryStruct2; - FStream: TFileStream; - SStream0, SStream1, SStream2: TSharedMemoryStream; - Res: NativeUInt; -begin - if FileExists(Output) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Output)); - S1 := IncludeTrailingBackSlash(GetCurrentDir) + - LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF3)); - SStream0 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S1); - try - Input.ReadBuffer(LEntry, SizeOf(TEntryStruct2)); - while LEntry.Op <> TPatchOp.opNone do - begin - if FileExists(Output) then - LFilename := Output - else - LFilename := BaseDir + LEntry.Filename; - case LEntry.Op of - TPatchOp.opDelete: - TFile.Delete(LFilename); - TPatchOp.opMissing: - begin - ForceDirectories(ExtractFilePath(LFilename)); - with TFileStream.Create(LFilename, fmCreate) do - try - CopyFrom(Input, LEntry.Size); - finally - Free; - end; - end; - TPatchOp.opDifferent: - begin - Input.ReadBuffer(I64, I64.Size); - SStream0.Position := 0; - CopyStreamEx(Input, SStream0, I64); - S2 := ChangeFileExt(LFilename, '_' + Random($7FFFFFFF).ToHexString + - XTOOL_MAPSUF3); - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S2); - B := False; - try - SStream2.Size := LEntry.Size; - B := xd3_decode(SStream0.Memory, I64, SStream1.Memory, - SStream1.Size, SStream2.Memory, @Res, SStream2.Size, 0) = 0; - finally - SStream1.Free; - SStream2.Free; - end; - if B then - begin - TFile.Delete(LFilename); - TFile.Move(S2, LFilename); - end - else if FileExists(S2) then - TFile.Delete(S2); - end; - end; - Input.ReadBuffer(LEntry, SizeOf(TEntryStruct2)); - end; - finally - SStream0.Free; - if FileExists(S1) then - TFile.Delete(S1); - end; -end; - -end. diff --git a/io/__history/IOPatch.pas.~310~ b/io/__history/IOPatch.pas.~310~ deleted file mode 100644 index 344cef7..0000000 --- a/io/__history/IOPatch.pas.~310~ +++ /dev/null @@ -1,431 +0,0 @@ -unit IOPatch; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - Threads: Integer; - MinSize, MaxSize: Int64; - end; - - PDecodeOptions = ^TDecodeOptions; - - TDecodeOptions = record - Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); - overload; -procedure Parse(ParamArg: TArray; out Options: TDecodeOptions); - overload; -procedure Encode(Input1, Input2: String; Output: TStream; - Options: TEncodeOptions); -procedure Decode(Input: TStream; Output: String; Options: TDecodeOptions); - -implementation - -uses - XDeltaDLL; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'patch - creates patches between two data sets'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, ' xtool patch [parameters] old_data new_data patch_data'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('--min=', 0, '64k'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.MinSize := Max(0, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('--max=', 0, '16g'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.MaxSize := Max(0, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Parse(ParamArg: TArray; out Options: TDecodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2: String; Output: TStream; - Options: TEncodeOptions); -var - I, J, K: Integer; - I64: Int64; - B, C: Boolean; - LFilename: String; - BaseDir1, BaseDir2: String; - LList1, LList2: TArray; - LBytes: TBytes; - LEntry: TEntryStruct2; - FStream: TFileStream; - SStream1, SStream2: TSharedMemoryStream; - Tasks: TArray; - CS: TCriticalSection; - TempDir: String; -begin - C := FileExists(Input1) and FileExists(Input2); - if FileExists(Input1) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)); - LList1 := GetFileList([Input1], True); - for I := Low(LList1) to High(LList1) do - LList1[I] := ReplaceText(LList1[I], BaseDir1, ''); - if FileExists(Input2) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input2)); - LList2 := GetFileList([Input2], True); - for I := Low(LList2) to High(LList2) do - LList2[I] := ReplaceText(LList2[I], BaseDir2, ''); - K := XTOOL_PATCH; - Output.WriteBuffer(K, K.Size); - if not C then - for I := High(LList1) downto Low(LList1) do - begin - if IndexText(LList1[I], LList2) < 0 then - begin - LEntry.Op := TPatchOp.opDelete; - LEntry.Filename := LList1[I]; - LEntry.Size := FileSize(BaseDir1 + LList1[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - Delete(LList1, I, 1); - end; - end; - if not C then - for I := High(LList2) downto Low(LList2) do - begin - if IndexText(LList2[I], LList1) < 0 then - begin - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir2 + LList2[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - Delete(LList2, I, 1); - end; - end; - for I := High(LList2) downto Low(LList2) do - begin - if C then - LFilename := Input1 - else - LFilename := BaseDir1 + LList2[I]; - if FileSize(LFilename) <> FileSize(BaseDir2 + LList2[I]) then - begin - if InRange(FileSize(BaseDir2 + LList2[I]), Options.MinSize, - Options.MaxSize) then - continue; - end - else - begin - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + LList2[I]); - try - B := SynCommons.CompareMem(SStream1.Memory, SStream2.Memory, - SStream1.Size); - finally - SStream1.Free; - SStream2.Free; - end; - if B then - if InRange(FileSize(BaseDir2 + LList2[I]), Options.MinSize, - Options.MaxSize) then - continue; - end; - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir2 + LList2[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - Delete(LList2, I, 1); - end; - TempDir := IncludeTrailingBackSlash(GetCurrentDir) + - LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF1)); - if not DirectoryExists(TempDir) then - CreateDir(TempDir); - SetLength(LList1, 0); - CS := TCriticalSection.Create; - SetLength(Tasks, Options.Threads); - J := -1; - K := 0; - try - for I := Low(Tasks) to High(Tasks) do - begin - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Y, Z: Integer; - S1, S2: String; - A: Boolean; - SS0, SS1, SS2: TSharedMemoryStream; - Res: NativeUInt; - begin - Z := Length(LList2); - Y := AtomicIncrement(J); - while Y < Z do - begin - S1 := IncludeTrailingBackSlash(TempDir) + Y.ToHexString + - XTOOL_MAPSUF3; - if C then - S2 := Input1 - else - S2 := BaseDir1 + LList2[Y]; - SS0 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S1); - SS1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S2); - SS2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + LList2[Y]); - try - ShowMessage(S2); - SS0.Size := Max(SS1.Size, SS2.Size); - A := xd3_encode(SS1.Memory, SS1.Size, SS2.Memory, SS2.Size, - SS0.Memory, @Res, SS0.Size, 0) = 0; - if A then - SS0.Size := Res; - finally - SS0.Free; - SS1.Free; - SS2.Free; - end; - if not A then - DeleteFile(S1); - CS.Acquire; - try - Insert(S1, LList1, Length(LList1)); - Inc(K); - finally - CS.Release; - end; - Y := AtomicIncrement(J); - end; - end); - Tasks[I].Start; - end; - I := 0; - while I < Length(LList2) do - begin - while I >= K do - Sleep(10); - LFilename := IncludeTrailingBackSlash(TempDir) + I.ToHexString + - XTOOL_MAPSUF3; - if FileExists(LFilename) then - begin - LEntry.Op := TPatchOp.opDifferent; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - I64 := FileSize(LFilename); - Output.WriteBuffer(I64, I64.Size); - FStream := TFileStream.Create(LFilename, fmShareDenyNone); - try - CopyStreamEx(FStream, Output, I64); - finally - FStream.Free; - end; - TFile.Delete(LFilename); - end - else - begin - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList1[I]; - LEntry.Size := FileSize(BaseDir1 + LList1[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir1 + LList1[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - end; - Inc(I); - end; - WaitForAll(Tasks); - finally - for I := Low(Tasks) to High(Tasks) do - Tasks[I].Free; - CS.Free; - if DirectoryExists(TempDir) then - TDirectory.Delete(TempDir); - end; - FillChar(LEntry, SizeOf(TEntryStruct2), 0); - LEntry.Op := TPatchOp.opNone; - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); -end; - -procedure Decode(Input: TStream; Output: String; Options: TDecodeOptions); -var - I64: Int64; - B: Boolean; - S1, S2: String; - LFilename: String; - BaseDir: String; - LEntry: TEntryStruct2; - FStream: TFileStream; - SStream0, SStream1, SStream2: TSharedMemoryStream; - Res: NativeUInt; -begin - if FileExists(Output) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Output)); - S1 := IncludeTrailingBackSlash(GetCurrentDir) + - LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF3)); - SStream0 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S1); - try - Input.ReadBuffer(LEntry, SizeOf(TEntryStruct2)); - while LEntry.Op <> TPatchOp.opNone do - begin - if FileExists(Output) then - LFilename := Output - else - LFilename := BaseDir + LEntry.Filename; - case LEntry.Op of - TPatchOp.opDelete: - TFile.Delete(LFilename); - TPatchOp.opMissing: - begin - ForceDirectories(ExtractFilePath(LFilename)); - with TFileStream.Create(LFilename, fmCreate) do - try - CopyFrom(Input, LEntry.Size); - finally - Free; - end; - end; - TPatchOp.opDifferent: - begin - Input.ReadBuffer(I64, I64.Size); - SStream0.Position := 0; - CopyStreamEx(Input, SStream0, I64); - S2 := ChangeFileExt(LFilename, '_' + Random($7FFFFFFF).ToHexString + - XTOOL_MAPSUF3); - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S2); - B := False; - try - SStream2.Size := LEntry.Size; - B := xd3_decode(SStream0.Memory, I64, SStream1.Memory, - SStream1.Size, SStream2.Memory, @Res, SStream2.Size, 0) = 0; - finally - SStream1.Free; - SStream2.Free; - end; - if B then - begin - TFile.Delete(LFilename); - TFile.Move(S2, LFilename); - end - else if FileExists(S2) then - TFile.Delete(S2); - end; - end; - Input.ReadBuffer(LEntry, SizeOf(TEntryStruct2)); - end; - finally - SStream0.Free; - if FileExists(S1) then - TFile.Delete(S1); - end; -end; - -end. diff --git a/io/__history/IOPatch.pas.~311~ b/io/__history/IOPatch.pas.~311~ deleted file mode 100644 index 2c5b100..0000000 --- a/io/__history/IOPatch.pas.~311~ +++ /dev/null @@ -1,430 +0,0 @@ -unit IOPatch; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - Threads: Integer; - MinSize, MaxSize: Int64; - end; - - PDecodeOptions = ^TDecodeOptions; - - TDecodeOptions = record - Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); - overload; -procedure Parse(ParamArg: TArray; out Options: TDecodeOptions); - overload; -procedure Encode(Input1, Input2: String; Output: TStream; - Options: TEncodeOptions); -procedure Decode(Input: TStream; Output: String; Options: TDecodeOptions); - -implementation - -uses - XDeltaDLL; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'patch - creates patches between two data sets'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, ' xtool patch [parameters] old_data new_data patch_data'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('--min=', 0, '64k'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.MinSize := Max(0, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('--max=', 0, '16g'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.MaxSize := Max(0, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Parse(ParamArg: TArray; out Options: TDecodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2: String; Output: TStream; - Options: TEncodeOptions); -var - I, J, K: Integer; - I64: Int64; - B, C: Boolean; - LFilename: String; - BaseDir1, BaseDir2: String; - LList1, LList2: TArray; - LBytes: TBytes; - LEntry: TEntryStruct2; - FStream: TFileStream; - SStream1, SStream2: TSharedMemoryStream; - Tasks: TArray; - CS: TCriticalSection; - TempDir: String; -begin - C := FileExists(Input1) and FileExists(Input2); - if FileExists(Input1) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)); - LList1 := GetFileList([Input1], True); - for I := Low(LList1) to High(LList1) do - LList1[I] := ReplaceText(LList1[I], BaseDir1, ''); - if FileExists(Input2) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input2)); - LList2 := GetFileList([Input2], True); - for I := Low(LList2) to High(LList2) do - LList2[I] := ReplaceText(LList2[I], BaseDir2, ''); - K := XTOOL_PATCH; - Output.WriteBuffer(K, K.Size); - if not C then - for I := High(LList1) downto Low(LList1) do - begin - if IndexText(LList1[I], LList2) < 0 then - begin - LEntry.Op := TPatchOp.opDelete; - LEntry.Filename := LList1[I]; - LEntry.Size := FileSize(BaseDir1 + LList1[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - Delete(LList1, I, 1); - end; - end; - if not C then - for I := High(LList2) downto Low(LList2) do - begin - if IndexText(LList2[I], LList1) < 0 then - begin - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir2 + LList2[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - Delete(LList2, I, 1); - end; - end; - for I := High(LList2) downto Low(LList2) do - begin - if C then - LFilename := Input1 - else - LFilename := BaseDir1 + LList2[I]; - if FileSize(LFilename) <> FileSize(BaseDir2 + LList2[I]) then - begin - if InRange(FileSize(BaseDir2 + LList2[I]), Options.MinSize, - Options.MaxSize) then - continue; - end - else - begin - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + LList2[I]); - try - B := SynCommons.CompareMem(SStream1.Memory, SStream2.Memory, - SStream1.Size); - finally - SStream1.Free; - SStream2.Free; - end; - if B then - if InRange(FileSize(BaseDir2 + LList2[I]), Options.MinSize, - Options.MaxSize) then - continue; - end; - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir2 + LList2[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - Delete(LList2, I, 1); - end; - TempDir := IncludeTrailingBackSlash(GetCurrentDir) + - LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF1)); - if not DirectoryExists(TempDir) then - CreateDir(TempDir); - SetLength(LList1, 0); - CS := TCriticalSection.Create; - SetLength(Tasks, Options.Threads); - J := -1; - K := 0; - try - for I := Low(Tasks) to High(Tasks) do - begin - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Y, Z: Integer; - S1, S2: String; - A: Boolean; - SS0, SS1, SS2: TSharedMemoryStream; - Res: NativeUInt; - begin - Z := Length(LList2); - Y := AtomicIncrement(J); - while Y < Z do - begin - S1 := IncludeTrailingBackSlash(TempDir) + Y.ToHexString + - XTOOL_MAPSUF3; - if C then - S2 := Input1 - else - S2 := BaseDir1 + LList2[Y]; - SS0 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S1); - SS1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S2); - SS2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), - BaseDir2 + LList2[Y]); - try - SS0.Size := Max(SS1.Size, SS2.Size); - A := xd3_encode(SS1.Memory, SS1.Size, SS2.Memory, SS2.Size, - SS0.Memory, @Res, SS0.Size, 0) = 0; - if A then - SS0.Size := Res; - finally - SS0.Free; - SS1.Free; - SS2.Free; - end; - if not A then - DeleteFile(S1); - CS.Acquire; - try - Insert(S1, LList1, Length(LList1)); - Inc(K); - finally - CS.Release; - end; - Y := AtomicIncrement(J); - end; - end); - Tasks[I].Start; - end; - I := 0; - while I < Length(LList2) do - begin - while I >= K do - Sleep(10); - LFilename := IncludeTrailingBackSlash(TempDir) + I.ToHexString + - XTOOL_MAPSUF3; - if FileExists(LFilename) then - begin - LEntry.Op := TPatchOp.opDifferent; - LEntry.Filename := LList2[I]; - LEntry.Size := FileSize(BaseDir2 + LList2[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - I64 := FileSize(LFilename); - Output.WriteBuffer(I64, I64.Size); - FStream := TFileStream.Create(LFilename, fmShareDenyNone); - try - CopyStreamEx(FStream, Output, I64); - finally - FStream.Free; - end; - TFile.Delete(LFilename); - end - else - begin - LEntry.Op := TPatchOp.opMissing; - LEntry.Filename := LList1[I]; - LEntry.Size := FileSize(BaseDir1 + LList1[I]); - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); - FStream := TFileStream.Create(BaseDir1 + LList1[I], fmShareDenyNone); - try - CopyStreamEx(FStream, Output, LEntry.Size); - finally - FStream.Free; - end; - end; - Inc(I); - end; - WaitForAll(Tasks); - finally - for I := Low(Tasks) to High(Tasks) do - Tasks[I].Free; - CS.Free; - if DirectoryExists(TempDir) then - TDirectory.Delete(TempDir); - end; - FillChar(LEntry, SizeOf(TEntryStruct2), 0); - LEntry.Op := TPatchOp.opNone; - Output.WriteBuffer(LEntry, SizeOf(TEntryStruct2)); -end; - -procedure Decode(Input: TStream; Output: String; Options: TDecodeOptions); -var - I64: Int64; - B: Boolean; - S1, S2: String; - LFilename: String; - BaseDir: String; - LEntry: TEntryStruct2; - FStream: TFileStream; - SStream0, SStream1, SStream2: TSharedMemoryStream; - Res: NativeUInt; -begin - if FileExists(Output) then - BaseDir := ExtractFilePath(TPath.GetFullPath(Output)) - else if DirectoryExists(Output) then - BaseDir := IncludeTrailingBackSlash(TPath.GetFullPath(Output)) - else - BaseDir := ExtractFilePath(TPath.GetFullPath(Output)); - S1 := IncludeTrailingBackSlash(GetCurrentDir) + - LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF3)); - SStream0 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S1); - try - Input.ReadBuffer(LEntry, SizeOf(TEntryStruct2)); - while LEntry.Op <> TPatchOp.opNone do - begin - if FileExists(Output) then - LFilename := Output - else - LFilename := BaseDir + LEntry.Filename; - case LEntry.Op of - TPatchOp.opDelete: - TFile.Delete(LFilename); - TPatchOp.opMissing: - begin - ForceDirectories(ExtractFilePath(LFilename)); - with TFileStream.Create(LFilename, fmCreate) do - try - CopyFrom(Input, LEntry.Size); - finally - Free; - end; - end; - TPatchOp.opDifferent: - begin - Input.ReadBuffer(I64, I64.Size); - SStream0.Position := 0; - CopyStreamEx(Input, SStream0, I64); - S2 := ChangeFileExt(LFilename, '_' + Random($7FFFFFFF).ToHexString + - XTOOL_MAPSUF3); - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), LFilename); - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF2)), S2); - B := False; - try - SStream2.Size := LEntry.Size; - B := xd3_decode(SStream0.Memory, I64, SStream1.Memory, - SStream1.Size, SStream2.Memory, @Res, SStream2.Size, 0) = 0; - finally - SStream1.Free; - SStream2.Free; - end; - if B then - begin - TFile.Delete(LFilename); - TFile.Move(S2, LFilename); - end - else if FileExists(S2) then - TFile.Delete(S2); - end; - end; - Input.ReadBuffer(LEntry, SizeOf(TEntryStruct2)); - end; - finally - SStream0.Free; - if FileExists(S1) then - TFile.Delete(S1); - end; -end; - -end. diff --git a/io/__history/IOReplace.pas.~50~ b/io/__history/IOReplace.pas.~50~ deleted file mode 100644 index f62f93e..0000000 --- a/io/__history/IOReplace.pas.~50~ +++ /dev/null @@ -1,360 +0,0 @@ -unit IOReplace; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Input3, Output: String; - Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'replace - replace sectors with another within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool replace [parameters] old_streams new_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Input3, Output: String; - Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - LFilename: String; - BaseDir1, BaseDir2: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream1, SStream2: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir1, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('%s is smaller than %d', [LList[I], MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('%s is larger than %d', - [LList[I], Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].CRCSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Input3) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input3)) - else if DirectoryExists(Input3) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Input3)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input3)); - LList := GetFileList([Input3], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir2, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - if FileExists(Input2) then - LFilename := Input2 - else - LFilename := BaseDir1 + PEntry^.Filename; - if FileExists(LFilename) then - begin - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), - LFilename); - try - Move(SStream2.Memory^, - (PByte(SStream1.Memory) + PEntry.Position)^, - Min(SStream1.Size, SStream2.Size)); - finally - SStream2.Free; - end; - end; - end; - finally - SStream1.Free; - end; - end; - end; - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOReplace.pas.~51~ b/io/__history/IOReplace.pas.~51~ deleted file mode 100644 index f7b1e29..0000000 --- a/io/__history/IOReplace.pas.~51~ +++ /dev/null @@ -1,363 +0,0 @@ -unit IOReplace; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Input3, Output: String; - Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'replace - replace sectors with another within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool replace [parameters] old_streams new_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Input3, Output: String; - Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - LFilename: String; - BaseDir1, BaseDir2: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream1, SStream2: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir1, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('%s is smaller than %d', [LList[I], MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('%s is larger than %d', - [LList[I], Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].CRCSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Input3) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input3)) - else if DirectoryExists(Input3) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Input3)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input3)); - LList := GetFileList([Input3], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir2, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - if FileExists(Input2) then - LFilename := Input2 - else - LFilename := BaseDir1 + PEntry^.Filename; - if FileExists(LFilename) then - begin - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), - LFilename); - try - Move(SStream2.Memory^, - (PByte(SStream1.Memory) + PEntry.Position)^, - Min(SStream1.Size, SStream2.Size)); - finally - SStream2.Free; - end; - end; - end; - finally - SStream1.Free; - end; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('%s is smaller than %d', - [LList[I], MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOReplace.pas.~52~ b/io/__history/IOReplace.pas.~52~ deleted file mode 100644 index c1893b5..0000000 --- a/io/__history/IOReplace.pas.~52~ +++ /dev/null @@ -1,363 +0,0 @@ -unit IOReplace; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Input3, Output: String; - Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'replace - replace sectors with another within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool replace [parameters] old_streams new_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Input3, Output: String; - Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - LFilename: String; - BaseDir1, BaseDir2: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream1, SStream2: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir1, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('%s is smaller than %d', [LList[I], MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('%s is larger than %d', - [LList[I], Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].CRCSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Input3) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input3)) - else if DirectoryExists(Input3) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Input3)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input3)); - LList := GetFileList([Input3], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir2, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - if FileExists(Input2) then - LFilename := Input2 - else - LFilename := BaseDir1 + PEntry^.Filename; - if FileExists(LFilename) then - begin - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), - LFilename); - try - Move(SStream2.Memory^, - (PByte(SStream1.Memory) + PEntry.Position)^, - Min(SStream1.Size, SStream2.Size)); - finally - SStream2.Free; - end; - end; - end; - finally - SStream1.Free; - end; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [LList[I], MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOReplace.pas.~53~ b/io/__history/IOReplace.pas.~53~ deleted file mode 100644 index 38cf4fa..0000000 --- a/io/__history/IOReplace.pas.~53~ +++ /dev/null @@ -1,363 +0,0 @@ -unit IOReplace; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Input3, Output: String; - Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'replace - replace sectors with another within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool replace [parameters] old_streams new_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Input3, Output: String; - Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - LFilename: String; - BaseDir1, BaseDir2: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream1, SStream2: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir1, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('%s is smaller than %d', [LList[I], MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('%s is larger than %d', - [LList[I], Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].CRCSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Input3) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input3)) - else if DirectoryExists(Input3) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Input3)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input3)); - LList := GetFileList([Input3], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir2, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - if FileExists(Input2) then - LFilename := Input2 - else - LFilename := BaseDir1 + PEntry^.Filename; - if FileExists(LFilename) then - begin - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), - LFilename); - try - Move(SStream2.Memory^, - (PByte(SStream1.Memory) + PEntry.Position)^, - Min(SStream1.Size, SStream2.Size)); - finally - SStream2.Free; - end; - end; - end; - finally - SStream1.Free; - end; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir2, ''), MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOReplace.pas.~54~ b/io/__history/IOReplace.pas.~54~ deleted file mode 100644 index 38cf4fa..0000000 --- a/io/__history/IOReplace.pas.~54~ +++ /dev/null @@ -1,363 +0,0 @@ -unit IOReplace; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Input3, Output: String; - Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'replace - replace sectors with another within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool replace [parameters] old_streams new_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Input3, Output: String; - Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - LFilename: String; - BaseDir1, BaseDir2: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream1, SStream2: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir1, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('%s is smaller than %d', [LList[I], MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('%s is larger than %d', - [LList[I], Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].CRCSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Input3) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input3)) - else if DirectoryExists(Input3) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Input3)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input3)); - LList := GetFileList([Input3], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir2, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - if FileExists(Input2) then - LFilename := Input2 - else - LFilename := BaseDir1 + PEntry^.Filename; - if FileExists(LFilename) then - begin - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), - LFilename); - try - Move(SStream2.Memory^, - (PByte(SStream1.Memory) + PEntry.Position)^, - Min(SStream1.Size, SStream2.Size)); - finally - SStream2.Free; - end; - end; - end; - finally - SStream1.Free; - end; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir2, ''), MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOReplace.pas.~55~ b/io/__history/IOReplace.pas.~55~ deleted file mode 100644 index 38cf4fa..0000000 --- a/io/__history/IOReplace.pas.~55~ +++ /dev/null @@ -1,363 +0,0 @@ -unit IOReplace; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Input3, Output: String; - Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'replace - replace sectors with another within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool replace [parameters] old_streams new_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Input3, Output: String; - Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - LFilename: String; - BaseDir1, BaseDir2: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream1, SStream2: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir1, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('%s is smaller than %d', [LList[I], MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('%s is larger than %d', - [LList[I], Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].CRCSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Input3) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input3)) - else if DirectoryExists(Input3) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Input3)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input3)); - LList := GetFileList([Input3], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir2, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - if FileExists(Input2) then - LFilename := Input2 - else - LFilename := BaseDir1 + PEntry^.Filename; - if FileExists(LFilename) then - begin - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), - LFilename); - try - Move(SStream2.Memory^, - (PByte(SStream1.Memory) + PEntry.Position)^, - Min(SStream1.Size, SStream2.Size)); - finally - SStream2.Free; - end; - end; - end; - finally - SStream1.Free; - end; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir2, ''), MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOReplace.pas.~56~ b/io/__history/IOReplace.pas.~56~ deleted file mode 100644 index 8096a51..0000000 --- a/io/__history/IOReplace.pas.~56~ +++ /dev/null @@ -1,364 +0,0 @@ -unit IOReplace; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Input3, Output: String; - Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'replace - replace sectors with another within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool replace [parameters] old_streams new_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Input3, Output: String; - Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - LFilename: String; - BaseDir1, BaseDir2: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream1, SStream2: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir1, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('%s is smaller than %d', - [ReplaceText(LList[I], BaseDir1, ''), MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('%s is larger than %d', - [ReplaceText(LList[I], BaseDir1, ''), Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].CRCSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Input3) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input3)) - else if DirectoryExists(Input3) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Input3)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input3)); - LList := GetFileList([Input3], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir2, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - if FileExists(Input2) then - LFilename := Input2 - else - LFilename := BaseDir1 + PEntry^.Filename; - if FileExists(LFilename) then - begin - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), - LFilename); - try - Move(SStream2.Memory^, - (PByte(SStream1.Memory) + PEntry.Position)^, - Min(SStream1.Size, SStream2.Size)); - finally - SStream2.Free; - end; - end; - end; - finally - SStream1.Free; - end; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir2, ''), MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOReplace.pas.~57~ b/io/__history/IOReplace.pas.~57~ deleted file mode 100644 index b268b63..0000000 --- a/io/__history/IOReplace.pas.~57~ +++ /dev/null @@ -1,364 +0,0 @@ -unit IOReplace; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Input3, Output: String; - Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'replace - replace sectors with another within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool replace [parameters] old_streams new_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Input3, Output: String; - Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - LFilename: String; - BaseDir1, BaseDir2: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct; - PEntry: PEntryStruct; - LBytes: TBytes; - FStream: TFileStream; - SStream1, SStream2: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir1, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir1, ''), MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('Skipped %s (Larger than %d)', - [ReplaceText(LList[I], BaseDir1, ''), Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].CRCSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Input3) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input3)) - else if DirectoryExists(Input3) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Input3)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input3)); - LList := GetFileList([Input3], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir2, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct)); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - if FileExists(Input2) then - LFilename := Input2 - else - LFilename := BaseDir1 + PEntry^.Filename; - if FileExists(LFilename) then - begin - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), - LFilename); - try - Move(SStream2.Memory^, - (PByte(SStream1.Memory) + PEntry.Position)^, - Min(SStream1.Size, SStream2.Size)); - finally - SStream2.Free; - end; - end; - end; - finally - SStream1.Free; - end; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir2, ''), MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOReplace.pas.~58~ b/io/__history/IOReplace.pas.~58~ deleted file mode 100644 index 5e54cee..0000000 --- a/io/__history/IOReplace.pas.~58~ +++ /dev/null @@ -1,364 +0,0 @@ -unit IOReplace; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Input3, Output: String; - Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'replace - replace sectors with another within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool replace [parameters] old_streams new_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Input3, Output: String; - Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - LFilename: String; - BaseDir1, BaseDir2: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct1; - PEntry: PEntryStruct1; - LBytes: TBytes; - FStream: TFileStream; - SStream1, SStream2: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir1, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir1, ''), MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('Skipped %s (Larger than %d)', - [ReplaceText(LList[I], BaseDir1, ''), Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct1; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].CRCSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Input3) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input3)) - else if DirectoryExists(Input3) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Input3)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input3)); - LList := GetFileList([Input3], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir2, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct1)); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct1(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - if FileExists(Input2) then - LFilename := Input2 - else - LFilename := BaseDir1 + PEntry^.Filename; - if FileExists(LFilename) then - begin - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), - LFilename); - try - Move(SStream2.Memory^, - (PByte(SStream1.Memory) + PEntry.Position)^, - Min(SStream1.Size, SStream2.Size)); - finally - SStream2.Free; - end; - end; - end; - finally - SStream1.Free; - end; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir2, ''), MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOReplace.pas.~59~ b/io/__history/IOReplace.pas.~59~ deleted file mode 100644 index 5e54cee..0000000 --- a/io/__history/IOReplace.pas.~59~ +++ /dev/null @@ -1,364 +0,0 @@ -unit IOReplace; - -{$POINTERMATH ON} - -interface - -uses - Threading, Utils, SynCommons, SynCrypto, ParseClass, ParseExpr, - IOUtils, - WinAPI.Windows, WinAPI.ShlObj, - System.SysUtils, System.Classes, System.SyncObjs, System.Math, System.Types, - System.StrUtils, System.RTLConsts, System.TimeSpan, System.Diagnostics, - System.IOUtils, System.Generics.Defaults, System.Generics.Collections; - -type - PEncodeOptions = ^TEncodeOptions; - - TEncodeOptions = record - ChunkSize, Threads: Integer; - end; - -procedure PrintHelp; -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -procedure Encode(Input1, Input2, Input3, Output: String; - Options: TEncodeOptions); - -implementation - -const - MinSize1 = 256; - MinSize2 = 65536; - -type - PScanInfo = ^TScanInfo; - - TScanInfo = record - Filename: String[255]; - CRCSize, ActualSize: Integer; - CRC1, CRC2: Cardinal; - end; - -var - SearchInfo: TArray>>; - SearchCount: TArray>; - -procedure PrintHelp; -var - I, J: Integer; - S: string; -begin - WriteLn(ErrOutput, 'replace - replace sectors with another within files'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Usage:'); - WriteLn(ErrOutput, - ' xtool replace [parameters] old_streams new_streams original_data [decode_data]'); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, ''); - WriteLn(ErrOutput, 'Parameters:'); - WriteLn(ErrOutput, ' -c# - scanning range [16mb]'); - WriteLn(ErrOutput, ' -t# - number of working threads [50p]'); - WriteLn(ErrOutput, ''); -end; - -procedure Parse(ParamArg: TArray; out Options: TEncodeOptions); -var - ArgParse: TArgParser; - ExpParse: TExpressionParser; - S: String; -begin - ArgParse := TArgParser.Create(ParamArg); - ExpParse := TExpressionParser.Create; - try - S := ArgParse.AsString('-c', 0, '16mb'); - S := ReplaceText(S, 'KB', '* 1024^1'); - S := ReplaceText(S, 'MB', '* 1024^2'); - S := ReplaceText(S, 'GB', '* 1024^3'); - S := ReplaceText(S, 'K', '* 1024^1'); - S := ReplaceText(S, 'M', '* 1024^2'); - S := ReplaceText(S, 'G', '* 1024^3'); - Options.ChunkSize := Max(4194304, Round(ExpParse.Evaluate(S))); - S := ArgParse.AsString('-t', 0, '50p'); - S := ReplaceText(S, 'p', '%'); - S := ReplaceText(S, '%', '%*' + CPUCount.ToString); - Options.Threads := Max(1, Round(ExpParse.Evaluate(S))); - finally - ArgParse.Free; - ExpParse.Free; - end; -end; - -procedure Encode(Input1, Input2, Input3, Output: String; - Options: TEncodeOptions); -const - BufferSize = 65536; -var - Buffer: array [0 .. BufferSize - 1] of Byte; - A: Word; - B: Byte; - I, J, K: Integer; - LastStream: Int64; - Found1, Found2: Boolean; - CountPos: NativeInt; - LFilename: String; - BaseDir1, BaseDir2: String; - LList: TArray; - LSInfo: PScanInfo; - LEntry: TEntryStruct1; - PEntry: PEntryStruct1; - LBytes: TBytes; - FStream: TFileStream; - SStream1, SStream2: TSharedMemoryStream; - OStream, MStream: TMemoryStream; - DataStore: TDataStore1; - Tasks: TArray; - InfoStore: TArray>; -begin - SetLength(SearchInfo, $10000); - SetLength(SearchCount, $10000); - for I := Low(SearchInfo) to High(SearchInfo) do - begin - SetLength(SearchInfo[I], $100); - SetLength(SearchCount[I], $100); - for J := Low(SearchCount[I]) to High(SearchCount[I]) do - SearchCount[I, J] := 0; - end; - if FileExists(Input1) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)) - else if DirectoryExists(Input1) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input1)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input1)); - LList := GetFileList([Input1], True); - for I := Low(LList) to High(LList) do - begin - if InRange(FileSize(LList[I]), MinSize1, Integer.MaxValue) then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - with FStream do - try - ReadBuffer(Buffer[0], MinSize1); - WordRec(A).Bytes[0] := Buffer[0]; - WordRec(A).Bytes[1] := Buffer[1]; - B := Buffer[MinSize1 - 1]; - J := MinSize1; - New(LSInfo); - LSInfo^.Filename := ReplaceText(LList[I], BaseDir1, ''); - LSInfo^.CRCSize := J; - LSInfo^.ActualSize := FileSize(LList[I]); - LSInfo^.CRC1 := Utils.Hash32(0, @Buffer[0], J); - LSInfo^.CRC2 := LSInfo^.CRC1; - while (J > 0) and (LSInfo^.CRCSize < Options.ChunkSize) do - begin - J := Read(Buffer[0], Min(Options.ChunkSize - LSInfo^.CRCSize, - BufferSize)); - Inc(LSInfo^.CRCSize, J); - LSInfo^.CRC2 := Utils.Hash32(LSInfo^.CRC2, @Buffer[0], J); - end; - finally - Free; - end; - Insert(LSInfo^, SearchInfo[A, B], Length(SearchInfo[A, B])); - Inc(SearchCount[A, B]); - end - else if FileSize(LList[I]) < MinSize1 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir1, ''), MinSize1])) - else if FileSize(LList[I]) > Integer.MaxValue then - WriteLn(ErrOutput, Format('Skipped %s (Larger than %d)', - [ReplaceText(LList[I], BaseDir1, ''), Integer.MaxValue])); - end; - DataStore := TDataStore1.Create(nil, True, Options.Threads, - Options.ChunkSize); - SetLength(Tasks, Options.Threads); - SetLength(InfoStore, Options.Threads); - OStream := TMemoryStream.Create; - MStream := TMemoryStream.Create; - if FileExists(Output) then - OStream.LoadFromFile(Output) - else - begin - K := XTOOL_IODEC; - OStream.WriteBuffer(K, K.Size); - end; - OStream.Position := OStream.Size; - Found1 := False; - try - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I] := TListEx.Create(EntryStructCmp); - Tasks[I] := TTask.Create(I); - Tasks[I].Perform( - procedure(X: IntPtr) - var - Ptr: PByte; - Y: Integer; - C: Word; - D: Byte; - Pos, Size, SizeEx: NativeInt; - CRC: Cardinal; - E: TEntryStruct1; - F: Boolean; - begin - Ptr := DataStore.Slot(X).Memory; - Pos := 0; - Size := DataStore.Size(X) - MinSize1; - SizeEx := DataStore.ActualSize(X); - while Pos < Size do - begin - C := PWord(Ptr + Pos)^; - D := (Ptr + Pos + MinSize1 - 1)^; - if (SearchCount[C, D] > 0) then - begin - F := False; - CRC := Utils.Hash32(0, Ptr + Pos, MinSize1); - for Y := 0 to SearchCount[C, D] - 1 do - begin - if (SearchInfo[C, D, Y].CRCSize <= (SizeEx - Pos)) then - if (CRC = SearchInfo[C, D, Y].CRC1) and - (Utils.Hash32(CRC, Ptr + Pos + MinSize1, SearchInfo[C, D, - Y].CRCSize - MinSize1) = SearchInfo[C, D, Y].CRC2) then - begin - E.Filename := SearchInfo[C, D, Y].Filename; - E.Position := DataStore.Position(X) + Pos; - E.Size := SearchInfo[C, D, Y].CRCSize; - InfoStore[X].Add(E); - Inc(Pos, E.Size); - F := True; - break; - end; - end; - if F then - continue; - end; - Inc(Pos); - end; - end); - end; - if FileExists(Input2) then - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)) - else if DirectoryExists(Input2) then - BaseDir1 := IncludeTrailingBackSlash(TPath.GetFullPath(Input2)) - else - BaseDir1 := ExtractFilePath(TPath.GetFullPath(Input2)); - if FileExists(Input3) then - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input3)) - else if DirectoryExists(Input3) then - BaseDir2 := IncludeTrailingBackSlash(TPath.GetFullPath(Input3)) - else - BaseDir2 := ExtractFilePath(TPath.GetFullPath(Input3)); - LList := GetFileList([Input3], True); - for I := Low(LList) to High(LList) do - begin - if FileSize(LList[I]) >= MinSize2 then - begin - FStream := TFileStream.Create(LList[I], fmShareDenyNone); - try - LastStream := 0; - MStream.Position := 0; - Found2 := False; - DataStore.ChangeInput(FStream); - DataStore.Load; - LBytes := BytesOf(ReplaceText(LList[I], BaseDir2, '')); - K := Length(LBytes); - MStream.WriteBuffer(K, K.Size); - MStream.WriteBuffer(LBytes[0], K); - CountPos := MStream.Position; - K := 0; - MStream.WriteBuffer(K, K.Size); - while not DataStore.Done do - begin - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Count := 0; - Tasks[J].Start; - end; - WaitForAll(Tasks); - for J := Low(Tasks) to High(Tasks) do - begin - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - if LEntry.Position < LastStream then - InfoStore[J].Delete(K) - else - break; - K := InfoStore[J].Get(LEntry); - end; - Inc(PInteger(PByte(MStream.Memory) + CountPos)^, - InfoStore[J].Count); - if InfoStore[J].Count > 0 then - begin - Found1 := True; - Found2 := True; - end; - InfoStore[J].Index := 0; - K := InfoStore[J].Get(LEntry); - while K >= 0 do - begin - MStream.WriteBuffer(LEntry, SizeOf(TEntryStruct1)); - LastStream := LEntry.Position + LEntry.Size; - K := InfoStore[J].Get(LEntry); - end; - end; - DataStore.Load; - end; - if Found2 then - OStream.WriteBuffer(MStream.Memory^, MStream.Position); - finally - FStream.Free; - end; - if Found2 then - begin - SStream1 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), LList[I]); - try - for J := PInteger(PByte(MStream.Memory) + CountPos)^ - 1 downto 0 do - begin - PEntry := PEntryStruct1(PByte(MStream.Memory) + CountPos + - Integer.Size) + J; - if FileExists(Input2) then - LFilename := Input2 - else - LFilename := BaseDir1 + PEntry^.Filename; - if FileExists(LFilename) then - begin - SStream2 := TSharedMemoryStream.Create - (LowerCase(ChangeFileExt(ExtractFileName(Utils.GetModuleName), - '_' + Random($7FFFFFFF).ToHexString + XTOOL_MAPSUF)), - LFilename); - try - Move(SStream2.Memory^, - (PByte(SStream1.Memory) + PEntry.Position)^, - Min(SStream1.Size, SStream2.Size)); - finally - SStream2.Free; - end; - end; - end; - finally - SStream1.Free; - end; - end; - end - else if FileSize(LList[I]) < MinSize2 then - WriteLn(ErrOutput, Format('Skipped %s (Smaller than %d)', - [ReplaceText(LList[I], BaseDir2, ''), MinSize2])); - end; - if Found1 and (Output <> '') then - OStream.SaveToFile(Output); - finally - for I := Low(Tasks) to High(Tasks) do - begin - InfoStore[I].Free; - Tasks[I].Free; - end; - DataStore.Free; - OStream.Free; - MStream.Free; - end; -end; - -end. diff --git a/io/__history/IOUtils.pas.~31~ b/io/__history/IOUtils.pas.~31~ deleted file mode 100644 index 9992acb..0000000 --- a/io/__history/IOUtils.pas.~31~ +++ /dev/null @@ -1,54 +0,0 @@ -unit IOUtils; - -interface - -uses - WinAPI.Windows, - System.SysUtils, System.Classes, System.StrUtils, System.Types, System.Math, - System.Generics.Defaults, System.Generics.Collections; - -const - XTOOL_IODEC = $314C5458; - XTOOL_PATCH = $324C5458; - XTOOL_MAPSUF = '_mapped.io'; - -type - PEntryStruct1 = ^TEntryStruct1; - - TEntryStruct1 = packed record - Filename: String[255]; - Position: Int64; - Size: Integer; - end; - - TEntryStructComparer = class(TComparer) - public - function Compare(const Left, Right: TEntryStruct1): Integer; override; - end; - - TPatchOp = (opDelete, opMissing, opDifferent); - - PEntryStruct2 = ^TEntryStruct2; - - TEntryStruct2 = packed record - Op: TPatchOp; - Filename: String[255]; - Size: Int64; - end; - -var - EntryStructCmp: TEntryStructComparer; - -implementation - -function TEntryStructComparer.Compare(const Left, Right: TEntryStruct1) - : Integer; -begin - Result := Integer(CompareValue(Left.Position, Right.Position)); -end; - -initialization - -EntryStructCmp := TEntryStructComparer.Create; - -end. diff --git a/io/__history/IOUtils.pas.~32~ b/io/__history/IOUtils.pas.~32~ deleted file mode 100644 index ff4e14e..0000000 --- a/io/__history/IOUtils.pas.~32~ +++ /dev/null @@ -1,54 +0,0 @@ -unit IOUtils; - -interface - -uses - WinAPI.Windows, - System.SysUtils, System.Classes, System.StrUtils, System.Types, System.Math, - System.Generics.Defaults, System.Generics.Collections; - -const - XTOOL_IODEC = $314C5458; - XTOOL_PATCH = $324C5458; - XTOOL_MAPSUF1 = '_mapped.io'; - -type - PEntryStruct1 = ^TEntryStruct1; - - TEntryStruct1 = packed record - Filename: String[255]; - Position: Int64; - Size: Integer; - end; - - TEntryStructComparer = class(TComparer) - public - function Compare(const Left, Right: TEntryStruct1): Integer; override; - end; - - TPatchOp = (opDelete, opMissing, opDifferent); - - PEntryStruct2 = ^TEntryStruct2; - - TEntryStruct2 = packed record - Op: TPatchOp; - Filename: String[255]; - Size: Int64; - end; - -var - EntryStructCmp: TEntryStructComparer; - -implementation - -function TEntryStructComparer.Compare(const Left, Right: TEntryStruct1) - : Integer; -begin - Result := Integer(CompareValue(Left.Position, Right.Position)); -end; - -initialization - -EntryStructCmp := TEntryStructComparer.Create; - -end. diff --git a/io/__history/IOUtils.pas.~33~ b/io/__history/IOUtils.pas.~33~ deleted file mode 100644 index e3d0e57..0000000 --- a/io/__history/IOUtils.pas.~33~ +++ /dev/null @@ -1,54 +0,0 @@ -unit IOUtils; - -interface - -uses - WinAPI.Windows, - System.SysUtils, System.Classes, System.StrUtils, System.Types, System.Math, - System.Generics.Defaults, System.Generics.Collections; - -const - XTOOL_IODEC = $314C5458; - XTOOL_PATCH = $324C5458; - XTOOL_MAPSUF2 = '_mapped.io'; - -type - PEntryStruct1 = ^TEntryStruct1; - - TEntryStruct1 = packed record - Filename: String[255]; - Position: Int64; - Size: Integer; - end; - - TEntryStructComparer = class(TComparer) - public - function Compare(const Left, Right: TEntryStruct1): Integer; override; - end; - - TPatchOp = (opDelete, opMissing, opDifferent); - - PEntryStruct2 = ^TEntryStruct2; - - TEntryStruct2 = packed record - Op: TPatchOp; - Filename: String[255]; - Size: Int64; - end; - -var - EntryStructCmp: TEntryStructComparer; - -implementation - -function TEntryStructComparer.Compare(const Left, Right: TEntryStruct1) - : Integer; -begin - Result := Integer(CompareValue(Left.Position, Right.Position)); -end; - -initialization - -EntryStructCmp := TEntryStructComparer.Create; - -end. diff --git a/io/__history/IOUtils.pas.~34~ b/io/__history/IOUtils.pas.~34~ deleted file mode 100644 index f61b222..0000000 --- a/io/__history/IOUtils.pas.~34~ +++ /dev/null @@ -1,55 +0,0 @@ -unit IOUtils; - -interface - -uses - WinAPI.Windows, - System.SysUtils, System.Classes, System.StrUtils, System.Types, System.Math, - System.Generics.Defaults, System.Generics.Collections; - -const - XTOOL_IODEC = $314C5458; - XTOOL_PATCH = $324C5458; - XTOOL_MAPSUF2 = '_mapped.io'; - XTOOL_MAPSUF2 = '_mapped.io'; - -type - PEntryStruct1 = ^TEntryStruct1; - - TEntryStruct1 = packed record - Filename: String[255]; - Position: Int64; - Size: Integer; - end; - - TEntryStructComparer = class(TComparer) - public - function Compare(const Left, Right: TEntryStruct1): Integer; override; - end; - - TPatchOp = (opDelete, opMissing, opDifferent); - - PEntryStruct2 = ^TEntryStruct2; - - TEntryStruct2 = packed record - Op: TPatchOp; - Filename: String[255]; - Size: Int64; - end; - -var - EntryStructCmp: TEntryStructComparer; - -implementation - -function TEntryStructComparer.Compare(const Left, Right: TEntryStruct1) - : Integer; -begin - Result := Integer(CompareValue(Left.Position, Right.Position)); -end; - -initialization - -EntryStructCmp := TEntryStructComparer.Create; - -end. diff --git a/io/__history/IOUtils.pas.~35~ b/io/__history/IOUtils.pas.~35~ deleted file mode 100644 index 633eaa7..0000000 --- a/io/__history/IOUtils.pas.~35~ +++ /dev/null @@ -1,55 +0,0 @@ -unit IOUtils; - -interface - -uses - WinAPI.Windows, - System.SysUtils, System.Classes, System.StrUtils, System.Types, System.Math, - System.Generics.Defaults, System.Generics.Collections; - -const - XTOOL_IODEC = $314C5458; - XTOOL_PATCH = $324C5458; - XTOOL_MAPSUF1 = '-vm.tmp'; - XTOOL_MAPSUF2 = '_mapped.io'; - -type - PEntryStruct1 = ^TEntryStruct1; - - TEntryStruct1 = packed record - Filename: String[255]; - Position: Int64; - Size: Integer; - end; - - TEntryStructComparer = class(TComparer) - public - function Compare(const Left, Right: TEntryStruct1): Integer; override; - end; - - TPatchOp = (opDelete, opMissing, opDifferent); - - PEntryStruct2 = ^TEntryStruct2; - - TEntryStruct2 = packed record - Op: TPatchOp; - Filename: String[255]; - Size: Int64; - end; - -var - EntryStructCmp: TEntryStructComparer; - -implementation - -function TEntryStructComparer.Compare(const Left, Right: TEntryStruct1) - : Integer; -begin - Result := Integer(CompareValue(Left.Position, Right.Position)); -end; - -initialization - -EntryStructCmp := TEntryStructComparer.Create; - -end. diff --git a/io/__history/IOUtils.pas.~36~ b/io/__history/IOUtils.pas.~36~ deleted file mode 100644 index a368094..0000000 --- a/io/__history/IOUtils.pas.~36~ +++ /dev/null @@ -1,56 +0,0 @@ -unit IOUtils; - -interface - -uses - WinAPI.Windows, - System.SysUtils, System.Classes, System.StrUtils, System.Types, System.Math, - System.Generics.Defaults, System.Generics.Collections; - -const - XTOOL_IODEC = $314C5458; - XTOOL_PATCH = $324C5458; - XTOOL_MAPSUF1 = '-vm.tmp'; - XTOOL_MAPSUF2 = '_mapped.io'; - XTOOL_MAPSUF3 = '-tmp'; - -type - PEntryStruct1 = ^TEntryStruct1; - - TEntryStruct1 = packed record - Filename: String[255]; - Position: Int64; - Size: Integer; - end; - - TEntryStructComparer = class(TComparer) - public - function Compare(const Left, Right: TEntryStruct1): Integer; override; - end; - - TPatchOp = (opDelete, opMissing, opDifferent); - - PEntryStruct2 = ^TEntryStruct2; - - TEntryStruct2 = packed record - Op: TPatchOp; - Filename: String[255]; - Size: Int64; - end; - -var - EntryStructCmp: TEntryStructComparer; - -implementation - -function TEntryStructComparer.Compare(const Left, Right: TEntryStruct1) - : Integer; -begin - Result := Integer(CompareValue(Left.Position, Right.Position)); -end; - -initialization - -EntryStructCmp := TEntryStructComparer.Create; - -end. diff --git a/io/__history/IOUtils.pas.~37~ b/io/__history/IOUtils.pas.~37~ deleted file mode 100644 index c07eae1..0000000 --- a/io/__history/IOUtils.pas.~37~ +++ /dev/null @@ -1,55 +0,0 @@ -unit IOUtils; - -interface - -uses - WinAPI.Windows, - System.SysUtils, System.Classes, System.StrUtils, System.Types, System.Math, - System.Generics.Defaults, System.Generics.Collections; - -const - XTOOL_IODEC = $314C5458; - XTOOL_PATCH = $324C5458; - XTOOL_MAPSUF1 = '-tmp'; - XTOOL_MAPSUF2 = '_mapped.io'; - -type - PEntryStruct1 = ^TEntryStruct1; - - TEntryStruct1 = packed record - Filename: String[255]; - Position: Int64; - Size: Integer; - end; - - TEntryStructComparer = class(TComparer) - public - function Compare(const Left, Right: TEntryStruct1): Integer; override; - end; - - TPatchOp = (opDelete, opMissing, opDifferent); - - PEntryStruct2 = ^TEntryStruct2; - - TEntryStruct2 = packed record - Op: TPatchOp; - Filename: String[255]; - Size: Int64; - end; - -var - EntryStructCmp: TEntryStructComparer; - -implementation - -function TEntryStructComparer.Compare(const Left, Right: TEntryStruct1) - : Integer; -begin - Result := Integer(CompareValue(Left.Position, Right.Position)); -end; - -initialization - -EntryStructCmp := TEntryStructComparer.Create; - -end. diff --git a/io/__history/IOUtils.pas.~38~ b/io/__history/IOUtils.pas.~38~ deleted file mode 100644 index c07eae1..0000000 --- a/io/__history/IOUtils.pas.~38~ +++ /dev/null @@ -1,55 +0,0 @@ -unit IOUtils; - -interface - -uses - WinAPI.Windows, - System.SysUtils, System.Classes, System.StrUtils, System.Types, System.Math, - System.Generics.Defaults, System.Generics.Collections; - -const - XTOOL_IODEC = $314C5458; - XTOOL_PATCH = $324C5458; - XTOOL_MAPSUF1 = '-tmp'; - XTOOL_MAPSUF2 = '_mapped.io'; - -type - PEntryStruct1 = ^TEntryStruct1; - - TEntryStruct1 = packed record - Filename: String[255]; - Position: Int64; - Size: Integer; - end; - - TEntryStructComparer = class(TComparer) - public - function Compare(const Left, Right: TEntryStruct1): Integer; override; - end; - - TPatchOp = (opDelete, opMissing, opDifferent); - - PEntryStruct2 = ^TEntryStruct2; - - TEntryStruct2 = packed record - Op: TPatchOp; - Filename: String[255]; - Size: Int64; - end; - -var - EntryStructCmp: TEntryStructComparer; - -implementation - -function TEntryStructComparer.Compare(const Left, Right: TEntryStruct1) - : Integer; -begin - Result := Integer(CompareValue(Left.Position, Right.Position)); -end; - -initialization - -EntryStructCmp := TEntryStructComparer.Create; - -end. diff --git a/io/__history/IOUtils.pas.~39~ b/io/__history/IOUtils.pas.~39~ deleted file mode 100644 index c07eae1..0000000 --- a/io/__history/IOUtils.pas.~39~ +++ /dev/null @@ -1,55 +0,0 @@ -unit IOUtils; - -interface - -uses - WinAPI.Windows, - System.SysUtils, System.Classes, System.StrUtils, System.Types, System.Math, - System.Generics.Defaults, System.Generics.Collections; - -const - XTOOL_IODEC = $314C5458; - XTOOL_PATCH = $324C5458; - XTOOL_MAPSUF1 = '-tmp'; - XTOOL_MAPSUF2 = '_mapped.io'; - -type - PEntryStruct1 = ^TEntryStruct1; - - TEntryStruct1 = packed record - Filename: String[255]; - Position: Int64; - Size: Integer; - end; - - TEntryStructComparer = class(TComparer) - public - function Compare(const Left, Right: TEntryStruct1): Integer; override; - end; - - TPatchOp = (opDelete, opMissing, opDifferent); - - PEntryStruct2 = ^TEntryStruct2; - - TEntryStruct2 = packed record - Op: TPatchOp; - Filename: String[255]; - Size: Int64; - end; - -var - EntryStructCmp: TEntryStructComparer; - -implementation - -function TEntryStructComparer.Compare(const Left, Right: TEntryStruct1) - : Integer; -begin - Result := Integer(CompareValue(Left.Position, Right.Position)); -end; - -initialization - -EntryStructCmp := TEntryStructComparer.Create; - -end. diff --git a/io/__history/IOUtils.pas.~40~ b/io/__history/IOUtils.pas.~40~ deleted file mode 100644 index 29103dd..0000000 --- a/io/__history/IOUtils.pas.~40~ +++ /dev/null @@ -1,56 +0,0 @@ -unit IOUtils; - -interface - -uses - WinAPI.Windows, - System.SysUtils, System.Classes, System.StrUtils, System.Types, System.Math, - System.Generics.Defaults, System.Generics.Collections; - -const - XTOOL_IODEC = $314C5458; - XTOOL_PATCH = $324C5458; - XTOOL_MAPSUF1 = '-tmp'; - XTOOL_MAPSUF2 = '_mapped.io'; - XTOOL_MAPSUF3 = '.tmp'; - -type - PEntryStruct1 = ^TEntryStruct1; - - TEntryStruct1 = packed record - Filename: String[255]; - Position: Int64; - Size: Integer; - end; - - TEntryStructComparer = class(TComparer) - public - function Compare(const Left, Right: TEntryStruct1): Integer; override; - end; - - TPatchOp = (opDelete, opMissing, opDifferent); - - PEntryStruct2 = ^TEntryStruct2; - - TEntryStruct2 = packed record - Op: TPatchOp; - Filename: String[255]; - Size: Int64; - end; - -var - EntryStructCmp: TEntryStructComparer; - -implementation - -function TEntryStructComparer.Compare(const Left, Right: TEntryStruct1) - : Integer; -begin - Result := Integer(CompareValue(Left.Position, Right.Position)); -end; - -initialization - -EntryStructCmp := TEntryStructComparer.Create; - -end.