Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting TMemoryStream to 'String' in Delphi 2009

We had the following code prior to Delphi 2009:

function MemoryStreamToString(M : TMemoryStream): String; var     NewCapacity: Longint; begin     if (M.Size = > 0) or (M.Memory = nil) then        Result:= ''      else     begin        if TMemoryStreamProtected(M).Capacity = M.Size then        begin            NewCapacity:= M.Size+1;            TMemoryStreamProtected(M).Realloc(NewCapacity);        end;        NullString(M.Memory^)[M.Size]:= #0;        Result:= StrPas(M.Memory);     end; end; 

How might we convert this code to support Unicode now with Delphi 2009?

like image 211
dmillam Avatar asked Apr 09 '09 03:04

dmillam


2 Answers

The code you have is unnecessarily complex, even for older Delphi versions. Why should fetching the string version of a stream force the stream's memory to be reallocated, after all?

function MemoryStreamToString(M: TMemoryStream): string; begin   SetString(Result, PChar(M.Memory), M.Size div SizeOf(Char)); end; 

That works in all Delphi versions, not just Delphi 2009. It works when the stream is empty without any special case. SetString is an under-appreciated function.

If the contents of your stream aren't changing to Unicode with your switch to Delphi 2009, then you should use this function instead:

function MemoryStreamToString(M: TMemoryStream): AnsiString; begin   SetString(Result, PAnsiChar(M.Memory), M.Size); end; 

That's equivalent to your original code, but skips the special cases.

like image 176
Rob Kennedy Avatar answered Sep 22 '22 17:09

Rob Kennedy


Or perhaps you can refactor your code to use directly a TStringStream directly? You can use it instead of TMemoryStream (they have the same interface) and you can 'convert' it to a string by simply calling myString := myStringStream.DataString;

like image 30
John Thomas Avatar answered Sep 20 '22 17:09

John Thomas