xref: /aosp_15_r20/external/lzma/CPP/Windows/PropVariant.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // Windows/PropVariant.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker #include "../Common/Defs.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "PropVariant.h"
8*f6dc9357SAndroid Build Coastguard Worker 
9*f6dc9357SAndroid Build Coastguard Worker namespace NWindows {
10*f6dc9357SAndroid Build Coastguard Worker namespace NCOM {
11*f6dc9357SAndroid Build Coastguard Worker 
AllocBstrFromAscii(const char * s)12*f6dc9357SAndroid Build Coastguard Worker BSTR AllocBstrFromAscii(const char *s) throw()
13*f6dc9357SAndroid Build Coastguard Worker {
14*f6dc9357SAndroid Build Coastguard Worker   if (!s)
15*f6dc9357SAndroid Build Coastguard Worker     return NULL;
16*f6dc9357SAndroid Build Coastguard Worker   UINT len = (UINT)strlen(s);
17*f6dc9357SAndroid Build Coastguard Worker   BSTR p = ::SysAllocStringLen(NULL, len);
18*f6dc9357SAndroid Build Coastguard Worker   if (p)
19*f6dc9357SAndroid Build Coastguard Worker   {
20*f6dc9357SAndroid Build Coastguard Worker     for (UINT i = 0; i <= len; i++)
21*f6dc9357SAndroid Build Coastguard Worker       p[i] = (Byte)s[i];
22*f6dc9357SAndroid Build Coastguard Worker   }
23*f6dc9357SAndroid Build Coastguard Worker   return p;
24*f6dc9357SAndroid Build Coastguard Worker }
25*f6dc9357SAndroid Build Coastguard Worker 
PropVarEm_Alloc_Bstr(PROPVARIANT * p,unsigned numChars)26*f6dc9357SAndroid Build Coastguard Worker HRESULT PropVarEm_Alloc_Bstr(PROPVARIANT *p, unsigned numChars) throw()
27*f6dc9357SAndroid Build Coastguard Worker {
28*f6dc9357SAndroid Build Coastguard Worker   p->bstrVal = ::SysAllocStringLen(NULL, numChars);
29*f6dc9357SAndroid Build Coastguard Worker   if (!p->bstrVal)
30*f6dc9357SAndroid Build Coastguard Worker   {
31*f6dc9357SAndroid Build Coastguard Worker     p->vt = VT_ERROR;
32*f6dc9357SAndroid Build Coastguard Worker     p->scode = E_OUTOFMEMORY;
33*f6dc9357SAndroid Build Coastguard Worker     return E_OUTOFMEMORY;
34*f6dc9357SAndroid Build Coastguard Worker   }
35*f6dc9357SAndroid Build Coastguard Worker   p->vt = VT_BSTR;
36*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
37*f6dc9357SAndroid Build Coastguard Worker }
38*f6dc9357SAndroid Build Coastguard Worker 
PropVarEm_Set_Str(PROPVARIANT * p,const char * s)39*f6dc9357SAndroid Build Coastguard Worker HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) throw()
40*f6dc9357SAndroid Build Coastguard Worker {
41*f6dc9357SAndroid Build Coastguard Worker   p->bstrVal = AllocBstrFromAscii(s);
42*f6dc9357SAndroid Build Coastguard Worker   if (p->bstrVal)
43*f6dc9357SAndroid Build Coastguard Worker   {
44*f6dc9357SAndroid Build Coastguard Worker     p->vt = VT_BSTR;
45*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
46*f6dc9357SAndroid Build Coastguard Worker   }
47*f6dc9357SAndroid Build Coastguard Worker   p->vt = VT_ERROR;
48*f6dc9357SAndroid Build Coastguard Worker   p->scode = E_OUTOFMEMORY;
49*f6dc9357SAndroid Build Coastguard Worker   return E_OUTOFMEMORY;
50*f6dc9357SAndroid Build Coastguard Worker }
51*f6dc9357SAndroid Build Coastguard Worker 
CPropVariant(const PROPVARIANT & varSrc)52*f6dc9357SAndroid Build Coastguard Worker CPropVariant::CPropVariant(const PROPVARIANT &varSrc)
53*f6dc9357SAndroid Build Coastguard Worker {
54*f6dc9357SAndroid Build Coastguard Worker   vt = VT_EMPTY;
55*f6dc9357SAndroid Build Coastguard Worker   InternalCopy(&varSrc);
56*f6dc9357SAndroid Build Coastguard Worker }
57*f6dc9357SAndroid Build Coastguard Worker 
CPropVariant(const CPropVariant & varSrc)58*f6dc9357SAndroid Build Coastguard Worker CPropVariant::CPropVariant(const CPropVariant &varSrc)
59*f6dc9357SAndroid Build Coastguard Worker {
60*f6dc9357SAndroid Build Coastguard Worker   vt = VT_EMPTY;
61*f6dc9357SAndroid Build Coastguard Worker   InternalCopy(&varSrc);
62*f6dc9357SAndroid Build Coastguard Worker }
63*f6dc9357SAndroid Build Coastguard Worker 
CPropVariant(BSTR bstrSrc)64*f6dc9357SAndroid Build Coastguard Worker CPropVariant::CPropVariant(BSTR bstrSrc)
65*f6dc9357SAndroid Build Coastguard Worker {
66*f6dc9357SAndroid Build Coastguard Worker   vt = VT_EMPTY;
67*f6dc9357SAndroid Build Coastguard Worker   *this = bstrSrc;
68*f6dc9357SAndroid Build Coastguard Worker }
69*f6dc9357SAndroid Build Coastguard Worker 
CPropVariant(LPCOLESTR lpszSrc)70*f6dc9357SAndroid Build Coastguard Worker CPropVariant::CPropVariant(LPCOLESTR lpszSrc)
71*f6dc9357SAndroid Build Coastguard Worker {
72*f6dc9357SAndroid Build Coastguard Worker   vt = VT_EMPTY;
73*f6dc9357SAndroid Build Coastguard Worker   *this = lpszSrc;
74*f6dc9357SAndroid Build Coastguard Worker }
75*f6dc9357SAndroid Build Coastguard Worker 
operator =(const CPropVariant & varSrc)76*f6dc9357SAndroid Build Coastguard Worker CPropVariant& CPropVariant::operator=(const CPropVariant &varSrc)
77*f6dc9357SAndroid Build Coastguard Worker {
78*f6dc9357SAndroid Build Coastguard Worker   InternalCopy(&varSrc);
79*f6dc9357SAndroid Build Coastguard Worker   return *this;
80*f6dc9357SAndroid Build Coastguard Worker }
81*f6dc9357SAndroid Build Coastguard Worker 
operator =(const PROPVARIANT & varSrc)82*f6dc9357SAndroid Build Coastguard Worker CPropVariant& CPropVariant::operator=(const PROPVARIANT &varSrc)
83*f6dc9357SAndroid Build Coastguard Worker {
84*f6dc9357SAndroid Build Coastguard Worker   InternalCopy(&varSrc);
85*f6dc9357SAndroid Build Coastguard Worker   return *this;
86*f6dc9357SAndroid Build Coastguard Worker }
87*f6dc9357SAndroid Build Coastguard Worker 
operator =(BSTR bstrSrc)88*f6dc9357SAndroid Build Coastguard Worker CPropVariant& CPropVariant::operator=(BSTR bstrSrc)
89*f6dc9357SAndroid Build Coastguard Worker {
90*f6dc9357SAndroid Build Coastguard Worker   *this = (LPCOLESTR)bstrSrc;
91*f6dc9357SAndroid Build Coastguard Worker   return *this;
92*f6dc9357SAndroid Build Coastguard Worker }
93*f6dc9357SAndroid Build Coastguard Worker 
94*f6dc9357SAndroid Build Coastguard Worker static const char * const kMemException = "out of memory";
95*f6dc9357SAndroid Build Coastguard Worker 
operator =(LPCOLESTR lpszSrc)96*f6dc9357SAndroid Build Coastguard Worker CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
97*f6dc9357SAndroid Build Coastguard Worker {
98*f6dc9357SAndroid Build Coastguard Worker   InternalClear();
99*f6dc9357SAndroid Build Coastguard Worker   vt = VT_BSTR;
100*f6dc9357SAndroid Build Coastguard Worker   wReserved1 = 0;
101*f6dc9357SAndroid Build Coastguard Worker   bstrVal = ::SysAllocString(lpszSrc);
102*f6dc9357SAndroid Build Coastguard Worker   if (!bstrVal && lpszSrc)
103*f6dc9357SAndroid Build Coastguard Worker   {
104*f6dc9357SAndroid Build Coastguard Worker     throw kMemException;
105*f6dc9357SAndroid Build Coastguard Worker     // vt = VT_ERROR;
106*f6dc9357SAndroid Build Coastguard Worker     // scode = E_OUTOFMEMORY;
107*f6dc9357SAndroid Build Coastguard Worker   }
108*f6dc9357SAndroid Build Coastguard Worker   return *this;
109*f6dc9357SAndroid Build Coastguard Worker }
110*f6dc9357SAndroid Build Coastguard Worker 
operator =(const UString & s)111*f6dc9357SAndroid Build Coastguard Worker CPropVariant& CPropVariant::operator=(const UString &s)
112*f6dc9357SAndroid Build Coastguard Worker {
113*f6dc9357SAndroid Build Coastguard Worker   InternalClear();
114*f6dc9357SAndroid Build Coastguard Worker   vt = VT_BSTR;
115*f6dc9357SAndroid Build Coastguard Worker   wReserved1 = 0;
116*f6dc9357SAndroid Build Coastguard Worker   bstrVal = ::SysAllocStringLen(s, s.Len());
117*f6dc9357SAndroid Build Coastguard Worker   if (!bstrVal)
118*f6dc9357SAndroid Build Coastguard Worker     throw kMemException;
119*f6dc9357SAndroid Build Coastguard Worker   return *this;
120*f6dc9357SAndroid Build Coastguard Worker }
121*f6dc9357SAndroid Build Coastguard Worker 
operator =(const UString2 & s)122*f6dc9357SAndroid Build Coastguard Worker CPropVariant& CPropVariant::operator=(const UString2 &s)
123*f6dc9357SAndroid Build Coastguard Worker {
124*f6dc9357SAndroid Build Coastguard Worker   /*
125*f6dc9357SAndroid Build Coastguard Worker   if (s.IsEmpty())
126*f6dc9357SAndroid Build Coastguard Worker     *this = L"";
127*f6dc9357SAndroid Build Coastguard Worker   else
128*f6dc9357SAndroid Build Coastguard Worker   */
129*f6dc9357SAndroid Build Coastguard Worker   {
130*f6dc9357SAndroid Build Coastguard Worker     InternalClear();
131*f6dc9357SAndroid Build Coastguard Worker     vt = VT_BSTR;
132*f6dc9357SAndroid Build Coastguard Worker     wReserved1 = 0;
133*f6dc9357SAndroid Build Coastguard Worker     bstrVal = ::SysAllocStringLen(s.GetRawPtr(), s.Len());
134*f6dc9357SAndroid Build Coastguard Worker     if (!bstrVal)
135*f6dc9357SAndroid Build Coastguard Worker       throw kMemException;
136*f6dc9357SAndroid Build Coastguard Worker     /* SysAllocStringLen probably appends a null-terminating character for NULL string.
137*f6dc9357SAndroid Build Coastguard Worker        But it doesn't specified in MSDN.
138*f6dc9357SAndroid Build Coastguard Worker        But we suppose that it works
139*f6dc9357SAndroid Build Coastguard Worker 
140*f6dc9357SAndroid Build Coastguard Worker     if (!s.GetRawPtr())
141*f6dc9357SAndroid Build Coastguard Worker     {
142*f6dc9357SAndroid Build Coastguard Worker       *bstrVal = 0;
143*f6dc9357SAndroid Build Coastguard Worker     }
144*f6dc9357SAndroid Build Coastguard Worker     */
145*f6dc9357SAndroid Build Coastguard Worker 
146*f6dc9357SAndroid Build Coastguard Worker     /* MSDN: Windows CE: SysAllocStringLen() : Passing invalid (and under some circumstances NULL)
147*f6dc9357SAndroid Build Coastguard Worker                          pointers to this function causes  an unexpected termination of the application.
148*f6dc9357SAndroid Build Coastguard Worker        Is it safe? Maybe we must chamnge the code for that case ? */
149*f6dc9357SAndroid Build Coastguard Worker   }
150*f6dc9357SAndroid Build Coastguard Worker   return *this;
151*f6dc9357SAndroid Build Coastguard Worker }
152*f6dc9357SAndroid Build Coastguard Worker 
operator =(const char * s)153*f6dc9357SAndroid Build Coastguard Worker CPropVariant& CPropVariant::operator=(const char *s)
154*f6dc9357SAndroid Build Coastguard Worker {
155*f6dc9357SAndroid Build Coastguard Worker   InternalClear();
156*f6dc9357SAndroid Build Coastguard Worker   vt = VT_BSTR;
157*f6dc9357SAndroid Build Coastguard Worker   wReserved1 = 0;
158*f6dc9357SAndroid Build Coastguard Worker   bstrVal = AllocBstrFromAscii(s);
159*f6dc9357SAndroid Build Coastguard Worker   if (!bstrVal)
160*f6dc9357SAndroid Build Coastguard Worker   {
161*f6dc9357SAndroid Build Coastguard Worker     throw kMemException;
162*f6dc9357SAndroid Build Coastguard Worker     // vt = VT_ERROR;
163*f6dc9357SAndroid Build Coastguard Worker     // scode = E_OUTOFMEMORY;
164*f6dc9357SAndroid Build Coastguard Worker   }
165*f6dc9357SAndroid Build Coastguard Worker   return *this;
166*f6dc9357SAndroid Build Coastguard Worker }
167*f6dc9357SAndroid Build Coastguard Worker 
operator =(bool bSrc)168*f6dc9357SAndroid Build Coastguard Worker CPropVariant& CPropVariant::operator=(bool bSrc) throw()
169*f6dc9357SAndroid Build Coastguard Worker {
170*f6dc9357SAndroid Build Coastguard Worker   if (vt != VT_BOOL)
171*f6dc9357SAndroid Build Coastguard Worker   {
172*f6dc9357SAndroid Build Coastguard Worker     InternalClear();
173*f6dc9357SAndroid Build Coastguard Worker     vt = VT_BOOL;
174*f6dc9357SAndroid Build Coastguard Worker   }
175*f6dc9357SAndroid Build Coastguard Worker   boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
176*f6dc9357SAndroid Build Coastguard Worker   return *this;
177*f6dc9357SAndroid Build Coastguard Worker }
178*f6dc9357SAndroid Build Coastguard Worker 
AllocBstr(unsigned numChars)179*f6dc9357SAndroid Build Coastguard Worker BSTR CPropVariant::AllocBstr(unsigned numChars)
180*f6dc9357SAndroid Build Coastguard Worker {
181*f6dc9357SAndroid Build Coastguard Worker   if (vt != VT_EMPTY)
182*f6dc9357SAndroid Build Coastguard Worker     InternalClear();
183*f6dc9357SAndroid Build Coastguard Worker   vt = VT_BSTR;
184*f6dc9357SAndroid Build Coastguard Worker   wReserved1 = 0;
185*f6dc9357SAndroid Build Coastguard Worker   bstrVal = ::SysAllocStringLen(NULL, numChars);
186*f6dc9357SAndroid Build Coastguard Worker   if (!bstrVal)
187*f6dc9357SAndroid Build Coastguard Worker   {
188*f6dc9357SAndroid Build Coastguard Worker     throw kMemException;
189*f6dc9357SAndroid Build Coastguard Worker     // vt = VT_ERROR;
190*f6dc9357SAndroid Build Coastguard Worker     // scode = E_OUTOFMEMORY;
191*f6dc9357SAndroid Build Coastguard Worker   }
192*f6dc9357SAndroid Build Coastguard Worker   return bstrVal;
193*f6dc9357SAndroid Build Coastguard Worker }
194*f6dc9357SAndroid Build Coastguard Worker 
195*f6dc9357SAndroid Build Coastguard Worker #define SET_PROP_id_dest(id, dest) \
196*f6dc9357SAndroid Build Coastguard Worker   if (vt != id) { InternalClear(); vt = id; } dest = value; wReserved1 = 0;
197*f6dc9357SAndroid Build Coastguard Worker 
Set_Int32(Int32 value)198*f6dc9357SAndroid Build Coastguard Worker void CPropVariant::Set_Int32(Int32 value) throw()
199*f6dc9357SAndroid Build Coastguard Worker {
200*f6dc9357SAndroid Build Coastguard Worker   SET_PROP_id_dest(VT_I4, lVal)
201*f6dc9357SAndroid Build Coastguard Worker }
202*f6dc9357SAndroid Build Coastguard Worker 
Set_Int64(Int64 value)203*f6dc9357SAndroid Build Coastguard Worker void CPropVariant::Set_Int64(Int64 value) throw()
204*f6dc9357SAndroid Build Coastguard Worker {
205*f6dc9357SAndroid Build Coastguard Worker   SET_PROP_id_dest(VT_I8, hVal.QuadPart)
206*f6dc9357SAndroid Build Coastguard Worker }
207*f6dc9357SAndroid Build Coastguard Worker 
208*f6dc9357SAndroid Build Coastguard Worker #define SET_PROP_FUNC(type, id, dest) \
209*f6dc9357SAndroid Build Coastguard Worker   CPropVariant& CPropVariant::operator=(type value) throw() \
210*f6dc9357SAndroid Build Coastguard Worker   { SET_PROP_id_dest(id, dest)  return *this; }
211*f6dc9357SAndroid Build Coastguard Worker 
SET_PROP_FUNC(Byte,VT_UI1,bVal)212*f6dc9357SAndroid Build Coastguard Worker SET_PROP_FUNC(Byte, VT_UI1, bVal)
213*f6dc9357SAndroid Build Coastguard Worker // SET_PROP_FUNC(Int16, VT_I2, iVal)
214*f6dc9357SAndroid Build Coastguard Worker // SET_PROP_FUNC(Int32, VT_I4, lVal)
215*f6dc9357SAndroid Build Coastguard Worker SET_PROP_FUNC(UInt32, VT_UI4, ulVal)
216*f6dc9357SAndroid Build Coastguard Worker SET_PROP_FUNC(UInt64, VT_UI8, uhVal.QuadPart)
217*f6dc9357SAndroid Build Coastguard Worker // SET_PROP_FUNC(Int64, VT_I8, hVal.QuadPart)
218*f6dc9357SAndroid Build Coastguard Worker SET_PROP_FUNC(const FILETIME &, VT_FILETIME, filetime)
219*f6dc9357SAndroid Build Coastguard Worker 
220*f6dc9357SAndroid Build Coastguard Worker #define CASE_SIMPLE_VT_VALUES \
221*f6dc9357SAndroid Build Coastguard Worker     case VT_EMPTY:    \
222*f6dc9357SAndroid Build Coastguard Worker     case VT_BOOL:     \
223*f6dc9357SAndroid Build Coastguard Worker     case VT_FILETIME: \
224*f6dc9357SAndroid Build Coastguard Worker     case VT_UI8:      \
225*f6dc9357SAndroid Build Coastguard Worker     case VT_UI4:      \
226*f6dc9357SAndroid Build Coastguard Worker     case VT_UI2:      \
227*f6dc9357SAndroid Build Coastguard Worker     case VT_UI1:      \
228*f6dc9357SAndroid Build Coastguard Worker     case VT_I8:       \
229*f6dc9357SAndroid Build Coastguard Worker     case VT_I4:       \
230*f6dc9357SAndroid Build Coastguard Worker     case VT_I2:       \
231*f6dc9357SAndroid Build Coastguard Worker     case VT_I1:       \
232*f6dc9357SAndroid Build Coastguard Worker     case VT_UINT:     \
233*f6dc9357SAndroid Build Coastguard Worker     case VT_INT:      \
234*f6dc9357SAndroid Build Coastguard Worker     case VT_NULL:     \
235*f6dc9357SAndroid Build Coastguard Worker     case VT_ERROR:    \
236*f6dc9357SAndroid Build Coastguard Worker     case VT_R4:       \
237*f6dc9357SAndroid Build Coastguard Worker     case VT_R8:       \
238*f6dc9357SAndroid Build Coastguard Worker     case VT_CY:       \
239*f6dc9357SAndroid Build Coastguard Worker     case VT_DATE:     \
240*f6dc9357SAndroid Build Coastguard Worker 
241*f6dc9357SAndroid Build Coastguard Worker 
242*f6dc9357SAndroid Build Coastguard Worker /*
243*f6dc9357SAndroid Build Coastguard Worker   ::VariantClear() and ::VariantCopy() don't work, if (vt == VT_FILETIME)
244*f6dc9357SAndroid Build Coastguard Worker   So we handle VT_FILETIME and another simple types directly
245*f6dc9357SAndroid Build Coastguard Worker   we call system functions for VT_BSTR and for unknown typed
246*f6dc9357SAndroid Build Coastguard Worker */
247*f6dc9357SAndroid Build Coastguard Worker 
248*f6dc9357SAndroid Build Coastguard Worker CPropVariant::~CPropVariant() throw()
249*f6dc9357SAndroid Build Coastguard Worker {
250*f6dc9357SAndroid Build Coastguard Worker   switch ((unsigned)vt)
251*f6dc9357SAndroid Build Coastguard Worker   {
252*f6dc9357SAndroid Build Coastguard Worker     CASE_SIMPLE_VT_VALUES
253*f6dc9357SAndroid Build Coastguard Worker       // vt = VT_EMPTY; // it's optional
254*f6dc9357SAndroid Build Coastguard Worker       return;
255*f6dc9357SAndroid Build Coastguard Worker     default: break;
256*f6dc9357SAndroid Build Coastguard Worker   }
257*f6dc9357SAndroid Build Coastguard Worker   ::VariantClear((tagVARIANT *)this);
258*f6dc9357SAndroid Build Coastguard Worker }
259*f6dc9357SAndroid Build Coastguard Worker 
PropVariant_Clear(PROPVARIANT * prop)260*f6dc9357SAndroid Build Coastguard Worker HRESULT PropVariant_Clear(PROPVARIANT *prop) throw()
261*f6dc9357SAndroid Build Coastguard Worker {
262*f6dc9357SAndroid Build Coastguard Worker   switch ((unsigned)prop->vt)
263*f6dc9357SAndroid Build Coastguard Worker   {
264*f6dc9357SAndroid Build Coastguard Worker     CASE_SIMPLE_VT_VALUES
265*f6dc9357SAndroid Build Coastguard Worker       prop->vt = VT_EMPTY;
266*f6dc9357SAndroid Build Coastguard Worker       break;
267*f6dc9357SAndroid Build Coastguard Worker     default:
268*f6dc9357SAndroid Build Coastguard Worker     {
269*f6dc9357SAndroid Build Coastguard Worker       const HRESULT res = ::VariantClear((VARIANTARG *)prop);
270*f6dc9357SAndroid Build Coastguard Worker       if (res != S_OK || prop->vt != VT_EMPTY)
271*f6dc9357SAndroid Build Coastguard Worker         return res;
272*f6dc9357SAndroid Build Coastguard Worker       break;
273*f6dc9357SAndroid Build Coastguard Worker     }
274*f6dc9357SAndroid Build Coastguard Worker   }
275*f6dc9357SAndroid Build Coastguard Worker   prop->wReserved1 = 0;
276*f6dc9357SAndroid Build Coastguard Worker   prop->wReserved2 = 0;
277*f6dc9357SAndroid Build Coastguard Worker   prop->wReserved3 = 0;
278*f6dc9357SAndroid Build Coastguard Worker   prop->uhVal.QuadPart = 0;
279*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
280*f6dc9357SAndroid Build Coastguard Worker }
281*f6dc9357SAndroid Build Coastguard Worker 
Clear()282*f6dc9357SAndroid Build Coastguard Worker HRESULT CPropVariant::Clear() throw()
283*f6dc9357SAndroid Build Coastguard Worker {
284*f6dc9357SAndroid Build Coastguard Worker   if (vt == VT_EMPTY)
285*f6dc9357SAndroid Build Coastguard Worker   {
286*f6dc9357SAndroid Build Coastguard Worker     wReserved1 = 0;
287*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
288*f6dc9357SAndroid Build Coastguard Worker   }
289*f6dc9357SAndroid Build Coastguard Worker   return PropVariant_Clear(this);
290*f6dc9357SAndroid Build Coastguard Worker }
291*f6dc9357SAndroid Build Coastguard Worker 
Copy(const PROPVARIANT * pSrc)292*f6dc9357SAndroid Build Coastguard Worker HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc) throw()
293*f6dc9357SAndroid Build Coastguard Worker {
294*f6dc9357SAndroid Build Coastguard Worker   Clear();
295*f6dc9357SAndroid Build Coastguard Worker   switch ((unsigned)pSrc->vt)
296*f6dc9357SAndroid Build Coastguard Worker   {
297*f6dc9357SAndroid Build Coastguard Worker     CASE_SIMPLE_VT_VALUES
298*f6dc9357SAndroid Build Coastguard Worker       memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT));
299*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
300*f6dc9357SAndroid Build Coastguard Worker     default: break;
301*f6dc9357SAndroid Build Coastguard Worker   }
302*f6dc9357SAndroid Build Coastguard Worker   return ::VariantCopy((tagVARIANT *)this, (tagVARIANT *)const_cast<PROPVARIANT *>(pSrc));
303*f6dc9357SAndroid Build Coastguard Worker }
304*f6dc9357SAndroid Build Coastguard Worker 
305*f6dc9357SAndroid Build Coastguard Worker 
Attach(PROPVARIANT * pSrc)306*f6dc9357SAndroid Build Coastguard Worker HRESULT CPropVariant::Attach(PROPVARIANT *pSrc) throw()
307*f6dc9357SAndroid Build Coastguard Worker {
308*f6dc9357SAndroid Build Coastguard Worker   const HRESULT hr = Clear();
309*f6dc9357SAndroid Build Coastguard Worker   if (FAILED(hr))
310*f6dc9357SAndroid Build Coastguard Worker     return hr;
311*f6dc9357SAndroid Build Coastguard Worker   // memcpy((PROPVARIANT *)this, pSrc, sizeof(PROPVARIANT));
312*f6dc9357SAndroid Build Coastguard Worker   *(PROPVARIANT *)this = *pSrc;
313*f6dc9357SAndroid Build Coastguard Worker   pSrc->vt = VT_EMPTY;
314*f6dc9357SAndroid Build Coastguard Worker   pSrc->wReserved1 = 0;
315*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
316*f6dc9357SAndroid Build Coastguard Worker }
317*f6dc9357SAndroid Build Coastguard Worker 
Detach(PROPVARIANT * pDest)318*f6dc9357SAndroid Build Coastguard Worker HRESULT CPropVariant::Detach(PROPVARIANT *pDest) throw()
319*f6dc9357SAndroid Build Coastguard Worker {
320*f6dc9357SAndroid Build Coastguard Worker   if (pDest->vt != VT_EMPTY)
321*f6dc9357SAndroid Build Coastguard Worker   {
322*f6dc9357SAndroid Build Coastguard Worker     const HRESULT hr = PropVariant_Clear(pDest);
323*f6dc9357SAndroid Build Coastguard Worker     if (FAILED(hr))
324*f6dc9357SAndroid Build Coastguard Worker       return hr;
325*f6dc9357SAndroid Build Coastguard Worker   }
326*f6dc9357SAndroid Build Coastguard Worker   // memcpy(pDest, this, sizeof(PROPVARIANT));
327*f6dc9357SAndroid Build Coastguard Worker   *pDest = *(PROPVARIANT *)this;
328*f6dc9357SAndroid Build Coastguard Worker   vt = VT_EMPTY;
329*f6dc9357SAndroid Build Coastguard Worker   wReserved1 = 0;
330*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
331*f6dc9357SAndroid Build Coastguard Worker }
332*f6dc9357SAndroid Build Coastguard Worker 
InternalClear()333*f6dc9357SAndroid Build Coastguard Worker HRESULT CPropVariant::InternalClear() throw()
334*f6dc9357SAndroid Build Coastguard Worker {
335*f6dc9357SAndroid Build Coastguard Worker   if (vt == VT_EMPTY)
336*f6dc9357SAndroid Build Coastguard Worker   {
337*f6dc9357SAndroid Build Coastguard Worker     wReserved1 = 0;
338*f6dc9357SAndroid Build Coastguard Worker     return S_OK;
339*f6dc9357SAndroid Build Coastguard Worker   }
340*f6dc9357SAndroid Build Coastguard Worker   const HRESULT hr = Clear();
341*f6dc9357SAndroid Build Coastguard Worker   if (FAILED(hr))
342*f6dc9357SAndroid Build Coastguard Worker   {
343*f6dc9357SAndroid Build Coastguard Worker     vt = VT_ERROR;
344*f6dc9357SAndroid Build Coastguard Worker     scode = hr;
345*f6dc9357SAndroid Build Coastguard Worker   }
346*f6dc9357SAndroid Build Coastguard Worker   return hr;
347*f6dc9357SAndroid Build Coastguard Worker }
348*f6dc9357SAndroid Build Coastguard Worker 
InternalCopy(const PROPVARIANT * pSrc)349*f6dc9357SAndroid Build Coastguard Worker void CPropVariant::InternalCopy(const PROPVARIANT *pSrc)
350*f6dc9357SAndroid Build Coastguard Worker {
351*f6dc9357SAndroid Build Coastguard Worker   const HRESULT hr = Copy(pSrc);
352*f6dc9357SAndroid Build Coastguard Worker   if (FAILED(hr))
353*f6dc9357SAndroid Build Coastguard Worker   {
354*f6dc9357SAndroid Build Coastguard Worker     if (hr == E_OUTOFMEMORY)
355*f6dc9357SAndroid Build Coastguard Worker       throw kMemException;
356*f6dc9357SAndroid Build Coastguard Worker     vt = VT_ERROR;
357*f6dc9357SAndroid Build Coastguard Worker     scode = hr;
358*f6dc9357SAndroid Build Coastguard Worker   }
359*f6dc9357SAndroid Build Coastguard Worker }
360*f6dc9357SAndroid Build Coastguard Worker 
361*f6dc9357SAndroid Build Coastguard Worker 
Compare(const CPropVariant & a)362*f6dc9357SAndroid Build Coastguard Worker int CPropVariant::Compare(const CPropVariant &a) throw()
363*f6dc9357SAndroid Build Coastguard Worker {
364*f6dc9357SAndroid Build Coastguard Worker   if (vt != a.vt)
365*f6dc9357SAndroid Build Coastguard Worker     return MyCompare(vt, a.vt);
366*f6dc9357SAndroid Build Coastguard Worker   switch ((unsigned)vt)
367*f6dc9357SAndroid Build Coastguard Worker   {
368*f6dc9357SAndroid Build Coastguard Worker     case VT_EMPTY: return 0;
369*f6dc9357SAndroid Build Coastguard Worker     // case VT_I1: return MyCompare(cVal, a.cVal);
370*f6dc9357SAndroid Build Coastguard Worker     case VT_UI1: return MyCompare(bVal, a.bVal);
371*f6dc9357SAndroid Build Coastguard Worker     case VT_I2: return MyCompare(iVal, a.iVal);
372*f6dc9357SAndroid Build Coastguard Worker     case VT_UI2: return MyCompare(uiVal, a.uiVal);
373*f6dc9357SAndroid Build Coastguard Worker     case VT_I4: return MyCompare(lVal, a.lVal);
374*f6dc9357SAndroid Build Coastguard Worker     case VT_UI4: return MyCompare(ulVal, a.ulVal);
375*f6dc9357SAndroid Build Coastguard Worker     // case VT_UINT: return MyCompare(uintVal, a.uintVal);
376*f6dc9357SAndroid Build Coastguard Worker     case VT_I8: return MyCompare(hVal.QuadPart, a.hVal.QuadPart);
377*f6dc9357SAndroid Build Coastguard Worker     case VT_UI8: return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart);
378*f6dc9357SAndroid Build Coastguard Worker     case VT_BOOL: return -MyCompare(boolVal, a.boolVal);
379*f6dc9357SAndroid Build Coastguard Worker     case VT_FILETIME:
380*f6dc9357SAndroid Build Coastguard Worker     {
381*f6dc9357SAndroid Build Coastguard Worker       const int res = CompareFileTime(&filetime, &a.filetime);
382*f6dc9357SAndroid Build Coastguard Worker       if (res != 0)
383*f6dc9357SAndroid Build Coastguard Worker         return res;
384*f6dc9357SAndroid Build Coastguard Worker       const unsigned v1 = Get_Ns100();
385*f6dc9357SAndroid Build Coastguard Worker       const unsigned v2 = a.Get_Ns100();
386*f6dc9357SAndroid Build Coastguard Worker       return MyCompare(v1, v2);
387*f6dc9357SAndroid Build Coastguard Worker     }
388*f6dc9357SAndroid Build Coastguard Worker     case VT_BSTR: return 0; // Not implemented
389*f6dc9357SAndroid Build Coastguard Worker     default: return 0;
390*f6dc9357SAndroid Build Coastguard Worker   }
391*f6dc9357SAndroid Build Coastguard Worker }
392*f6dc9357SAndroid Build Coastguard Worker 
393*f6dc9357SAndroid Build Coastguard Worker }}
394