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.
199 lines
5.1 KiB
Plaintext
199 lines
5.1 KiB
Plaintext
{
|
|
This file is part of R&Q.
|
|
Under same license
|
|
}
|
|
{$I RnQConfig.inc}
|
|
unit ICQflap;
|
|
|
|
interface
|
|
|
|
uses
|
|
sysutils, types, RDGlobal, OverbyteIcsUtils;
|
|
|
|
{$I NoRTTI.inc}
|
|
|
|
const
|
|
|
|
FLAP_HEAD_SIZE = 6;
|
|
SNAC_HEAD_SIZE = 10;
|
|
|
|
type
|
|
TsnacService = word;
|
|
|
|
TflapQueue = class(Tobject)
|
|
buff: RawByteString;
|
|
constructor create;
|
|
procedure add(const s: RawByteString);
|
|
function error: boolean; // errore di protocollo, è necessario invocare popError per continuare
|
|
function errorTill: integer; // fino a questo byte i dati sono considerati errati
|
|
function available: boolean; // disponibilità di un pacchetto
|
|
function pop: RawByteString; // estrale il pacchetto
|
|
function popError: RawByteString; // estrae i dati errati dalla coda
|
|
function bodySize: integer;
|
|
procedure reset;
|
|
end; // TflapQueue
|
|
|
|
// snac/flap/mp
|
|
function getFlapChannel(const s: RawByteString): byte;
|
|
function getSnacService(const s: RawByteString): TsnacService;
|
|
function getSnacRef(const s: RawByteString): dword;
|
|
function getSnacFlags(const s: RawByteString): word;
|
|
function getMPservice(const s: RawByteString): word;
|
|
|
|
// build data
|
|
function SNAC(fam, sub, flags: word; ref: integer): RawByteString; overload;
|
|
function SNAC(fam, sub: word; ref: integer): RawByteString; overload;
|
|
|
|
function SNAC_ver(fam, sub, flags: word; ref: integer; ver: word): RawByteString; overload;
|
|
function SNAC_shortver(fam, sub, flags: word; ref: integer; ver: word): RawByteString; overload;
|
|
|
|
// read data
|
|
function getBUIN2(const s: RawByteString; var ofs: integer): RawByteString;
|
|
function getBUIN(const s: RawByteString; var ofs: integer): integer;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Windows,
|
|
RnQBinUtils, RQUtil;
|
|
|
|
// For ICQ
|
|
function getMPservice(const s: RawByteString): word;
|
|
begin
|
|
result := byte(s[16 + 11]);
|
|
if (result = $DA) or (result = $D0) then
|
|
result := result shl 8 + byte(s[16 + 11 + 4])
|
|
end; // getMPservice
|
|
|
|
function getSnacRef(const s: RawByteString): dword;
|
|
begin
|
|
result := dword_BEat(@s[13])
|
|
end;
|
|
|
|
function getSnacFlags(const s: RawByteString): word;
|
|
begin
|
|
result := word_BEat(@s[11])
|
|
end;
|
|
|
|
function getSnacService(const s: RawByteString): word;
|
|
begin
|
|
result := byte(s[8]) shl 8 + byte(s[10])
|
|
end;
|
|
|
|
function getFlapChannel(const s: RawByteString): byte;
|
|
begin
|
|
result := byte(s[2])
|
|
end;
|
|
|
|
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 SNAC(fam, sub, flags: word; ref: integer): RawByteString; overload;
|
|
begin
|
|
result := word_BEasStr(fam) + word_BEasStr(sub) + word_BEasStr(flags) + dword_BEasStr(ref)
|
|
end;
|
|
|
|
function SNAC(fam, sub: word; ref: integer): RawByteString; overload;
|
|
begin
|
|
result := word_BEasStr(fam) + word_BEasStr(sub) + word_BEasStr(0) + dword_BEasStr(ref)
|
|
end;
|
|
|
|
function SNAC_ver(fam, sub, flags: word; ref: integer; ver: word): RawByteString; overload;
|
|
begin
|
|
result := word_BEasStr(fam) + word_BEasStr(sub) + word_BEasStr(flags or $8000) + dword_BEasStr(ref) +
|
|
Length_BE(TLV(1, word(ver)));
|
|
end;
|
|
|
|
function SNAC_shortver(fam, sub, flags: word; ref: integer; ver: word): RawByteString; overload;
|
|
begin
|
|
result := word_BEasStr(fam) + word_BEasStr(sub) + word_BEasStr(flags) + dword_BEasStr(ref);
|
|
end;
|
|
|
|
/// /////////////////////////// FLAP QUEUE ////////////////////////////
|
|
|
|
constructor TflapQueue.create;
|
|
begin
|
|
reset
|
|
end;
|
|
|
|
procedure TflapQueue.reset;
|
|
begin
|
|
buff := ''
|
|
end;
|
|
|
|
procedure TflapQueue.add(const s: RawByteString);
|
|
begin
|
|
buff := buff + s
|
|
end;
|
|
|
|
function TflapQueue.error: boolean;
|
|
begin
|
|
error := ((buff > '') and (buff[1] <> '*')) or ((length(buff) > 1) and ((buff[2] = #0) or (buff[2] > #5)))
|
|
end; // error
|
|
|
|
function TflapQueue.errorTill: integer;
|
|
begin
|
|
result := -1;
|
|
if buff = '' then
|
|
exit;
|
|
result := 1;
|
|
while (result <= length(buff)) and ((buff[result] <> '*') or (result < length(buff)) and
|
|
((buff[result + 1] = #0) or (buff[result + 1] > #4))) do
|
|
inc(result);
|
|
end; // errorTill
|
|
|
|
function TflapQueue.popError: RawByteString;
|
|
var
|
|
i: integer;
|
|
begin
|
|
i := errorTill;
|
|
result := copy(buff, 1, i);
|
|
delete(buff, 1, i);
|
|
end; // popError
|
|
|
|
function TflapQueue.bodySize: integer;
|
|
begin
|
|
result := word_BEat(@buff[5])
|
|
end;
|
|
|
|
function TflapQueue.available: boolean;
|
|
begin
|
|
result := not error and (length(buff) >= FLAP_HEAD_SIZE) // bodysize exists only if this is true
|
|
and (length(buff) >= FLAP_HEAD_SIZE + bodySize)
|
|
end; // available
|
|
|
|
function TflapQueue.pop: RawByteString;
|
|
var
|
|
i: integer;
|
|
begin
|
|
if not available then
|
|
begin
|
|
result := '';
|
|
exit;
|
|
end;
|
|
i := FLAP_HEAD_SIZE + bodySize;
|
|
result := copy(buff, 1, i);
|
|
delete(buff, 1, i);
|
|
end; // pop
|
|
|
|
end.
|