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