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