Subversion Repositories oidplus

Rev

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