Removing elements from an array of records containing string fields?
Check the example below... I have an array TSrvClientList.Items
with record elements. These elements have string fields. When I remove an element, I need to move the following ones in that empty space left. I don't like to copy field by field... And I thought I'd use the Move
function to do it faster, but I'm not sure if this is a proper way to do it. If the record contained only unmanaged types, I'm sure it's OK, I uesed many times. But with those strings, I don't know... Should I call a Finalize
first ? Or do it differently ? My test code seems it works as it is, directly moving those strings, but I'd like to make sure it's not just a coincidence.
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, SynCommons, System.SyncObjs,
Vcl.StdCtrls;
type
TSrvClientInfo = record
ClientIP: String;
ClientGUID: Cardinal;
AESKey: THash256;
TransCons: Integer;
end;
TSrvClientList = record
private
Valid: DWord;
public
Items: array of TSrvClientInfo;
procedure Init;
procedure Free;
procedure AddClient(const IP: String; GUID: Cardinal; AESKey: THash256);
procedure RemoveClient(const IP: String; GUID: Cardinal);
end;
TForm1 = class(TForm)
BAddItem: TButton;
BRemoveItem: TButton;
procedure FormCreate(Sender: TObject);
procedure BAddItemClick(Sender: TObject);
procedure BRemoveItemClick(Sender: TObject);
public
Code: Byte;
Clients: TSrvClientList;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//===== TSrvClientList =======================================================
procedure TSrvClientList.Init;
begin
if Valid <> $12344321 then begin
Valid:= $12344321;
SetLength(Items, 0);
end;
end;
procedure TSrvClientList.Free;
begin
if Valid = $12344321 then begin
SetLength(Items, 0);
Valid:= 0;
end;
end;
procedure TSrvClientList.AddClient(const IP: String; GUID: Cardinal; AESKey: THash256);
var I: Integer;
begin
if Valid <> $12344321 then Exit;
I:= Length(Items); SetLength(Items, I+1);
Items[I].ClientIP:= IP;
Items[I].ClientGUID:= GUID;
Items[I].AESKey:= AESKey;
Items[I].TransCons:= 0;
end;
procedure TSrvClientList.RemoveClient(const IP: String; GUID: Cardinal);
var I, R: Integer;
begin
if Valid <> $12344321 then Exit;
I:= 0; while (I < Length(Items)) and ((Items[I].ClientIP <> IP) or (Items[I].ClientGUID <> GUID)) do Inc(I);
if (I > High(Items)) then Exit;
R:= High(Items) - I;
if R > 0 then Move(Items[I+1], Items[I], SizeOf(TSrvClientInfo) * R);
SetLength(Items, Length(Items)-1);
end;
// ----------------------------------------------------
procedure TForm1.FormCreate(Sender: TObject);
begin
Clients.Init;
Code:= 1;
end;
procedure TForm1.BAddItemClick(Sender: TObject);
var IP: String;
GUID: Cardinal;
AESKey: THash256;
begin
IP:= '192.168.0.3';
GUID:= $12345678;
FillChar(AESKey[0], 32, 0); AESKey[0]:= Code; Inc(Code);
Clients.AddClient(IP, GUID, AESKey);
Caption:= IntToStr(Length(Clients.Items));
end;
procedure TForm1.BRemoveItemClick(Sender: TObject);
var IP: String;
GUID: Cardinal;
begin
IP:= '192.168.0.3';
GUID:= $12345678;
Clients.RemoveClient(IP, GUID);
Caption:= IntToStr(Length(Clients.Items));
end;
end.
from Recent Questions - Stack Overflow https://ift.tt/2ZWS1ZS
https://ift.tt/eA8V8J
Comments
Post a Comment