123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665 |
- {
- This file is part of the Free Pascal run time library.
- Copyright (c) 2000,2001 by the Free Pascal development team
- Interface and OS-dependent part of variant support
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- Resourcestring
- SNoWidestrings = 'No widestrings supported';
- SNoInterfaces = 'No interfaces supported';
- Procedure NoWidestrings;
- begin
- Raise Exception.Create(SNoWideStrings);
- end;
- Procedure NoInterfaces;
- begin
- Raise Exception.Create(SNoInterfaces);
- end;
- Procedure VariantTypeMismatch;
- begin
- Raise EVariantError.CreateCode(VAR_TYPEMISMATCH);
- end;
- Function ExceptionToVariantError (E : Exception): HResult;
- begin
- If E is EoutOfMemory then
- Result:=VAR_OUTOFMEMORY
- else
- Result:=VAR_EXCEPTION;
- end;
- { ---------------------------------------------------------------------
- OS-independent functions not present in Windows
- ---------------------------------------------------------------------}
- Function VariantToSmallInt(Const VargSrc : TVarData) : SmallInt;
- var
- l : longint;
- begin
- With VargSrc do
- Case (VType and VarTypeMask) of
- VarSmallInt: Result:=VSmallInt;
- VarShortInt: Result:=VShortInt;
- VarInteger : Result:=VInteger;
- VarSingle : Result:=Round(VSingle);
- VarDouble : Result:=Round(VDouble);
- VarCurrency: Result:=Round(VCurrency);
- VarDate : Result:=Round(VDate);
- VarBoolean : Result:=SmallInt(VBoolean);
- VarByte : Result:=VByte;
- VarWord : Result:=VWord;
- VarLongWord : Result:=VLongWord;
- VarInt64 : Result:=VInt64;
- VarQword : Result:=VQWord;
- VarOleStr :
- begin
- if not(TryStrToInt(WideCharToString(vOleStr),l)) then
- VariantTypeMismatch;
- result:=l;
- end;
- VarString :
- begin
- if not(TryStrToInt(ansistring(vString),l)) then
- VariantTypeMismatch;
- result:=l;
- end;
- else
- VariantTypeMismatch;
- end;
- end;
- Function VariantToShortInt(Const VargSrc : TVarData) : ShortInt;
- var
- l : longint;
- begin
- With VargSrc do
- Case (VType and VarTypeMask) of
- VarSmallInt: Result:=VSmallInt;
- VarShortInt: Result:=VShortInt;
- VarInteger : Result:=VInteger;
- VarSingle : Result:=Round(VSingle);
- VarDouble : Result:=Round(VDouble);
- VarCurrency: Result:=Round(VCurrency);
- VarDate : Result:=Round(VDate);
- VarBoolean : Result:=SmallInt(VBoolean);
- VarByte : Result:=VByte;
- VarWord : Result:=VWord;
- VarLongWord : Result:=VLongWord;
- VarInt64 : Result:=VInt64;
- VarQword : Result:=VQWord;
- VarOleStr :
- begin
- if not(TryStrToInt(WideCharToString(vOleStr),l)) then
- VariantTypeMismatch;
- result:=l;
- end;
- VarString :
- begin
- if not(TryStrToInt(ansistring(vString),l)) then
- VariantTypeMismatch;
- result:=l;
- end;
- else
- VariantTypeMismatch;
- end;
- end;
- Function VariantToLongint(Const VargSrc : TVarData) : Longint;
- begin
- With VargSrc do
- Case (VType and VarTypeMask) of
- VarSmallInt: Result:=VSmallInt;
- VarShortInt: Result:=VShortInt;
- VarInteger : Result:=VInteger;
- VarSingle : Result:=Round(VSingle);
- VarDouble : Result:=Round(VDouble);
- VarCurrency: Result:=Round(VCurrency);
- VarDate : Result:=Round(VDate);
- VarOleStr :
- if not(TryStrToInt(WideCharToString(vOleStr),Result)) then
- VariantTypeMismatch;
- VarString :
- if not(TryStrToInt(ansistring(vString),Result)) then
- VariantTypeMismatch;
- VarBoolean : Result:=Longint(VBoolean);
- VarByte : Result:=VByte;
- VarWord : Result:=VWord;
- VarLongWord : Result:=VLongWord;
- VarInt64 : Result:=VInt64;
- VarQword : Result:=VQWord;
- else
- VariantTypeMismatch;
- end;
- end;
- Function VariantToCardinal(Const VargSrc : TVarData) : Cardinal;
- var
- l : longint;
- begin
- With VargSrc do
- Case (VType and VarTypeMask) of
- VarSmallInt: Result:=VSmallInt;
- VarShortInt: Result:=VShortInt;
- VarInteger : Result:=VInteger;
- VarSingle : Result:=Round(VSingle);
- VarDouble : Result:=Round(VDouble);
- VarCurrency: Result:=Round(VCurrency);
- VarDate : Result:=Round(VDate);
- VarOleStr :
- begin
- if not(TryStrToInt(WideCharToString(vOleStr),l)) then
- VariantTypeMismatch;
- result:=l;
- end;
- VarString :
- begin
- if not(TryStrToInt(ansistring(vString),l)) then
- VariantTypeMismatch;
- result:=l;
- end;
- VarBoolean : Result:=Longint(VBoolean);
- VarByte : Result:=VByte;
- VarWord : Result:=VWord;
- VarLongWord : Result:=VLongWord;
- VarInt64 : Result:=VInt64;
- VarQword : Result:=VQWord;
- else
- VariantTypeMismatch;
- end;
- end;
- Function VariantToSingle(Const VargSrc : TVarData) : Single;
- begin
- With VargSrc do
- Case (VType and VarTypeMask) of
- VarSmallInt: Result:=VSmallInt;
- VarShortInt: Result:=VShortInt;
- VarInteger : Result:=VInteger;
- VarSingle : Result:=VSingle;
- VarDouble : Result:=VDouble;
- VarCurrency: Result:=VCurrency;
- VarDate : Result:=VDate;
- VarOleStr :
- begin
- if not(TryStrToFloat(WideCharToString(vOleStr),Result)) then
- VariantTypeMismatch;
- end;
- VarString :
- begin
- if not(TryStrToFloat(ansistring(vString),Result)) then
- VariantTypeMismatch;
- end;
- VarBoolean : Result:=Longint(VBoolean);
- VarByte : Result:=VByte;
- VarWord : Result:=VWord;
- VarLongWord : Result:=VLongWord;
- VarInt64 : Result:=VInt64;
- VarQword : Result:=VQWord;
- else
- VariantTypeMismatch;
- end;
- end;
- Function VariantToDouble(Const VargSrc : TVarData) : Double;
- begin
- With VargSrc do
- Case (VType and VarTypeMask) of
- VarSmallInt: Result:=VSmallInt;
- VarShortInt: Result:=VShortInt;
- VarInteger : Result:=VInteger;
- VarSingle : Result:=VSingle;
- VarDouble : Result:=VDouble;
- VarCurrency: Result:=VCurrency;
- VarDate : Result:=VDate;
- VarOleStr :
- begin
- if not(TryStrToFloat(WideCharToString(vOleStr),Result)) then
- VariantTypeMismatch;
- end;
- VarString :
- begin
- if not(TryStrToFloat(ansistring(vString),Result)) then
- VariantTypeMismatch;
- end;
- VarBoolean : Result:=Longint(VBoolean);
- VarByte : Result:=VByte;
- VarWord : Result:=VWord;
- VarLongWord : Result:=VLongWord;
- VarInt64 : Result:=VInt64;
- VarQword : Result:=VQWord;
- else
- VariantTypeMismatch;
- end;
- end;
- Function VariantToCurrency(Const VargSrc : TVarData) : Currency;
- begin
- Try
- With VargSrc do
- Case (VType and VarTypeMask) of
- VarSmallInt: Result:=VSmallInt;
- VarShortInt: Result:=VShortInt;
- VarInteger : Result:=VInteger;
- VarSingle : Result:=FloatToCurr(VSingle);
- VarDouble : Result:=FloatToCurr(VDouble);
- VarCurrency: Result:=VCurrency;
- VarDate : Result:=FloatToCurr(VDate);
- VarOleStr :
- if not(TryStrToCurr(WideCharToString(vOleStr),Result)) then
- VariantTypeMismatch;
- VarString :
- if not(TryStrToCurr(ansistring(vString),Result)) then
- VariantTypeMismatch;
- VarBoolean : Result:=Longint(VBoolean);
- VarByte : Result:=VByte;
- VarWord : Result:=VWord;
- VarLongWord : Result:=VLongWord;
- VarInt64 : Result:=VInt64;
- VarQword : Result:=VQWord;
- else
- VariantTypeMismatch;
- end;
- except
- On EConvertError do
- VariantTypeMismatch;
- else
- Raise;
- end;
- end;
- Function VariantToDate(Const VargSrc : TVarData) : TDateTime;
- begin
- Try
- With VargSrc do
- Case (VType and VarTypeMask) of
- VarSmallInt: Result:=FloatToDateTime(VSmallInt);
- VarShortInt: Result:=FloatToDateTime(VShortInt);
- VarInteger : Result:=FloatToDateTime(VInteger);
- VarSingle : Result:=FloatToDateTime(VSingle);
- VarDouble : Result:=FloatToDateTime(VDouble);
- VarCurrency: Result:=FloatToDateTime(VCurrency);
- VarDate : Result:=VDate;
- VarOleStr : NoWideStrings;
- VarBoolean : Result:=FloatToDateTime(Longint(VBoolean));
- VarByte : Result:=FloatToDateTime(VByte);
- VarWord : Result:=FloatToDateTime(VWord);
- VarLongWord : Result:=FloatToDateTime(VLongWord);
- VarInt64 : Result:=FloatToDateTime(VInt64);
- VarQWord : Result:=FloatToDateTime(VQword);
- else
- VariantTypeMismatch;
- end;
- except
- On EConvertError do
- VariantTypeMismatch;
- else
- Raise;
- end;
- end;
- Function VariantToBoolean(Const VargSrc : TVarData) : Boolean;
- begin
- With VargSrc do
- Case (VType and VarTypeMask) of
- VarSmallInt: Result:=VSmallInt<>0;
- VarShortInt: Result:=VShortInt<>0;
- VarInteger : Result:=VInteger<>0;
- VarSingle : Result:=VSingle<>0;
- VarDouble : Result:=VDouble<>0;
- VarCurrency: Result:=VCurrency<>0;
- VarDate : Result:=VDate<>0;
- VarOleStr : NoWideStrings;
- VarBoolean : Result:=VBoolean;
- VarByte : Result:=VByte<>0;
- VarWord : Result:=VWord<>0;
- VarLongWord : Result:=VLongWord<>0;
- VarInt64 : Result:=Vint64<>0;
- VarQword : Result:=VQWord<>0;
- else
- VariantTypeMismatch;
- end;
- end;
- Function VariantToByte(Const VargSrc : TVarData) : Byte;
- var
- l : longint;
- begin
- Try
- With VargSrc do
- Case (VType and VarTypeMask) of
- VarSmallInt: Result:=VSmallInt;
- VarShortInt: Result:=VShortInt;
- VarInteger : Result:=VInteger;
- VarSingle : Result:=Round(VSingle);
- VarDouble : Result:=Round(VDouble);
- VarCurrency: Result:=Round(VCurrency);
- VarDate : Result:=Round(VDate);
- VarBoolean : Result:=Longint(VBoolean);
- VarByte : Result:=VByte;
- VarWord : Result:=VWord;
- VarLongWord : Result:=VLongWord;
- VarInt64 : Result:=Vint64;
- VarQword : Result:=VQWord;
- VarOleStr :
- begin
- if not(TryStrToInt(WideCharToString(vOleStr),l)) then
- VariantTypeMismatch;
- result:=l;
- end;
- VarString :
- begin
- if not(TryStrToInt(ansistring(vString),l)) then
- VariantTypeMismatch;
- result:=l;
- end;
- else
- VariantTypeMismatch;
- end;
- except
- On EConvertError do
- VariantTypeMismatch;
- else
- Raise;
- end;
- end;
- Function VariantToInt64(Const VargSrc : TVarData) : Int64;
- begin
- Try
- With VargSrc do
- Case (VType and VarTypeMask) of
- VarSmallInt: Result:=VSmallInt;
- VarShortInt: Result:=VShortInt;
- VarInteger : Result:=VInteger;
- VarSingle : Result:=Trunc(VSingle);
- VarDouble : Result:=Trunc(VDouble);
- VarCurrency: Result:=Trunc(VCurrency);
- VarDate : Result:=Trunc(VDate);
- VarBoolean : Result:=Longint(VBoolean);
- VarByte : Result:=VByte;
- VarWord : Result:=VWord;
- VarLongWord : Result:=VLongWord;
- VarInt64 : Result:=VInt64;
- VarQword : Result:=VQWord;
- VarOleStr :
- if not(TryStrToInt64(WideCharToString(vOleStr),Result)) then
- VariantTypeMismatch;
- VarString :
- if not(TryStrToInt64(ansistring(vString),Result)) then
- VariantTypeMismatch;
- else
- VariantTypeMismatch;
- end;
- except
- On EConvertError do
- VariantTypeMismatch;
- else
- Raise;
- end;
- end;
- Function VariantToQWord(Const VargSrc : TVarData) : QWord;
- var
- l : int64;
- begin
- Try
- With VargSrc do
- Case (VType and VarTypeMask) of
- VarSmallInt: Result:=VSmallint;
- VarShortInt: Result:=VShortInt;
- VarInteger : Result:=VInteger;
- VarSingle : Result:=Trunc(VSingle);
- VarDouble : Result:=Trunc(VDouble);
- VarCurrency: Result:=Trunc(VCurrency);
- VarDate : Result:=Trunc(VDate);
- VarBoolean : Result:=Longint(VBoolean);
- VarByte : Result:=VByte;
- VarWord : Result:=VWord;
- VarLongWord : Result:=VLongWord;
- VarInt64 : Result:=VInt64;
- VarQword : Result:=VQWord;
- VarOleStr :
- begin
- if not(TryStrToInt64(WideCharToString(vOleStr),l)) then
- VariantTypeMismatch;
- result:=l;
- end;
- VarString :
- begin
- if not(TryStrToInt64(ansistring(vString),l)) then
- VariantTypeMismatch;
- result:=l;
- end;
- else
- VariantTypeMismatch;
- end;
- except
- On EConvertError do
- VariantTypeMismatch;
- else
- Raise;
- end;
- end;
- Function VariantToWideString(Const VargSrc : TVarData) : WideString;
- Const
- BS : Array[Boolean] of WideString = ('False','True');
- begin
- Try
- With VargSrc do
- Case (VType and VarTypeMask) of
- VarSmallInt : Result:=IntTostr(VSmallint);
- VarShortInt : Result:=IntToStr(VShortInt);
- VarInteger : Result:=IntToStr(VInteger);
- VarSingle : Result:=FloatToStr(VSingle);
- VarDouble : Result:=FloatToStr(VDouble);
- VarCurrency : Result:=FloatToStr(VCurrency);
- VarDate : Result:=DateTimeToStr(VDate);
- VarOleStr : Result:=WideString(Pointer(VOleStr));
- VarBoolean : Result:=BS[VBoolean];
- VarByte : Result:=IntToStr(VByte);
- VarWord : Result:=IntToStr(VWord);
- VarLongWord : Result:=IntToStr(VLongWord);
- VarInt64 : Result:=IntToStr(VInt64);
- VarQword : Result:=IntToStr(VQWord);
- else
- VariantTypeMismatch;
- end;
- except
- On EConvertError do
- VariantTypeMismatch;
- else
- Raise;
- end;
- end;
- Function VariantToAnsiString(Const VargSrc : TVarData) : AnsiString;
- Const
- BS : Array[Boolean] of AnsiString = ('False','True');
- begin
- Try
- With VargSrc do
- Case (VType and VarTypeMask) of
- VarSmallInt : Result:=IntTostr(VSmallint);
- VarShortInt : Result:=IntToStr(VShortInt);
- VarInteger : Result:=IntToStr(VInteger);
- VarSingle : Result:=FloatToStr(VSingle);
- VarDouble : Result:=FloatToStr(VDouble);
- VarCurrency : Result:=FloatToStr(VCurrency);
- VarDate : Result:=DateTimeToStr(VDate);
- VarOleStr : Result:=WideCharToString(VOleStr);
- VarBoolean : Result:=BS[VBoolean];
- VarByte : Result:=IntToStr(VByte);
- VarWord : Result:=IntToStr(VWord);
- VarLongWord : Result:=IntToStr(VLongWord);
- VarInt64 : Result:=IntToStr(VInt64);
- VarQword : Result:=IntToStr(VQWord);
- VarString : Result:=ansistring(VString);
- else
- VariantTypeMismatch;
- end;
- except
- On EConvertError do
- VariantTypeMismatch;
- else
- Raise;
- end;
- end;
- Function VariantToShortString(Const VargSrc : TVarData) : ShortString;
- Var
- S : AnsiString;
- begin
- S:=VariantToAnsiString(VArgSrc);
- Result:=S;
- end;
- { ---------------------------------------------------------------------
- Some debug routines
- ---------------------------------------------------------------------}
- Procedure DumpVariant(Const VArgSrc : TVarData);
- begin
- DumpVariant(Output,VArgSrc);
- end;
- (*
- tvardata = packed record
- vtype : tvartype;
- case integer of
- 0:(res1 : word;
- case integer of
- 0:
- (res2,res3 : word;
- case word of
- varsmallint : (vsmallint : smallint);
- varinteger : (vinteger : longint);
- varsingle : (vsingle : single);
- vardouble : (vdouble : double);
- varcurrency : (vcurrency : currency);
- vardate : (vdate : tdatetime);
- varolestr : (volestr : pwidechar);
- vardispatch : (vdispatch : pointer);
- varerror : (verror : dword);
- varboolean : (vboolean : wordbool);
- varunknown : (vunknown : pointer);
- // vardecimal : ( : );
- varshortint : (vshortint : shortint);
- varbyte : (vbyte : byte);
- varword : (vword : word);
- varlongword : (vlongword : dword);
- varint64 : (vint64 : int64);
- varqword : (vqword : qword);
- varword64 : (vword64 : qword);
- varstring : (vstring : pointer);
- varany : (vany : pointer);
- vararray : (varray : pvararray);
- varbyref : (vpointer : pointer);
- );
- 1:
- (vlongs : array[0..2] of longint);
- );
- 1:(vwords : array[0..6] of word);
- 2:(vbytes : array[0..13] of byte);
- end;
- *)
- Const
- VarTypeStrings : Array [varEmpty..varqword] of string = (
- 'empty', 'null', 'smallint', 'integer', 'single', 'double',
- 'currency', 'date', 'olestr', 'dispatch', 'error', 'boolean',
- 'variant', 'unknown', 'unknown','decimal', 'shortint', 'byte', 'word',
- 'longword', 'int64', 'qword');
- Procedure DumpVariant(Var F : Text; Const VArgSrc : TVarData);
- Var
- W : WideString;
- begin
- If VArgSrc.vType in [varEmpty..varqword] then
- Writeln(F,'Variant has type : ',VarTypeStrings[VArgSrc.vType])
- else if (VArgSrc.vType=VarArray) Then
- begin
- Write(F,'Variant is array.');
- exit;
- end
- else if (VargSrc.vType=VarByRef) then
- begin
- Writeln(F,'Variant is by reference.');
- exit;
- end
- else
- begin
- Writeln(F,'Variant has unknown type: ', VargSrc.vType);
- Exit;
- end;
- If VArgSrc.vType<>varEmpty then
- With VArgSrc do
- begin
- Write(F,'Value is: ') ;
- Case vtype of
- varnull : Write(F,'Null');
- varsmallint : Write(F,vsmallint);
- varinteger : Write(F,vinteger);
- varsingle : Write(F,vsingle);
- vardouble : Write(F,vdouble);
- varcurrency : Write(F,vcurrency) ;
- vardate : Write(F,vdate) ;
- varolestr : begin
- W:=vOleStr;
- Write(F,W) ;
- end;
- vardispatch : Write(F,'Not suppordted') ;
- varerror : Write(F,'Error') ;
- varboolean : Write(F,vboolean) ;
- varvariant : Write(F,'Unsupported') ;
- varunknown : Write(F,'Unsupported') ;
- vardecimal : Write(F,'Unsupported') ;
- varshortint : Write(F,vshortint) ;
- varbyte : Write(F,vbyte) ;
- varword : Write(F,vword) ;
- varlongword : Write(F,vlongword) ;
- varint64 : Write(F,vint64) ;
- varqword : Write(F,vqword) ;
- end;
- Writeln(f);
- end;
- end;
|