Subversion Repositories oidplus

Rev

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

Rev Author Line No. Line
733 daniel-mar 1
unit VTSFUNCS;
2
 
3
(************************************************)
4
(* VTSFUNCS.PAS                                 *)
5
(* Author:   Daniel Marschall                   *)
748 daniel-mar 6
(* Revision: 2022-02-19                         *)
733 daniel-mar 7
(* License:  Apache 2.0                         *)
8
(* This file contains:                          *)
9
(* - Various functions                          *)
10
(************************************************)
11
 
12
interface
13
 
739 daniel-mar 14
function Max(a, b: integer): integer;
15
function Min(a, b: integer): integer;
16
 
733 daniel-mar 17
function CompareEqualLengthString(a, b: string): integer;
18
function CompareNumericString(a, b: string): integer;
739 daniel-mar 19
 
733 daniel-mar 20
procedure Beep;
739 daniel-mar 21
 
733 daniel-mar 22
function Trim(s: string): string;
740 daniel-mar 23
function TrimLineToWidth(s: string; width: integer): string;
733 daniel-mar 24
function ZeroPad(i: LongInt; n: integer): string;
739 daniel-mar 25
function LeftPadStr(s: string; n: integer; ch: char): string;
26
function RightPadStr(s: string; n: integer; ch: char): string;
740 daniel-mar 27
function RepeatStr(ch: char; n: integer): string;
739 daniel-mar 28
 
29
function DeleteFile(filename: string): boolean;
733 daniel-mar 30
function FileExists(filename: string): boolean;
739 daniel-mar 31
 
747 daniel-mar 32
function IsPositiveIntegerOrZero(s: string): boolean;
733 daniel-mar 33
function StrToInt(s: string): Integer;
34
function IntToStr(Value: Integer): string;
35
 
747 daniel-mar 36
function StringReplace(s, search, replace: string): string;
37
 
748 daniel-mar 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
 
733 daniel-mar 42
implementation
43
 
44
uses
45
  Crt;
46
 
739 daniel-mar 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
 
733 daniel-mar 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
739 daniel-mar 87
  EqualLength: integer;
733 daniel-mar 88
begin
739 daniel-mar 89
  EqualLength := Max(Length(a), Length(b));
90
  a := LeftPadStr(a, EqualLength, '0');
91
  b := LeftPadStr(b, EqualLength, '0');
92
  CompareNumericString := CompareEqualLengthString(a, b);
733 daniel-mar 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
 
740 daniel-mar 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
 
739 daniel-mar 130
function ZeroPad(i: LongInt; n: integer): string;
733 daniel-mar 131
var
739 daniel-mar 132
  s: string;
733 daniel-mar 133
begin
739 daniel-mar 134
  s := IntToStr(i);
135
  ZeroPad := LeftPadStr(s, n, '0');
136
end;
733 daniel-mar 137
 
739 daniel-mar 138
function LeftPadStr(s: string; n: integer; ch: char): string;
139
begin
140
  while Length(s) < n do
733 daniel-mar 141
  begin
739 daniel-mar 142
    s := ch + s;
733 daniel-mar 143
  end;
739 daniel-mar 144
  LeftPadStr := s;
733 daniel-mar 145
end;
146
 
739 daniel-mar 147
function RightPadStr(s: string; n: integer; ch: char): string;
733 daniel-mar 148
begin
149
  while Length(s) < n do
150
  begin
739 daniel-mar 151
    s := s + ch;
733 daniel-mar 152
  end;
739 daniel-mar 153
  RightPadStr := s;
733 daniel-mar 154
end;
155
 
740 daniel-mar 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
 
739 daniel-mar 169
function DeleteFile(filename: string): boolean;
733 daniel-mar 170
var
739 daniel-mar 171
  F:  file;
172
  Ch: Char;
733 daniel-mar 173
begin
739 daniel-mar 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;
733 daniel-mar 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+}
740 daniel-mar 200
  if IoResult = 0 then
201
  begin
202
    Close(F);
203
    FileExists := true;
204
  end
205
  else
206
  begin
207
    FileExists := false;
208
  end;
733 daniel-mar 209
end;
210
 
747 daniel-mar 211
function IsPositiveIntegerOrZero(s: string): boolean;
739 daniel-mar 212
var
213
  i: integer;
214
begin
747 daniel-mar 215
  IsPositiveIntegerOrZero := false;
739 daniel-mar 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
 
747 daniel-mar 224
  IsPositiveIntegerOrZero := true;
739 daniel-mar 225
end;
226
 
733 daniel-mar 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
 
747 daniel-mar 243
function StringReplace(s, search, replace: string): string;
244
var
245
  i: integer;
246
  output: string;
247
begin
748 daniel-mar 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;
747 daniel-mar 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
 
748 daniel-mar 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
 
733 daniel-mar 374
end.