You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
RnQ/for.RnQ/RTL/RnQBinUtils.pas

1026 lines
26 KiB
Plaintext

{
This file is part of R&Q.
Under same license
}
unit RnQBinUtils;
{$I ForRnQConfig.inc}
{ $INLINE ON }
interface
uses
sysutils, types, RDGlobal;
{$I NoRTTI.inc}
function dword_LE2ip(d: dword): AnsiString;
{$IFDEF UNICODE}
function dword_LE2ipU(d: dword): UnicodeString;
{$ENDIF UNICODE}
// function invert(d:integer):integer; OverLoad;
// function invert64(const d:int64):int64; OverLoad; inline;
// function BSwapInt(Value: LongWord): LongWord; assembler; register;
// procedure SwapShort(const P: PWord; const Count: Cardinal);
// procedure SwapLong(P: PInteger; Count: Cardinal);
// function SwapLong(Value: Cardinal): Cardinal; overload;
function incPtr(p: pointer; d: integer): pointer; inline;
function findTLV(idx: integer; const s: RawByteString; ofs: integer = 1): integer;
function existsTLV(idx: integer; const s: RawByteString; ofs: integer = 1): boolean; inline;
function deleteTLV(idx: integer; const s: RawByteString; ofs: integer = 1): RawByteString;
// build data
function qword_LEasStr(d: int64): RawByteString;
function qword_BEasStr(d: int64): RawByteString;
function dword_LEasStr(d: dword): RawByteString;
function dword_BEasStr(d: dword): RawByteString;
function word_BEasStr(w: word): RawByteString; inline;
function word_LEasStr(w: word): RawByteString;
function TLV(t: word; v: dword): RawByteString; overload;
function TLV(t: word; v: word): RawByteString; overload;
function TLV(t: word; v: integer): RawByteString; overload;
function TLV(t: word; v: int64): RawByteString; overload;
function TLV(t: word; const v: RawByteString): RawByteString; overload;
function TLV_LE(t: word; const v: RawByteString): RawByteString;
function TLV2(code: integer; const data: RawByteString): RawByteString; overload;
function TLV2(code: integer; const data: TDateTime): RawByteString; overload;
function TLV2(code: integer; const data: integer): RawByteString; overload;
function TLV2(code: integer; const data: boolean): RawByteString; overload;
function TLV2_IFNN(code: integer; const data: RawByteString): RawByteString; overload; // if data not null
function TLV2_IFNN(code: integer; const data: TDateTime): RawByteString; overload; // if data not null
function TLV2_IFNN(code: integer; data: integer): RawByteString; overload; // if data not null
function TLV2U_IFNN(code: integer; const str: String): RawByteString; // overload; // if data not null. Unicode String
function TLV3(code: integer; const data: RawByteString): RawByteString;
function TLV3U(code: integer; const str: UnicodeString): RawByteString;
function Length_LE(const data: RawByteString): RawByteString;
function Length_BE(const data: RawByteString): RawByteString;
function Length_DLE(const data: RawByteString): RawByteString;
function Length_B(const data: RawByteString): RawByteString;
function WNTS(const s: RawByteString): RawByteString;
function WNTSU(const s: String): RawByteString;
// read data
function Qword_LEat(p: pointer): int64; inline; // inline;
function Qword_BEat(p: pointer): int64; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
function dword_BEat(const s: RawByteString; ofs: integer): integer; overload; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
function dword_BEat(p: pointer): LongWord; overload; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
function dword_LEat(p: pointer): LongWord; inline; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
function word_LEat(p: pointer): word; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
function word_BEat(p: pointer): word; overload; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
function ptrWNTS(p: pointer): RawByteString;
function word_BEat(const s: RawByteString; ofs: integer): word; overload;
// function word_BEat(s:string; ofs:integer):word; overload;
function readQWORD(const snac: RawByteString; var ofs: integer): int64;
function readWORD(const snac: RawByteString; var ofs: integer): word;
function readBEWORD(const snac: RawByteString; var ofs: integer): word; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
function readINT(const snac: RawByteString; var ofs: integer): integer; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
function readDWORD(const snac: RawByteString; var ofs: integer): cardinal;
function readBEDWORD(const snac: RawByteString; var ofs: integer): cardinal;
function readBYTE(const snac: RawByteString; var ofs: integer): byte;
// function getBUIN2(const s:RawByteString; var ofs:integer): RawByteString;
// function getBUIN(const s:RawByteString; var ofs:integer): Integer;
function getDLS(const s: RawByteString; var ofs: integer): RawByteString;
function getWNTS(const s: RawByteString; var ofs: integer): RawByteString;
function getBEWNTS(const s: RawByteString; var ofs: integer): RawByteString;
function getTLV(p: pointer): RawByteString; overload;
function getTLVwordBE(p: pointer): word; overload;
function getTLVdwordBE(p: pointer): dword; overload;
function getTLV(idx: integer; const s: RawByteString; ofs: integer = 1): RawByteString; overload;
function getTLVwordBE(idx: integer; const s: RawByteString; ofs: integer = 1): word; overload;
function getTLVdwordBE(idx: integer; const s: RawByteString; ofs: integer = 1): dword; overload;
function getTLVqwordBE(idx: integer; const s: RawByteString; ofs: integer = 1): int64;
function getTLVSafe(idx: integer; s: RawByteString; ofs: integer = 1): RawByteString;
function getTLVSafeDelete(idx: integer; var s: RawByteString; ofs: integer = 1): RawByteString;
function replaceAddTLV(idx: integer; s: RawByteString; ofs: integer = 1; NewTLV: RawByteString = ''): RawByteString;
// ----------------------------
function findTLV3(const idx: integer; const s: RawByteString; ofs: integer): integer;
function getTLV3Safe(const idx: integer; const s: RawByteString; const ofs: integer): RawByteString;
function getTLV3dwordBE(p: pointer): dword;
function getTLV3wordBE(p: pointer): dword;
function getwTLD(const s: RawByteString; var ofs: integer): RawByteString;
function getwTLD_DWORD(const s: RawByteString; var ofs: integer): LongWord;
/// //----------------------------
function int2str(i: integer): RawByteString;
function int2str64(i: int64): RawByteString;
function dt2str(dt: TDateTime): RawByteString;
function str2int(const s: RawByteString): integer; overload;
function str2int(p: pointer): integer; overload; inline;
implementation
uses
{$IFDEF UNICODE}
AnsiStrings,
{$ENDIF UNICODE}
{$IFNDEF FPC}
OverbyteIcsUtils,
{$ENDIF ~FPC}
Windows,
RDUtils;
{$IFDEF Linux}
// <20><> Lazarus
// Function Swap (X : Integer) : Integer;{$ifdef SYSTEMINLINE}inline;{$endif}
Function Swap(X: word): word; {$IFDEF SYSTEMINLINE}inline; {$ENDIF}
Begin
{ the extra 'and $ff' in the right term is necessary because the }
{ 'X shr 8' is turned into "longint(X) shr 8", so if x < 0 then }
{ the sign bits from the upper 16 bits are shifted in rather than }
{ zeroes. Another bug for TP/Delphi compatibility... }
Swap := (X and $FF) shl 8 + ((X shr 8) and $FF)
End;
{$ENDIF Linux}
{$IFDEF FPC}
// From ICS!
{ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * }
function IcsSwap32(Value: LongWord): LongWord;
{$IFDEF PUREPASCAL}
begin
Result := word(((Value shr 16) shr 8) or ((Value shr 16) shl 8)) or word((word(Value) shr 8) or (word(Value) shl 8)) shl 16;
{$ELSE}
asm
{$IFDEF CPUX64}
MOV EAX, ECX
{$ENDIF}
BSWAP EAX
{$ENDIF}
end;
{ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * }
function IcsSwap64(Value: int64): int64;
{$IFDEF PUREPASCAL}
var
H, L: LongWord;
begin
H := LongWord(Value shr 32);
L := LongWord(Value);
H := word(((H shr 16) shr 8) or ((H shr 16) shl 8)) or word((word(H) shr 8) or (word(H) shl 8)) shl 16;
L := word(((L shr 16) shr 8) or ((L shr 16) shl 8)) or word((word(L) shr 8) or (word(L) shl 8)) shl 16;
Result := int64(H) or int64(L) shl 32;
{$ELSE}
asm
{$IFDEF CPUX64}
MOV RAX, RCX
BSWAP RAX
{$ELSE}
MOV EDX, [EBP + $08]
MOV EAX, [EBP + $0C]
BSWAP EAX
BSWAP EDX
{$ENDIF}
{$ENDIF}
end;
{$ENDIF FPC}
{$WARN UNSAFE_CAST OFF}
{$WARN UNSAFE_CODE OFF}
{ function invert(d:integer):integer; assembler; register;
//begin
// result:=swap(d shr 16)+swap(d) shl 16
asm
BSWAP EAX
end; }
{
function BSwapInt(Value: LongWord): LongWord; assembler; register;
asm
BSWAP EAX
end;
function invert64(const d:int64):int64;
//var
// i : Int64Rec
begin
Int64Rec(result).Words[0] := Swap(Int64Rec(d).Words[3]);
Int64Rec(result).Words[1] := Swap(Int64Rec(d).Words[2]);
Int64Rec(result).Words[2] := Swap(Int64Rec(d).Words[1]);
Int64Rec(result).Words[3] := Swap(Int64Rec(d).Words[0]);
// result := swap(Word(d shr 48)) + swap(Word(d shr 32)) shl 16 +
// swap(word(d shr 16)) shl 32 + swap(word( d)) shl 48;
end;
}
{
Here's another one that uses the SSSE3 instruction PSHUFB:
function Swap(const X: Int64): Int64;
const
SHUFIDX: array [0..1] of Int64 = ($0001020304050607, 0);
asm
MOVQ XMM0,[X]
PSHUFB XMM0,SHUFIDX
MOVQ [Result],XMM0
end;
}
{ procedure SwapShort(const P: PWord; const Count: Cardinal);
asm
@@Loop:
MOV CX, [EAX]
XCHG CH, CL
MOV [EAX], CX
ADD EAX, 2
DEC EDX
JNZ @@Loop
end;
procedure SwapLong(P: PInteger; Count: Cardinal); overload;
asm
@@Loop:
MOV ECX, [EAX]
BSWAPl ECX
MOV [EAX], ECX
ADD EAX, 4
DEC EDX
JNZ @@Loop
end;
}
function int2str(i: integer): RawByteString;
var
v: RawByteString;
begin
setLength(v, 4);
move(i, pointer(v)^, 4);
Result := v;
end;
function ptrWNTS(p: pointer): RawByteString;
var
v: RawByteString;
begin
setLength(v, word(p^) - 1);
move(incPtr(p, 2)^, pointer(v)^, length(v));
Result := v;
end; // ptrWNTS
{
function getBUIN2(const s:RawByteString; var ofs:integer): RawByteString;
begin
//result:=strToInt(copy(s,ofs+1,ord(s[ofs])));
result:= copy(s,ofs+1,ord(s[ofs]));
inc(ofs, 1+ord(s[ofs]));
end; // getBUIN
function getBUIN(const s:RawByteString; var ofs:integer): Integer;
var
E: Integer;
// ss : AnsiString;
ss : String;
begin
// result:=strToInt(ss);
ss := copy(s, ofs+1, byte(s[ofs]));
Val(ss, Result, E);
if e <> 0 then
Result := 0;
//result:= copy(s,ofs+1,ord(s[ofs]));
inc(ofs, 1+ byte(s[ofs]));
end; // getBUIN
}
function getWNTS(const s: RawByteString; var ofs: integer): RawByteString;
var
i: integer;
begin
i := word((@s[ofs])^);
Result := copy(s, ofs + 2, i - 1);
inc(ofs, 2 + i);
end; // getWNTS
function getBEWNTS(const s: RawByteString; var ofs: integer): RawByteString;
var
i: integer;
begin
i := Swap(word((@s[ofs])^));
Result := copy(s, ofs + 2, i);
inc(ofs, 2 + i);
end; // getBEWNTS
function getDLS(const s: RawByteString; var ofs: integer): RawByteString;
var
i: integer;
begin
i := integer((@s[ofs])^);
if i > 100 * 1024 then
Result := ''
else
begin
Result := copy(s, ofs + 4, i);
inc(ofs, 4 + i);
end;
end; // getDLS
function incPtr(p: pointer; d: integer): pointer; inline;
begin
Result := pointer(PtrInt(p) + d)
end;
function existsTLV(idx: integer; const s: RawByteString; ofs: integer): boolean;
begin
Result := findTLV(idx, s, ofs) > 0
end;
function findTLV(idx: integer; const s: RawByteString; ofs: integer): integer;
var
L: integer;
begin
Result := -1;
{
l := length(s);
if (l >= 4)and(ofs < l) then
// if l > 2 then
begin
while word_BEat(@s[ofs])<>idx do
begin
inc(ofs, word_BEat(@s[ofs+2])+4);
if ofs >= l then
exit;
end;
result:=ofs;
end; }
L := length(s) - 2;
if (L >= 2) and (ofs < L) then
// if l > 2 then
begin
while word_BEat(@s[ofs]) <> idx do
begin
inc(ofs, word_BEat(@s[ofs + 2]) + 4);
if ofs >= L then
exit;
end;
Result := ofs;
end;
end; // findTLV
function deleteTLV(idx: integer; const s: RawByteString; ofs: integer = 1): RawByteString;
var
i, L: integer;
begin
i := findTLV(idx, s, ofs);
if i > 0 then
begin
L := word_BEat(@s[i + 2]);
Result := copy(s, 1, i - 1) + copy(s, i + 4 + L, length(s));
end
else
Result := s;
end;
function getTLV(p: pointer): RawByteString;
var
pw: pword absolute p;
begin
if pw = NIL then
Result := ''
else
begin
inc(pw);
setLength(Result, Swap(pw^));
inc(pw);
move(pw^, pointer(Result)^, length(Result));
end;
end; // getTLV
function getTLVwordBE(p: pointer): word;
var
pw: pword absolute p;
begin
inc(pw, 2);
Result := Swap(pw^);
end; // getTLVwordBE
function getTLVdwordBE(p: pointer): dword;
var
pw: pword absolute p;
pd: pinteger absolute p;
begin
inc(pw, 2);
// result:= BSwapInt(pd^);
Result := IcsSwap32(pd^);
end;
function getTLV(idx: integer; const s: RawByteString; ofs: integer): RawByteString;
begin
Result := getTLV(@s[findTLV(idx, s, ofs)])
end;
function getTLVSafe(idx: integer; s: RawByteString; ofs: integer): RawByteString;
var
i: integer;
begin
i := findTLV(idx, s, ofs);
if i > 0 then
Result := getTLV(@s[i])
else
Result := '';
end;
function getTLVSafeDelete(idx: integer; var s: RawByteString; ofs: integer = 1): RawByteString;
var
i: integer;
begin
i := findTLV(idx, s, ofs);
if i > 0 then
begin
Result := getTLV(@s[i]);
s := deleteTLV(idx, s, i);
end
else
Result := '';
end;
function replaceAddTLV(idx: integer; s: RawByteString; ofs: integer = 1; NewTLV: RawByteString = ''): RawByteString;
var
i, L: integer;
begin
i := findTLV(idx, s, ofs);
if i > 0 then
begin
L := word_BEat(@s[i + 2]);
Result := copy(s, 1, i - 1) + TLV(idx, NewTLV) + copy(s, i + 4 + L, length(s));
end
else
Result := s + TLV(idx, NewTLV);
end;
function getTLVwordBE(idx: integer; const s: RawByteString; ofs: integer = 1): word;
begin
Result := getTLVwordBE(@s[findTLV(idx, s, ofs)])
end;
function getTLVdwordBE(idx: integer; const s: RawByteString; ofs: integer = 1): dword;
begin
Result := getTLVdwordBE(@s[findTLV(idx, s, ofs)])
end;
function getTLVqwordBE(idx: integer; const s: RawByteString; ofs: integer = 1): int64;
var
i: integer;
begin
i := findTLV(idx, s, ofs);
if i > 0 then
Result := Qword_BEat(@s[i + 4])
else
Result := 0;
end;
function findTLV3(const idx: integer; const s: RawByteString; ofs: integer): integer;
var
L: integer;
begin
Result := -1;
L := length(s) - 2;
if (L >= 8) and (ofs < L) then
// if l > 2 then
begin
while dword_BEat(@s[ofs]) <> idx do
begin
inc(ofs, dword_BEat(@s[ofs + 4]) + 8);
if ofs >= L then
exit;
end;
Result := ofs;
end;
end; // findTLV3
function getTLV3(p: pointer): RawByteString;
var
// pw:PDWord absolute p;
pw: PINT absolute p;
a: integer;
begin
if pw = NIL then
Result := ''
else
begin
inc(pw);
// setLength(result, swap(pw^));
// a := BSwapInt(pw^);
a := IcsSwap32(pw^);
setLength(Result, a);
inc(pw);
move(pw^, Result[1], a);
end;
end; // getTLV
function getTLV3Safe(const idx: integer; const s: RawByteString; const ofs: integer): RawByteString;
var
i: integer;
begin
i := findTLV3(idx, s, ofs);
if i > 0 then
Result := getTLV3(@s[i])
else
Result := '';
end;
function getTLV3dwordBE(p: pointer): dword;
var
pw: PDWORD absolute p;
pd: pinteger absolute p;
begin
inc(pw, 2);
// result:= BSwapInt(pd^);
Result := IcsSwap32(pd^);
end;
function getTLV3wordBE(p: pointer): dword;
var
pw: PDWORD absolute p;
pd: pword absolute p;
begin
inc(pw, 2);
Result := Swap(pd^);
end;
function getwTLD(const s: RawByteString; var ofs: integer): RawByteString;
var
i: integer;
begin
// i:= BSwapInt(integer((@s[ofs+4])^));
i := IcsSwap32(integer((@s[ofs + 4])^));
if i > 100 * 1024 then
Result := ''
else
begin
Result := copy(s, ofs + 4 + 4, i);
inc(ofs, 4 + 4 + i);
end;
end; // getwTLD
function getwTLD_DWORD(const s: RawByteString; var ofs: integer): LongWord;
var
i: integer;
begin
inc(ofs, 4);
// i:= BSwapInt(integer((@s[ofs])^));
i := IcsSwap32(LongWord((@s[ofs])^));
if i <> 4 then
Result := 0
else
begin
inc(ofs, 4);
Result := dword_BEat(@s[ofs]);
inc(ofs, i);
end;
end;
function Length_LE(const data: RawByteString): RawByteString;
begin
Result := word_LEasStr(length(data)) + data
end;
function Length_DLE(const data: RawByteString): RawByteString;
begin
Result := dword_LEasStr(length(data)) + data
end;
function Length_BE(const data: RawByteString): RawByteString;
begin
Result := word_BEasStr(length(data)) + data
end;
function Length_B(const data: RawByteString): RawByteString;
begin
Result := AnsiChar(byte(length(data))) + data
end;
function WNTS(const s: RawByteString): RawByteString;
begin
Result := word_LEasStr(length(s) + 1) + s + #0
end;
function WNTSU(const s: String): RawByteString;
var
s1: RawByteString;
begin
s1 := StrToUTF8(s);
Result := word_LEasStr(length(s1) + 1) + s1 + #0
end;
function TLV(t: word; v: dword): RawByteString;
begin
Result := TLV(t, dword_BEasStr(v))
end;
function TLV(t: word; v: word): RawByteString;
begin
Result := TLV(t, word_BEasStr(v))
end;
function TLV(t: word; v: integer): RawByteString;
begin
Result := TLV(t, dword_BEasStr(v))
end;
function TLV(t: word; v: int64): RawByteString;
begin
Result := TLV(t, qword_BEasStr(v))
end;
function TLV(t: word; const v: RawByteString): RawByteString;
// begin result:=word_BEasStr(t)+word_BEasStr(length(v))+v end;
var
s: RawByteString;
ps: pointer;
i: word;
a: word;
begin
i := length(v);
setLength(s, 2 + 2 + i);
ps := pointer(s);
a := Swap(t);
move(a, ps^, 2);
inc(PByte(ps), 2);
a := Swap(i);
move(a, ps^, 2);
inc(PByte(ps), 2);
if i > 0 then
move(pointer(v)^, ps^, i);
Result := s;
end;
// function TLV_LE(t:word; v:word):string;
// begin result:= TLV_LE(t, word_LEasStr(v)) end;
function TLV_LE(t: word; const v: RawByteString): RawByteString;
begin
Result := word_LEasStr(t) + word_LEasStr(length(v)) + v
end;
function TLV2(code: integer; const data: RawByteString): RawByteString;
var
s: RawByteString;
// ps : PAnsiChar;
ps: pointer;
i: integer;
begin
i := length(data);
setLength(s, 4 + 4 + i);
ps := pointer(s);
// Move(code, ps^, 4);
pinteger(ps)^ := code;
inc(PByte(ps), 4);
// Move(i, ps^, 4);
pinteger(ps)^ := i;
inc(PByte(ps), 4);
if i > 0 then
move(pointer(data)^, ps^, i);
Result := s;
{
move(code, Result[1], 4);
i := length(data);
// inc(ps, 4);
move(i, Result[5], 4);
// inc(ps, 4);
move(data[1], Result[9], i);
}
end;
function TLV3U(code: integer; const str: UnicodeString): RawByteString;
begin
if str > '' then
Result := TLV3(code, StrToUTF8(str))
else
Result := TLV3(code, '');
end;
function TLV3(code: integer; const data: RawByteString): RawByteString;
var
s: RawByteString;
ps: pointer;
i: integer;
// a : Integer;
begin
i := length(data);
setLength(s, 4 + 4 + i);
ps := pointer(s);
// a := BSwapInt(code);
// Move(a, ps^, 4);
// PInteger(ps)^ := BSwapInt(code);
pinteger(ps)^ := IcsSwap32(code);
inc(PByte(ps), 4);
// a := BSwapInt(i);
// Move(a, ps^, 4);
// PInteger(ps)^ := BSwapInt(i);
pinteger(ps)^ := IcsSwap32(i);
inc(PByte(ps), 4);
if i > 0 then
move(pointer(data)^, ps^, i);
Result := s;
end;
function TLV2(code: integer; const data: TDateTime): RawByteString;
var
s: RawByteString;
ps: pointer;
// i : Integer;
begin
setLength(s, 4 + 4 + 8);
ps := pointer(s);
pinteger(ps)^ := code;
inc(PByte(ps), 4);
// i := 8;
// Move(i, ps^, 4);
pinteger(ps)^ := 8;
inc(PByte(ps), 4);
// Move(data, ps^, 8);
PDateTime(ps)^ := data;
Result := s;
end;
// function TLV2(code:integer; const data:Integer):RawByteString;
// var
// s : RawByteString;
// ps : Pointer;
// i : Integer;
// begin
// SetLength(s, 4+ 4+ 4);
// ps := Pointer(s);
// Move(code, ps^, 4);
// i := 4;
// inc(Cardinal(ps), 4);
// Move(i, ps^, 4);
// inc(Cardinal(ps), 4);
// Move(data, ps^, 4);
// Result := s;
// end;
function TLV2(code: integer; const data: integer): RawByteString;
var
s: RawByteString;
ps: pointer;
// i : Integer;
begin
setLength(s, 4 + 4 + 4);
ps := pointer(s);
pinteger(ps)^ := code;
inc(PByte(ps), 4);
pinteger(ps)^ := 4;
inc(PByte(ps), 4);
pinteger(ps)^ := data;
Result := s;
end;
function TLV2(code: integer; const data: boolean): RawByteString;
// begin result:=int2str(code)+int2str(1)+ AnsiChar(data) end;
var
s: RawByteString;
ps: pointer;
// i : Integer;
begin
setLength(s, 4 + 4 + 1);
ps := pointer(s);
// Move(code, ps^, 4);
pinteger(ps)^ := code;
// i := 1;
inc(PByte(ps), 4);
// Move(i, ps^, 4);
pinteger(ps)^ := 1;
// Result[9] := AnsiChar(data);
inc(PByte(ps), 4);
// Move(data, ps^, 1);
PByte(ps)^ := byte(data);
Result := s;
end;
function TLV2_IFNN(code: integer; const data: RawByteString): RawByteString; // if data not null
begin
if length(data) > 0 then
Result := int2str(code) + int2str(length(data)) + data
else
Result := '';
end;
function TLV2U_IFNN(code: integer; const str: String): RawByteString; // if data not null. Unicode String
var
s1: RawByteString;
begin
if str > '' then
s1 := StrToUTF8(str)
else
begin
Result := '';
exit;
end;
if length(s1) > 0 then
// result:=int2str(code)+int2str(length(s1))+s1
Result := TLV2(code, s1)
else
Result := '';
end;
function TLV2_IFNN(code: integer; data: integer): RawByteString; // if data not null
begin
if data > 0 then
Result := int2str(code) + int2str(4) + int2str(data)
else
Result := '';
end;
function TLV2_IFNN(code: integer; const data: TDateTime): RawByteString;
var
s: RawByteString;
ps: pointer;
// i : Integer;
begin
if data > 0 then
begin
setLength(s, 4 + 4 + 8);
ps := pointer(s);
// Move(code, ps^, 4);
pinteger(ps)^ := code;
inc(PByte(ps), 4);
// i := 8;
// Move(i, ps^, 4);
pinteger(ps)^ := 8;
inc(PByte(ps), 4);
// Move(data, ps^, 8);
PDateTime(ps)^ := data;
Result := s;
end
else
Result := '';
end;
function Qword_LEat(p: pointer): int64; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
begin
Result := int64(p^)
end;
function Qword_BEat(p: pointer): int64; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
begin
// result:=invert64(int64(p^))
Result := IcsSwap64(int64(p^))
end;
function dword_BEat(p: pointer): LongWord; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
begin
// result:= BSwapInt(integer(p^))
Result := IcsSwap32(LongWord(p^))
end;
function dword_BEat(const s: RawByteString; ofs: integer): integer; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
begin
Result := dword_BEat(@s[ofs])
end;
function dword_LEat(p: pointer): LongWord; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
begin
Result := integer(p^)
end;
function word_LEat(p: pointer): word; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
begin
Result := word(p^)
end;
function word_BEat(p: pointer): word; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
begin
Result := Swap(word(p^))
end;
function word_BEat(const s: RawByteString; ofs: integer): word; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
begin
Result := word_BEat(@s[ofs])
end;
function dword_LE2ip(d: dword): AnsiString;
begin
Result := format(AnsiString('%d.%d.%d.%d'), [byte(d shr 24), byte(d shr 16), byte(d shr 8), byte(d)])
end;
{$IFDEF UNICODE}
function dword_LE2ipU(d: dword): UnicodeString;
begin
Result := format('%d.%d.%d.%d', [byte(d shr 24), byte(d shr 16), byte(d shr 8), byte(d)])
end;
{$ENDIF UNICODE}
function word_LEasStr(w: word): RawByteString;
begin
Result := AnsiChar(w) + AnsiChar(w shr 8)
end;
function word_BEasStr(w: word): RawByteString;
begin
Result := AnsiChar(w shr 8) + AnsiChar(w)
end;
function dword_BEasStr(d: dword): RawByteString;
begin
Result := AnsiChar(d shr 24) + AnsiChar(d shr 16) + AnsiChar(d shr 8) + AnsiChar(d)
end;
function dword_LEasStr(d: dword): RawByteString;
begin
Result := AnsiChar(d) + AnsiChar(d shr 8) + AnsiChar(d shr 16) + AnsiChar(d shr 24)
end;
function qword_LEasStr(d: int64): RawByteString;
begin
setLength(Result, 8);
move(d, pointer(Result)^, 8);
end; // qword_LEasStr
function qword_BEasStr(d: int64): RawByteString;
begin
setLength(Result, 8);
// d := Invert64(d);
d := IcsSwap64(d);
move(d, pointer(Result)^, 8);
end; // qword_LEasStr
function readBYTE(const snac: RawByteString; var ofs: integer): byte;
// begin result:=byte((@snac[ofs])^); inc(ofs) end;
// function readBYTE:byte;
begin
Result := byte(snac[ofs]);
inc(ofs)
end;
function readWORD(const snac: RawByteString; var ofs: integer): word;
begin
Result := word_LEat(@snac[ofs]);
inc(ofs, 2)
end;
function readBEWORD(const snac: RawByteString; var ofs: integer): word;
begin
Result := word_BEat(@snac[ofs]);
inc(ofs, 2)
end;
function readINT(const snac: RawByteString; var ofs: integer): integer;
begin
Result := dword_LEat(@snac[ofs]);
inc(ofs, 4)
end;
function readDWORD(const snac: RawByteString; var ofs: integer): cardinal;
begin
Result := dword_LEat(@snac[ofs]);
inc(ofs, 4)
end;
function readBEDWORD(const snac: RawByteString; var ofs: integer): cardinal;
begin
Result := dword_BEat(@snac[ofs]);
inc(ofs, 4)
end;
function readQWORD(const snac: RawByteString; var ofs: integer): int64;
begin
Result := Qword_LEat(@snac[ofs]);
inc(ofs, 8)
end;
function int2str64(i: int64): RawByteString;
var
v: RawByteString;
begin
setLength(v, 8);
move(i, pointer(v)^, 8);
Result := v;
end;
function dt2str(dt: TDateTime): RawByteString;
var
v: RawByteString;
begin
setLength(v, 8);
move(dt, pointer(v)^, 8);
Result := v;
end;
function str2int(const s: RawByteString): integer;
begin
Result := dword_LEat(pointer(s))
end;
function str2int(p: pointer): integer;
begin
Result := dword_LEat(p)
end;
end.