Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting TMemoryStream to variant

How do I convert contents of a TMemoryStream to a variant? I use Delphi 2010.

TMemoryStream stores contents of a file, it can be PDF or JPG (scanned document).

File is being kept inside MS SQL base. When I go to editing mode in my program, I extract contents of that file from base into a TMemoryStream.

After editing document's card, I need to post document back to base. Scanned file could be changed also (or replaced with some other file). To post record back, I use a stored procedure with a bunch of parameters - one for every field. I pass parameters to stored procedure as variants.

That's why I need to convert TMemoryStream to a variant.

like image 283
Vasiliy Volkov Avatar asked Dec 09 '22 18:12

Vasiliy Volkov


2 Answers

Assuming you need the Variant to hold an array of bytes, you can use this:

var
  MS: TMemoryStream;
  V: Variant;
  P: Pointer;
begin
  ...
  V := VarArrayCreate([0, MS.Size-1], varByte);
  if MS.Size > 0 then
  begin
    P := VarArrayLock(V);
    Move(MS.Memory^, P^, MS.Size);
    VarArrayUnlock(V);
  end;
  ...
end;
like image 161
Remy Lebeau Avatar answered Dec 31 '22 02:12

Remy Lebeau


TMemoryStream doesn't have a convenient way to get direct access to the internal data. It provides a property that gives you a pointer, but not any useful data type. However, if you use TBytesStream, which derives from TMemoryStream, you can get the data from the stream as a variable of type TBytes.

After this, assuming your parameter is a standard parameter object of type TParam, you don't need to use a variant. You can do it like this:

param.AsBlob := MyTBytesVariable;

Or, even simpler than that, you can use the stream directly:

param.AsStream := MyMemoryStream;

(If you do this, make sure that the stream's Position is set to 0 first.)

like image 41
Mason Wheeler Avatar answered Dec 31 '22 04:12

Mason Wheeler