MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey / TokenToVarType

Function TokenToVarType

source/script_com.cpp:851–949  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

849
850
851HRESULT TokenToVarType(ExprTokenType &aToken, VARTYPE aVarType, void *apValue, bool aCallerIsComValue)
852// Copy the value of a given token into a variable of the given VARTYPE.
853{
854 if (aVarType == VT_VARIANT)
855 {
856 VariantClear((VARIANT *)apValue);
857 TokenToVariant(aToken, *(VARIANT *)apValue, FALSE);
858 return S_OK;
859 }
860
861#define U 0 // Unsupported in SAFEARRAY/VARIANT (but vt 15 has no assigned meaning).
862#define P sizeof(void *)
863 // Unfortunately there appears to be no function to get the size of a given VARTYPE,
864 // and VariantCopyInd() copies in the wrong direction. An alternative approach to
865 // the following would be to switch(aVarType) and copy using the appropriate pointer
866 // type, but disassembly shows that approach produces larger code and internally uses
867 // an array of sizes like this anyway:
868 static char vt_size[] = {U,U,2,4,4,8,8,8,P,P,4,2,U,P,U,U,1,1,2,4,8,8,4,4,U,U,U,U,U,U,U,U,U,U,U,U,U,P,P};
869 // Checking aCallerIsComValue has these purposes:
870 // - Let ComValue() accept a raw pointer/integer value for VT_BYREF, VT_ARRAY and
871 // any types not explicitly supported.
872 // - When an integer value is passed by ComValue(), copy all 64 bits.
873 size_t vsize = aCallerIsComValue ? 8 : (aVarType < _countof(vt_size)) ? vt_size[aVarType] : 0;
874 if (!vsize)
875 return DISP_E_BADVARTYPE;
876#undef P
877#undef U
878
879 VARIANT src;
880
881 if (aVarType == VT_BOOL)
882 {
883 // Use AutoHotkey's boolean evaluation rules, but VARIANT_TRUE == -1.
884 *((VARIANT_BOOL*)apValue) = -TokenToBOOL(aToken);
885 return S_OK;
886 }
887
888 if (TypeOfToken(aToken) == SYM_INTEGER)
889 {
890 // This has a few uses:
891 // - Allows pointer types to be initialized by pointer value for ComValue().
892 // - Avoids truncation or loss of precision for large integer values,
893 // since TokenToVariant() only uses the common VT_I4 or VT_R8 types.
894 // - Probably faster.
895 src.vt = VT_I8;
896 src.llVal = TokenToInt64(aToken);
897 switch (aVarType)
898 {
899 case VT_R4:
900 case VT_R8:
901 case VT_DATE: // Date is "double" based.
902 // Doesn't make sense to reinterpret the bits of an integer value as float.
903 break;
904 case VT_CY:
905 // This ensures 42 and 42.0 produce the same value.
906 src.llVal *= 10000;
907 *((CY*)apValue) = src.cyVal;
908 return S_OK;

Callers 3

BIF_DECLFunction · 0.85
InvokeMethod · 0.85
SafeArrayItemMethod · 0.85

Calls 5

TokenToVariantFunction · 0.85
TokenToBOOLFunction · 0.85
TypeOfTokenFunction · 0.85
TokenToInt64Function · 0.85
ReleaseMethod · 0.45

Tested by

no test coverage detected