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.
229 lines
4.6 KiB
Plaintext
229 lines
4.6 KiB
Plaintext
{
|
|
This file is part of R&Q.
|
|
Under same license
|
|
}
|
|
unit uinlistLib;
|
|
{$I RnQConfig.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, Types, ICQContacts;
|
|
|
|
{$I NoRTTI.inc}
|
|
|
|
type
|
|
PuinList = ^TuinList;
|
|
|
|
TuinList = record
|
|
name: string;
|
|
desc: string;
|
|
cl: TRnQCList;
|
|
end;
|
|
|
|
TuinLists = class(Tlist)
|
|
private
|
|
enumidx: integer;
|
|
public
|
|
destructor Destroy; override;
|
|
function exists(const name: string): boolean;
|
|
function idxOf(const name: string): integer;
|
|
function getAt(idx: integer): PuinList;
|
|
function put(const name: string): PuinList;
|
|
function remove(ul: PuinList): boolean; overload;
|
|
procedure fromString(s: RawByteString);
|
|
function toString: RawByteString; reintroduce;
|
|
procedure Clear; override;
|
|
function names: string;
|
|
function get(const name: string): PuinList;
|
|
procedure resetEnumeration;
|
|
function hasMore: boolean;
|
|
function getNext: PuinList;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
SysUtils, utilLib, RQUtil, RDUtils, RnQBinUtils, ICQCommon, ICQSession;
|
|
|
|
function TuinLists.exists(const name: string): boolean;
|
|
begin
|
|
result := idxOf(name) >= 0
|
|
end;
|
|
|
|
function TuinLists.idxOf(const name: string): integer;
|
|
begin
|
|
result := count - 1;
|
|
while (result >= 0) and (compareText(getAt(result).name, name) <> 0) do
|
|
dec(result);
|
|
end; // idxof
|
|
|
|
function TuinLists.getAt(idx: integer): PuinList;
|
|
begin
|
|
result := PuinList(items[idx])
|
|
end;
|
|
|
|
function TuinLists.put(const name: string): PuinList;
|
|
var
|
|
idx: integer;
|
|
begin
|
|
idx := idxOf(name);
|
|
if idx >= 0 then
|
|
begin
|
|
result := getAt(idx);
|
|
exit;
|
|
end;
|
|
new(result);
|
|
result.name := name;
|
|
result.desc := '';
|
|
result.cl := TRnQCList.create;
|
|
add(result);
|
|
end;
|
|
|
|
function TuinLists.remove(ul: PuinList): boolean;
|
|
var
|
|
i: integer;
|
|
begin
|
|
result := FALSE;
|
|
for i := 0 to count - 1 do
|
|
if items[i] = ul then
|
|
begin
|
|
dispose(ul);
|
|
inherited remove(ul);
|
|
result := TRUE;
|
|
exit;
|
|
end;
|
|
end; // remove
|
|
|
|
procedure TuinLists.Clear;
|
|
var
|
|
i: integer;
|
|
begin
|
|
for i := 0 to count - 1 do
|
|
begin
|
|
PuinList(items[i]).cl.Free;
|
|
dispose(PuinList(items[i]));
|
|
end;
|
|
inherited;
|
|
end;
|
|
|
|
destructor TuinLists.Destroy;
|
|
begin
|
|
Clear;
|
|
inherited;
|
|
end; // destroy
|
|
|
|
const
|
|
FK_NAME = 1;
|
|
FK_DESC = 2;
|
|
FK_UIN = 3;
|
|
FK_UID = 4;
|
|
|
|
procedure TuinLists.fromString(s: RawByteString);
|
|
var
|
|
l, t, n: integer;
|
|
u: TUID;
|
|
begin
|
|
Clear;
|
|
while Length(s) >= 8 do
|
|
begin
|
|
l := integer((@s[1])^);
|
|
t := integer((@s[5])^);
|
|
case t of
|
|
FK_NAME:
|
|
put(UnUTF(copy(s, 9, l)));
|
|
FK_DESC:
|
|
PuinList(last)^.desc := UnUTF(copy(s, 9, l));
|
|
FK_UIN:
|
|
begin
|
|
n := integer((@s[9])^);
|
|
// PuinList(last)^.cl.add(contactsDB.get(IntToStr(n)));
|
|
PuinList(last)^.cl.add(TICQSession.ContactsDB.add(IntToStr(n)));
|
|
end;
|
|
FK_UID:
|
|
begin
|
|
{$IFDEF UID_IS_UNICODE}
|
|
U := UnUTF(copy(s,9,l));
|
|
{$else ansi}
|
|
U := copy(s,9,l);
|
|
{$ENDIF UID_IS_UNICODE}
|
|
PuinList(last)^.cl.add(TICQSession.contactsDB.add(u));
|
|
end;
|
|
end;
|
|
system.delete(s, 1, 8 + l);
|
|
end;
|
|
end; // fromstring
|
|
|
|
function TuinLists.toString: RawByteString;
|
|
|
|
procedure writeDown(code: integer; const data: RawByteString);
|
|
begin
|
|
result := result + int2str(length(data)) + int2str(code) + data
|
|
end;
|
|
|
|
var
|
|
i: Integer;
|
|
c: TICQContact;
|
|
begin
|
|
result := '';
|
|
for i := 0 to count - 1 do
|
|
with getAt(i)^ do
|
|
begin
|
|
writeDown(FK_NAME, UTF(name));
|
|
writeDown(FK_DESC, UTF(desc));
|
|
for c in cl do
|
|
if StrToIntDef(c.uid, 0) <> 0 then
|
|
writedown(FK_UIN, Int2Str(StrToIntDef(c.uid, 0)))
|
|
else
|
|
{$IFDEF UID_IS_UNICODE}
|
|
writedown(FK_UID, StrToUTF8(c.UID))
|
|
{$else ansi}
|
|
writedown(FK_UID, c.UID)
|
|
{$ENDIF UID_IS_UNICODE};
|
|
end;
|
|
end; // tostring
|
|
|
|
function TuinLists.names: string;
|
|
var
|
|
i: integer;
|
|
begin
|
|
result := '';
|
|
try
|
|
for i := 0 to count - 1 do
|
|
result := result + getAt(i)^.name + #13;
|
|
if result > '' then
|
|
setLength(result, length(result) - 1);
|
|
except
|
|
result := '';
|
|
end;
|
|
end; // names
|
|
|
|
function TuinLists.get(const name: string): PuinList;
|
|
var
|
|
i: integer;
|
|
begin
|
|
i := idxOf(name);
|
|
if i < 0 then
|
|
result := NIL
|
|
else
|
|
result := getAt(i);
|
|
end; // get
|
|
|
|
procedure TuinLists.resetEnumeration;
|
|
begin
|
|
enumidx := 0
|
|
end;
|
|
|
|
function TuinLists.hasMore: boolean;
|
|
begin
|
|
result := enumidx < count
|
|
end;
|
|
|
|
function TuinLists.getNext: PuinList;
|
|
begin
|
|
result := getAt(enumidx);
|
|
inc(enumidx);
|
|
end; // getNext
|
|
|
|
end.
|