Fri, 16 Jan 2015 18:13:44 +0100
Integrate suggestion from review to improve consistency with existing code.
1 // Windows/PropVariant.cpp
3 #include "StdAfx.h"
5 #include "PropVariant.h"
7 #include "../Common/Defs.h"
9 namespace NWindows {
10 namespace NCOM {
12 CPropVariant::CPropVariant(const PROPVARIANT& varSrc)
13 {
14 vt = VT_EMPTY;
15 InternalCopy(&varSrc);
16 }
18 CPropVariant::CPropVariant(const CPropVariant& varSrc)
19 {
20 vt = VT_EMPTY;
21 InternalCopy(&varSrc);
22 }
24 CPropVariant::CPropVariant(BSTR bstrSrc)
25 {
26 vt = VT_EMPTY;
27 *this = bstrSrc;
28 }
30 CPropVariant::CPropVariant(LPCOLESTR lpszSrc)
31 {
32 vt = VT_EMPTY;
33 *this = lpszSrc;
34 }
36 CPropVariant& CPropVariant::operator=(const CPropVariant& varSrc)
37 {
38 InternalCopy(&varSrc);
39 return *this;
40 }
41 CPropVariant& CPropVariant::operator=(const PROPVARIANT& varSrc)
42 {
43 InternalCopy(&varSrc);
44 return *this;
45 }
47 CPropVariant& CPropVariant::operator=(BSTR bstrSrc)
48 {
49 *this = (LPCOLESTR)bstrSrc;
50 return *this;
51 }
53 CPropVariant& CPropVariant::operator=(LPCOLESTR lpszSrc)
54 {
55 InternalClear();
56 vt = VT_BSTR;
57 bstrVal = ::SysAllocString(lpszSrc);
58 if (bstrVal == NULL && lpszSrc != NULL)
59 {
60 vt = VT_ERROR;
61 scode = E_OUTOFMEMORY;
62 }
63 return *this;
64 }
67 CPropVariant& CPropVariant::operator=(bool bSrc)
68 {
69 if (vt != VT_BOOL)
70 {
71 InternalClear();
72 vt = VT_BOOL;
73 }
74 boolVal = bSrc ? VARIANT_TRUE : VARIANT_FALSE;
75 return *this;
76 }
78 CPropVariant& CPropVariant::operator=(UInt32 value)
79 {
80 if (vt != VT_UI4)
81 {
82 InternalClear();
83 vt = VT_UI4;
84 }
85 ulVal = value;
86 return *this;
87 }
89 CPropVariant& CPropVariant::operator=(UInt64 value)
90 {
91 if (vt != VT_UI8)
92 {
93 InternalClear();
94 vt = VT_UI8;
95 }
96 uhVal.QuadPart = value;
97 return *this;
98 }
100 CPropVariant& CPropVariant::operator=(const FILETIME &value)
101 {
102 if (vt != VT_FILETIME)
103 {
104 InternalClear();
105 vt = VT_FILETIME;
106 }
107 filetime = value;
108 return *this;
109 }
111 CPropVariant& CPropVariant::operator=(Int32 value)
112 {
113 if (vt != VT_I4)
114 {
115 InternalClear();
116 vt = VT_I4;
117 }
118 lVal = value;
120 return *this;
121 }
123 CPropVariant& CPropVariant::operator=(Byte value)
124 {
125 if (vt != VT_UI1)
126 {
127 InternalClear();
128 vt = VT_UI1;
129 }
130 bVal = value;
131 return *this;
132 }
134 CPropVariant& CPropVariant::operator=(Int16 value)
135 {
136 if (vt != VT_I2)
137 {
138 InternalClear();
139 vt = VT_I2;
140 }
141 iVal = value;
142 return *this;
143 }
145 /*
146 CPropVariant& CPropVariant::operator=(LONG value)
147 {
148 if (vt != VT_I4)
149 {
150 InternalClear();
151 vt = VT_I4;
152 }
153 lVal = value;
154 return *this;
155 }
156 */
158 static HRESULT MyPropVariantClear(PROPVARIANT *propVariant)
159 {
160 switch(propVariant->vt)
161 {
162 case VT_UI1:
163 case VT_I1:
164 case VT_I2:
165 case VT_UI2:
166 case VT_BOOL:
167 case VT_I4:
168 case VT_UI4:
169 case VT_R4:
170 case VT_INT:
171 case VT_UINT:
172 case VT_ERROR:
173 case VT_FILETIME:
174 case VT_UI8:
175 case VT_R8:
176 case VT_CY:
177 case VT_DATE:
178 propVariant->vt = VT_EMPTY;
179 return S_OK;
180 }
181 return ::VariantClear((VARIANTARG *)propVariant);
182 }
184 HRESULT CPropVariant::Clear()
185 {
186 return MyPropVariantClear(this);
187 }
189 HRESULT CPropVariant::Copy(const PROPVARIANT* pSrc)
190 {
191 ::VariantClear((tagVARIANT *)this);
192 switch(pSrc->vt)
193 {
194 case VT_UI1:
195 case VT_I1:
196 case VT_I2:
197 case VT_UI2:
198 case VT_BOOL:
199 case VT_I4:
200 case VT_UI4:
201 case VT_R4:
202 case VT_INT:
203 case VT_UINT:
204 case VT_ERROR:
205 case VT_FILETIME:
206 case VT_UI8:
207 case VT_R8:
208 case VT_CY:
209 case VT_DATE:
210 memmove((PROPVARIANT*)this, pSrc, sizeof(PROPVARIANT));
211 return S_OK;
212 }
213 return ::VariantCopy((tagVARIANT *)this, (tagVARIANT *)(pSrc));
214 }
217 HRESULT CPropVariant::Attach(PROPVARIANT* pSrc)
218 {
219 HRESULT hr = Clear();
220 if (FAILED(hr))
221 return hr;
222 memcpy(this, pSrc, sizeof(PROPVARIANT));
223 pSrc->vt = VT_EMPTY;
224 return S_OK;
225 }
227 HRESULT CPropVariant::Detach(PROPVARIANT* pDest)
228 {
229 HRESULT hr = MyPropVariantClear(pDest);
230 if (FAILED(hr))
231 return hr;
232 memcpy(pDest, this, sizeof(PROPVARIANT));
233 vt = VT_EMPTY;
234 return S_OK;
235 }
237 HRESULT CPropVariant::InternalClear()
238 {
239 HRESULT hr = Clear();
240 if (FAILED(hr))
241 {
242 vt = VT_ERROR;
243 scode = hr;
244 }
245 return hr;
246 }
248 void CPropVariant::InternalCopy(const PROPVARIANT* pSrc)
249 {
250 HRESULT hr = Copy(pSrc);
251 if (FAILED(hr))
252 {
253 vt = VT_ERROR;
254 scode = hr;
255 }
256 }
258 int CPropVariant::Compare(const CPropVariant &a)
259 {
260 if(vt != a.vt)
261 return 0; // it's mean some bug
262 switch (vt)
263 {
264 case VT_EMPTY:
265 return 0;
267 /*
268 case VT_I1:
269 return MyCompare(cVal, a.cVal);
270 */
271 case VT_UI1:
272 return MyCompare(bVal, a.bVal);
274 case VT_I2:
275 return MyCompare(iVal, a.iVal);
276 case VT_UI2:
277 return MyCompare(uiVal, a.uiVal);
279 case VT_I4:
280 return MyCompare(lVal, a.lVal);
281 /*
282 case VT_INT:
283 return MyCompare(intVal, a.intVal);
284 */
285 case VT_UI4:
286 return MyCompare(ulVal, a.ulVal);
287 /*
288 case VT_UINT:
289 return MyCompare(uintVal, a.uintVal);
290 */
291 case VT_I8:
292 return MyCompare(hVal.QuadPart, a.hVal.QuadPart);
293 case VT_UI8:
294 return MyCompare(uhVal.QuadPart, a.uhVal.QuadPart);
296 case VT_BOOL:
297 return -MyCompare(boolVal, a.boolVal);
299 case VT_FILETIME:
300 return ::CompareFileTime(&filetime, &a.filetime);
301 case VT_BSTR:
302 return 0; // Not implemented
303 // return MyCompare(aPropVarint.cVal);
305 default:
306 return 0;
307 }
308 }
310 }}