Source code of Windows XP (NT5)
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
//+-------------------------------------------------------------------------
//
// File: dvariant.h
//
// Contents: dvariant
//
// History: Sep-09-99 Davepl Like dvariant, but with type operators
//
//--------------------------------------------------------------------------
#ifndef __DVARIANT_H__
#define __DVARIANT_H__
#include "dexception.h"
class dvariant : public tagVARIANT { // Constructors
public: dvariant() { vt = VT_EMPTY; } ~dvariant() { Clear(); }
dvariant(const VARIANT& varSrc) { vt = VT_EMPTY; InternalCopy(&varSrc); }
dvariant(const dvariant& varSrc) { vt = VT_EMPTY; InternalCopy(&varSrc); }
dvariant(BSTR bstrSrc) { vt = VT_EMPTY; *this = bstrSrc; } dvariant(LPCOLESTR lpszSrc) { vt = VT_EMPTY; *this = lpszSrc; }
#ifndef OLE2ANSI
dvariant(LPCSTR lpszSrc) { vt = VT_EMPTY; *this = lpszSrc; } #endif
dvariant(bool bSrc) { vt = VT_BOOL; #pragma warning(disable: 4310) // cast truncates constant value
boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE; #pragma warning(default: 4310) // cast truncates constant value
}
dvariant(int nSrc) { vt = VT_I4; lVal = nSrc; } dvariant(BYTE nSrc) { vt = VT_UI1; bVal = nSrc; } dvariant(short nSrc) { vt = VT_I2; iVal = nSrc; } dvariant(long nSrc, VARTYPE vtSrc = VT_I4) { ATLASSERT(vtSrc == VT_I4 || vtSrc == VT_ERROR); vt = vtSrc; lVal = nSrc; } dvariant(float fltSrc) { vt = VT_R4; fltVal = fltSrc; } dvariant(double dblSrc) { vt = VT_R8; dblVal = dblSrc; } dvariant(CY cySrc) { vt = VT_CY; cyVal.Hi = cySrc.Hi; cyVal.Lo = cySrc.Lo; } dvariant(IDispatch* pSrc) { vt = VT_DISPATCH; pdispVal = pSrc; // Need to AddRef as VariantClear will Release
if (pdispVal != NULL) pdispVal->AddRef(); } dvariant(IUnknown* pSrc) { vt = VT_UNKNOWN; punkVal = pSrc; // Need to AddRef as VariantClear will Release
if (punkVal != NULL) punkVal->AddRef(); }
// Assignment Operators
public: dvariant& operator=(const dvariant& varSrc) { InternalCopy(&varSrc); return *this; } dvariant& operator=(const VARIANT& varSrc) { InternalCopy(&varSrc); return *this; }
dvariant& operator=(BSTR bstrSrc) { InternalClear(); vt = VT_BSTR; bstrVal = ::SysAllocString(bstrSrc); if (bstrVal == NULL && bstrSrc != NULL) { vt = VT_ERROR; scode = E_OUTOFMEMORY; } return *this; }
dvariant& operator=(LPCOLESTR lpszSrc) { InternalClear(); vt = VT_BSTR; bstrVal = ::SysAllocString(lpszSrc);
if (bstrVal == NULL && lpszSrc != NULL) { vt = VT_ERROR; scode = E_OUTOFMEMORY; } return *this; }
#ifndef OLE2ANSI
dvariant& operator=(LPCSTR lpszSrc) { USES_CONVERSION; InternalClear(); vt = VT_BSTR; bstrVal = ::SysAllocString(A2COLE(lpszSrc));
if (bstrVal == NULL && lpszSrc != NULL) { vt = VT_ERROR; scode = E_OUTOFMEMORY; } return *this; } #endif
dvariant& operator=(bool bSrc) { if (vt != VT_BOOL) { InternalClear(); vt = VT_BOOL; } #pragma warning(disable: 4310) // cast truncates constant value
boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE; #pragma warning(default: 4310) // cast truncates constant value
return *this; }
dvariant& operator=(int nSrc) { if (vt != VT_I4) { InternalClear(); vt = VT_I4; } lVal = nSrc;
return *this; }
dvariant& operator=(BYTE nSrc) { if (vt != VT_UI1) { InternalClear(); vt = VT_UI1; } bVal = nSrc; return *this; }
dvariant& operator=(short nSrc) { if (vt != VT_I2) { InternalClear(); vt = VT_I2; } iVal = nSrc; return *this; }
dvariant& operator=(long nSrc) { if (vt != VT_I4) { InternalClear(); vt = VT_I4; } lVal = nSrc; return *this; }
dvariant& operator=(float fltSrc) { if (vt != VT_R4) { InternalClear(); vt = VT_R4; } fltVal = fltSrc; return *this; }
dvariant& operator=(double dblSrc) { if (vt != VT_R8) { InternalClear(); vt = VT_R8; } dblVal = dblSrc; return *this; }
dvariant& operator=(CY cySrc) { if (vt != VT_CY) { InternalClear(); vt = VT_CY; } cyVal.Hi = cySrc.Hi; cyVal.Lo = cySrc.Lo; return *this; }
dvariant& operator=(IDispatch* pSrc) { InternalClear(); vt = VT_DISPATCH; pdispVal = pSrc; // Need to AddRef as VariantClear will Release
if (pdispVal != NULL) pdispVal->AddRef(); return *this; }
dvariant& operator=(IUnknown* pSrc) { InternalClear(); vt = VT_UNKNOWN; punkVal = pSrc;
// Need to AddRef as VariantClear will Release
if (punkVal != NULL) punkVal->AddRef(); return *this; }
// Comparison Operators
public: bool operator==(const VARIANT& varSrc) const { if (this == &varSrc) return true;
// Variants not equal if types don't match
if (vt != varSrc.vt) return false;
// Check type specific values
switch (vt) { case VT_EMPTY: case VT_NULL: return true;
case VT_BOOL: return boolVal == varSrc.boolVal;
case VT_UI1: return bVal == varSrc.bVal;
case VT_I2: return iVal == varSrc.iVal;
case VT_I4: return lVal == varSrc.lVal;
case VT_R4: return fltVal == varSrc.fltVal;
case VT_R8: return dblVal == varSrc.dblVal;
case VT_BSTR: return (::SysStringByteLen(bstrVal) == ::SysStringByteLen(varSrc.bstrVal)) && (::memcmp(bstrVal, varSrc.bstrVal, ::SysStringByteLen(bstrVal)) == 0);
case VT_ERROR: return scode == varSrc.scode;
case VT_DISPATCH: return pdispVal == varSrc.pdispVal;
case VT_UNKNOWN: return punkVal == varSrc.punkVal;
default: ATLASSERT(false); // fall through
}
return false; } bool operator!=(const VARIANT& varSrc) const {return !operator==(varSrc);} bool operator<(const VARIANT& varSrc) const {return VarCmp((VARIANT*)this, (VARIANT*)&varSrc, LOCALE_USER_DEFAULT)==VARCMP_LT;} bool operator>(const VARIANT& varSrc) const {return VarCmp((VARIANT*)this, (VARIANT*)&varSrc, LOCALE_USER_DEFAULT)==VARCMP_GT;}
// Operations
public: HRESULT Clear() { return ::VariantClear(this); } HRESULT Copy(const VARIANT* pSrc) { return ::VariantCopy(this, const_cast<VARIANT*>(pSrc)); } HRESULT Attach(VARIANT* pSrc) { // Clear out the variant
HRESULT hr = Clear(); if (!FAILED(hr)) { // Copy the contents and give control to dvariant
memcpy(this, pSrc, sizeof(VARIANT)); pSrc->vt = VT_EMPTY; hr = S_OK; } return hr; }
HRESULT Detach(VARIANT* pDest) { // Clear out the variant
HRESULT hr = ::VariantClear(pDest); if (!FAILED(hr)) { // Copy the contents and remove control from dvariant
memcpy(pDest, this, sizeof(VARIANT)); vt = VT_EMPTY; hr = S_OK; } return hr; }
HRESULT ChangeType(VARTYPE vtNew, const VARIANT* pSrc = NULL) { VARIANT* pVar = const_cast<VARIANT*>(pSrc); // Convert in place if pSrc is NULL
if (pVar == NULL) pVar = this; // Do nothing if doing in place convert and vts not different
return ::VariantChangeType(this, pVar, 0, vtNew); }
HRESULT WriteToStream(IStream* pStream); HRESULT ReadFromStream(IStream* pStream);
// Implementation
public: HRESULT InternalClear() { HRESULT hr = Clear(); ATLASSERT(SUCCEEDED(hr)); if (FAILED(hr)) { vt = VT_ERROR; scode = hr; } return hr; }
void InternalCopy(const VARIANT* pSrc) { HRESULT hr = Copy(pSrc); if (FAILED(hr)) { vt = VT_ERROR; scode = hr; } }
// Need other operators? Add them...
operator BSTR() { if (vt != VT_BSTR) THROW_IF_FAILS( ChangeType(VT_BSTR) ); return bstrVal; }
operator tstring() { return tstring( (BSTR)*this ); }
operator long() { if (vt != VT_I4) THROW_IF_FAILS( ChangeType(VT_I4) ); return lVal; }
operator FILETIME() { if (vt != VT_FILETIME) THROW_IF_FAILS( ChangeType(VT_DATE) ); SYSTEMTIME st; if (!VariantTimeToSystemTime( date, &st)) throw win32error();
FILETIME ft; if (!SystemTimeToFileTime(&st, &ft)) throw win32error();
return ft; } };
#endif // __DVARIANT_H__
|