Reading VARIANT from Stream - Delphi’s Way

In this post I described an efficient way to write a VARIANT to a stream in a binary format.  Doing so will be of no use whatsoever if you cannot bring back a fully-fledged VARIANT from the stream.

Reading a VARIANT is analoguous to writing it, but there is an interesting points.  You have to know how to set properly the type of the output variant.  If the VARIANT is a single value, the right way to do it is to use VarCast function.  If the VARIANT is an array, however, you should create it by using VarArrayCreate.  Only after you set the type, you can assign the data. 

Here comes the code:

 

This entry was posted on Thursday, July 10th, 2008 at 11:40 am and is filed under Delphi, Win32. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

 

11 Responses to “Reading VARIANT from Stream - Delphi’s Way”

  1. HornPoertef Says:

    Very nice!!

  2. Serialização de Variants : Malta on Delphi Says:

    […] tarde encontrei os posts de Nikolay Pavlov - nem acredito que encontrei um parente de Pavlov e ainda um que programa em Delphi! Nikolay estava […]

  3. Alex Says:

    Your blog is interesting!

    Keep up the good work!

  4. Hans Says:

    Thanx, for the sample, Nic. Which unit did you use for IsSimpleType() and GetSimpleTypeSize(0) ?

  5. Nik Says:

    Hans,

    These two functions are mine as well, but I forgot to provide the code for them. They don’t do anything much special, I use them as kind of C macros.

    Here they are.

    function IsSimpleType (VarType: word) : boolean;
    begin
    Result := (VarType and varTypeMask) in
    [varByte, varSmallint, varInteger, varSingle, varDouble, varCurrency, varDate, varError, varBoolean];
    end;

    function GetSimpleTypeSize (VarType: word): integer;
    begin
    case VarType and varTypeMask of
    varSmallint: Result := SizeOf (Smallint);
    varInteger: Result := SizeOf (Integer);
    varSingle: Result := SizeOf (Single);
    varDouble: Result := SizeOf (Double);
    varCurrency: Result := SizeOf (Currency);
    varDate: Result := SizeOf (Double);
    varError: Result := SizeOf (Longint);
    varBoolean: Result := SizeOf (Boolean);
    varByte: Result := SizeOf (Byte);
    else
    Result := -1;
    end;
    end;

  6. Tim Lichtenberg Says:

    the line
    Stream.Seek (0, soFromBeginning);
    is problematic. What if someone writes several variants into the same stream?
    It should be up to the user to set the correct position in the stream.

  7. Nik Says:

    Tim, I agree. Thanks for pointing this out.

    However, my goal was to show how to (de)serialize variants, and such details like position in the stream can be handled by developers themselves. That’s why I won’t edit the code in the post.

  8. Christian Says:

    Very nice code! Thanks for the great work.

    However, when I try to deserialize a TFileStream, Delphi raises the exception EVariantTypeCastError: \’Could not convert variant of type (Empty) into type ($0996)\’. The file stream contains a TClientDataSet (that has been saved to a file).

    How can I solve the problem?

  9. Nik Says:

    Christian, I believe you misunderstood the purpose of the code. The sample above deserializes a variant, serialized by the the appropriate code of another post (see the link in the first sentence).

  10. Christian Says:

    Nik, I’m sorry, I think I’ve got some things wrong in my original question. However, I am using your code (this post and the other one) to transmit stream data via variants. Now I want to do the following: I have a TClientDataset that has been created and saved to a file (by another application). In my code, on the server side, I read this TClientDataset into a file stream. When trying to convert this file stream to a variant to send it to the Client, I get the mentioned EVariantTypeCastError.

  11. KATHRYNBROOKS Says:

    I propose not to wait until you get enough money to buy goods! You should just take the credit loans or just collateral loan and feel fine

Leave a Reply