// Windows/PropVariant.cpp #include "StdAfx.h" #include "PropVariant.h" #include "../Common/Defs.h" namespace NWindows { namespace NCOM { CPropVariant::CPropVariant(const PROPVARIANT& varSrc) { vt = VT_EMPTY; InternalCopy(&varSrc); } CPropVariant::CPropVariant(const CPropVariant& varSrc) { vt = VT_EMPTY; InternalCopy(&varSrc); } CPropVariant::CPropVariant(BSTR bstrSrc) { vt = VT_EMPTY; *this = bstrSrc; } CPropVariant::CPropVariant(LPCOLESTR lpszSrc) { vt = VT_EMPTY; *this = lpszSrc; } CPropVariant& CPropVariant::operator=(const CPropVariant& varSrc) { InternalCopy(&varSrc); return *this; } CPropVariant& CPropVariant::operator=(const PROPVARIANT& varSrc) { InternalCopy(&varSrc); return *this; } CPropVariant& CPropVariant::operator=(BSTR bstrSrc) { *this = (LPCOLESTR)bstrSrc; return *this; } CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc) { InternalClear(); vt = VT_BSTR; wReserved1 = 0; bstrVal = ::SysAllocString(lpszSrc); if (bstrVal == NULL && lpszSrc != NULL) { vt = VT_ERROR; scode = E_OUTOFMEMORY; } return *this; } CPropVariant& CPropVariant::operator=(const char *s) { InternalClear(); vt = VT_BSTR; wReserved1 = 0; UINT len = (UINT)strlen(s); bstrVal = ::SysAllocStringByteLen(0, (UINT)len * sizeof(OLECHAR)); if (bstrVal == NULL) { vt = VT_ERROR; scode = E_OUTOFMEMORY; } else { for (UINT i = 0; i <= len; i++) bstrVal[i] = s[i]; } return *this; } CPropVariant& CPropVariant::operator=(bool bSrc) { if (vt != VT_BOOL) { InternalClear(); vt = VT_BOOL; } boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE; return *this; } CPropVariant& CPropVariant::operator=(UInt32 value) { if (vt != VT_UI4) { InternalClear(); vt = VT_UI4; } ulVal = value; return *this; } CPropVariant& CPropVariant::operator=(UInt64 value) { if (vt != VT_UI8) { InternalClear(); vt = VT_UI8; } uhVal.QuadPart = value; return *this; } CPropVariant& CPropVariant::operator=(const FILETIME &value) { if (vt != VT_FILETIME) { InternalClear(); vt = VT_FILETIME; } filetime = value; return *this; } CPropVariant& CPropVariant::operator=(Int32 value) { if (vt != VT_I4) { InternalClear(); vt = VT_I4; } lVal = value; return *this; } CPropVariant& CPropVariant::operator=(Byte value) { if (vt != VT_UI1) { InternalClear(); vt = VT_UI1; } bVal = value; return *this; } CPropVariant& CPropVariant::operator=(Int16 value) { if (vt != VT_I2) { InternalClear(); vt = VT_I2; } iVal = value; return *this; } /* CPropVariant& CPropVariant::operator=(LONG value) { if (vt != VT_I4) { InternalClear(); vt = VT_I4; } lVal = value; return *this; } */ static HRESULT MyPropVariantClear(PROPVARIANT *propVariant) { switch(propVariant->vt) { case VT_UI1: case VT_I1: case VT_I2: case VT_UI2: case VT_BOOL: case VT_I4: case VT_UI4: case VT_R4: case VT_INT: case VT_UINT: case VT_ERROR: case VT_FILETIME: case VT_UI8: case VT_R8: case VT_CY: case VT_DATE: propVariant->vt = VT_EMPTY; propVariant->wReserved1 = 0; return S_OK; } return ::VariantClear((VARIANTARG *)propVariant); } HRESULT CPropVariant::Clear() { return MyPropVariantClear(this); } HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) { ::VariantClear((tagVARIANT *)this); switch(pSrc->vt) { case VT_UI1: case VT_I1: case VT_I2: case VT_UI2: case VT_BOOL: case VT_I4: case VT_UI4: case VT_R4: case VT_INT: case VT_UINT: case VT_ERROR: case VT_FILETIME: case VT_UI8: case VT_R8: case VT_CY: case VT_DATE: memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT)); return S_OK; } return ::VariantCopy((tagVARIANT *)this, (tagVARIANT *)(pSrc)); } HRESULT CPropVariant::Attach(PROPVARIANT* pSrc) { HRESULT hr = Clear(); if (FAILED(hr)) return hr; memcpy(this, pSrc, sizeof(PROPVARIANT)); pSrc->vt = VT_EMPTY; return S_OK; } HRESULT CPropVariant::Detach(PROPVARIANT* pDest) { HRESULT hr = MyPropVariantClear(pDest); if (FAILED(hr)) return hr; memcpy(pDest, this, sizeof(PROPVARIANT)); vt = VT_EMPTY; return S_OK; } HRESULT CPropVariant::InternalClear() { HRESULT hr = Clear(); if (FAILED(hr)) { vt = VT_ERROR; scode = hr; } return hr; } void CPropVariant::InternalCopy(const PROPVARIANT* pSrc) { HRESULT hr = Copy(pSrc); if (FAILED(hr)) { vt = VT_ERROR; scode = hr; } } int CPropVariant::Compare(const CPropVariant &a) { if (vt != a.vt) return 0; // it's mean some bug switch (vt) { case VT_EMPTY: return 0; /* case VT_I1: return MyCompare(cVal, a.cVal); */ case VT_UI1: return MyCompare(bVal, a.bVal); case VT_I2: return MyCompare(iVal, a.iVal); case VT_UI2: return MyCompare(uiVal, a.uiVal); case VT_I4: return MyCompare(lVal, a.lVal); /* case VT_INT: return MyCompare(intVal, a.intVal); */ case VT_UI4: return MyCompare(ulVal, a.ulVal); /* case VT_UINT: return MyCompare(uintVal, a.uintVal); */ case VT_I8: return MyCompare(hVal.QuadPart, a.hVal.QuadPart); case VT_UI8: return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart); case VT_BOOL: return -MyCompare(boolVal, a.boolVal); case VT_FILETIME: return ::CompareFileTime(&filetime, &a.filetime); case VT_BSTR: return 0; // Not implemented // return MyCompare(aPropVarint.cVal); default: return 0; } } }}