diff options
Diffstat (limited to '3rdparty/lzma/CPP/Windows/PropVariant.cpp')
-rw-r--r-- | 3rdparty/lzma/CPP/Windows/PropVariant.cpp | 158 |
1 files changed, 101 insertions, 57 deletions
diff --git a/3rdparty/lzma/CPP/Windows/PropVariant.cpp b/3rdparty/lzma/CPP/Windows/PropVariant.cpp index e95cbd2b8d5..457b1dcbbee 100644 --- a/3rdparty/lzma/CPP/Windows/PropVariant.cpp +++ b/3rdparty/lzma/CPP/Windows/PropVariant.cpp @@ -91,7 +91,7 @@ CPropVariant& CPropVariant::operator=(BSTR bstrSrc) return *this; } -static const char *kMemException = "out of memory"; +static const char * const kMemException = "out of memory"; CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc) { @@ -192,80 +192,108 @@ BSTR CPropVariant::AllocBstr(unsigned numChars) return bstrVal; } +#define SET_PROP_id_dest(id, dest) \ + if (vt != id) { InternalClear(); vt = id; } dest = value; wReserved1 = 0; + +void CPropVariant::Set_Int32(Int32 value) throw() +{ + SET_PROP_id_dest(VT_I4, lVal) +} + +void CPropVariant::Set_Int64(Int64 value) throw() +{ + SET_PROP_id_dest(VT_I8, hVal.QuadPart) +} + #define SET_PROP_FUNC(type, id, dest) \ CPropVariant& CPropVariant::operator=(type value) throw() \ - { if (vt != id) { InternalClear(); vt = id; } \ - dest = value; return *this; } + { SET_PROP_id_dest(id, dest) 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(Int32, VT_I4, lVal) SET_PROP_FUNC(UInt32, VT_UI4, ulVal) SET_PROP_FUNC(UInt64, VT_UI8, uhVal.QuadPart) -SET_PROP_FUNC(Int64, VT_I8, hVal.QuadPart) +// SET_PROP_FUNC(Int64, VT_I8, hVal.QuadPart) SET_PROP_FUNC(const FILETIME &, VT_FILETIME, filetime) +#define CASE_SIMPLE_VT_VALUES \ + case VT_EMPTY: \ + case VT_BOOL: \ + case VT_FILETIME: \ + case VT_UI8: \ + case VT_UI4: \ + case VT_UI2: \ + case VT_UI1: \ + case VT_I8: \ + case VT_I4: \ + case VT_I2: \ + case VT_I1: \ + case VT_UINT: \ + case VT_INT: \ + case VT_NULL: \ + case VT_ERROR: \ + case VT_R4: \ + case VT_R8: \ + case VT_CY: \ + case VT_DATE: \ + + +/* + ::VariantClear() and ::VariantCopy() don't work, if (vt == VT_FILETIME) + So we handle VT_FILETIME and another simple types directly + we call system functions for VT_BSTR and for unknown typed +*/ + +CPropVariant::~CPropVariant() throw() +{ + switch ((unsigned)vt) + { + CASE_SIMPLE_VT_VALUES + // vt = VT_EMPTY; // it's optional + return; + } + ::VariantClear((tagVARIANT *)this); +} + HRESULT PropVariant_Clear(PROPVARIANT *prop) throw() { - switch (prop->vt) + switch ((unsigned)prop->vt) { - case VT_EMPTY: - 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: + CASE_SIMPLE_VT_VALUES prop->vt = VT_EMPTY; - prop->wReserved1 = 0; - prop->wReserved2 = 0; - prop->wReserved3 = 0; - prop->uhVal.QuadPart = 0; - return S_OK; + break; + default: + { + const HRESULT res = ::VariantClear((VARIANTARG *)prop); + if (res != S_OK || prop->vt != VT_EMPTY) + return res; + break; + } } - return ::VariantClear((VARIANTARG *)prop); - // return ::PropVariantClear(prop); - // PropVariantClear can clear VT_BLOB. + prop->wReserved1 = 0; + prop->wReserved2 = 0; + prop->wReserved3 = 0; + prop->uhVal.QuadPart = 0; + return S_OK; } HRESULT CPropVariant::Clear() throw() { if (vt == VT_EMPTY) + { + wReserved1 = 0; return S_OK; + } return PropVariant_Clear(this); } HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) throw() { - ::VariantClear((tagVARIANT *)this); - switch (pSrc->vt) + Clear(); + switch ((unsigned)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: + CASE_SIMPLE_VT_VALUES memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT)); return S_OK; } @@ -275,11 +303,13 @@ HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) throw() HRESULT CPropVariant::Attach(PROPVARIANT *pSrc) throw() { - HRESULT hr = Clear(); + const HRESULT hr = Clear(); if (FAILED(hr)) return hr; - memcpy(this, pSrc, sizeof(PROPVARIANT)); + // memcpy((PROPVARIANT *)this, pSrc, sizeof(PROPVARIANT)); + *(PROPVARIANT *)this = *pSrc; pSrc->vt = VT_EMPTY; + pSrc->wReserved1 = 0; return S_OK; } @@ -287,20 +317,25 @@ HRESULT CPropVariant::Detach(PROPVARIANT *pDest) throw() { if (pDest->vt != VT_EMPTY) { - HRESULT hr = PropVariant_Clear(pDest); + const HRESULT hr = PropVariant_Clear(pDest); if (FAILED(hr)) return hr; } - memcpy(pDest, this, sizeof(PROPVARIANT)); + // memcpy(pDest, this, sizeof(PROPVARIANT)); + *pDest = *(PROPVARIANT *)this; vt = VT_EMPTY; + wReserved1 = 0; return S_OK; } HRESULT CPropVariant::InternalClear() throw() { if (vt == VT_EMPTY) + { + wReserved1 = 0; return S_OK; - HRESULT hr = Clear(); + } + const HRESULT hr = Clear(); if (FAILED(hr)) { vt = VT_ERROR; @@ -311,7 +346,7 @@ HRESULT CPropVariant::InternalClear() throw() void CPropVariant::InternalCopy(const PROPVARIANT *pSrc) { - HRESULT hr = Copy(pSrc); + const HRESULT hr = Copy(pSrc); if (FAILED(hr)) { if (hr == E_OUTOFMEMORY) @@ -321,11 +356,12 @@ void CPropVariant::InternalCopy(const PROPVARIANT *pSrc) } } + int CPropVariant::Compare(const CPropVariant &a) throw() { if (vt != a.vt) return MyCompare(vt, a.vt); - switch (vt) + switch ((unsigned)vt) { case VT_EMPTY: return 0; // case VT_I1: return MyCompare(cVal, a.cVal); @@ -338,7 +374,15 @@ int CPropVariant::Compare(const CPropVariant &a) throw() 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_FILETIME: + { + const int res = CompareFileTime(&filetime, &a.filetime); + if (res != 0) + return res; + const unsigned v1 = Get_Ns100(); + const unsigned v2 = a.Get_Ns100(); + return MyCompare(v1, v2); + } case VT_BSTR: return 0; // Not implemented default: return 0; } |