program Project1;
{$APPTYPE CONSOLE}
uses SysUtils, Classes, Variants;
type
TStreamWithVariant = class helper for TStream
function ReadVariant: Variant;
procedure WriteVariant(const Value: Variant);
end;
function TStreamWithVariant.ReadVariant: Variant;
function ReadPWideChar: PWideChar;
var
Len: Cardinal;
U: UnicodeString = '';
begin
Len := ReadDWord;
if Len > 0 then
begin
SetLength(U, Len);
ReadBuffer(Pointer(U)^, Len * SizeOf(WideChar));
end;
Result := StringToOleStr(U);
end;
procedure ReadString(var V: TVarData);
begin
V.VString := nil;
string(V.VString) := ReadAnsiString;
end;
var
V: TVarData absolute Result;
begin
VarClear(Result);
V.VType := ReadWord;
if (V.VType and not varTypeMask) <> 0 then // (varByRef or varArray)
Exit; // not supported yet - ignore
case V.VType of
varEmpty, varNull, varUnknown:
{ All done };
varBoolean, varShortInt, varByte:
V.VByte := ReadByte;
varSmallInt, varWord:
V.VWord := ReadWord;
varInteger, varSingle, varError, varLongWord:
V.VLongWord := ReadDWord;
varDouble, varDate, varCurrency, varInt64, varQword{, varWord64, varUint64}:
V.VQword := ReadQWord;
varString:
ReadString(V);
varOleStr:
V.VOleStr := ReadPWideChar;
varDispatch, varAny, varRecord:
{ not Supported - ignore };
else
Assert(True, 'Unknown Variant type');
end;
end;
procedure TStreamWithVariant.WriteVariant(const Value: Variant);
procedure WritePWideChar(P: PWideChar);
var
Len: Cardinal;
begin
Len := Length(P);
WriteDWord(Len);
if Len > 0 then
WriteBuffer(P^, Len * SizeOf(WideChar));
end;
var
V: TVarData absolute Value;
begin
WriteWord(V.VType);
if (V.VType and not varTypeMask) <> 0 then // (varByRef or varArray)
Exit; // not supported yet - ignore
case V.VType of
varEmpty, varNull, varUnknown:
{ All done };
varBoolean, varShortInt, varByte:
WriteByte(V.VByte);
varSmallInt, varWord:
WriteWord(V.VWord);
varInteger, varSingle, varError, varLongWord:
WriteDWord(V.VLongWord);
varDouble, varDate, varCurrency, varInt64, varQword{, varWord64, varUint64}:
WriteQWord(V.VQword);
varString:
WriteAnsiString(string(V.VString));
varOleStr:
WritePWideChar(V.VOleStr);
varDispatch, varAny, varRecord:
{ not Supported - ignore };
else
Assert(True, 'Unknown Variant type');
end;
end;
var
Stream: TMemoryStream;
Data: Variant;
i: Integer;
begin
Data := VarArrayOf(['1111', 22, 3333, 4444444444444, 55.55, PWideChar('6666'), 7e77, Now]);
Stream := TMemoryStream.Create;
try
for i := VarArrayLowBound(Data, 1) to VarArrayHighBound(Data, 1) do
Stream.WriteVariant(Data[i]);
Stream.Position := 0;
for i := VarArrayLowBound(Data, 1) to VarArrayHighBound(Data, 1) do
Writeln(Stream.ReadVariant);
finally
Stream.Free;
end;
Readln;
end.