Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I adapt my code for compatibility between TBytes and TIdBytes?

Tags:

delphi

indy10

I am having the same problem as mentioned in "Delphi XE4 Indy compatibility issue between TBytes and TidBytes ", i.e. compatibility issues between TBytes(Delphi RTL) and TIdBytes(Indy) datatypes when compiling with the Delphi XE4. The source of my problem is that the code is not exactly according to Indy's interface and some of functions use TBytes, instead of TIdBytes, when calling native Indy IO procedures.

So I was wondering what will the best fix be?

As I see it there are two approaches:

  1. Refactor all functions in the project to use TIdBytes rather than TBytes.

  2. Implement a TBytesToTidBytes conversion procedure (converts the TBytes to TIdBytes) and call that procedure prior to making the mentioned native Indy calls.

Which of the approaches is better/best? Do you have any other ideas on how I can do that?

FYI: The project I am trying to configure with the XE4 is available online on sourceforge : http://sourceforge.net/projects/indy10clieservr/?source=directory

The suggested conversion procedure should be something like:

procedure TBytesToTIdBytes(const Input:TBytes, var Output: TIdBytes)
var 
    i,L : Integer;
    allocate : Boolean;
begin
    L := Length(Input);
    if(Length(Output) <> L) then 
    begin 
        SetLength(Output,L);
    end;
    if(L > 0) then 
        move(Pointer(Input)^,Pointer(Output)^,L);
end;
like image 944
kenny Avatar asked Sep 17 '13 11:09

kenny


2 Answers

Both types are not the same at implementation level, in newer Delphi versions (TBytes is a simple alias for TArray<Byte> in recent Delphi releases).

So I guess you can use such a procedure:

procedure TBytesToTIdBytes(const Input: TBytes; var Output: TIdBytes);
var L: integer;
begin
  L := Length(Input);
  SetLength(Output,L);
  move(Input[0],Output[0],L);
end;

Here move() is faster than a loop.

like image 25
Arnaud Bouchez Avatar answered Sep 28 '22 08:09

Arnaud Bouchez


TBytes and TIdBytes are both implemented as dynamic arrays, they are simply declared differently. The "politically correct" solution is to make a copy of the bytes. But that can waste memory for large arrays. A simpler solution is to use a typecast so you can utilize the array's internal reference count, eg:

type
  PIdBytes = ^TIdBytes;
var
  B1: TBytes;
  B2: TIdBytes;
begin
  B1 := ...;
  B2 := PIdBytes(@B1)^;
end;

Or simply:

var
  B1: TBytes;
  B2: TIdBytes;
begin
  B1 := ...;
  B2 := TIdBytes(B1);
end;
like image 72
Remy Lebeau Avatar answered Sep 28 '22 09:09

Remy Lebeau