Changeset 21 for trunk/Packages/Common/Common.pas
- Timestamp:
- Apr 3, 2025, 10:49:00 PM (2 weeks ago)
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/Packages/Common/Common.pas ¶
r20 r21 1 unit UCommon; 2 3 {$mode delphi} 1 unit Common; 4 2 5 3 interface 6 4 7 5 uses 8 {$ ifdef Windows}Windows,{$endif}9 {$ ifdef Linux}baseunix,{$endif}10 Classes, SysUtils, StrUtils, Dialogs, Process, LCLIntf, 11 FileUtil ; //, ShFolder, ShellAPI;6 {$IFDEF WINDOWS}Windows,{$ENDIF} 7 {$IFDEF UNIX}baseunix,{$ENDIF} 8 Classes, SysUtils, StrUtils, Dialogs, Process, LCLIntf, Graphics, 9 FileUtil, Generics.Collections; //, ShFolder, ShellAPI; 12 10 13 11 type 14 12 TArrayOfByte = array of Byte; 15 TArrayOfString = array of string;16 13 TExceptionEvent = procedure(Sender: TObject; E: Exception) of object; 17 14 … … 28 25 unfDNSDomainName = 11); 29 26 27 TFilterMethod = function (FileName: string): Boolean of object; 28 TFileNameMethod = procedure (FileName: string) of object; 29 30 30 var 31 31 ExceptionHandler: TExceptionEvent; 32 32 DLLHandle1: HModule; 33 33 34 {$IFDEF Windows} 35 GetUserNameEx: procedure (NameFormat: DWORD; 36 lpNameBuffer: LPSTR; nSize: PULONG); stdcall; 37 {$ENDIF} 38 39 function IntToBin(Data: Int64; Count: Byte): string; 34 {$IFDEF WINDOWS} 35 GetUserNameEx: procedure (NameFormat: DWORD; 36 lpNameBuffer: LPSTR; nSize: PULONG); stdcall; 37 {$ENDIF} 38 39 const 40 clLightBlue = TColor($FF8080); 41 clLightGreen = TColor($80FF80); 42 clLightRed = TColor($8080FF); 43 44 function AddLeadingZeroes(const aNumber, Length : integer) : string; 40 45 function BinToInt(BinStr: string): Int64; 41 function TryHexToInt(Data: string; var Value: Integer): Boolean;42 function TryBinToInt(Data: string; var Value: Integer): Boolean;43 46 function BinToHexString(Source: AnsiString): string; 44 47 //function DelTree(DirName : string): Boolean; … … 46 49 function BCDToInt(Value: Byte): Byte; 47 50 function CompareByteArray(Data1, Data2: TArrayOfByte): Boolean; 51 procedure CopyStringArray(Dest: TStringArray; Source: array of string); 52 function CombinePaths(Path1, Path2: string): string; 53 function ComputerName: string; 54 procedure DeleteFiles(APath, AFileSpec: string); 55 function EndsWith(Text, What: string): Boolean; 56 function Explode(Separator: Char; Data: string): TStringArray; 57 procedure ExecuteProgram(Executable: string; Parameters: array of string; 58 Environment: array of string; CurrentDirectory: string = ''); 59 procedure ExecuteProgramOutput(Executable: string; Parameters: array of string; 60 Environment: array of string; out Output, Error: string; 61 out ExitCode: Integer; CurrentDirectory: string = ''); 62 procedure FileDialogUpdateFilterFileType(FileDialog: TOpenDialog); 63 procedure FreeThenNil(var Obj); 64 function GetDirCount(Dir: string): Integer; 48 65 function GetUserName: string; 49 function LoggedOnUserNameEx(Format: TUserNameFormat): string;50 function SplitString(var Text: string; Count: Word): string;51 66 function GetBitCount(Variable: QWord; MaxIndex: Integer): Integer; 52 67 function GetBit(Variable: QWord; Index: Byte): Boolean; 68 function GetStringPart(var Text: string; Separator: string): string; 69 function GetEnvironmentVariables: TStringArray; 70 function GenerateNewName(OldName: string): string; 71 function GetFileFilterItemExt(Filter: string; Index: Integer): string; 72 function IntToBin(Data: Int64; Count: Byte): string; 73 function Implode(Separator: string; List: TList<string>): string; overload; 74 function Implode(Separator: string; List: array of string): string; overload; 75 function Implode(Separator: string; List: TStringList; Around: string = ''): string; overload; 76 function LastPos(const SubStr: String; const S: String): Integer; 77 function LoadFileToStr(const FileName: TFileName): AnsiString; 78 function LoggedOnUserNameEx(Format: TUserNameFormat): string; 79 function MergeArray(A, B: array of string): TStringArray; 80 function OccurenceOfChar(What: Char; Where: string): Integer; 81 procedure OpenWebPage(URL: string); 82 procedure OpenEmail(Email: string); 83 procedure OpenFileInShell(FileName: string); 84 function PosFromIndex(SubStr: string; Text: string; 85 StartIndex: Integer): Integer; 86 function PosFromIndexReverse(SubStr: string; Text: string; 87 StartIndex: Integer): Integer; 88 function RemoveQuotes(Text: string): string; 89 procedure SaveStringToFile(S, FileName: string); 53 90 procedure SetBit(var Variable: Int64; Index: Byte; State: Boolean); overload; 54 91 procedure SetBit(var Variable: QWord; Index: Byte; State: Boolean); overload; 55 92 procedure SetBit(var Variable: Cardinal; Index: Byte; State: Boolean); overload; 56 93 procedure SetBit(var Variable: Word; Index: Byte; State: Boolean); overload; 57 function AddLeadingZeroes(const aNumber, Length : integer) : string; 58 function LastPos(const SubStr: String; const S: String): Integer; 59 function GenerateNewName(OldName: string): string; 60 function GetFileFilterItemExt(Filter: string; Index: Integer): string; 61 procedure FileDialogUpdateFilterFileType(FileDialog: TOpenDialog); 62 procedure DeleteFiles(APath, AFileSpec: string); 63 procedure OpenWebPage(URL: string); 64 procedure OpenFileInShell(FileName: string); 65 procedure ExecuteProgram(CommandLine: string); 66 procedure FreeThenNil(var Obj); 67 function RemoveQuotes(Text: string): string; 68 function ComputerName: string; 69 function OccurenceOfChar(What: Char; Where: string): Integer; 70 function GetDirCount(Dir: string): Integer; 71 function MergeArray(A, B: array of string): TArrayOfString; 72 function LoadFileToStr(const FileName: TFileName): AnsiString; 94 procedure SearchFiles(AList: TStrings; Dir: string; 95 FilterMethod: TFilterMethod = nil; FileNameMethod: TFileNameMethod = nil); 96 procedure SortStrings(Strings: TStrings); 97 function SplitString(var Text: string; Count: Word): string; 98 function StripTags(const S: string): string; 99 function StartsWith(Text, What: string): Boolean; 100 function TryHexToInt(Data: string; out Value: Integer): Boolean; 101 function TryBinToInt(Data: string; out Value: Integer): Boolean; 73 102 74 103 75 104 implementation 76 105 77 function BinToInt(BinStr : string) : Int64; 78 var 79 i : byte; 80 RetVar : Int64; 106 resourcestring 107 SExecutionError = 'Excution error: %s (exit code: %d)'; 108 109 function StartsWith(Text, What: string): Boolean; 110 begin 111 Result := Copy(Text, 1, Length(Text)) = What; 112 end; 113 114 function EndsWith(Text, What: string): Boolean; 115 begin 116 Result := Copy(Text, Length(Text) - Length(What) + 1, MaxInt) = What; 117 end; 118 119 function BinToInt(BinStr: string): Int64; 120 var 121 I: Byte; 122 RetVar: Int64; 81 123 begin 82 124 BinStr := UpperCase(BinStr); 83 if BinStr[length(BinStr)] = 'B' then Delete(BinStr, length(BinStr),1);125 if BinStr[length(BinStr)] = 'B' then Delete(BinStr, Length(BinStr), 1); 84 126 RetVar := 0; 85 for i := 1 to length(BinStr) do begin86 if not (BinStr[ i] in ['0','1']) then begin127 for I := 1 to Length(BinStr) do begin 128 if not (BinStr[I] in ['0','1']) then begin 87 129 RetVar := 0; 88 130 Break; 89 131 end; 90 RetVar := (RetVar shl 1) + ( byte(BinStr[i]) and 1);132 RetVar := (RetVar shl 1) + (Byte(BinStr[I]) and 1); 91 133 end; 92 134 … … 98 140 I: Integer; 99 141 begin 142 Result := ''; 100 143 for I := 1 to Length(Source) do begin 101 144 Result := Result + LowerCase(IntToHex(Ord(Source[I]), 2)); 102 145 end; 103 146 end; 104 105 147 106 148 procedure DeleteFiles(APath, AFileSpec: string); … … 112 154 Path := IncludeTrailingPathDelimiter(APath); 113 155 114 Find := FindFirst( UTF8Decode(Path + AFileSpec), faAnyFile xor faDirectory, SearchRec);156 Find := FindFirst(Path + AFileSpec, faAnyFile xor faDirectory, SearchRec); 115 157 while Find = 0 do begin 116 DeleteFile(Path + UTF8Encode(SearchRec.Name));158 DeleteFile(Path + SearchRec.Name); 117 159 118 160 Find := SysUtils.FindNext(SearchRec); … … 120 162 FindClose(SearchRec); 121 163 end; 122 123 164 124 165 function GetFileFilterItemExt(Filter: string; Index: Integer): string; … … 143 184 if FileExt <> '.*' then 144 185 FileDialog.FileName := ChangeFileExt(FileDialog.FileName, FileExt) 186 end; 187 188 function GetEnvironmentVariables: TStringArray; 189 var 190 I: Integer; 191 begin 192 Result := Default(TStringArray); 193 SetLength(Result, GetEnvironmentVariableCount); 194 for I := 0 to GetEnvironmentVariableCount - 1 do 195 Result[I] := GetEnvironmentString(I); 145 196 end; 146 197 … … 185 236 end;*) 186 237 238 function Implode(Separator: string; List: array of string): string; 239 var 240 I: Integer; 241 begin 242 Result := ''; 243 for I := 0 to Length(List) - 1 do begin 244 Result := Result + List[I]; 245 if I < Length(List) - 1 then Result := Result + Separator; 246 end; 247 end; 248 249 function Implode(Separator: string; List: TStringList; Around: string = ''): string; 250 var 251 I: Integer; 252 begin 253 Result := ''; 254 for I := 0 to List.Count - 1 do begin 255 Result := Result + Around + List[I] + Around; 256 if I < List.Count - 1 then Result := Result + Separator; 257 end; 258 end; 259 187 260 function LastPos(const SubStr: String; const S: String): Integer; 188 261 begin … … 230 303 end; 231 304 232 function TryHexToInt(Data: string; varValue: Integer): Boolean;305 function TryHexToInt(Data: string; out Value: Integer): Boolean; 233 306 var 234 307 I: Integer; … … 246 319 end; 247 320 248 function TryBinToInt(Data: string; varValue: Integer): Boolean;321 function TryBinToInt(Data: string; out Value: Integer): Boolean; 249 322 var 250 323 I: Integer; … … 274 347 end; 275 348 276 function Explode(Separator: char; Data: string): TArrayOfString; 277 begin 278 SetLength(Result, 0); 279 while Pos(Separator, Data) > 0 do begin 349 function Explode(Separator: Char; Data: string): TStringArray; 350 var 351 Index: Integer; 352 begin 353 Result := Default(TStringArray); 354 repeat 355 Index := Pos(Separator, Data); 356 if Index > 0 then begin 357 SetLength(Result, Length(Result) + 1); 358 Result[High(Result)] := Copy(Data, 1, Index - 1); 359 Delete(Data, 1, Index); 360 end else Break; 361 until False; 362 if Data <> '' then begin 280 363 SetLength(Result, Length(Result) + 1); 281 Result[High(Result)] := Copy(Data, 1, Pos(Separator, Data) - 1); 282 Delete(Data, 1, Pos(Separator, Data)); 283 end; 284 SetLength(Result, Length(Result) + 1); 285 Result[High(Result)] := Data; 286 end; 287 288 {$IFDEF Windows} 364 Result[High(Result)] := Data; 365 end; 366 end; 367 368 function Implode(Separator: string; List: TList<string>): string; 369 var 370 I: Integer; 371 begin 372 Result := ''; 373 for I := 0 to List.Count - 1 do begin 374 Result := Result + List[I]; 375 if I < List.Count - 1 then Result := Result + Separator; 376 end; 377 end; 378 379 {$IFDEF WINDOWS} 289 380 function GetUserName: string; 290 381 const … … 294 385 begin 295 386 L := MAX_USERNAME_LENGTH + 2; 387 Result := Default(string); 296 388 SetLength(Result, L); 297 389 if Windows.GetUserName(PChar(Result), L) and (L > 0) then begin … … 307 399 end; 308 400 end; 309 {$ endif}401 {$ENDIF} 310 402 311 403 function ComputerName: string; 312 {$ ifdef mswindows}404 {$IFDEF WINDOWS} 313 405 const 314 406 INFO_BUFFER_SIZE = 32767; … … 325 417 end; 326 418 end; 327 {$ endif}328 {$ ifdef unix}419 {$ENDIF} 420 {$IFDEF UNIX} 329 421 var 330 422 Name: UtsName; 331 423 begin 424 Name := Default(UtsName); 332 425 fpuname(Name); 333 426 Result := Name.Nodename; 334 427 end; 335 {$ endif}336 337 {$ ifdef windows}428 {$ENDIF} 429 430 {$IFDEF WINDOWS} 338 431 function LoggedOnUserNameEx(Format: TUserNameFormat): string; 339 432 const … … 413 506 procedure LoadLibraries; 414 507 begin 415 {$IFDEF W indows}508 {$IFDEF WINDOWS} 416 509 DLLHandle1 := LoadLibrary('secur32.dll'); 417 510 if DLLHandle1 <> 0 then … … 424 517 procedure FreeLibraries; 425 518 begin 426 {$IFDEF W indows}519 {$IFDEF WINDOWS} 427 520 if DLLHandle1 <> 0 then FreeLibrary(DLLHandle1); 428 521 {$ENDIF} 429 522 end; 430 523 431 procedure ExecuteProgram(CommandLine: string); 524 procedure ExecuteProgram(Executable: string; Parameters: array of string; 525 Environment: array of string; CurrentDirectory: string = ''); 432 526 var 433 527 Process: TProcess; 434 begin 528 I: Integer; 529 begin 530 Process := TProcess.Create(nil); 435 531 try 436 Process := TProcess.Create(nil); 437 Process.CommandLine := CommandLine; 532 Process.Executable := Executable; 533 for I := 0 to Length(Parameters) - 1 do 534 Process.Parameters.Add(Parameters[I]); 535 for I := 0 to Length(Environment) - 1 do 536 Process.Environment.Add(Environment[I]); 537 Process.CurrentDirectory := CurrentDirectory; 538 Process.ShowWindow := swoHIDE; 438 539 Process.Options := [poNoConsole]; 439 540 Process.Execute; … … 443 544 end; 444 545 546 procedure ExecuteProgramOutput(Executable: string; Parameters: array of string; 547 Environment: array of string; out Output, Error: string; out ExitCode: Integer; 548 CurrentDirectory: string); 549 var 550 Process: TProcess; 551 I: Integer; 552 ReadCount: Integer; 553 Buffer: string; 554 const 555 BufferSize = 1000; 556 begin 557 Process := TProcess.Create(nil); 558 try 559 Process.Executable := Executable; 560 for I := 0 to Length(Parameters) - 1 do 561 Process.Parameters.Add(Parameters[I]); 562 for I := 0 to Length(Environment) - 1 do 563 Process.Environment.Add(Environment[I]); 564 Process.CurrentDirectory := CurrentDirectory; 565 Process.ShowWindow := swoHIDE; 566 Process.Options := [poNoConsole, poUsePipes]; 567 Process.Execute; 568 569 Output := ''; 570 Error := ''; 571 Buffer := ''; 572 SetLength(Buffer, BufferSize); 573 while Process.Running do begin 574 if Process.Output.NumBytesAvailable > 0 then begin 575 ReadCount := Process.Output.Read(Buffer[1], Length(Buffer)); 576 Output := Output + Copy(Buffer, 1, ReadCount); 577 end; 578 579 if Process.Stderr.NumBytesAvailable > 0 then begin 580 ReadCount := Process.Stderr.Read(Buffer[1], Length(Buffer)); 581 Error := Error + Copy(Buffer, 1, ReadCount) 582 end; 583 584 Sleep(10); 585 end; 586 587 if Process.Output.NumBytesAvailable > 0 then begin 588 ReadCount := Process.Output.Read(Buffer[1], Length(Buffer)); 589 Output := Output + Copy(Buffer, 1, ReadCount); 590 end; 591 592 if Process.Stderr.NumBytesAvailable > 0 then begin 593 ReadCount := Process.Stderr.Read(Buffer[1], Length(Buffer)); 594 Error := Error + Copy(Buffer, 1, ReadCount); 595 end; 596 597 ExitCode := Process.ExitCode; 598 599 if (ExitCode <> 0) or (Error <> '') then 600 raise Exception.Create(Format(SExecutionError, [Output + Error, ExitCode])); 601 finally 602 Process.Free; 603 end; 604 end; 605 445 606 procedure FreeThenNil(var Obj); 446 607 begin … … 454 615 end; 455 616 617 procedure OpenEmail(Email: string); 618 begin 619 OpenURL('mailto:' + Email); 620 end; 621 456 622 procedure OpenFileInShell(FileName: string); 457 623 begin 458 ExecuteProgram('cmd.exe /c start "' + FileName + '"');624 ExecuteProgram('cmd.exe', ['/c', 'start', FileName], []); 459 625 end; 460 626 … … 482 648 end; 483 649 484 function MergeArray(A, B: array of string): TArrayOfString; 485 var 486 I: Integer; 487 begin 650 function MergeArray(A, B: array of string): TStringArray; 651 var 652 I: Integer; 653 begin 654 Result := Default(TStringArray); 488 655 SetLength(Result, Length(A) + Length(B)); 489 656 for I := 0 to Length(A) - 1 do … … 511 678 end; 512 679 680 function DefaultSearchFilter(const FileName: string): Boolean; 681 begin 682 Result := True; 683 end; 684 685 procedure SaveStringToFile(S, FileName: string); 686 var 687 F: TextFile; 688 begin 689 AssignFile(F, FileName); 690 try 691 ReWrite(F); 692 Write(F, S); 693 finally 694 CloseFile(F); 695 end; 696 end; 697 698 procedure SearchFiles(AList: TStrings; Dir: string; 699 FilterMethod: TFilterMethod = nil; FileNameMethod: TFileNameMethod = nil); 700 var 701 SR: TSearchRec; 702 begin 703 Dir := IncludeTrailingPathDelimiter(Dir); 704 if FindFirst(Dir + '*', faAnyFile, SR) = 0 then 705 try 706 repeat 707 if (SR.Name = '.') or (SR.Name = '..') or (Assigned(FilterMethod) and (not FilterMethod(SR.Name) or 708 not FilterMethod(Copy(Dir, 3, Length(Dir)) + SR.Name))) then Continue; 709 if Assigned(FileNameMethod) then 710 FileNameMethod(Dir + SR.Name); 711 AList.Add(Dir + SR.Name); 712 if (SR.Attr and faDirectory) <> 0 then 713 SearchFiles(AList, Dir + SR.Name, FilterMethod); 714 until FindNext(SR) <> 0; 715 finally 716 FindClose(SR); 717 end; 718 end; 719 720 function GetStringPart(var Text: string; Separator: string): string; 721 var 722 P: Integer; 723 begin 724 P := Pos(Separator, Text); 725 if P > 0 then begin 726 Result := Copy(Text, 1, P - 1); 727 Delete(Text, 1, P - 1 + Length(Separator)); 728 end else begin 729 Result := Text; 730 Text := ''; 731 end; 732 Result := Trim(Result); 733 Text := Trim(Text); 734 end; 735 736 function StripTags(const S: string): string; 737 var 738 Len: Integer; 739 740 function ReadUntil(const ReadFrom: Integer; const C: Char): Integer; 741 var 742 J: Integer; 743 begin 744 for J := ReadFrom to Len do 745 if (S[j] = C) then 746 begin 747 Result := J; 748 Exit; 749 end; 750 Result := Len + 1; 751 end; 752 753 var 754 I, APos: Integer; 755 begin 756 Len := Length(S); 757 I := 0; 758 Result := ''; 759 while (I <= Len) do begin 760 Inc(I); 761 APos := ReadUntil(I, '<'); 762 Result := Result + Copy(S, I, APos - i); 763 I := ReadUntil(APos + 1, '>'); 764 end; 765 end; 766 767 function PosFromIndex(SubStr: string; Text: string; 768 StartIndex: Integer): Integer; 769 var 770 I, MaxLen: SizeInt; 771 Ptr: PAnsiChar; 772 begin 773 Result := 0; 774 if (StartIndex < 1) or (StartIndex > Length(Text) - Length(SubStr)) then Exit; 775 if Length(SubStr) > 0 then begin 776 MaxLen := Length(Text) - Length(SubStr) + 1; 777 I := StartIndex; 778 Ptr := @Text[StartIndex]; 779 while (I <= MaxLen) do begin 780 if (SubStr[1] = Ptr^) and (CompareByte(Substr[1], Ptr^, Length(SubStr)) = 0) then begin 781 Result := I; 782 Exit; 783 end; 784 Inc(I); 785 Inc(Ptr); 786 end; 787 end; 788 end; 789 790 function PosFromIndexReverse(SubStr: string; Text: string; 791 StartIndex: Integer): Integer; 792 var 793 I: SizeInt; 794 Ptr: PAnsiChar; 795 begin 796 Result := 0; 797 if (StartIndex < 1) or (StartIndex > Length(Text)) then Exit; 798 if Length(SubStr) > 0 then begin 799 I := StartIndex; 800 Ptr := @Text[StartIndex]; 801 while (I > 0) do begin 802 if (SubStr[1] = Ptr^) and (CompareByte(Substr[1], Ptr^, Length(SubStr)) = 0) then begin 803 Result := I; 804 Exit; 805 end; 806 Dec(I); 807 Dec(Ptr); 808 end; 809 end; 810 end; 811 812 procedure CopyStringArray(Dest: TStringArray; Source: array of string); 813 var 814 I: Integer; 815 begin 816 SetLength(Dest, Length(Source)); 817 for I := 0 to Length(Dest) - 1 do 818 Dest[I] := Source[I]; 819 end; 820 821 function CombinePaths(Path1, Path2: string): string; 822 begin 823 Result := Path1; 824 if Result <> '' then Result := Result + DirectorySeparator + Path2 825 else Result := Path2; 826 end; 827 828 procedure SortStrings(Strings: TStrings); 829 var 830 Tmp: TStringList; 831 begin 832 Strings.BeginUpdate; 833 try 834 if Strings is TStringList then begin 835 TStringList(Strings).Sort; 836 end else begin 837 Tmp := TStringList.Create; 838 try 839 Tmp.Assign(Strings); 840 Tmp.Sort; 841 Strings.Assign(Tmp); 842 finally 843 Tmp.Free; 844 end; 845 end; 846 finally 847 Strings.EndUpdate; 848 end; 849 end; 513 850 514 851
Note:
See TracChangeset
for help on using the changeset viewer.