6 ConstantsClass
, TypesClass
,
9 function AddressToString(Address
: Pointer): String;
10 function CartesianOfStrings(First
: String; Second
: TStrings
): TStrings
;
11 function CodeToHexadecimal(Input
: String): String;
12 function ContainsCharacter(Input
: String; Character
: Char): Boolean;
13 function CustomBCDToStr(Input
: PChar
; Size
: Integer): String;
14 function CustomDataToHex(Input
: PChar
; Size
: Integer): String;
15 function CustomFloatToStr(Input
: PChar
; Size
: Integer): String;
16 function CustomSIntToStr(Input
: PChar
; Size
: Integer): String;
17 function CustomUIntToStr(Input
: PChar
; Size
: Integer): String;
18 function EqualBeforeFirstParser(First
, Second
: String; Parser
: Char): Boolean;
19 function IsAddress(Input
: String): Boolean;
20 function IsHexaChar(Input
: Char): Boolean;
21 function FloatType(Input
: PChar
; Size
: Integer): Integer;
22 function IsPrefixOf(Prefix
, OfWhat
: String): Boolean;
23 function MaxOf(First
, Second
: Integer): Integer;
24 function MergeStringTStrings(First
: String; Second
: TStrings
): TStrings
;
25 function MergeTLinesLine(First
: TLines
; Second
: TLine
): TLines
;
26 function MergeTStringsString(First
: TStrings
; Second
: String): TStrings
;
27 function MinOf(First
, Second
: Integer): Integer;
28 function MirrorString(Input
: String): String;
29 function NeutralizeDoubles(Input
: String; Character
: Char): String;
30 function OmmitAfter(Input
: String; Character
, What
: Char): String;
31 function OmmitBefore(Input
: String; Character
, What
: Char): String;
32 function OmmitEverywhere(Input
: String; Character
, What
: Char): String;
33 function ParseAfterFirst(Input
: String; Parser
: Char): String;
34 function ParseAfterLast(Input
: String; Parser
: Char): String;
35 function ParseBeforeFirst(Input
: String; Parser
: Char): String;
36 function ParseBeforeLast(Input
: String; Parser
: Char): String;
37 function ParseFirst(var Input
: String; Parser
: Char): String;
38 function ParseToStrings(Input
: PChar
; Parser
: Char): TStrings
;
39 function RemoveCharacter(Input
: String): String;
40 function RemoveExactString(From
: TStrings
; What
: String): TStrings
;
41 function RemovePrefix(Prefix
, From
: String): String;
42 function ReplaceCharacters(Input
: String; Find
, Replace
: Char): String;
43 function SeparateFloat(Input
: PChar
; Size
: Integer): TFloatRecord
;
44 function StringToAddress(Input
: String; Offset
: Integer = 0): Integer;
45 function StringBefore(Input
: String; Before
: Integer): String;
46 function StringCompare(First
, Second
: PChar
; Size
: Integer): Boolean;
47 function TrimCharacter(Input
: String; Character
: Char): String;
48 function TrimCharacterLeft(Input
: String; Character
: Char): String;
49 function TrimCharacterRight(Input
: String; Character
: Char): String;
50 function ToTLine(Line
: String; Number
: Integer): TLine
;
51 function UpperCase(Input
: String): String;
52 function ZeroPaddedInteger(Input
: Integer; Padding
: Integer = 0): String;
53 procedure ConstantToFloat(Input
: String; Result
: PChar
; Size
: Integer);
54 procedure CustomHexToData(Input
: String; Data
: PChar
; Size
: Integer);
55 procedure CustomStrToBCD(Input
: String; Result
: PChar
; Size
: Integer);
56 procedure CustomStrToFloat(Input
: String; Result
: PChar
; Size
: Integer);
57 procedure CustomStrToSInt(Input
: String; Result
: PChar
; Size
: Integer);
58 procedure CustomStrToUInt(Input
: String; Result
: PChar
; Size
: Integer);
60 procedure LogSystemTime
;
61 procedure LogWrite(Log
: String; Error
: Boolean = False);
62 procedure InitializeMemory(Input
: PChar
; Size
: Integer; Character
: Char);
65 Log_OnClear
: TLogClearEvent
;
66 Log_OnWrite
: TLogWriteEvent
;
72 function AddressToString(Address
: Pointer): String;
74 SetLength(Result
, SizeOf(Pointer));
75 PInteger(Result
)^ := Integer(Address
);
78 function CartesianOfStrings(First
: String; Second
: TStrings
): TStrings
;
83 for i
:= 0 to (Length(Second
) - 1) do
85 SetLength(Result
, Length(Result
) + 1);
86 Result
[Length(Result
) - 1] := First
+ Second
[i
];
90 function CodeToHexadecimal(Input
: String): String;
96 if (Input
= '') then Exit
;
97 for i
:= 1 to Length(Input
) do
99 lbyte
:= Ord(Input
[i
]);
100 Result
:= Result
+ CHARS_HEXA
[lbyte
shr 4] + CHARS_HEXA
[lbyte
and $F];
104 function ContainsCharacter(Input
: String; Character
: Char): Boolean;
109 if (Input
= '') then Exit
;
110 for i
:= 1 to Length(Input
) do
111 if (Input
[i
] = Character
) then
118 function CustomBCDToStr(Input
: PChar
; Size
: Integer): String;
124 if not(Size
= 10) then Exit
;
125 with PBCDRecord(Input
)^ do
127 if (Bytes
[9] = $FF) and (Bytes
[8] = $FF) and (Bytes
[7] = $C0) then
132 for i
:= 8 downto 0 do
134 lbyte
:= Bytes
[i
] shr 4;
135 if not(lbyte
= 0) then Result
:= Result
+ CHARS_HEXA
[lbyte
];
136 lbyte
:= Bytes
[i
] and $F;
137 if not(lbyte
= 0) then Result
:= Result
+ CHARS_HEXA
[lbyte
];
139 if (Result
= '') then Result
:= CHARS_HEXA
[0];
140 if not(Bytes
[9] and $80 = 0) then Result
:= '-' + Result
;
144 function CustomDataToHex(Input
: PChar
; Size
: Integer): String;
150 for i
:= (Size
- 1) downto 0 do
152 lbyte
:= Ord(Input
[i
]);
153 Result
:= Result
+ CHARS_HEXA
[lbyte
shr 4] + CHARS_HEXA
[lbyte
and $F];
157 function CustomFloatToStr(Input
: PChar
; Size
: Integer): String;
159 linput
: TFloatRecord
;
160 lcmp
: TSeparateConstants
;
165 10: lcmp
:= SEP_FP_10
;
169 linput
:= SeparateFloat(Input
, Size
);
172 if (Exponent
= lcmp
.ExponCmp
) then
173 if (Significand
= lcmp
.SigniCmp
) then
175 if Sign
then Result
:= DESC_NEG_INF
176 else Result
:= DESC_POS_INF
;
180 if (Significand
and lcmp
.SigniAnd
= 0) then
183 Result
:= DESC_NAN_Q
;
184 Result
:= Result
+ DESC_NAN
;
188 4: Result
:= FloatToStr(PSingle(Input
)^);
189 8: Result
:= FloatToStr(PDouble(Input
)^);
190 10: Result
:= FloatToStr(PExtended(Input
)^);
195 function CustomSIntToStr(Input
: PChar
; Size
: Integer): String;
199 1: Result
:= IntToStr(PShortint(Input
)^);
200 2: Result
:= IntToStr(PSmallint(Input
)^);
201 4: Result
:= IntToStr(PInteger(Input
)^);
202 8: Result
:= IntToStr(PInt64(Input
)^);
206 function CustomUIntToStr(Input
: PChar
; Size
: Integer): String;
210 1: Result
:= IntToStr(PByte(Input
)^);
211 2: Result
:= IntToStr(PWord(Input
)^);
212 4: Result
:= IntToStr(PCardinal(Input
)^);
213 8: Result
:= IntToStr(PInt64(Input
)^);
217 function EqualBeforeFirstParser(First
, Second
: String; Parser
: Char): Boolean;
219 if (ParseBeforeFirst(First
, Parser
) = ParseBeforeFirst(Second
, Parser
)) then
225 function IsAddress(Input
: String): Boolean;
230 Input
:= TrimCharacter(Input
, ' ');
231 if (Input
= '') then Exit
;
232 if not(Input
[1] in ['0'..'9', '+', '-']) then Exit
;
233 if (Input
[1] in ['+', '-']) and (Length(Input
) = 1) then Exit
;
234 for i
:= 2 to Length(Input
) do
235 if not(Input
[i
] in ['0'..'9']) then Exit
;
239 function IsHexaChar(Input
: Char): Boolean;
244 for i
:= 0 to (Length(CHARS_HEXA
) - 1) do
245 if (Input
= CHARS_HEXA
[i
]) then
252 function FloatType(Input
: PChar
; Size
: Integer): Integer;
257 lresult
:= CustomFloatToStr(Input
, Size
);
258 if (lresult
= '0') then Result
:= 0
259 else if (lresult
= DESC_NEG_INF
) or (lresult
= DESC_POS_INF
)
260 or (lresult
= DESC_QNAN
) or (lresult
= DESC_SNAN
) then Result
:= -1;
263 function IsPrefixOf(Prefix
, OfWhat
: String): Boolean;
268 if (Length(Prefix
) > Length(OfWhat
)) then Exit
;
269 for i
:= 1 to Length(Prefix
) do
270 if not(Prefix
[i
] = OfWhat
[i
]) then Exit
;
274 function MaxOf(First
, Second
: Integer): Integer;
276 if (First
> Second
) then Result
:= First
277 else Result
:= Second
;
280 function MergeStringTStrings(First
: String; Second
: TStrings
): TStrings
;
284 SetLength(Result
, Length(Second
) + 1);
286 for i
:= 0 to (Length(Second
) - 1) do
287 Result
[i
+ 1] := Second
[i
];
290 function MergeTLinesLine(First
: TLines
; Second
: TLine
): TLines
;
294 SetLength(Result
, Length(First
) + 1);
295 Result
[Length(First
)] := Second
;
296 for i
:= 0 to (Length(First
) - 1) do
297 Result
[i
] := First
[i
];
300 function MergeTStringsString(First
: TStrings
; Second
: String): TStrings
;
304 SetLength(Result
, Length(First
) + 1);
305 Result
[Length(First
)] := Second
;
306 for i
:= 0 to (Length(First
) - 1) do
307 Result
[i
] := First
[i
];
310 function MinOf(First
, Second
: Integer): Integer;
312 if (First
< Second
) then Result
:= First
313 else Result
:= Second
;
316 function MirrorString(Input
: String): String;
321 if (Input
= '') then Exit
;
322 for i
:= Length(Input
) downto 1 do
323 Result
:= Result
+ Input
[i
];
326 function NeutralizeDoubles(Input
: String; Character
: Char): String;
328 Result
:= OmmitAfter(Input
, Character
, Character
);
331 function OmmitAfter(Input
: String; Character
, What
: Char): String;
337 if (Input
= '') then Exit
;
338 llast
:= Chr(Ord(Character
) + 1);
339 for i
:= 1 to Length(Input
) do
340 if not((llast
= Character
) and (Input
[i
] = What
)) then
342 Result
:= Result
+ Input
[i
];
347 function OmmitBefore(Input
: String; Character
, What
: Char): String;
353 if (Input
= '') then Exit
;
354 llast
:= Chr(Ord(Character
) + 1);
355 for i
:= Length(Input
) downto 1 do
356 if not((llast
= Character
) and (Input
[i
] = What
)) then
358 Result
:= Result
+ Input
[i
];
361 Result
:= MirrorString(Result
);
364 function OmmitEverywhere(Input
: String; Character
, What
: Char): String;
366 Result
:= OmmitBefore(OmmitAfter(Input
, Character
, What
), Character
, What
);
369 function ParseAfterFirst(Input
: String; Parser
: Char): String;
374 if (Input
= '') then Exit
;
375 for i
:= 1 to Length(Input
) do
376 if (Input
[i
] = Parser
) then Break
;
378 for i
:= lpos
to Length(Input
) do
379 Result
:= Result
+ Input
[i
];
382 function ParseAfterLast(Input
: String; Parser
: Char): String;
387 if (Input
= '') then Exit
;
388 for i
:= Length(Input
) downto 1 do
389 if (Input
[i
] = Parser
) then Break
;
391 for i
:= lpos
to Length(Input
) do
392 Result
:= Result
+ Input
[i
];
395 function ParseBeforeFirst(Input
: String; Parser
: Char): String;
400 if (Input
= '') then Exit
;
401 for i
:= 1 to Length(Input
) do
402 if (Input
[i
] = Parser
) then Break
403 else Result
:= Result
+ Input
[i
];
406 function ParseBeforeLast(Input
: String; Parser
: Char): String;
411 if (Input
= '') then Exit
;
412 for i
:= Length(Input
) downto 1 do
413 if (Input
[i
] = Parser
) then Break
;
415 for i
:= 1 to lpos
do
416 Result
:= Result
+ Input
[i
];
419 function ParseFirst(var Input
: String; Parser
: Char): String;
421 Result
:= ParseAfterFirst(Input
, Parser
);
422 Input
:= ParseBeforeFirst(Input
, Parser
);
425 function ParseToStrings(Input
: PChar
; Parser
: Char): TStrings
;
428 llast
, lstring
: PChar
;
430 SetLength(Result
, 0);
431 if (Length(Input
) = 0) then Exit
;
433 lstring
:= GetMemory(Length(Input
) + 1);
434 Move(Input
^, lstring
^, Length(Input
) + 1);
436 while (i
< Length(Input
)) do
438 if (Input
[i
] = Parser
) then
441 SetLength(Result
, Length(Result
) + 1);
442 Result
[Length(Result
) - 1] := String(llast
);
443 llast
:= @lstring
[i
+ 1];
447 SetLength(Result
, Length(Result
) + 1);
448 Result
[Length(Result
) - 1] := String(llast
);
452 function RemoveCharacter(Input
: String): String;
455 if (Input
= '') then Exit
;
457 SetLength(Result
, Length(Input
) - 1);
460 function RemoveExactString(From
: TStrings
; What
: String): TStrings
;
464 SetLength(Result
, 0);
465 for i
:= 0 to (Length(From
) - 1) do
466 if not(From
[i
] = What
) then
468 SetLength(Result
, Length(Result
) + 1);
469 Result
[Length(Result
) - 1] := From
[i
];
473 function RemovePrefix(Prefix
, From
: String): String;
478 if not IsPrefixOf(Prefix
, From
) then Exit
;
479 for i
:= (Length(Prefix
) + 1) to Length(From
) do
480 Result
:= Result
+ From
[i
];
483 function ReplaceCharacters(Input
: String; Find
, Replace
: Char): String;
488 if (Input
= '') then Exit
;
489 for i
:= 1 to Length(Input
) do
490 if (Input
[i
] = Find
) then
491 Result
:= Result
+ Replace
493 Result
:= Result
+ Input
[i
];
496 function SeparateFloat(Input
: PChar
; Size
: Integer): TFloatRecord
;
501 Result
.Significand
:= PInteger(Input
)^ and $7FFFFF;
502 Result
.Exponent
:= (PWord(Integer(Input
) + 2)^ shr 7) and $FF;
503 Result
.Sign
:= not((PByte(Integer(Input
) + 3)^ and $80) = 0);
507 Result
.Significand
:= PInt64(Input
)^ and $FFFFFFFFFFFFF;
508 Result
.Exponent
:= (PWord(Integer(Input
) + 6)^ shr 4) and $7FF;
509 Result
.Sign
:= not((PByte(Integer(Input
) + 7)^ and $80) = 0);
513 Result
.Significand
:= PInt64(Input
)^;
514 Result
.Exponent
:= PWord(Integer(Input
) + 8)^ and $7FFF;
515 Result
.Sign
:= not((PByte(Integer(Input
) + 9)^ and $80) = 0);
520 function StringToAddress(Input
: String; Offset
: Integer = 0): Integer;
522 i
, lstart
, lmul
: Integer;
524 Input
:= TrimCharacter(Input
, ' ');
541 for i
:= lstart
to Length(Input
) do
542 Result
:= (10 * Result
) + Ord(Input
[i
]) - Ord(CHARS_HEXA
[0]);
543 Result
:= (Result
* lmul
) + Offset
;
546 function StringBefore(Input
: String; Before
: Integer): String;
551 for i
:= 1 to Before
do
552 Result
:= Result
+ Input
[i
];
555 function StringCompare(First
, Second
: PChar
; Size
: Integer): Boolean;
560 for i
:= 0 to (Size
- 1) do
561 if not(First
[i
] = Second
[i
]) then Exit
;
565 function TrimCharacter(Input
: String; Character
: Char): String;
567 Result
:= TrimCharacterLeft(TrimCharacterRight(Input
, Character
), Character
);
570 function TrimCharacterLeft(Input
: String; Character
: Char): String;
575 if (Input
= '') then Exit
;
576 for i
:= 1 to Length(Input
) do
577 if not(Input
[i
] = Character
) then Break
;
579 for i
:= lstart
to Length(Input
) do
580 Result
:= Result
+ Input
[i
];
583 function TrimCharacterRight(Input
: String; Character
: Char): String;
588 if (Input
= '') then Exit
;
589 for i
:= Length(Input
) downto 1 do
590 if not(Input
[i
] = Character
) then Break
;
592 for i
:= 1 to lend
do
593 Result
:= Result
+ Input
[i
];
596 function ToTLine(Line
: String; Number
: Integer): TLine
;
599 Result
.Number
:= Number
;
602 function UpperCase(Input
: String): String;
607 if (Input
= '') then Exit
;
608 for i
:= 1 to Length(Input
) do
609 Result
:= Result
+ UpCase(Input
[i
]);
612 function ZeroPaddedInteger(Input
, Padding
: Integer): String;
623 else lminus
:= False;
626 Result
:= Result
+ CHARS_HEXA
[Input
mod 10];
627 Input
:= Input
div 10;
629 for i
:= Length(Result
) to (Padding
- 1) do
630 Result
:= Result
+ CHARS_HEXA
[0];
631 if lminus
then Result
:= Result
+ '-';
632 Result
:= MirrorString(Result
);
635 procedure ConstantToFloat(Input
: String; Result
: PChar
; Size
: Integer);
637 if not(Length(Input
) = Size
) then Exit
;
638 Move(PChar(Input
)[0], Result
^, Size
);
641 procedure CustomHexToData(Input
: String; Data
: PChar
; Size
: Integer);
646 Input
:= UpperCase(TrimCharacter(Input
, ' '));
647 InitializeMemory(Data
, Size
, #0);
648 if (Length(Input
) > Size
* 2) then Exit
;
649 j
:= (Size
* 2) - Length(Input
);
651 Input
:= CHARS_HEXA
[0] + Input
;
652 Input
:= MirrorString(Input
);
653 for i
:= 1 to Length(Input
) do
654 if not IsHexaChar(Input
[i
]) then Exit
;
655 for i
:= 1 to Size
do
658 for j
:= 0 to (Length(CHARS_HEXA
) - 1) do
659 if (CHARS_HEXA
[j
] = Input
[2 * i
]) then
664 lbyte
:= lbyte
shl 4;
665 for j
:= 0 to (Length(CHARS_HEXA
) - 1) do
666 if (CHARS_HEXA
[j
] = Input
[(2 * i
) - 1]) then
671 Data
[i
- 1] := Chr(lbyte
);
675 procedure CustomStrToBCD(Input
: String; Result
: PChar
; Size
: Integer);
680 if not(Size
= 10) then Exit
;
681 InitializeMemory(Result
, 10, #0);
682 lint
:= StrToInt64Def(Input
, 0);
683 if (lint
< -999999999999999999) then Exit
;
684 if (lint
> 999999999999999999) then Exit
;
685 with PBCDRecord(Result
)^ do
695 Bytes
[i
] := (((lint
mod 100) div 10) shl 4) + (lint
mod 10);
697 lint
:= lint
div 100;
702 procedure CustomStrToFloat(Input
: String; Result
: PChar
; Size
: Integer);
704 ltrans
: TTranslateConstants
;
707 4: ltrans
:= TRANS_FP_4
;
708 8: ltrans
:= TRANS_FP_8
;
709 10: ltrans
:= TRANS_FP_10
;
713 Input
:= UpperCase(TrimCharacter(Input
, ' '));
714 if (Input
= '') then Exit
;
715 if (Input
= DESC_NEG_INF
) then
717 ConstantToFloat(ltrans
.NegInf
, Result
, Size
);
720 if (Input
= DESC_POS_INF
) or (Input
= DESC_INF
) then
722 ConstantToFloat(ltrans
.PosInf
, Result
, Size
);
725 if (Input
= DESC_QNAN
) or (Input
= DESC_NAN
) then
727 ConstantToFloat(ltrans
.QNaN
, Result
, Size
);
730 if (Input
= DESC_SNAN
) then
732 ConstantToFloat(ltrans
.SNaN
, Result
, Size
);
737 4: PSingle(Result
)^ := StrToFloat(Input
);
738 8: PDouble(Result
)^ := StrToFloat(Input
);
739 10: PExtended(Result
)^ := StrToFloat(Input
);
744 4: PSingle(Result
)^ := 0;
745 8: PDouble(Result
)^ := 0;
746 10: PExtended(Result
)^ := 0;
751 procedure CustomStrToSInt(Input
: String; Result
: PChar
; Size
: Integer);
755 lint
:= StrToInt64Def(Input
, 0);
758 if (lint
> 127) or (lint
< -128) then PShortint(Result
)^ := 0
759 else PShortInt(Result
)^ := lint
;
761 if (lint
> 32767) or (lint
< -32768) then PSmallint(Result
)^ := 0
762 else PSmallInt(Result
)^ := lint
;
763 4: PInteger(Result
)^ := StrToIntDef(Input
, 0);
764 8: PInt64(Result
)^ := lint
;
768 procedure CustomStrToUInt(Input
: String; Result
: PChar
; Size
: Integer);
772 lint
:= StrToInt64Def(Input
, 0);
775 if (lint
> 255) or (lint
< 0) then PShortint(Result
)^ := 0
776 else PShortInt(Result
)^ := lint
;
778 if (lint
> 65536) or (lint
< 0) then PSmallint(Result
)^ := 0
779 else PSmallInt(Result
)^ := lint
;
781 if (lint
> 4294967295) or (lint
< 0) then PInteger(Result
)^ := 0
782 else PInteger(Result
)^ := lint
;
784 PInt64(Result
)^ := lint
;
790 if not(@Log_OnClear
= nil) then Log_OnClear(Log_Sender
);
793 procedure LogSystemTime
;
796 LogWrite(APP_VERSION
+ ' [' + TimeToStr(Time
) + ']');
799 procedure LogWrite(Log
: String; Error
: Boolean = False);
801 if not(@Log_OnWrite
= nil) then Log_OnWrite(Log_Sender
, Log
, Error
);
804 procedure InitializeMemory(Input
: PChar
; Size
: Integer; Character
: Char);
808 for i
:= 0 to (Size
- 1) do
809 Input
[i
] := Character
;
813 DecimalSeparator
:= '.';