My server returns a string stream as OleVariant via a COM/DCOM call.
This code works well for the client, but can probably be improved.
Hints are welcome.
And as a follow up, what if the server returns the OleVariant stream as UTF-8,
what is the best way for the client to convert it to unicode ?
procedure TClientToServer.GetText( mode : integer;
const infoText : widestring;
txt : TStrings);
var
size : integer;
dataP : pointer;
data : OleVariant;
strStream : TStringStream;
begin
txt.Clear;
data:= fDComServer.GetData( mode,infoText);
if VarIsNull(data) then Exit;
size:= VarArrayHighBound(data,1) + 1;
dataP:= VarArrayLock( data);
try
strStream:= TStringStream.Create;
try
strStream.Write( dataP^,size);
strStream.Seek(0,0);
txt.LoadFromStream( strStream);
finally
strStream.Free;
end;
finally
VarArrayUnlock( data);
end;
end;
Edit :
Going for UTF8 means that less bandwidth is used on the network, and I can reuse the COM/DCOM routines more or less intact when later implementing a http protocol interface based on UTF8 strings.
Thanks David for pointing me in the right direction to trim the code a little bit.
Here is the updated procedure :
procedure TClientToServer.GetText( mode : integer;
const infoText : widestring;
txt : TStrings);
var
size : integer;
dataP : Pointer;
data : OleVariant;
utf8Str : Utf8String;
begin
txt.Clear;
data:= fDComServer.GetData( mode,infoText);
if VarIsNull(data) then Exit;
size:= VarArrayHighBound(data,1) + 1;
dataP:= VarArrayLock( data);
try
SetString( utf8Str, PAnsiChar(dataP), size);
txt.Text:= utf8Str;
finally
VarArrayUnlock( data);
end;
end;
You don’t really need the string stream. You can just call
SetString()to create a Delphi string containing the contents ofdataPand then assign that string totxt.Text. If you have UTF8 data then pass a UTF8 string toSetString().Using
SetString()still involves an intermediate buffer allocation so I guess what would really be nice would be a read-onlyTStreamdescendant which you could pass a pointer and a size. You could that pass that stream toTStrings.LoadFromStream. It would be easy enough to write such a thing.Do you actually have performance problems though? If not then why change from your current approach.