123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 |
- {
- $Id$
- This file is part of the Free Pascal run time library.
- Copyright (c) 1999-2000 by the Free Pascal development team
- Interface and OS-independent 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.
- **********************************************************************}
- {$MODE ObjFPC}
- Unit varutils;
- Interface
- Uses sysutils;
- Type
- // Types needed to make this work. These should be moved to the system unit.
-
- currency = int64;
- HRESULT = Longint;
- PSmallInt = ^Smallint;
- PLongint = ^Longint;
- PSingle = ^Single;
- PDouble = ^Double;
- PCurrency = ^Currency;
- TDateTime = Double;
- PDate = ^TDateTime;
- PPWideChar = ^PWideChar;
- Error = Longint;
- PError = ^Error;
- PWordBool = ^WordBool;
- PByte = ^Byte;
-
- EVarianterror = Class(Exception)
- ErrCode : longint;
- Constructor CreateCode(Code : Longint);
- end;
-
- TVarArrayBound = packed record
- ElementCount: Longint;
- LowBound: Longint;
- end;
- TVarArrayBoundArray = Array [0..0] of TVarArrayBound;
- PVarArrayBoundArray = ^TVarArrayBoundArray;
- TVarArrayCoorArray = Array [0..0] of Longint;
- PVarArrayCoorArray = ^TVarArrayCoorArray;
- PVarArray = ^TVarArray;
- TVarArray = packed record
- DimCount: Word;
- Flags: Word;
- ElementSize: Longint;
- LockCount: Integer;
- Data: Pointer;
- Bounds: TVarArrayBoundArray;
- end;
-
- TVarType = Word;
- PVarData = ^TVarData;
- TVarData = packed record
- VType: TVarType;
- case Integer of
- 0: (Reserved1: Word;
- case Integer of
- 0: (Reserved2, Reserved3: Word;
- case Integer of
- varSmallInt: (VSmallInt: SmallInt);
- varInteger: (VInteger: Longint);
- varSingle: (VSingle: Single);
- varDouble: (VDouble: Double);
- varCurrency: (VCurrency: Currency);
- varDate: (VDate: Double);
- varOleStr: (VOleStr: PWideChar);
- varDispatch: (VDispatch: Pointer);
- varError: (VError: LongWord);
- varBoolean: (VBoolean: WordBool);
- varUnknown: (VUnknown: Pointer);
- varByte: (VByte: Byte);
- varString: (VString: Pointer);
- varAny: (VAny: Pointer);
- varArray: (VArray: PVarArray);
- varByRef: (VPointer: Pointer);
- );
- 1: (VLongs: array[0..2] of LongInt);
- );
- 2: (VWords: array [0..6] of Word);
- 3: (VBytes: array [0..13] of Byte);
- end;
- Variant = TVarData;
- PVariant = ^Variant;
- { Variant functions }
- function VariantChangeTypeEx(var VargDest: TVarData; const VargSrc: TVarData; LCID: Integer; Flags: Word; VarType: Word): HRESULT; stdcall;
- function VariantClear(var Varg: TVarData): HRESULT; stdcall;
- function VariantCopy(var VargDest: TVarData; const VargSrc: TVarData): HRESULT; stdcall;
- function VariantCopyInd(var VargDest: TVarData; const VargSrc: TVarData): HRESULT; stdcall;
- function VariantInit(var Varg: TVarData): HRESULT; stdcall;
- { Variant array functions }
- function SafeArrayAccessData(psa: PVarArray; var ppvdata: Pointer): HRESULT; stdcall;
- function SafeArrayAllocData(psa: PVarArray): HRESULT; stdcall;
- function SafeArrayAllocDescriptor(DimCount: Integer; var psa: PVarArray): HRESULT; stdcall;
- function SafeArrayCopy(psa: PVarArray; var psaout: PVarArray): HRESULT; stdcall;
- function SafeArrayCopyData(psa, psaOut: PVarArray): HRESULT; stdcall;
- function SafeArrayCreate(VarType, Dim: Integer; const Bounds: TVarArrayBoundArray): PVarArray; stdcall;
- function SafeArrayDestroy(psa: PVarArray): HRESULT; stdcall;
- function SafeArrayDestroyData(psa: PVarArray): HRESULT; stdcall;
- function SafeArrayDestroyDescriptor(psa: PVarArray): HRESULT; stdcall;
- function SafeArrayGetDim(psa: PVarArray): Integer; stdcall;
- function SafeArrayGetElemSize(psa: PVarArray): LongWord; stdcall;
- function SafeArrayGetElement(psa: PVarArray; Indices: PVarArrayCoorArray; Data: Pointer): HRESULT; stdcall;
- function SafeArrayGetLBound(psa: PVarArray; Dim: Integer; var LBound: Integer): HRESULT; stdcall;
- function SafeArrayGetUBound(psa: PVarArray; Dim: Integer; var UBound: Integer): HRESULT; stdcall;
- function SafeArrayLock(psa: PVarArray): HRESULT; stdcall;
- function SafeArrayPtrOfIndex(psa: PVarArray; Indices: PVarArrayCoorArray; var Address: Pointer): HRESULT; stdcall;
- function SafeArrayPutElement(psa: PVarArray; Indices: PVarArrayCoorArray; const Data: Pointer): HRESULT; stdcall;
- function SafeArrayRedim(psa: PVarArray; const NewBound: TVarArrayBound): HRESULT; stdcall;
- function SafeArrayUnaccessData(psa: PVarArray): HRESULT; stdcall;
- function SafeArrayUnlock(psa: PVarArray): HRESULT; stdcall;
- { Conversion routines NOT in windows oleaut }
- Function VariantToSmallInt(Const VargSrc : TVarData) : SmallInt;
- Function VariantToLongint(Const VargSrc : TVarData) : Longint;
- Function VariantToSingle(Const VargSrc : TVarData) : Single;
- Function VariantToDouble(Const VargSrc : TVarData) : Double;
- Function VariantToCurrency(Const VargSrc : TVarData) : Currency;
- Function VariantToDate(Const VargSrc : TVarData) : TDateTime;
- Function VariantToBoolean(Const VargSrc : TVarData) : Boolean;
- Function VariantToByte(Const VargSrc : TVarData) : Byte;
- // Names match the ones in Borland varutils unit.
- const
- VAR_OK = HRESULT($00000000);
- VAR_TYPEMISMATCH = HRESULT($80020005);
- VAR_BADVARTYPE = HRESULT($80020008);
- VAR_EXCEPTION = HRESULT($80020009);
- VAR_OVERFLOW = HRESULT($8002000A);
- VAR_BADINDEX = HRESULT($8002000B);
- VAR_ARRAYISLOCKED = HRESULT($8002000D);
- VAR_NOTIMPL = HRESULT($80004001);
- VAR_OUTOFMEMORY = HRESULT($8007000E);
- VAR_INVALIDARG = HRESULT($80070057);
- VAR_UNEXPECTED = HRESULT($8000FFFF);
- ARR_NONE = $0000;
- ARR_FIXEDSIZE = $0010;
- ARR_OLESTR = $0100;
- ARR_UNKNOWN = $0200;
- ARR_DISPATCH = $0400;
- ARR_VARIANT = $0800;
- Implementation
- 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;
- Constructor EVariantError.CreateCode (Code : longint);
- begin
- ErrCode:=Code;
- 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;
- {$i varutils.inc}
- { ---------------------------------------------------------------------
- OS-independent functions not present in Windows
- ---------------------------------------------------------------------}
-
- Function VariantToSmallInt(Const VargSrc : TVarData) : SmallInt;
- begin
- With VargSrc do
- Case (VType and VarTypeMask) of
- VarSmallInt: Result:=VSmallInt;
- VarInteger : Result:=VInteger;
- VarSingle : Result:=Round(VSingle);
- VarDouble : Result:=Round(VDouble);
- VarCurrency: Result:=Round(VCurrency);
- VarDate : Result:=Round(VDate);
- VarOleStr : NoWideStrings;
- VarBoolean : Result:=SmallInt(VBoolean);
- VarByte : Result:=VByte;
- else
- VariantTypeMismatch;
- end;
- end;
- Function VariantToLongint(Const VargSrc : TVarData) : Longint;
- begin
- With VargSrc do
- Case (VType and VarTypeMask) of
- VarSmallInt: Result:=VSmallInt;
- VarInteger : Result:=VInteger;
- VarSingle : Result:=Round(VSingle);
- VarDouble : Result:=Round(VDouble);
- VarCurrency: Result:=Round(VCurrency);
- VarDate : Result:=Round(VDate);
- VarOleStr : NoWideStrings;
- VarBoolean : Result:=Longint(VBoolean);
- VarByte : Result:=VByte;
- else
- VariantTypeMismatch;
- end;
- end;
- Function VariantToSingle(Const VargSrc : TVarData) : Single;
- begin
- With VargSrc do
- Case (VType and VarTypeMask) of
- VarSmallInt: Result:=VSmallInt;
- VarInteger : Result:=VInteger;
- VarSingle : Result:=VSingle;
- VarDouble : Result:=VDouble;
- VarCurrency: Result:=VCurrency;
- VarDate : Result:=VDate;
- VarOleStr : NoWideStrings;
- VarBoolean : Result:=Longint(VBoolean);
- VarByte : Result:=VByte;
- else
- VariantTypeMismatch;
- end;
- end;
- Function VariantToDouble(Const VargSrc : TVarData) : Double;
- begin
- With VargSrc do
- Case (VType and VarTypeMask) of
- VarSmallInt: Result:=VSmallInt;
- VarInteger : Result:=VInteger;
- VarSingle : Result:=VSingle;
- VarDouble : Result:=VDouble;
- VarCurrency: Result:=VCurrency;
- VarDate : Result:=VDate;
- VarOleStr : NoWideStrings;
- VarBoolean : Result:=Longint(VBoolean);
- VarByte : Result:=VByte;
- else
- VariantTypeMismatch;
- end;
- end;
- Function VariantToCurrency(Const VargSrc : TVarData) : Currency;
- begin
- Try
- With VargSrc do
- Case (VType and VarTypeMask) of
- VarSmallInt: Result:=VSmallInt;
- VarInteger : Result:=VInteger;
- VarSingle : Result:=FloatToCurr(VSingle);
- VarDouble : Result:=FloatToCurr(VDouble);
- VarCurrency: Result:=VCurrency;
- VarDate : Result:=FloatToCurr(VDate);
- VarOleStr : NoWideStrings;
- VarBoolean : Result:=Longint(VBoolean);
- VarByte : Result:=VByte;
- 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);
- 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);
- 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;
- 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;
- else
- VariantTypeMismatch;
- end;
- end;
- Function VariantToByte(Const VargSrc : TVarData) : Byte;
- begin
- Try
- With VargSrc do
- Case (VType and VarTypeMask) of
- VarSmallInt: Result:=VSmallInt;
- VarInteger : Result:=VInteger;
- VarSingle : Result:=Round(VSingle);
- VarDouble : Result:=Round(VDouble);
- VarCurrency: Result:=Round(VCurrency);
- VarDate : Result:=Round(VDate);
- VarOleStr : NoWideStrings;
- VarBoolean : Result:=Longint(VBoolean);
- VarByte : Result:=VByte;
- else
- VariantTypeMismatch;
- end;
- except
- On EConvertError do
- VariantTypeMismatch;
- else
- Raise;
- end;
- end;
- end.
|