Subversion Repositories oidplus

Rev

Rev 747 | Rev 749 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. unit VTSFUNCS;
  2.  
  3. (************************************************)
  4. (* VTSFUNCS.PAS                                 *)
  5. (* Author:   Daniel Marschall                   *)
  6. (* Revision: 2022-02-19                         *)
  7. (* License:  Apache 2.0                         *)
  8. (* This file contains:                          *)
  9. (* - Various functions                          *)
  10. (************************************************)
  11.  
  12. interface
  13.  
  14. function Max(a, b: integer): integer;
  15. function Min(a, b: integer): integer;
  16.  
  17. function CompareEqualLengthString(a, b: string): integer;
  18. function CompareNumericString(a, b: string): integer;
  19.  
  20. procedure Beep;
  21.  
  22. function Trim(s: string): string;
  23. function TrimLineToWidth(s: string; width: integer): string;
  24. function ZeroPad(i: LongInt; n: integer): string;
  25. function LeftPadStr(s: string; n: integer; ch: char): string;
  26. function RightPadStr(s: string; n: integer; ch: char): string;
  27. function RepeatStr(ch: char; n: integer): string;
  28.  
  29. function DeleteFile(filename: string): boolean;
  30. function FileExists(filename: string): boolean;
  31.  
  32. function IsPositiveIntegerOrZero(s: string): boolean;
  33. function StrToInt(s: string): Integer;
  34. function IntToStr(Value: Integer): string;
  35.  
  36. function StringReplace(s, search, replace: string): string;
  37.  
  38. function LastCharPos(const S: string; const Chr: char): integer;
  39. function LowerCase(s: string): string;
  40. function base_convert_bigint(numstring: string; frombase, tobase: integer): string;
  41.  
  42. implementation
  43.  
  44. uses
  45.   Crt;
  46.  
  47. function Max(a, b: integer): integer;
  48. begin
  49.   if a > b then
  50.     Max := a
  51.   else
  52.     Max := b;
  53. end;
  54.  
  55. function Min(a, b: integer): integer;
  56. begin
  57.   if a < b then
  58.     Min := a
  59.   else
  60.     Min := b;
  61. end;
  62.  
  63. function CompareEqualLengthString(a, b: string): integer;
  64. var
  65.   ao, bo, i: integer;
  66. begin
  67.   CompareEqualLengthString := 0;
  68.   for i := 1 to Length(a) do
  69.   begin
  70.     ao := Ord(a[i]);
  71.     bo := Ord(b[i]);
  72.     if ao > bo then
  73.     begin
  74.       CompareEqualLengthString := 1;
  75.       break;
  76.     end;
  77.     if ao < bo then
  78.     begin
  79.       CompareEqualLengthString := -1;
  80.       break;
  81.     end;
  82.   end;
  83. end;
  84.  
  85. function CompareNumericString(a, b: string): integer;
  86. var
  87.   EqualLength: integer;
  88. begin
  89.   EqualLength := Max(Length(a), Length(b));
  90.   a := LeftPadStr(a, EqualLength, '0');
  91.   b := LeftPadStr(b, EqualLength, '0');
  92.   CompareNumericString := CompareEqualLengthString(a, b);
  93. end;
  94.  
  95. procedure Beep;
  96. begin
  97.   Sound(220); (*220Hz*)
  98.   Delay(200); (*200ms*)
  99.   NoSound;
  100. end;
  101.  
  102. function Trim(s: string): string;
  103. begin
  104.   while Length(s) > 0 do
  105.   begin
  106.     if s[1] in [#9,#10,#13,' '] then
  107.       Delete(s,1,1)
  108.     else
  109.       break;
  110.   end;
  111.   while Length(s) > 0 do
  112.   begin
  113.     if s[Length(s)] in [#9,#10,#13,' '] then
  114.       Delete(s,Length(s),1)
  115.     else
  116.       break;
  117.   end;
  118.   Trim := s;
  119. end;
  120.  
  121. function TrimLineToWidth(s: string; width: integer): string;
  122. begin
  123.   if Length(s) > width then
  124.   begin
  125.     s := Copy(s, 1, width-3) + '...';
  126.   end;
  127.   TrimLineToWidth := s;
  128. end;
  129.  
  130. function ZeroPad(i: LongInt; n: integer): string;
  131. var
  132.   s: string;
  133. begin
  134.   s := IntToStr(i);
  135.   ZeroPad := LeftPadStr(s, n, '0');
  136. end;
  137.  
  138. function LeftPadStr(s: string; n: integer; ch: char): string;
  139. begin
  140.   while Length(s) < n do
  141.   begin
  142.     s := ch + s;
  143.   end;
  144.   LeftPadStr := s;
  145. end;
  146.  
  147. function RightPadStr(s: string; n: integer; ch: char): string;
  148. begin
  149.   while Length(s) < n do
  150.   begin
  151.     s := s + ch;
  152.   end;
  153.   RightPadStr := s;
  154. end;
  155.  
  156. function RepeatStr(ch: char; n: integer): string;
  157. var
  158.   i: integer;
  159.   res: string;
  160. begin
  161.   res := '';
  162.   for i := 1 to n do
  163.   begin
  164.     res := res + ch;
  165.   end;
  166.   RepeatStr := res;
  167. end;
  168.  
  169. function DeleteFile(filename: string): boolean;
  170. var
  171.   F:  file;
  172.   Ch: Char;
  173. begin
  174.   Assign(F, filename);
  175.   {$I-}
  176.   Reset(F);
  177.   {$I+}
  178.   if IOResult <> 0 then
  179.   begin
  180.     DeleteFile := false; (* cannot find file *)
  181.   end
  182.   else
  183.   begin
  184.     Close(F);
  185.     {$I-}
  186.     Erase(F);
  187.     {$I+}
  188.     DeleteFile := IOResult = 0;
  189.   end;
  190. end;
  191.  
  192. function FileExists(filename: string): boolean;
  193. var
  194.   F: Text;
  195. begin
  196.   Assign(F, filename);
  197.   {$I-}
  198.   Reset(F);
  199.   {$I+}
  200.   if IoResult = 0 then
  201.   begin
  202.     Close(F);
  203.     FileExists := true;
  204.   end
  205.   else
  206.   begin
  207.     FileExists := false;
  208.   end;
  209. end;
  210.  
  211. function IsPositiveIntegerOrZero(s: string): boolean;
  212. var
  213.   i: integer;
  214. begin
  215.   IsPositiveIntegerOrZero := false;
  216.  
  217.   if Length(s) = 0 then exit;
  218.   if (s[1] = '0') and (s <> '0') then exit;
  219.   for i := 1 to Length(s) do
  220.   begin
  221.     if not (s[i] in ['0'..'9']) then exit;
  222.   end;
  223.  
  224.   IsPositiveIntegerOrZero := true;
  225. end;
  226.  
  227. function StrToInt(s: string): Integer;
  228. var
  229.   i, Error: Integer;
  230. begin
  231.   Val(s, i, Error);
  232.   StrToInt := i;
  233. end;
  234.  
  235. function IntToStr(Value: Integer): string;
  236. var
  237.   s: string;
  238. begin
  239.   Str(Value, s);
  240.   IntToStr := s;
  241. end;
  242.  
  243. function StringReplace(s, search, replace: string): string;
  244. var
  245.   i: integer;
  246.   output: string;
  247. begin
  248.   if s = '' then
  249.   begin
  250.     StringReplace := '';
  251.     Exit;
  252.   end;
  253.   if search = '' then
  254.   begin
  255.     StringReplace := s;
  256.     exit; (* invalid arg *)
  257.   end;
  258.  
  259.   output := '';
  260.   while s <> '' do
  261.   begin
  262.     if Copy(s, 1, Length(search)) = search then
  263.     begin
  264.       output := output + replace;
  265.       Delete(s, 1, Length(search));
  266.     end
  267.     else
  268.     begin
  269.       output := output + Copy(s, 1, 1);
  270.       Delete(s, 1, 1);
  271.     end;
  272.   end;
  273.  
  274.   StringReplace := output;
  275. end;
  276.  
  277. function LastCharPos(const S: string; const Chr: char): integer;
  278. var
  279.   i: Integer;
  280. begin
  281.   for i := length(S) downto 1 do
  282.   begin
  283.     if S[i] = Chr then
  284.     begin
  285.       LastCharPos := i;
  286.       Exit;
  287.     end;
  288.   end;
  289.   LastCharPos := 0;
  290.   Exit;
  291. end;
  292.  
  293. function LowerCase(s: string): string;
  294. var
  295.   res: string;
  296.   i: integer;
  297. begin
  298.   res := '';
  299.   for i := 1 to Length(s) do
  300.   begin
  301.     if s[i] in ['A'..'Z'] then
  302.     begin
  303.       res := res + Chr(Ord('a')+(Ord(s[i])-Ord('A')));
  304.     end
  305.     else
  306.     begin
  307.       res := res + s[i];
  308.     end;
  309.   end;
  310.   LowerCase := res;
  311. end;
  312.  
  313. function base_convert_bigint(numstring: string; frombase, tobase: integer): string;
  314. var
  315.   i: Integer;
  316.   frombase_str: string;
  317.   tobase_str: string;
  318.   len: Integer;
  319.   number: string;
  320.   divide: Integer;
  321.   newlen: Integer;
  322.   res: string;
  323. begin
  324.   frombase_str := '';
  325.   for i := 0 to frombase-1 do
  326.   begin
  327.     if i < 10 then
  328.       frombase_str := frombase_str + IntToStr(i)
  329.     else
  330.       frombase_str := frombase_str + Chr(Ord('A') + (i-10));
  331.   end;
  332.  
  333.   tobase_str := '';
  334.   for i := 0 to tobase-1 do
  335.   begin
  336.     if i < 10 then
  337.       tobase_str := tobase_str + IntToStr(i)
  338.     else
  339.       tobase_str := tobase_str + Chr(Ord('A') + (i-10));
  340.   end;
  341.  
  342.   len := Length(numstring);
  343.   base_convert_bigint := '';
  344.   number := numstring; (* this is a fake "Int8" array (implemented with chars) *)
  345.   for i := 0 to len-1 do
  346.   begin
  347.     number[i+1] := Chr(Pos(UpCase(numstring[i+1]), frombase_str)-1);
  348.   end;
  349.   res := '';
  350.   repeat (* Loop until whole number is converted *)
  351.     divide := 0;
  352.     newlen := 0;
  353.     for i := 0 to len-1 do (* Perform division manually (which is why this works with big numbers) *)
  354.     begin
  355.       divide := divide * frombase + Ord(number[i+1]);
  356.       if (divide >= tobase) then
  357.       begin
  358.         number[newlen+1] := Chr(divide div tobase);
  359.         Inc(newlen);
  360.         divide := divide mod tobase;
  361.       end
  362.       else if newlen > 0 then
  363.       begin
  364.         number[newlen+1] := #0;
  365.         Inc(newlen);
  366.       end;
  367.     end;
  368.     len := newlen;
  369.     res := tobase_str[divide+1] + res; (* Divide is basically $numstring % $tobase (i.e. the new character) *)
  370.   until newlen = 0;
  371.   base_convert_bigint := res;
  372. end;
  373.  
  374. end.
  375.