From 33ef3fda4f65de721a660d023aabb3790859b85d Mon Sep 17 00:00:00 2001 From: Olly Date: Mon, 10 Jul 2023 01:52:08 +0100 Subject: [PATCH] Finish new file interface --- .../imports/simba/simba.import_file.pas | 64 +++----- .../imports/simba/simba.import_system.pas | 43 +++-- Source/simba.files.pas | 151 ++++++++++++------ 3 files changed, 159 insertions(+), 99 deletions(-) diff --git a/Source/script/imports/simba/simba.import_file.pas b/Source/script/imports/simba/simba.import_file.pas index 3a28f2ea8..1f8b574a2 100644 --- a/Source/script/imports/simba/simba.import_file.pas +++ b/Source/script/imports/simba/simba.import_file.pas @@ -33,19 +33,24 @@ procedure _LapeDeleteINI(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV DeleteINI(PString(Params^[0])^, PString(Params^[1])^, PString(Params^[1])^); end; -procedure _LapeUnZipFile(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV +procedure _LapeZipExtractAll(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV begin - UnZipFile(PString(Params^[0])^, PString(Params^[1])^); + PBoolean(Result)^ := ZipExtractAll(PString(Params^[0])^, PString(Params^[1])^); end; -procedure _LapeUnZipOneFile(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV +procedure _LapeZipExtractOne(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV begin - PBoolean(Result)^ := UnZipOneFile(PString(Params^[0])^, PString(Params^[1])^, PString(Params^[2])^); + PBoolean(Result)^ := ZipExtractOne(PString(Params^[0])^, PString(Params^[1])^, PString(Params^[2])^); end; -procedure _LapeZipFiles(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV +procedure _LapeZipFiles(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV begin - ZipFiles(PString(Params^[0])^, PStringArray(Params^[1])^); + PBoolean(Result)^ := ZipFiles(PString(Params^[0])^, PStringArray(Params^[1])^); +end; + +procedure _LapeZipEntries(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV +begin + PStringArray(Result)^ := ZipEntries(PString(Params^[0])^); end; procedure _LapeFileAppend(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV @@ -213,6 +218,11 @@ procedure _LapePathIncludeLeadingSep(const Params: PParamArray; const Result: Po PString(Result)^ := TSimbaPath.PathIncludeLeadingSep(PString(Params^[0])^); end; +procedure _LapePathExtractRelative(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV +begin + PString(Result)^ := TSimbaPath.PathExtractRelative(PString(Params^[0])^, PString(Params^[1])^); +end; + procedure _LapeDirList(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV begin PStringArray(Result)^ := TSimbaDir.DirList(PString(Params^[0])^, PBoolean(Params^[1])^); @@ -273,39 +283,15 @@ procedure _LapeGetTempFileName(const Params: PParamArray; const Result: Pointer) PString(Result)^ := GetTempFileName(); end; -procedure _LapeGetEnvVar(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV -begin - PString(Result)^ := GetEnvironmentVariable(PString(Params^[0])^); -end; - -procedure _LapeGetEnvVars(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV - - function _GetEnvVars: TStringArray; - var - Count, I: Integer; - begin - Count := 0; - - SetLength(Result, GetEnvironmentVariableCount() + 1); - for I := 1 to GetEnvironmentVariableCount() do - if (GetEnvironmentString(I) <> '') then - begin - Result[Count] := GetEnvironmentString(I); - Inc(Count); - end; - SetLength(Result, Count); - end; - -begin - PStringArray(Result)^ := _GetEnvVars(); -end; - procedure ImportFile(Compiler: TSimbaScript_Compiler); begin with Compiler do begin ImportingSection := 'File'; + addGlobalVar(PATH_SEP, 'PATH_SEP').isConstant := True; + addGlobalVar(LINE_SEP, 'LINE_SEP').isConstant := True; + addGlobalVar(GetIncludePath(), 'IncludePath').isConstant := True; addGlobalVar(GetPluginPath(), 'PluginPath').isConstant := True; addGlobalVar(GetSimbaPath(), 'SimbaPath').isConstant := True; @@ -316,17 +302,16 @@ procedure ImportFile(Compiler: TSimbaScript_Compiler); addGlobalFunc('procedure WriteINI(Section, KeyName, NewString, FileName: String)', @_LapeWriteINI); addGlobalFunc('function ReadINI(Section, KeyName, FileName: String): String', @_LapeReadINI); addGlobalFunc('procedure DeleteINI(Section, KeyName, FileName: String)', @_LapeDeleteINI); - addGlobalFunc('procedure ZipFiles(ArchiveFileName: String; const Files: TStringArray)', @_LapeZipFiles); - addGlobalFunc('procedure UnZipFile(ArchiveFileName, OutputDirectory: String)', @_LapeUnZipFile); - addGlobalFunc('function UnZipOneFile(ArchiveFileName, FileName, OutputDirectory: String): Boolean', @_LapeUnZipOneFile); + + addGlobalFunc('function ZipExtractAll(ZipFileName, OutputDir: String): Boolean', @_LapeZipExtractAll); + addGlobalFunc('function ZipExtractOne(ZipFileName, FileName, OutputDir: String): Boolean', @_LapeZipExtractOne); + addGlobalFunc('function ZipFiles(ZipFileName: String; Files: TStringArray): Boolean', @_LapeZipFiles); + addGlobalFunc('function ZipEntries(ZipFileName: String): TStringArray', @_LapeZipEntries); addGlobalFunc('function GetUserDir: String', @_LapeGetUserDir); addGlobalFunc('function GetTempDir: String', @_LapeGetTempDir); addGlobalFunc('function GetTempFileName: String', @_LapeGetTempFileName); - addGlobalFunc('function GetEnvVar(Name: String): String', @_LapeGetEnvVar); - addGlobalFunc('function GetEnvVars: TStringArray', @_LapeGetEnvVars); - addGlobalFunc('function FileRead(FileName: String): String', @_LapeFileRead); addGlobalFunc('function FileReadEx(FileName: String; Offset: Integer): String', @_LapeFileReadEx); addGlobalFunc('function FileWrite(FileName: String; Text: String): Boolean', @_LapeFileWrite); @@ -363,6 +348,7 @@ procedure ImportFile(Compiler: TSimbaScript_Compiler); addGlobalFunc('function PathIncludeTrailingSep(Path: String): String', @_LapePathIncludeTrailingSep); addGlobalFunc('function PathExcludeLeadingSep(Path: String): String', @_LapePathExcludeLeadingSep); addGlobalFunc('function PathIncludeLeadingSep(Path: String): String', @_LapePathIncludeLeadingSep); + addGlobalFunc('function PathExtractRelative(BasePath, DestPath: String): String', @_LapePathExtractRelative); addGlobalFunc('function DirList(Path: String; Recursive: Boolean = False): TStringArray', @_LapeDirList); addGlobalFunc('function DirSearch(Path: String; Mask: String; Recursive: Boolean = False): TStringArray', @_LapeDirSearch); diff --git a/Source/script/imports/simba/simba.import_system.pas b/Source/script/imports/simba/simba.import_system.pas index 90e3d58e0..d5aa843c4 100644 --- a/Source/script/imports/simba/simba.import_system.pas +++ b/Source/script/imports/simba/simba.import_system.pas @@ -11,11 +11,6 @@ implementation lptypes, lpparser, ffi, simba.script_compiler, simba.mufasatypes, simba.nativeinterface; -procedure _LapeGetEnvironmentVariable(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV -begin - PString(Result)^ := GetEnvironmentVariable(PString(Params^[0])^); -end; - procedure _LapeGetCurrentThreadID(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV begin PPtrUInt(Result)^ := PtrUInt(GetCurrentThreadID()); @@ -26,11 +21,6 @@ procedure _LapeGetMainThreadID(const Params: PParamArray; const Result: Pointer) PPtrUInt(Result)^ := PtrUInt(MainThreadID); end; -procedure _LapeWait(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV -begin - Sleep(PUInt32(Params^[0])^); -end; - procedure _LapePreciseSleep(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV begin SimbaNativeInterface.PreciseSleep(PUInt32(Params^[0])^); @@ -65,6 +55,33 @@ procedure _LapeGetThreadCount(const Params: PParamArray; const Result: Pointer); PPtrUInt(Result)^ := TThread.ProcessorCount; end; +procedure _LapeGetEnvVar(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV +begin + PString(Result)^ := GetEnvironmentVariable(PString(Params^[0])^); +end; + +procedure _LapeGetEnvVars(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV + + function _GetEnvVars: TStringArray; + var + Count, I: Integer; + begin + Count := 0; + + SetLength(Result, GetEnvironmentVariableCount() + 1); + for I := 1 to GetEnvironmentVariableCount() do + if (GetEnvironmentString(I) <> '') then + begin + Result[Count] := GetEnvironmentString(I); + Inc(Count); + end; + SetLength(Result, Count); + end; + +begin + PStringArray(Result)^ := _GetEnvVars(); +end; + procedure ImportSystem(Compiler: TSimbaScript_Compiler); begin with Compiler do @@ -99,9 +116,9 @@ procedure ImportSystem(Compiler: TSimbaScript_Compiler); addGlobalType('array of TColor', 'TColorArray'); addGlobalType('array of String', 'TStringArray'); + addGlobalType('array of TStringArray', 'T2DStringArray'); addGlobalType('array of Integer', 'TIntegerArray'); addGlobalType('array of TIntegerArray', 'T2DIntegerArray'); - addGlobalType('array of T2DIntegerArray', 'T3DIntegerArray'); addGlobalType('array of Int64', 'TInt64Array'); addGlobalType('array of Byte', 'TByteArray'); addGlobalType('array of Single', 'TSingleArray'); @@ -127,7 +144,6 @@ procedure ImportSystem(Compiler: TSimbaScript_Compiler); addGlobalFunc('function GetThreadCount: Integer', @_LapeGetThreadCount); addGlobalFunc('function GetMainThreadID: PtrUInt', @_LapeGetMainThreadID); addGlobalFunc('function GetCurrentThreadID: PtrUInt', @_LapeGetCurrentThreadID); - addGlobalFunc('function GetEnvironmentVariable(const Name: String): String', @_LapeGetEnvironmentVariable); addGlobalType('procedure() of object', 'TSyncMethod', {$IF DEFINED(CPU32) and DEFINED(LAPE_CDECL)}FFI_CDECL{$ELSE}FFI_DEFAULT_ABI{$ENDIF}); addGlobalFunc('procedure Sync(Method: TSyncMethod)', @_LapeSync); @@ -139,6 +155,9 @@ procedure ImportSystem(Compiler: TSimbaScript_Compiler); 'end;' ]); + addGlobalFunc('function GetEnvVar(Name: String): String', @_LapeGetEnvVar); + addGlobalFunc('function GetEnvVars: TStringArray', @_LapeGetEnvVars); + ImportingSection := ''; end; end; diff --git a/Source/simba.files.pas b/Source/simba.files.pas index 1bc21d483..94f71c287 100644 --- a/Source/simba.files.pas +++ b/Source/simba.files.pas @@ -13,6 +13,10 @@ interface Classes, SysUtils, simba.mufasatypes; +const + PATH_SEP = DirectorySeparator; + LINE_SEP = LineEnding; + type TSimbaFile = class protected @@ -62,6 +66,7 @@ TSimbaPath = class class function PathIncludeTrailingSep(Path: String): String; class function PathExcludeLeadingSep(Path: String): String; class function PathIncludeLeadingSep(Path: String): String; + class function PathExtractRelative(BasePath, DestPath: String): String; end; TSimbaDir = class @@ -75,11 +80,13 @@ TSimbaDir = class class function DirIsEmpty(Path: String): Boolean; class function DirSize(Path: String): Int64; class function DirSizeInMegaBytes(Path: String): Single; + class function DirCopy(SourceDir, DestDir: String): Boolean; end; - procedure ZipFiles(const ArchiveFileName: String; const Files: TStringArray); - procedure UnZipFile(const ArchiveFileName, OutputDirectory: String); - function UnZipOneFile(const ArchiveFileName, FileName, OutputDirectory: String): Boolean; + function ZipExtractAll(ZipFileName, OutputDir: String): Boolean; + function ZipExtractOne(ZipFileName, FileName, OutputDir: String): Boolean; + function ZipFiles(ZipFileName: String; Files: TStringArray): Boolean; + function ZipEntries(ZipFileName: String): TStringArray; function ReadINI(const Section, KeyName: string; FileName: string): string; procedure DeleteINI(const Section, KeyName : string; FileName : string); @@ -94,8 +101,8 @@ implementation {$IFDEF UNIX} BaseUnix, {$ENDIF} - FileUtil, LazFileUtils, Zipper, IniFiles, - simba.encoding, md5, sha1; + FileUtil, LazFileUtils, Zipper, IniFiles, md5, sha1, + simba.encoding; class function TSimbaDir.DirList(Path: String; Recursive: Boolean): TStringArray; var @@ -172,6 +179,11 @@ class function TSimbaDir.DirSizeInMegaBytes(Path: String): Single; Result := DirSize(Path) / (1024 * 1024); end; +class function TSimbaDir.DirCopy(SourceDir, DestDir: String): Boolean; +begin + Result := CopyDirTree(SourceDir, DestDir); +end; + class function TSimbaPath.PathExists(Path: String): Boolean; begin Result := FileExists(Path) or DirectoryExists(Path); @@ -242,6 +254,11 @@ class function TSimbaPath.PathIncludeLeadingSep(Path: String): String; Result := IncludeLeadingPathDelimiter(Path); end; +class function TSimbaPath.PathExtractRelative(BasePath, DestPath: String): String; +begin + Result := ExtractRelativePath(BasePath, DestPath); +end; + class function TSimbaFile.DoFileRead(const FileName: String; var Buffer; const Len: Integer; Offset: Integer): Boolean; var Stream: TFileStream; @@ -464,77 +481,115 @@ class function TSimbaFile.FileSizeInMegaBytes(FileName: String): Single; class function TSimbaFile.FileHash(FileName: String; HashType: String): String; begin case HashType.ToUpper() of + 'MD5': Result := MD5Print(MD5File(FileName)); 'SHA1': Result := SHA1Print(SHA1File(FileName)); 'SHA256': Result := SHA256File(FileName); 'SHA512': Result := SHA512File(FileName); - 'MD5': Result := MD5Print(MD5File(FileName)); else SimbaException('Invalid hashtype. Expected: SHA1,SHA256,SHA512,MD5'); end; end; -procedure ZipFiles(const ArchiveFileName: String; const Files: TStringArray); +function ZipExtractAll(ZipFileName, OutputDir: String): Boolean; var - Zipper: TZipper; - I: Integer; + UnZipper: TUnZipper; begin - if (Length(Files) = 0) then - raise Exception.Create('ZipFiles: No files to zip'); + Result := False; - Zipper := TZipper.Create; - try - Zipper.FileName := ArchiveFileName; - for I := 0 to High(Files) do - Zipper.Entries.AddFileEntry(Files[I], ExtractFileName(Files[I])); + if FileExists(ZipFileName) then + begin + UnZipper := TUnZipper.Create(); - Zipper.ZipAllFiles(); - finally - Zipper.Free; + try + UnZipper.FileName := ZipFileName; + UnZipper.OutputPath := OutputDir; + UnZipper.UnZipAllFiles(); + + Result := True; + except + end; + + UnZipper.Free(); end; end; -procedure UnZipFile(const ArchiveFileName, OutputDirectory: String); +function ZipExtractOne(ZipFileName, FileName, OutputDir: String): Boolean; var UnZipper: TUnZipper; + I: Integer; begin - if (not FileExists(ArchiveFileName)) then - raise Exception.CreateFmt('UnZipFile: Archive "%s" does not exist', [ArchiveFileName]); + Result := False; + + if FileExists(ZipFileName) then + begin + UnZipper := TUnZipper.Create(); + + try + UnZipper.Files.Add(FileName); + UnZipper.FileName := ZipFileName; + UnZipper.OutputPath := OutputDir; + UnZipper.Examine(); + + for I := 0 to UnZipper.Entries.Count - 1 do + if (UnZipper.Entries[I].ArchiveFileName = FileName) then + begin + UnZipper.UnZipAllFiles(); + + Result := True; + Break; + end; + except + end; - UnZipper := TUnZipper.Create(); - try - UnZipper.FileName := ArchiveFileName; - UnZipper.OutputPath := OutputDirectory; - UnZipper.Examine(); - UnZipper.UnZipAllFiles(); - finally UnZipper.Free(); end; end; -function UnZipOneFile(const ArchiveFileName, FileName, OutputDirectory: String): Boolean; +function ZipFiles(ZipFileName: String; Files: TStringArray): Boolean; var - UnZipper: TUnZipper; - I: Int32; + Zipper: TZipper; + I: Integer; begin Result := False; - UnZipper := TUnZipper.Create(); - UnZipper.Files.Add(FileName); + if (Length(Files) > 0) then + begin + Zipper := TZipper.Create(); - try - UnZipper.FileName := ArchiveFileName; - UnZipper.OutputPath := OutputDirectory; - UnZipper.Examine(); - - for I := 0 to UnZipper.Entries.Count - 1 do - if (UnZipper.Entries[I].ArchiveFileName = FileName) then - begin - UnZipper.UnZipAllFiles(); - - Result := True; - Break; - end; - finally + try + Zipper.FileName := ZipFileName; + for I := 0 to High(Files) do + Zipper.Entries.AddFileEntry(Files[I], ExtractFileName(Files[I])); + + Zipper.ZipAllFiles(); + + Result := True; + except + end; + + Zipper.Free(); + end; +end; + +function ZipEntries(ZipFileName: String): TStringArray; +var + UnZipper: TUnZipper; + I: Integer; +begin + Result := []; + + if FileExists(ZipFileName) then + begin + UnZipper := TUnZipper.Create(); + try + UnZipper.FileName := ZipFileName; + UnZipper.Examine(); + + SetLength(Result, UnZipper.Entries.Count); + for I := 0 to UnZipper.Entries.Count - 1 do + Result[I] := UnZipper.Entries[I].ArchiveFileName; + except + end; UnZipper.Free(); end; end;