|
#include "StdAfx.h"
#include ".\variant.h"
// Constructors
CVariant::CVariant()
{
vt = VT_EMPTY;
}
CVariant::CVariant(bool bValue)
{
vt = VT_BOOL;
boolVal = bValue;
}
CVariant::CVariant(int nValue)
{
// Integer overload, set the type and assign the value
vt = VT_I4;
intVal = nValue;
}
CVariant::CVariant(LPCTSTR szValue)
{
// String overload
USES_CONVERSION;
// Validate the input string
ASSERT(szValue);
ASSERT(AfxIsValidString(szValue));
// Set the type and allocate a BSTR
vt = VT_BSTR;
bstrVal = SysAllocString(A2W(szValue));
}
CVariant::CVariant(VARIANT *pV)
{
// Validate the input (and make sure it's writeable)
ASSERT(pV);
ASSERT(AfxIsValidAddress(pV, sizeof(VARIANT), TRUE));
vt = VT_VARIANT;
pvarVal = pV;
}
CVariant::CVariant(int lBound, int iElementCount)
{
// Set the type to an array of variants...
vt = VT_ARRAY | VT_VARIANT;
parray = new SAFEARRAY;
// We only support 1 dimensional arrays..
parray->cDims = 1;
parray->fFeatures = FADF_VARIANT | FADF_HAVEVARTYPE | FADF_FIXEDSIZE | FADF_STATIC;
parray->cbElements = sizeof(VARIANT);
parray->cLocks = 0;
// Allocate the array of variants we point to...
parray->pvData = new VARIANT[iElementCount];
memset(parray->pvData, 0, sizeof(VARIANT) * iElementCount);
parray->rgsabound[0].lLbound = lBound;
parray->rgsabound[0].cElements = iElementCount;
}
// Destructor
CVariant::~CVariant(void)
{
unsigned long i;
switch (vt)
{
case VT_BSTR:
SysFreeString(bstrVal);
break;
case VT_ARRAY | VT_VARIANT:
for (i = 0; i < parray->rgsabound[0].cElements; i++)
if (((VARIANT *) parray->pvData)[i].vt == VT_BSTR)
SysFreeString(((VARIANT *) parray->pvData)[i].bstrVal);
delete parray->pvData;
delete parray;
break;
case VT_VARIANT:
// We do nothing in this case because it's a
// wrapped VARIANT pointer we know little about.
// We certainly don't have enough information to
// safely delete it so we let it's originator
// worry about it
break;
}
}
// Attributes
BOOL CVariant::IsArray(int iElement)
{
VARIANT *pV = ElementAt(iElement);
VARTYPE v;
if (pV != (VARIANT *) NULL)
{
// One level of indirection
if (pV->vt == VT_VARIANT && pV->pvarVal != (VARIANT *) NULL)
v = pV->pvarVal->vt;
else
v = pV->vt;
return v & VT_ARRAY;
}
return FALSE;
}
BOOL CVariant::IsInt(int iElement)
{
VARIANT *pV = ElementAt(iElement);
VARTYPE v;
if (pV != (VARIANT *) NULL)
{
// One level of indirection
if (pV->vt == VT_VARIANT && pV->pvarVal != (VARIANT *) NULL)
v = pV->pvarVal->vt;
else
v = pV->vt;
switch (v)
{
case VT_I1:
case VT_I2:
case VT_I4:
return TRUE;
default:
return FALSE;
}
}
return FALSE;
}
// Private helper function
BOOL CVariant::SingleTypeCheck(VARTYPE vType, int iElement)
{
VARIANT *pV = ElementAt(iElement);
VARTYPE v;
if (pV != (VARIANT *) NULL)
{
// One level of indirection
if (pV->vt == VT_VARIANT && pV->pvarVal != (VARIANT *) NULL)
v = pV->pvarVal->vt;
else
v = pV->vt;
return v == vType;
}
return FALSE;
}
// Array operations
VARIANT *CVariant::ElementAt(int iElement)
{
if (vt == VT_VARIANT)
// It's a pointer to an external VARIANT
// so return that variant
return pvarVal;
if (!(vt & VT_ARRAY))
// It's not an array so return ourselves
return this;
// Calculate our element offset
int offset = iElement - parray->rgsabound[0].lLbound;
// Offset must be zero or greater and less than the bounds
if (offset >= 0 && offset <= int(parray->rgsabound[0].cElements))
return &((VARIANT *) parray->pvData)[offset];
else
return (VARIANT *) NULL;
}
CString CVariant::ToString(int iElement)
{
USES_CONVERSION;
// Get the VARIANT at the iElement offset
VARIANT *v = ElementAt(iElement);
// Must be a valid pointer and must be valid readable memory
if (v != (VARIANT *) NULL && AfxIsValidAddress(v, sizeof(VARIANT), FALSE) && v->vt == VT_BSTR)
return W2A(v->bstrVal);
return _T("");
}
int CVariant::ToInt(int iElement)
{
// Get the VARIANT at the iElement offset
VARIANT *v = ElementAt(iElement);
if (v != (VARIANT *) NULL)
{
// Make sure it's valid readable memory
if (AfxIsValidAddress(v, sizeof(VARIANT), FALSE))
{
// Now switch on the type to ensure we return
// a valid value.
switch (v->vt)
{
case VT_I1:
return (int) v->bVal;
case VT_I2:
return (int) v->iVal;
case VT_I4:
return v->lVal;
}
}
}
return 0;
}
BOOL CVariant::ToBool(int iElement)
{
VARIANT *v = ElementAt(iElement);
if (v->vt == VT_BOOL)
return v->boolVal;
else
return FALSE;
}
void CVariant::Set(LPCTSTR szString, int iElement)
{
USES_CONVERSION;
ASSERT(szString);
ASSERT(AfxIsValidString(szString));
// Get the VARIANT at the iElement offset
VARIANT *v = ElementAt(iElement);
// Make sure it's valid writeable memory
if (v != (VARIANT *) NULL && AfxIsValidAddress(v, sizeof(VARIANT), TRUE))
{
v->vt = VT_BSTR;
v->bstrVal = SysAllocString(A2W(szString));
}
}
void CVariant::Set(int iValue, int iElement)
{
VARIANT *v = ElementAt(iElement);
// Make sure it's valid readable memory
if (v != (VARIANT *) NULL && AfxIsValidAddress(v, sizeof(VARIANT), TRUE))
{
v->vt = VT_I4;
v->lVal = iValue;
}
}
void CVariant::Set(bool bValue, int iElement)
{
VARIANT *v = ElementAt(iElement);
// Make sure it's valid readable memory
if (v != (VARIANT *) NULL && AfxIsValidAddress(v, sizeof(VARIANT), TRUE))
{
v->vt = VT_BOOL;
v->lVal = bValue;
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I've been programming for 35 years - started in machine language on the National Semiconductor SC/MP chip, moved via the 8080 to the Z80 - graduated through HP Rocky Mountain Basic and HPL - then to C and C++ and now C#.
I used (30 or so years ago when I worked for Hewlett Packard) to repair HP Oscilloscopes and Spectrum Analysers - for a while there I was the one repairing DC to daylight SpecAns in the Asia Pacific area.
Afterward I was the fourth team member added to the Australia Post EPOS project at Unisys Australia. We grew to become an A$400 million project. I wrote a few device drivers for the project under Microsoft OS/2 v 1.3 - did hardware qualification and was part of the rollout team dealing directly with the customer.
Born and bred in Melbourne Australia, now living in Scottsdale Arizona USA, became a US Citizen on September 29th, 2006.
I work for a medical insurance broker, learning how to create ASP.NET websites in VB.Net and C#. It's all good.
Oh, I'm also a Kentucky Colonel.
http://www.kycolonels.org