@ -4,122 +4,27 @@
}
unit RnQBinUtils;
{$I ForRnQConfig.inc}
{ $INLINE ON }
interface
uses
sysutils, t ypes, RDGlobal;
SysUtils, T ypes, 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; inline;
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; overload; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
function dword_LEat(const s: RawByteString; ofs: Integer): Integer; overload; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
function word_LEat(p: pointer): word; overload; {$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_LEat(const s: RawByteString; ofs: integer): word; overload; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
function word_BEat(const s: RawByteString; ofs: integer): word; overload; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
// 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(const s: RawByteString; ofs: integer=1): RawByteString; INLINE; overload;
function getTLVwordBE(const s: RawByteString; ofs: integer=1): word; INLINE; overload;
function getTLVdwordBE(const s: RawByteString; ofs: integer=1): dword; INLINE; overload;
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 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 dword_LEat(p: Pointer): LongWord; overload; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
function dword_LEat(const s: RawByteString; ofs: Integer): Integer; overload; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
function getTLVSafe(idx: integer; const s: RawByteString; ofs: integer = 1): RawByteString;
function getTLVSafeDelete(idx: integer; var s: RawByteString; ofs: integer = 1): RawByteString;
function replaceAddTLV(idx: integer; const s: RawByteString; ofs: integer = 1; const NewTLV: RawByteString = ''): RawByteString;
function int2str(i: integer): RawByteString;
function dt2str(dt: TDateTime): 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;
function str2int(const s: RawByteString): integer; overload;
function str2int(p: pointer): integer; overload; inline;
implementation
@ -127,927 +32,107 @@ uses
{$IFDEF UNICODE}
AnsiStrings,
{$ENDIF UNICODE}
{$IFNDEF FPC}
OverbyteIcsUtils,
{$ENDIF ~FPC}
Windows,
RDUtils;
{$IFDEF Linux}
// Äëÿ 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;
Windows, RDUtils;
{ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * }
function IcsSwap64(Value: int64): int64;
{$IFDEF PUREPASCAL}
function Int2Str(I: Integer): RawByteString;
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 incPtr(p: pointer; d: integer): pointer; inline;
V: RawByteString;
begin
Result := pointer(PtrInt(p) + d)
SetLength(V, 4);
Move(I, pointer(V)^, 4);
Result := V;
end;
function Qword_LEat(p: pointer): int64; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
function dword_LEat(P: Pointer): LongWord; overLoad; {$IFDEF HAS_INLINE}inline;{$ENDIF HAS_INLINE}
begin
Result := int64(p ^)
Result := LongWord(P^)
end;
function Qword_BEat(p: pointer): int64; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
function dword_LEat(const S: RawByteString; Ofs: Integer): Integer; {$IFDEF HAS_INLINE}inline;{$ENDIF HAS_INLINE}
begin
// result:=invert64(int64(p^))
Result := IcsSwap64(int64(p^))
Result := Int32((@S[Ofs])^)
end;
function dword_BEat(p: pointer): LongWord; overLoad; {$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; overLoad; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
begin
Result := LongWord(p^)
end;
function dword_LEat(const s: RawByteString; ofs: Integer): Integer; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
begin
Result := int32((@s[ofs])^)
end;
function word_LEat(const s: RawByteString; ofs: integer): word; {$IFDEF HAS_INLINE}inline; {$ENDIF HAS_INLINE}
begin
result := word_LEat(@s[ofs])
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 ptrWNTS(p: pointer): RawByteString;
function TLV2(Code: Integer; const Data: RawByteString): RawByteString;
var
v: RawByteString;
S: RawByteString;
Ps: Pointer;
I: Integer;
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 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);