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.
245 lines
4.9 KiB
245 lines
4.9 KiB
10 months ago
|
// This file is based on the following file from the LZMA SDK (http://www.7-zip.org/sdk.html):
|
||
|
// ./CPP/Windows/PropVariant.cpp
|
||
|
#include "PropVariant2.h"
|
||
|
#include "../CPP/Common/Defs.h"
|
||
|
|
||
|
|
||
|
namespace SevenZip
|
||
|
{
|
||
|
namespace intl
|
||
|
{
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
static const char *kMemException = "out of memory";
|
||
|
|
||
|
CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
|
||
|
{
|
||
|
InternalClear();
|
||
|
vt = VT_BSTR;
|
||
|
wReserved1 = 0;
|
||
|
bstrVal = ::SysAllocString(lpszSrc);
|
||
|
if (bstrVal == NULL && lpszSrc != NULL)
|
||
|
{
|
||
|
throw kMemException;
|
||
|
// 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)
|
||
|
{
|
||
|
throw kMemException;
|
||
|
// 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;
|
||
|
}
|
||
|
|
||
|
#define SET_PROP_FUNC(type, id, dest) \
|
||
|
CPropVariant& CPropVariant::operator=(type value) \
|
||
|
{ if (vt != id) { InternalClear(); vt = id; } \
|
||
|
dest = value; return *this; }
|
||
|
|
||
|
SET_PROP_FUNC(Byte, VT_UI1, bVal)
|
||
|
SET_PROP_FUNC(Int16, VT_I2, iVal)
|
||
|
SET_PROP_FUNC(Int32, VT_I4, lVal)
|
||
|
SET_PROP_FUNC(UInt32, VT_UI4, ulVal)
|
||
|
SET_PROP_FUNC(UInt64, VT_UI8, uhVal.QuadPart)
|
||
|
SET_PROP_FUNC(const FILETIME &, VT_FILETIME, filetime)
|
||
|
|
||
|
static HRESULT MyPropVariantClear(PROPVARIANT *prop)
|
||
|
{
|
||
|
switch(prop->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:
|
||
|
prop->vt = VT_EMPTY;
|
||
|
prop->wReserved1 = 0;
|
||
|
return S_OK;
|
||
|
}
|
||
|
return ::VariantClear((VARIANTARG *)prop);
|
||
|
}
|
||
|
|
||
|
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 *)const_cast<PROPVARIANT *>(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))
|
||
|
{
|
||
|
if (hr == E_OUTOFMEMORY)
|
||
|
throw kMemException;
|
||
|
vt = VT_ERROR;
|
||
|
scode = hr;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int CPropVariant::Compare(const CPropVariant &a)
|
||
|
{
|
||
|
if (vt != a.vt)
|
||
|
return MyCompare(vt, a.vt);
|
||
|
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_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;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|