Mercurial > projects > dwt-win
annotate dwt/ole/win32/Variant.d @ 162:619faee45ef6
add missing default cases
author | Thomas Graber <d4rkdragon@gmail.com> |
---|---|
date | Wed, 20 Feb 2008 21:41:58 +0100 |
parents | ecba636b634e |
children | ab60f3309436 |
rev | line source |
---|---|
97 | 1 /******************************************************************************* |
2 * Copyright (c) 2000, 2006 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
98 | 10 * Port to the D programming language: |
11 * Frank Benoit <benoit@tionex.de> | |
97 | 12 *******************************************************************************/ |
13 module dwt.ole.win32.Variant; | |
14 | |
15 import dwt.DWT; | |
16 import dwt.DWTException; | |
17 import dwt.internal.ole.win32.extras; | |
18 import dwt.internal.ole.win32.COM; | |
19 import dwt.internal.ole.win32.COMTYPES; | |
20 import dwt.internal.ole.win32.OAIDL; | |
21 import dwt.internal.win32.OS; | |
22 | |
23 import dwt.ole.win32.OleAutomation; | |
24 import dwt.ole.win32.OLE; | |
25 | |
26 import tango.util.Convert; | |
27 import tango.text.convert.Format; | |
28 | |
29 /** | |
30 * | |
31 * A Variant is a generic OLE mechanism for passing data of different types via a common interface. | |
32 * | |
33 * <p>It is used within the OleAutomation object for getting a property, setting a property or invoking | |
34 * a method on an OLE Control or OLE Document. | |
35 * | |
36 */ | |
37 public final class Variant | |
38 { | |
39 /** | |
40 * A variant always takes up 16 bytes, no matter what you | |
41 * store in it. Objects, strings, and arrays are not physically | |
42 * stored in the Variant; in these cases, four bytes of the | |
43 * Variant are used to hold either an object reference, or a | |
44 * pointer to the string or array. The actual data are stored elsewhere. | |
45 */ | |
46 //public static final int sizeof = 16; | |
47 private short type; // OLE.VT_* type | |
48 | |
49 private bool booleanData; | |
50 private byte byteData; | |
51 private short shortData; | |
52 private char charData; | |
53 private int intData; | |
54 private long longData; | |
55 private float floatData; | |
56 private double doubleData; | |
57 private char[] stringData; | |
58 private void* byRefPtr; | |
59 private IDispatch dispatchData; | |
60 private IUnknown unknownData; | |
61 | |
62 /** | |
63 * Invokes platform specific functionality to copy a variant | |
64 * into operating system memory. | |
65 * <p> | |
66 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public | |
67 * API for <code>Variant</code>. It is marked public only so that it | |
68 * can be shared within the packages provided by DWT. It is not | |
69 * available on all platforms, and should never be called from | |
70 * application code. | |
71 * </p> | |
72 * | |
73 * @param pVarDest destination pointer to a variant | |
74 * @param varSrc source <code>Variant</code> | |
75 * | |
76 * @since 3.3 | |
77 */ | |
78 public static void win32_copy (VARIANT* pVarDest, Variant varSrc) { | |
79 varSrc.getData (pVarDest); | |
80 } | |
81 | |
82 /** | |
83 * Invokes platform specific functionality to wrap a variant | |
84 * that was allocated in operating system memory. | |
85 * <p> | |
86 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public | |
87 * API for <code>Variant</code>. It is marked public only so that it | |
88 * can be shared within the packages provided by DWT. It is not | |
89 * available on all platforms, and should never be called from | |
90 * application code. | |
91 * </p> | |
92 * | |
93 * @param pVariant pointer to a variant | |
94 * | |
95 * @return a new <code>Variant</code> | |
96 * | |
97 * @since 3.3 | |
98 */ | |
99 public static Variant win32_new (VARIANT* pVariant) { | |
100 Variant variant = new Variant (); | |
101 variant.setData (pVariant); | |
102 return variant; | |
103 } | |
104 | |
105 /** | |
106 * Create an empty Variant object with type VT_EMPTY. | |
107 * | |
108 * @since 2.0 | |
109 */ | |
110 public this(){ | |
111 type = COM.VT_EMPTY; | |
112 } | |
113 /** | |
114 * Create a Variant object which represents a Java float as a VT_R4. | |
115 * | |
116 * @param val the Java float value that this Variant represents | |
117 * | |
118 */ | |
119 public this(float val) { | |
120 type = COM.VT_R4; | |
121 floatData = val; | |
122 | |
123 } | |
124 /** | |
125 * Create a Variant object which represents a Java double as a VT_R8. | |
126 * | |
127 * @param val the Java double value that this Variant represents | |
128 * | |
129 * @since 3.2 | |
130 */ | |
131 public this(double val) { | |
132 type = COM.VT_R8; | |
133 doubleData = val; | |
134 } | |
135 /** | |
136 * Create a Variant object which represents a Java int as a VT_I4. | |
137 * | |
138 * @param val the Java int value that this Variant represents | |
139 * | |
140 */ | |
141 public this(int val) { | |
142 type = COM.VT_I4; | |
143 intData = val; | |
144 } | |
145 public this(uint val) { | |
146 type = COM.VT_I4; | |
147 intData = val; | |
148 } | |
149 /** | |
150 * Create a Variant object which contains a reference to the data being transferred. | |
151 * | |
152 * <p>When creating a VT_BYREF Variant, you must give the full Variant type | |
153 * including VT_BYREF such as | |
154 * | |
155 * <pre><code>short byRefType = OLE.VT_BSTR | OLE.VT_BYREF</code></pre>. | |
156 * | |
157 * @param ptr a pointer to the data being transferred. | |
158 * @param byRefType the type of the data being transferred such as OLE.VT_BSTR | OLE.VT_BYREF | |
159 * | |
160 */ | |
161 public this(void* ptr, ushort byRefType) { | |
162 type = byRefType; | |
163 byRefPtr = ptr; | |
164 } | |
165 /** | |
166 * Create a Variant object which represents an IDispatch interface as a VT_Dispatch. | |
167 * | |
168 * @param automation the OleAutomation object that this Variant represents | |
169 * | |
170 */ | |
171 public this(OleAutomation automation) { | |
172 type = COM.VT_DISPATCH; | |
173 dispatchData = automation.getAddress(); | |
174 } | |
175 /** | |
176 * Create a Variant object which represents an IDispatch interface as a VT_Dispatch. | |
177 * <p>The caller is expected to have appropriately invoked unknown.AddRef() before creating | |
178 * this Variant. | |
179 * | |
180 * @since 2.0 | |
181 * | |
182 * @param idispatch the IDispatch object that this Variant represents | |
183 * | |
184 */ | |
185 public this(IDispatch idispatch) { | |
186 type = COM.VT_DISPATCH; | |
187 dispatchData = idispatch; | |
188 } | |
189 /** | |
190 * Create a Variant object which represents an IUnknown interface as a VT_UNKNOWN. | |
191 * | |
192 * <p>The caller is expected to have appropriately invoked unknown.AddRef() before creating | |
193 * this Variant. | |
194 * | |
195 * @param unknown the IUnknown object that this Variant represents | |
196 * | |
197 */ | |
198 public this(IUnknown unknown) { | |
199 type = COM.VT_UNKNOWN; | |
200 unknownData = unknown; | |
201 } | |
202 /** | |
203 * Create a Variant object which represents a Java long as a VT_I8. | |
204 * | |
205 * @param val the Java long value that this Variant represents | |
206 * | |
207 *@since 3.2 | |
208 */ | |
209 public this(long val) { | |
210 type = COM.VT_I8; | |
211 longData = val; | |
212 } | |
213 /** | |
214 * Create a Variant object which represents a Java String as a VT_BSTR. | |
215 * | |
216 * @param string the Java String value that this Variant represents | |
217 * | |
218 */ | |
219 public this(char[] string) { | |
220 type = COM.VT_BSTR; | |
221 stringData = string; | |
222 } | |
223 /** | |
224 * Create a Variant object which represents a Java short as a VT_I2. | |
225 * | |
226 * @param val the Java short value that this Variant represents | |
227 * | |
228 */ | |
229 public this(short val) { | |
230 type = COM.VT_I2; | |
231 shortData = val; | |
232 } | |
233 /** | |
234 * Create a Variant object which represents a Java bool as a VT_BOOL. | |
235 * | |
236 * @param val the Java bool value that this Variant represents | |
237 * | |
238 */ | |
239 public this(bool val) { | |
240 type = COM.VT_BOOL; | |
241 booleanData = val; | |
242 } | |
243 | |
244 /** | |
245 * Calling dispose will release resources associated with this Variant. | |
246 * If the resource is an IDispatch or IUnknown interface, Release will be called. | |
247 * If the resource is a ByRef pointer, nothing is released. | |
248 * | |
249 * @since 2.1 | |
250 */ | |
251 public void dispose() { | |
252 if ((type & COM.VT_BYREF) is COM.VT_BYREF) { | |
253 return; | |
254 } | |
255 | |
256 switch (type) { | |
257 case COM.VT_DISPATCH : | |
258 dispatchData.Release(); | |
259 break; | |
260 case COM.VT_UNKNOWN : | |
261 unknownData.Release(); | |
262 break; | |
263 default: | |
264 } | |
265 | |
266 } | |
267 /** | |
268 * Returns the OleAutomation object represented by this Variant. | |
269 * | |
270 * <p>If this Variant does not contain an OleAutomation object, an attempt is made to | |
271 * coerce the Variant type into an OleAutomation object. If this fails, an error is | |
272 * thrown. Note that OleAutomation objects must be disposed when no longer | |
273 * needed. | |
274 * | |
275 * @return the OleAutomation object represented by this Variant | |
276 * | |
277 * @exception DWTException <ul> | |
278 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into an OleAutomation object</li> | |
279 * </ul> | |
280 */ | |
281 public OleAutomation getAutomation() { | |
282 if (type is COM.VT_EMPTY) { | |
98 | 283 OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); |
97 | 284 } |
285 if (type is COM.VT_DISPATCH) { | |
286 return new OleAutomation(dispatchData); | |
287 } | |
288 // try to coerce the value to the desired type | |
98 | 289 VARIANT oldPtr, newPtr; |
97 | 290 try { |
98 | 291 getData(&oldPtr); |
292 HRESULT result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_DISPATCH); | |
97 | 293 if (result !is COM.S_OK) |
98 | 294 OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); |
97 | 295 Variant autoVar = new Variant(); |
98 | 296 autoVar.setData(&newPtr); |
97 | 297 return autoVar.getAutomation(); |
298 } finally { | |
98 | 299 COM.VariantClear(&oldPtr); |
300 COM.VariantClear(&newPtr); // Note: This must absolutely be done AFTER the | |
97 | 301 // OleAutomation object is created as Variant Clear |
302 // will result in a Release being performed on the | |
303 // Dispatch object | |
304 } | |
305 } | |
306 /** | |
307 * Returns the IDispatch object represented by this Variant. | |
308 * | |
309 * <p>If this Variant does not contain an IDispatch object, an attempt is made to | |
310 * coerce the Variant type into an IDIspatch object. If this fails, an error is | |
311 * thrown. | |
312 * | |
313 * @since 2.0 | |
314 * | |
315 * @return the IDispatch object represented by this Variant | |
316 * | |
317 * @exception DWTException <ul> | |
318 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into an IDispatch object</li> | |
319 * </ul> | |
320 */ | |
321 public IDispatch getDispatch() { | |
322 if (type is COM.VT_EMPTY) { | |
98 | 323 OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); |
97 | 324 } |
98 | 325 |
97 | 326 if (type is COM.VT_DISPATCH) { |
327 return dispatchData; | |
328 } | |
329 // try to coerce the value to the desired type | |
98 | 330 VARIANT oldPtr, newPtr; |
97 | 331 try { |
98 | 332 getData(&oldPtr); |
333 HRESULT result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_DISPATCH); | |
97 | 334 if (result !is COM.S_OK) |
98 | 335 OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); |
97 | 336 Variant autoVar = new Variant(); |
98 | 337 autoVar.setData(&newPtr); |
97 | 338 return autoVar.getDispatch(); |
339 } finally { | |
98 | 340 COM.VariantClear(&oldPtr); |
341 COM.VariantClear(&newPtr); // Note: This must absolutely be done AFTER the | |
97 | 342 // OleAutomation object is created as Variant Clear |
343 // will result in a Release being performed on the | |
344 // Dispatch object | |
345 } | |
346 } | |
347 /** | |
348 * Returns the Java bool represented by this Variant. | |
349 * | |
350 * <p>If this Variant does not contain a Java bool, an attempt is made to | |
351 * coerce the Variant type into a Java bool. If this fails, an error is thrown. | |
352 * | |
353 * @return the Java bool represented by this Variant | |
354 * | |
355 * @exception DWTException <ul> | |
356 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a bool</li> | |
357 * </ul> | |
358 * | |
359 */ | |
360 public bool getBoolean() { | |
361 if (type is COM.VT_EMPTY) { | |
98 | 362 OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); |
97 | 363 } |
364 if (type is COM.VT_BOOL) { | |
365 return booleanData; | |
366 } | |
367 // try to coerce the value to the desired type | |
98 | 368 VARIANT oldPtr, newPtr; |
97 | 369 try { |
98 | 370 getData(&oldPtr); |
371 HRESULT result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_BOOL); | |
97 | 372 if (result !is COM.S_OK) |
98 | 373 OLE.error(__FILE__, __LINE__, OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); |
97 | 374 Variant boolVar = new Variant(); |
98 | 375 boolVar.setData(&newPtr); |
97 | 376 return boolVar.getBoolean(); |
377 } finally { | |
98 | 378 COM.VariantClear(&oldPtr); |
379 COM.VariantClear(&newPtr); | |
97 | 380 } |
381 } | |
382 /** | |
383 * Returns a pointer to the referenced data represented by this Variant. | |
384 * | |
385 * <p>If this Variant does not contain a reference to data, zero is returned. | |
386 * | |
387 * @return a pointer to the referenced data represented by this Variant or 0 | |
388 * | |
389 */ | |
390 public void* getByRef() { | |
391 if (type is COM.VT_EMPTY) { | |
392 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
393 } | |
394 if ((type & COM.VT_BYREF)is COM.VT_BYREF) { | |
395 return byRefPtr; | |
396 } | |
397 | |
398 return null; | |
399 } | |
400 /** | |
401 * Returns the Java byte represented by this Variant. | |
402 * | |
403 * <p>If this Variant does not contain a Java byte, an attempt is made to | |
404 * coerce the Variant type into a Java byte. If this fails, an error is thrown. | |
405 * | |
406 * @return the Java byte represented by this Variant | |
407 * | |
408 * @exception DWTException <ul> | |
409 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a byte</li> | |
410 * </ul> | |
411 * | |
412 * @since 3.3 | |
413 */ | |
414 public byte getByte() { | |
415 if (type is COM.VT_EMPTY) { | |
416 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
417 } | |
418 if (type is COM.VT_I1) { | |
419 return byteData; | |
420 } | |
421 | |
422 // try to coerce the value to the desired type | |
98 | 423 VARIANT oldPtr, newPtr; |
97 | 424 try { |
98 | 425 getData(&oldPtr); |
426 int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_I1); | |
97 | 427 if (result !is COM.S_OK) |
428 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
429 Variant byteVar = new Variant(); | |
98 | 430 byteVar.setData(&newPtr); |
97 | 431 return byteVar.getByte(); |
432 } finally { | |
98 | 433 COM.VariantClear(&oldPtr); |
434 COM.VariantClear(&newPtr); | |
97 | 435 } |
436 } | |
437 /** | |
438 * Returns the Java char represented by this Variant. | |
439 * | |
440 * <p>If this Variant does not contain a Java char, an attempt is made to | |
441 * coerce the Variant type into a Java char. If this fails, an error is thrown. | |
442 * | |
443 * @return the Java char represented by this Variant | |
444 * | |
445 * @exception DWTException <ul> | |
446 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a char</li> | |
447 * </ul> | |
448 * | |
449 * @since 3.3 | |
450 */ | |
451 public char getChar() { | |
452 if (type is COM.VT_EMPTY) { | |
453 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
454 } | |
455 if (type is COM.VT_UI2) { | |
456 return charData; | |
457 } | |
458 | |
459 // try to coerce the value to the desired type | |
98 | 460 VARIANT oldPtr, newPtr; |
97 | 461 try { |
98 | 462 getData(&oldPtr); |
463 int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_UI2); | |
97 | 464 if (result !is COM.S_OK) |
465 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
466 Variant charVar = new Variant(); | |
98 | 467 charVar.setData(&newPtr); |
97 | 468 return charVar.getChar(); |
469 } finally { | |
98 | 470 COM.VariantClear(&oldPtr); |
471 COM.VariantClear(&newPtr); | |
97 | 472 } |
473 } | |
474 void getData(VARIANT* pData){ | |
475 if (pData is null) OLE.error(OLE.ERROR_OUT_OF_MEMORY); | |
476 | |
477 COM.VariantInit(pData); | |
478 | |
479 // set type | |
480 pData.vt = type; | |
481 if ((type & COM.VT_BYREF) is COM.VT_BYREF) { | |
482 COM.MoveMemory(pData, &type, 2); | |
483 COM.MoveMemory(pData + 8, &byRefPtr, 4); | |
484 return; | |
485 } | |
486 | |
487 switch (type) { | |
488 case COM.VT_EMPTY : | |
489 case COM.VT_NULL : | |
490 COM.MoveMemory(pData, &type, 2); | |
491 break; | |
492 case COM.VT_BOOL : | |
493 COM.MoveMemory(pData, &type, 2); | |
494 auto v = booleanData ? COM.VARIANT_TRUE : COM.VARIANT_FALSE; | |
495 COM.MoveMemory(pData + 8, &v, 2); | |
496 break; | |
497 case COM.VT_I1 : | |
498 COM.MoveMemory(pData, &type, 2); | |
499 COM.MoveMemory(pData + 8, &byteData, 1); | |
500 break; | |
501 case COM.VT_I2 : | |
502 COM.MoveMemory(pData, &type, 2); | |
503 COM.MoveMemory(pData + 8, &shortData, 2); | |
504 break; | |
505 case COM.VT_UI2 : | |
506 COM.MoveMemory(pData, &type, 2); | |
507 COM.MoveMemory(pData + 8, &charData, 2); | |
508 break; | |
509 case COM.VT_I4 : | |
510 COM.MoveMemory(pData, &type, 2); | |
511 COM.MoveMemory(pData + 8, &intData, 4); | |
512 break; | |
513 case COM.VT_I8 : | |
514 COM.MoveMemory(pData, &type, 2); | |
515 COM.MoveMemory(pData + 8, &longData, 8); | |
516 break; | |
517 case COM.VT_R4 : | |
518 COM.MoveMemory(pData, &type, 2); | |
519 COM.MoveMemory(pData + 8, &floatData, 4); | |
520 break; | |
521 case COM.VT_R8 : | |
522 COM.MoveMemory(pData, &type, 2); | |
523 COM.MoveMemory(pData + 8, &doubleData, 8); | |
524 break; | |
525 case COM.VT_DISPATCH : | |
526 dispatchData.AddRef(); | |
527 COM.MoveMemory(pData, &type, 2); | |
528 auto v = cast(void*)dispatchData; | |
529 COM.MoveMemory(pData + 8, &v, 4); | |
530 break; | |
531 case COM.VT_UNKNOWN : | |
532 unknownData.AddRef(); | |
533 COM.MoveMemory(pData, &type, 2); | |
534 auto v = cast(void*)dispatchData; | |
535 COM.MoveMemory(pData + 8, &v, 4); | |
536 break; | |
537 case COM.VT_BSTR : | |
538 COM.MoveMemory(pData, &type, 2); | |
539 wchar[] data = StrToWCHARs(stringData); | |
540 auto ptr = COM.SysAllocString(data.ptr); | |
541 COM.MoveMemory(pData + 8, &ptr, 4); | |
542 break; | |
543 | |
544 default : | |
545 OLE.error(DWT.ERROR_NOT_IMPLEMENTED); | |
546 } | |
547 } | |
548 /** | |
549 * Returns the Java double represented by this Variant. | |
550 * | |
551 * <p>If this Variant does not contain a Java double, an attempt is made to | |
552 * coerce the Variant type into a Java double. If this fails, an error is thrown. | |
553 * | |
554 * @return the Java double represented by this Variant | |
555 * | |
556 * @exception DWTException <ul> | |
557 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a double</li> | |
558 * </ul> | |
559 * | |
560 * @since 3.2 | |
561 */ | |
562 public double getDouble() { | |
563 if (type is COM.VT_EMPTY) { | |
564 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
565 } | |
566 if (type is COM.VT_R8) { | |
567 return doubleData; | |
568 } | |
569 | |
570 // try to coerce the value to the desired type | |
98 | 571 VARIANT oldPtr, newPtr; |
97 | 572 try { |
98 | 573 getData(&oldPtr); |
574 int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_R8); | |
97 | 575 if (result !is COM.S_OK) |
576 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
577 Variant doubleVar = new Variant(); | |
98 | 578 doubleVar.setData(&newPtr); |
97 | 579 return doubleVar.getDouble(); |
580 } finally { | |
98 | 581 COM.VariantClear(&oldPtr); |
582 COM.VariantClear(&newPtr); | |
97 | 583 } |
584 } | |
585 | |
586 /** | |
587 * Returns the Java float represented by this Variant. | |
588 * | |
589 * <p>If this Variant does not contain a Java float, an attempt is made to | |
590 * coerce the Variant type into a Java float. If this fails, an error is thrown. | |
591 * | |
592 * @return the Java float represented by this Variant | |
593 * | |
594 * @exception DWTException <ul> | |
595 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a float</li> | |
596 * </ul> | |
597 */ | |
598 public float getFloat() { | |
599 if (type is COM.VT_EMPTY) { | |
600 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
601 } | |
602 if (type is COM.VT_R4) { | |
603 return floatData; | |
604 } | |
605 | |
606 // try to coerce the value to the desired type | |
98 | 607 VARIANT oldPtr, newPtr; |
97 | 608 try { |
98 | 609 getData(&oldPtr); |
610 int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_R4); | |
97 | 611 if (result !is COM.S_OK) |
612 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
613 Variant floatVar = new Variant(); | |
98 | 614 floatVar.setData(&newPtr); |
97 | 615 return floatVar.getFloat(); |
616 } finally { | |
98 | 617 COM.VariantClear(&oldPtr); |
618 COM.VariantClear(&newPtr); | |
97 | 619 } |
620 | |
621 } | |
622 /** | |
623 * Returns the Java int represented by this Variant. | |
624 * | |
625 * <p>If this Variant does not contain a Java int, an attempt is made to | |
626 * coerce the Variant type into a Java int. If this fails, an error is thrown. | |
627 * | |
628 * @return the Java int represented by this Variant | |
629 * | |
630 * @exception DWTException <ul> | |
631 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a int</li> | |
632 * </ul> | |
633 */ | |
634 public int getInt() { | |
635 if (type is COM.VT_EMPTY) { | |
636 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
637 } | |
638 if (type is COM.VT_I4) { | |
639 return intData; | |
640 } | |
641 | |
642 // try to coerce the value to the desired type | |
98 | 643 VARIANT oldPtr, newPtr; |
97 | 644 try { |
98 | 645 getData(&oldPtr); |
646 int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_I4); | |
97 | 647 if (result !is COM.S_OK) |
648 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
649 Variant intVar = new Variant(); | |
98 | 650 intVar.setData(&newPtr); |
97 | 651 return intVar.getInt(); |
652 } finally { | |
98 | 653 COM.VariantClear(&oldPtr); |
654 COM.VariantClear(&newPtr); | |
97 | 655 } |
656 } | |
657 /** | |
658 * Returns the Java long represented by this Variant. | |
659 * | |
660 * <p>If this Variant does not contain a Java long, an attempt is made to | |
661 * coerce the Variant type into a Java long. If this fails, an error is thrown. | |
662 * | |
663 * @return the Java long represented by this Variant | |
664 * | |
665 * @exception DWTException <ul> | |
666 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a long</li> | |
667 * </ul> | |
668 * | |
669 * @since 3.2 | |
670 */ | |
671 public long getLong() { | |
672 if (type is COM.VT_EMPTY) { | |
673 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
674 } | |
675 if (type is COM.VT_I8) { | |
676 return longData; | |
677 } | |
678 | |
679 // try to coerce the value to the desired type | |
98 | 680 VARIANT oldPtr, newPtr; |
97 | 681 try { |
98 | 682 getData(&oldPtr); |
683 int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_I8); | |
97 | 684 if (result !is COM.S_OK) |
685 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
686 Variant longVar = new Variant(); | |
98 | 687 longVar.setData(&newPtr); |
97 | 688 return longVar.getLong(); |
689 } finally { | |
98 | 690 COM.VariantClear(&oldPtr); |
691 COM.VariantClear(&newPtr); | |
97 | 692 } |
693 } | |
694 /** | |
695 * Returns the Java short represented by this Variant. | |
696 * | |
697 * <p>If this Variant does not contain a Java short, an attempt is made to | |
698 * coerce the Variant type into a Java short. If this fails, an error is thrown. | |
699 * | |
700 * @return the Java short represented by this Variant | |
701 * | |
702 * @exception DWTException <ul> | |
703 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a short</li> | |
704 * </ul> | |
705 */ | |
706 public short getShort() { | |
707 if (type is COM.VT_EMPTY) { | |
708 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
709 } | |
710 if (type is COM.VT_I2) { | |
711 return shortData; | |
712 } | |
713 | |
714 // try to coerce the value to the desired type | |
98 | 715 VARIANT oldPtr, newPtr; |
97 | 716 try { |
98 | 717 getData(&oldPtr); |
718 int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_I2); | |
97 | 719 if (result !is COM.S_OK) |
720 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
721 Variant shortVar = new Variant(); | |
98 | 722 shortVar.setData(&newPtr); |
97 | 723 return shortVar.getShort(); |
724 } finally { | |
98 | 725 COM.VariantClear(&oldPtr); |
726 COM.VariantClear(&newPtr); | |
97 | 727 } |
728 | |
729 } | |
730 /** | |
731 * Returns the Java String represented by this Variant. | |
732 * | |
733 * <p>If this Variant does not contain a Java String, an attempt is made to | |
734 * coerce the Variant type into a Java String. If this fails, an error is thrown. | |
735 * | |
736 * @return the Java String represented by this Variant | |
737 * | |
738 * @exception DWTException <ul> | |
739 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a String</li> | |
740 * </ul> | |
741 */ | |
742 public char[] getString() { | |
743 if (type is COM.VT_EMPTY) { | |
744 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
745 } | |
746 if (type is COM.VT_BSTR) { | |
747 return stringData; | |
748 } | |
749 | |
750 // try to coerce the value to the desired type | |
98 | 751 VARIANT oldPtr, newPtr; |
97 | 752 try { |
98 | 753 getData(&oldPtr); |
754 int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_BSTR); | |
97 | 755 if (result !is COM.S_OK) |
756 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
757 | |
758 Variant stringVar = new Variant(); | |
98 | 759 stringVar.setData(&newPtr); |
97 | 760 return stringVar.getString(); |
761 | |
762 } finally { | |
98 | 763 COM.VariantClear(&oldPtr); |
764 COM.VariantClear(&newPtr); | |
97 | 765 } |
766 } | |
767 /** | |
768 * Returns the type of the variant type. This will be an OLE.VT_* value or | |
769 * a bitwise combination of OLE.VT_* values as in the case of | |
770 * OLE.VT_BSTR | OLE.VT_BYREF. | |
771 * | |
772 * @return the type of the variant data | |
773 * | |
774 * @since 2.0 | |
775 */ | |
776 public short getType() { | |
777 return type; | |
778 } | |
779 /** | |
780 * Returns the IUnknown object represented by this Variant. | |
781 * | |
782 * <p>If this Variant does not contain an IUnknown object, an attempt is made to | |
783 * coerce the Variant type into an IUnknown object. If this fails, an error is | |
784 * thrown. | |
785 * | |
786 * @return the IUnknown object represented by this Variant | |
787 * | |
788 * @exception DWTException <ul> | |
789 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into | |
790 * an IUnknown object</li> | |
791 * </ul> | |
792 */ | |
793 public IUnknown getUnknown() { | |
794 if (type is COM.VT_EMPTY) { | |
795 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1); | |
796 } | |
797 if (type is COM.VT_UNKNOWN) { | |
798 return unknownData; | |
799 } | |
800 | |
801 // try to coerce the value to the desired type | |
98 | 802 VARIANT oldPtr, newPtr; |
97 | 803 try { |
98 | 804 getData(&oldPtr); |
805 int result = COM.VariantChangeType(&newPtr, &oldPtr, 0, COM.VT_UNKNOWN); | |
97 | 806 if (result !is COM.S_OK) |
807 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result); | |
808 Variant unknownVar = new Variant(); | |
98 | 809 unknownVar.setData(&newPtr); |
97 | 810 return unknownVar.getUnknown(); |
811 } finally { | |
98 | 812 COM.VariantClear(&oldPtr); |
813 COM.VariantClear(&newPtr); // Note: This must absolutely be done AFTER the | |
97 | 814 // IUnknown object is created as Variant Clear |
815 // will result in a Release being performed on the | |
816 // Dispatch object | |
817 } | |
818 } | |
819 /** | |
820 * Update the by reference value of this variant with a new bool value. | |
821 * | |
822 * @param val the new bool value | |
823 * | |
824 * @exception DWTException <ul> | |
825 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant is not | |
826 * a (VT_BYREF | VT_BOOL) object</li> | |
827 * </ul> | |
828 * | |
829 * @since 2.1 | |
830 */ | |
831 public void setByRef(bool val) { | |
832 if ((type & COM.VT_BYREF) is 0 || (type & COM.VT_BOOL) is 0) { | |
833 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE); | |
834 } | |
835 auto v = val ? COM.VARIANT_TRUE : COM.VARIANT_FALSE; | |
836 COM.MoveMemory(byRefPtr, &v, 2); | |
837 } | |
838 /** | |
839 * Update the by reference value of this variant with a new float value. | |
840 * | |
841 * @param val the new float value | |
842 * | |
843 * @exception DWTException <ul> | |
844 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant is not | |
845 * a (VT_BYREF | VT_R4) object</li> | |
846 * </ul> | |
847 * | |
848 * @since 2.1 | |
849 */ | |
850 public void setByRef(float val) { | |
851 if ((type & COM.VT_BYREF) is 0 || (type & COM.VT_R4) is 0) { | |
852 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE); | |
853 } | |
854 COM.MoveMemory(byRefPtr, &val, 4); | |
855 } | |
856 /** | |
857 * Update the by reference value of this variant with a new integer value. | |
858 * | |
859 * @param val the new integer value | |
860 * | |
861 * @exception DWTException <ul> | |
862 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant is not a (VT_BYREF | VT_I4) object</li> | |
863 * </ul> | |
864 * | |
865 * @since 2.1 | |
866 */ | |
867 public void setByRef(int val) { | |
868 if ((type & COM.VT_BYREF) is 0 || (type & COM.VT_I4) is 0) { | |
869 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE); | |
870 } | |
871 COM.MoveMemory(byRefPtr, &val, 4); | |
872 } | |
873 /** | |
874 * Update the by reference value of this variant with a new short value. | |
875 * | |
876 * @param val the new short value | |
877 * | |
878 * @exception DWTException <ul> | |
879 * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant is not a (VT_BYREF | VT_I2) object | |
880 * </ul> | |
881 * | |
882 * @since 2.1 | |
883 */ | |
884 public void setByRef(short val) { | |
885 if ((type & COM.VT_BYREF) is 0 || (type & COM.VT_I2) is 0) { | |
886 OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE); | |
887 } | |
888 COM.MoveMemory(byRefPtr, &val, 2); | |
889 } | |
890 | |
891 void setData(VARIANT* pData){ | |
892 if (pData is null) OLE.error(OLE.ERROR_INVALID_ARGUMENT); | |
893 | |
894 short[1] dataType ; | |
895 COM.MoveMemory(dataType.ptr, pData, 2); | |
896 type = dataType[0]; | |
897 | |
898 if ((type & COM.VT_BYREF) is COM.VT_BYREF) { | |
899 void*[1] newByRefPtr; | |
900 OS.MoveMemory(newByRefPtr.ptr, pData + 8, 4); | |
901 byRefPtr = newByRefPtr[0]; | |
902 return; | |
903 } | |
904 | |
905 switch (type) { | |
906 case COM.VT_EMPTY : | |
907 case COM.VT_NULL : | |
908 break; | |
909 case COM.VT_BOOL : | |
910 short[1] newBooleanData; | |
911 COM.MoveMemory(newBooleanData.ptr, pData + 8, 2); | |
912 booleanData = (newBooleanData[0] !is COM.VARIANT_FALSE); | |
913 break; | |
914 case COM.VT_I1 : | |
915 byte[1] newByteData; | |
916 COM.MoveMemory(newByteData.ptr, pData + 8, 1); | |
917 byteData = newByteData[0]; | |
918 break; | |
919 case COM.VT_I2 : | |
920 short[1] newShortData; | |
921 COM.MoveMemory(newShortData.ptr, pData + 8, 2); | |
922 shortData = newShortData[0]; | |
923 break; | |
924 case COM.VT_UI2 : | |
925 char[1] newCharData; | |
926 COM.MoveMemory(newCharData.ptr, pData + 8, 2); | |
927 charData = newCharData[0]; | |
928 break; | |
929 case COM.VT_I4 : | |
930 int[1] newIntData; | |
931 OS.MoveMemory(newIntData.ptr, pData + 8, 4); | |
932 intData = newIntData[0]; | |
933 break; | |
934 case COM.VT_I8 : | |
935 long[1] newLongData; | |
936 OS.MoveMemory(newLongData.ptr, pData + 8, 8); | |
937 longData = newLongData[0]; | |
938 break; | |
939 case COM.VT_R4 : | |
940 float[1] newFloatData; | |
941 COM.MoveMemory(newFloatData.ptr, pData + 8, 4); | |
942 floatData = newFloatData[0]; | |
943 break; | |
944 case COM.VT_R8 : | |
945 double[1] newDoubleData; | |
946 COM.MoveMemory(newDoubleData.ptr, pData + 8, 8); | |
947 doubleData = newDoubleData[0]; | |
948 break; | |
949 case COM.VT_DISPATCH : { | |
950 IDispatch[1] ppvObject; | |
951 OS.MoveMemory(ppvObject.ptr, pData + 8, 4); | |
952 if (ppvObject[0] is null) { | |
953 type = COM.VT_EMPTY; | |
954 break; | |
955 } | |
956 dispatchData = ppvObject[0]; | |
957 dispatchData.AddRef(); | |
958 break; | |
959 } | |
960 case COM.VT_UNKNOWN : { | |
961 IUnknown[1] ppvObject; | |
962 OS.MoveMemory(ppvObject.ptr, pData + 8, 4); | |
963 if (ppvObject[0] is null) { | |
964 type = COM.VT_EMPTY; | |
965 break; | |
966 } | |
967 unknownData = ppvObject[0]; | |
968 unknownData.AddRef(); | |
969 break; | |
970 } | |
971 case COM.VT_BSTR : | |
972 // get the address of the memory in which the string resides | |
973 wchar*[1] hMem; | |
974 OS.MoveMemory(hMem.ptr, pData + 8, 4); | |
975 if (hMem[0] is null) { | |
976 type = COM.VT_EMPTY; | |
977 break; | |
978 } | |
979 // Get the size of the string from the OS - the size is expressed in number | |
980 // of bytes - each unicode character is 2 bytes. | |
981 int size = COM.SysStringByteLen(hMem[0]); | |
982 if (size > 0){ | |
983 // get the unicode character array from the global memory and create a String | |
984 wchar[] buffer = new wchar[(size + 1) /2]; // add one to avoid rounding errors | |
985 COM.MoveMemory(buffer.ptr, hMem[0], size); | |
986 stringData = WCHARsToStr( buffer ); | |
987 } else { | |
988 stringData = ""; //$NON-NLS-1$ | |
989 } | |
990 break; | |
991 | |
992 default : | |
993 // try coercing it into one of the known forms | |
994 auto newPData = cast(VARIANT*) OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, VARIANT.sizeof); | |
995 if (COM.VariantChangeType(newPData, pData, 0, COM.VT_R4) is COM.S_OK) { | |
996 setData(newPData); | |
997 } else if (COM.VariantChangeType(newPData, pData, 0, COM.VT_I4) is COM.S_OK) { | |
998 setData(newPData); | |
999 } else if (COM.VariantChangeType(newPData, pData, 0, COM.VT_BSTR) is COM.S_OK) { | |
1000 setData(newPData); | |
1001 } | |
1002 COM.VariantClear(newPData); | |
1003 OS.GlobalFree(newPData); | |
1004 break; | |
1005 } | |
1006 } | |
1007 | |
1008 /** | |
1009 * Returns a string containing a concise, human-readable | |
1010 * description of the receiver. | |
1011 * | |
1012 * @return a string representation of the Variant | |
1013 */ | |
1014 public char[] toString () { | |
1015 switch (type) { | |
1016 case COM.VT_BOOL : | |
1017 return "VT_BOOL{"~to!(char[])(booleanData)~"}"; | |
1018 case COM.VT_I1 : | |
1019 return "VT_I1{"~to!(char[])(byteData)~"}"; | |
1020 case COM.VT_I2 : | |
1021 return "VT_I2{"~to!(char[])(shortData)~"}"; | |
1022 case COM.VT_UI2 : | |
1023 return "VT_UI2{"~charData~"}"; | |
1024 case COM.VT_I4 : | |
1025 return "VT_I4{"~to!(char[])(intData)~"}"; | |
1026 case COM.VT_I8 : | |
1027 return "VT_I8{"~to!(char[])(longData)~"}"; | |
1028 case COM.VT_R4 : | |
1029 return "VT_R4{"~to!(char[])(floatData)~"}"; | |
1030 case COM.VT_R8 : | |
1031 return "VT_R8{"~to!(char[])(doubleData)~"}"; | |
1032 case COM.VT_BSTR : | |
1033 return "VT_BSTR{"~stringData~"}"; | |
1034 case COM.VT_DISPATCH : | |
1035 return Format("VT_DISPATCH{{0x{:X}}", cast(void*) (dispatchData is null ? null : dispatchData)); | |
1036 case COM.VT_UNKNOWN : | |
1037 return Format("VT_UNKNOWN{{0x{:X}}", cast(void*) (unknownData is null ? null : unknownData)); | |
1038 case COM.VT_EMPTY : | |
1039 return "VT_EMPTY"; | |
1040 case COM.VT_NULL : | |
1041 return "VT_NULL"; | |
162
619faee45ef6
add missing default cases
Thomas Graber <d4rkdragon@gmail.com>
parents:
98
diff
changeset
|
1042 default: |
97 | 1043 } |
1044 if ((type & COM.VT_BYREF) !is 0) { | |
1045 return Format("VT_BYREF|{}{{{}}",(type & ~COM.VT_BYREF), byRefPtr ); | |
1046 } | |
1047 return "Unsupported Type "~to!(char[])(type); | |
1048 } | |
1049 } |