KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > ole > win32 > Variant


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
10  *******************************************************************************/

11 // Modified by Google
12
package org.eclipse.swt.ole.win32;
13
14 import org.eclipse.swt.*;
15 import org.eclipse.swt.internal.ole.win32.*;
16 import org.eclipse.swt.internal.win32.*;
17 /**
18  *
19  * A Variant is a generic OLE mechanism for passing data of different types via a common interface.
20  *
21  * <p>It is used within the OleAutomation object for getting a property, setting a property or invoking
22  * a method on an OLE Control or OLE Document.
23  *
24  */

25 public final class Variant
26 {
27     /**
28      * A variant always takes up 16 bytes, no matter what you
29      * store in it. Objects, strings, and arrays are not physically
30      * stored in the Variant; in these cases, four bytes of the
31      * Variant are used to hold either an object reference, or a
32      * pointer to the string or array. The actual data are stored elsewhere.
33      */

34     public static final int sizeof = 16;
35     private short type; // OLE.VT_* type
36

37     private boolean booleanData;
38     private byte byteData;
39     private char charData;
40     private double doubleData;
41     private int intData;
42     private float floatData;
43     private long longData;
44     private short shortData;
45     private String JavaDoc stringData;
46     private int byRefPtr;
47     private IDispatch dispatchData;
48     private IUnknown unknownData;
49
50
51 /**
52  * Invokes platform specific functionality to wrap a variant.
53  * <p>
54  * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
55  * API for <code>GC</code>. It is marked public only so that it
56  * can be shared within the packages provided by SWT. It is not
57  * available on all platforms, and should never be called from
58  * application code.
59  * </p>
60  *
61  * @param pVariant pointer to a variant
62  *
63  * @return a new <code>GC</code>
64  *
65  * @since 3.3
66  */

67 public static Variant win32_new (int pVariant) {
68     Variant variant = new Variant ();
69     variant.setData (pVariant);
70     return variant;
71 }
72
73 /**
74  * Invokes platform specific functionality to copy a variant
75  * into operating system memory.
76  * <p>
77  * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
78  * API for <code>Variant</code>. It is marked public only so that it
79  * can be shared within the packages provided by SWT. It is not
80  * available on all platforms, and should never be called from
81  * application code.
82  * </p>
83  *
84  * @param pVarDest destination pointer to a variant
85  * @param varSrc source <code>Variant</code>
86  *
87  * @since 3.3
88  */

89 public static void win32_copy (int pVarDest, Variant varSrc) {
90     varSrc.getData (pVarDest);
91 }
92
93 /**
94  * Create an empty Variant object with type VT_EMPTY.
95  *
96  * @since 2.0
97  */

98 public Variant(){
99     type = COM.VT_EMPTY;
100 }
101 /**
102  * Create a Variant object which represents a Java float as a VT_R4.
103  *
104  * @param val the Java float value that this Variant represents
105  *
106  */

107 public Variant(float val) {
108     type = COM.VT_R4;
109     floatData = val;
110     
111 }
112 /**
113  * Create a Variant object which represents a Java double as a VT_R8.
114  *
115  * @param val the Java double value that this Variant represents
116  *
117  * @since 3.2
118  */

119 public Variant(double val) {
120     type = COM.VT_R8;
121     doubleData = val;
122 }
123 /**
124  * Create a Variant object which represents a Java int as a VT_I4.
125  *
126  * @param val the Java int value that this Variant represents
127  *
128  */

129  public Variant(int val) {
130     type = COM.VT_I4;
131     intData = val;
132 }
133 /**
134  * Create a Variant object which contains a reference to the data being transferred.
135  *
136  * <p>When creating a VT_BYREF Variant, you must give the full Variant type
137  * including VT_BYREF such as
138  *
139  * <pre><code>short byRefType = OLE.VT_BSTR | OLE.VT_BYREF</code></pre>.
140  *
141  * @param ptr a pointer to the data being transferred.
142  * @param byRefType the type of the data being transferred such as OLE.VT_BSTR | OLE.VT_BYREF
143  *
144  */

145 public Variant(int ptr, short byRefType) {
146     type = byRefType;
147     byRefPtr = ptr;
148 }
149 /**
150  * Create a Variant object which represents an IDispatch interface as a VT_Dispatch.
151  *
152  * @param automation the OleAutomation object that this Variant represents
153  *
154  */

155 public Variant(OleAutomation automation) {
156     type = COM.VT_DISPATCH;
157     dispatchData = new IDispatch(automation.getAddress());
158 }
159 /**
160  * Create a Variant object which represents an IDispatch interface as a VT_Dispatch.
161  * <p>The caller is expected to have appropriately invoked unknown.AddRef() before creating
162  * this Variant.
163  *
164  * @since 2.0
165  *
166  * @param idispatch the IDispatch object that this Variant represents
167  *
168  */

169 public Variant(IDispatch idispatch) {
170     type = COM.VT_DISPATCH;
171     dispatchData = idispatch;
172 }
173 /**
174  * Create a Variant object which represents an IUnknown interface as a VT_UNKNOWN.
175  *
176  * <p>The caller is expected to have appropriately invoked unknown.AddRef() before creating
177  * this Variant.
178  *
179  * @param unknown the IUnknown object that this Variant represents
180  *
181  */

182 public Variant(IUnknown unknown) {
183     type = COM.VT_UNKNOWN;
184     unknownData = unknown;
185 }
186 /**
187  * Create a Variant object which represents a Java long as a VT_I8.
188  *
189  * @param val the Java long value that this Variant represents
190  *
191  *@since 3.2
192  */

193  public Variant(long val) {
194     type = COM.VT_I8;
195     longData = val;
196 }
197 /**
198  * Create a Variant object which represents a Java String as a VT_BSTR.
199  *
200  * @param string the Java String value that this Variant represents
201  *
202  */

203 public Variant(String JavaDoc string) {
204     type = COM.VT_BSTR;
205     stringData = string;
206 }
207 /**
208  * Create a Variant object which represents a Java short as a VT_I2.
209  *
210  * @param val the Java short value that this Variant represents
211  *
212  */

213 public Variant(short val) {
214     type = COM.VT_I2;
215     shortData = val;
216 }
217 /**
218  * Create a Variant object which represents a Java boolean as a VT_BOOL.
219  *
220  * @param val the Java boolean value that this Variant represents
221  *
222  */

223 public Variant(boolean val) {
224     type = COM.VT_BOOL;
225     booleanData = val;
226 }
227
228 /**
229  * Calling dispose will release resources associated with this Variant.
230  * If the resource is an IDispatch or IUnknown interface, Release will be called.
231  * If the resource is a ByRef pointer, nothing is released.
232  *
233  * @since 2.1
234  */

235 public void dispose() {
236     if ((type & COM.VT_BYREF) == COM.VT_BYREF) {
237         return;
238     }
239         
240     switch (type) {
241         case COM.VT_DISPATCH :
242             dispatchData.Release();
243             break;
244         case COM.VT_UNKNOWN :
245             unknownData.Release();
246             break;
247     }
248     
249 }
250 /**
251  * Returns the OleAutomation object represented by this Variant.
252  *
253  * <p>If this Variant does not contain an OleAutomation object, an attempt is made to
254  * coerce the Variant type into an OleAutomation object. If this fails, an error is
255  * thrown. Note that OleAutomation objects must be disposed when no longer
256  * needed.
257  *
258  * @return the OleAutomation object represented by this Variant
259  *
260  * @exception SWTException <ul>
261  * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into an OleAutomation object</li>
262  * </ul>
263  */

264 public OleAutomation getAutomation() {
265     if (type == COM.VT_EMPTY) {
266         OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
267     }
268     if (type == COM.VT_DISPATCH) {
269         return new OleAutomation(dispatchData);
270     }
271     // try to coerce the value to the desired type
272
int oldPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
273     int newPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
274     Variant autoVar = null; // GOOGLE: prevent memory leaks
275
try {
276         getData(oldPtr);
277         int result = COM.VariantChangeType(newPtr, oldPtr, (short) 0, COM.VT_DISPATCH);
278         if (result != COM.S_OK)
279             OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
280         autoVar = new Variant();
281         autoVar.setData(newPtr);
282         return autoVar.getAutomation();
283     } finally {
284         COM.VariantClear(oldPtr);
285         OS.GlobalFree(oldPtr);
286         COM.VariantClear(newPtr); // Note: This must absolutely be done AFTER the
287
// OleAutomation object is created as Variant Clear
288
// will result in a Release being performed on the
289
// Dispatch object
290
OS.GlobalFree(newPtr);
291         // GOOGLE: prevent memory leaks
292
if (autoVar != null)
293             autoVar.dispose();
294     }
295 }
296 /**
297  * Returns the IDispatch object represented by this Variant.
298  *
299  * <p>If this Variant does not contain an IDispatch object, an attempt is made to
300  * coerce the Variant type into an IDIspatch object. If this fails, an error is
301  * thrown.
302  *
303  * @since 2.0
304  *
305  * @return the IDispatch object represented by this Variant
306  *
307  * @exception SWTException <ul>
308  * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into an IDispatch object</li>
309  * </ul>
310  */

311 public IDispatch getDispatch() {
312     if (type == COM.VT_EMPTY) {
313         OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
314     }
315     if (type == COM.VT_DISPATCH) {
316         return dispatchData;
317     }
318     // try to coerce the value to the desired type
319
int oldPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
320     int newPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
321     Variant autoVar = null; // GOOGLE: prevent memory leaks
322
try {
323         getData(oldPtr);
324         int result = COM.VariantChangeType(newPtr, oldPtr, (short) 0, COM.VT_DISPATCH);
325         if (result != COM.S_OK)
326             OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
327         autoVar = new Variant();
328         autoVar.setData(newPtr);
329         return autoVar.getDispatch();
330     } finally {
331         COM.VariantClear(oldPtr);
332         OS.GlobalFree(oldPtr);
333         COM.VariantClear(newPtr); // Note: This must absolutely be done AFTER the
334
// OleAutomation object is created as Variant Clear
335
// will result in a Release being performed on the
336
// Dispatch object
337
OS.GlobalFree(newPtr);
338         // GOOGLE: prevent memory leaks
339
if (autoVar != null)
340             autoVar.dispose();
341     }
342 }
343 /**
344  * Returns the Java boolean represented by this Variant.
345  *
346  * <p>If this Variant does not contain a Java boolean, an attempt is made to
347  * coerce the Variant type into a Java boolean. If this fails, an error is thrown.
348  *
349  * @return the Java boolean represented by this Variant
350  *
351  * @exception SWTException <ul>
352  * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a boolean</li>
353  * </ul>
354  *
355  */

356 public boolean getBoolean() {
357     if (type == COM.VT_EMPTY) {
358         OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
359     }
360     if (type == COM.VT_BOOL) {
361         return booleanData;
362     }
363
364     // try to coerce the value to the desired type
365
int oldPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
366     int newPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
367     try {
368         getData(oldPtr);
369         int result = COM.VariantChangeType(newPtr, oldPtr, (short) 0, COM.VT_BOOL);
370         if (result != COM.S_OK)
371             OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
372         Variant boolVar = new Variant();
373         boolVar.setData(newPtr);
374         return boolVar.getBoolean();
375     } finally {
376         COM.VariantClear(oldPtr);
377         OS.GlobalFree(oldPtr);
378         COM.VariantClear(newPtr);
379         OS.GlobalFree(newPtr);
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 int getByRef() {
391     if (type == COM.VT_EMPTY) {
392         OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
393     }
394     if ((type & COM.VT_BYREF)== COM.VT_BYREF) {
395         return byRefPtr;
396     }
397         
398     return 0;
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 SWTException <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 == COM.VT_EMPTY) {
416         OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
417     }
418     if (type == COM.VT_I1) {
419         return byteData;
420     }
421         
422     // try to coerce the value to the desired type
423
int oldPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
424     int newPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
425     try {
426         getData(oldPtr);
427         int result = COM.VariantChangeType(newPtr, oldPtr, (short) 0, COM.VT_I1);
428         if (result != COM.S_OK)
429             OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
430         Variant byteVar = new Variant();
431         byteVar.setData(newPtr);
432         return byteVar.getByte();
433     } finally {
434         COM.VariantClear(oldPtr);
435         OS.GlobalFree(oldPtr);
436         COM.VariantClear(newPtr);
437         OS.GlobalFree(newPtr);
438     }
439 }
440 /**
441  * Returns the Java char represented by this Variant.
442  *
443  * <p>If this Variant does not contain a Java char, an attempt is made to
444  * coerce the Variant type into a Java char. If this fails, an error is thrown.
445  *
446  * @return the Java char represented by this Variant
447  *
448  * @exception SWTException <ul>
449  * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a char</li>
450  * </ul>
451  *
452  * @since 3.3
453  */

454 public char getChar() {
455     if (type == COM.VT_EMPTY) {
456         OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
457     }
458     if (type == COM.VT_UI2) {
459         return charData;
460     }
461         
462     // try to coerce the value to the desired type
463
int oldPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
464     int newPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
465     try {
466         getData(oldPtr);
467         int result = COM.VariantChangeType(newPtr, oldPtr, (short) 0, COM.VT_UI2);
468         if (result != COM.S_OK)
469             OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
470         Variant charVar = new Variant();
471         charVar.setData(newPtr);
472         return charVar.getChar();
473     } finally {
474         COM.VariantClear(oldPtr);
475         OS.GlobalFree(oldPtr);
476         COM.VariantClear(newPtr);
477         OS.GlobalFree(newPtr);
478     }
479 }
480 void getData(int pData){
481     if (pData == 0) OLE.error(OLE.ERROR_OUT_OF_MEMORY);
482     
483     COM.VariantInit(pData);
484
485     if ((type & COM.VT_BYREF) == COM.VT_BYREF) {
486         COM.MoveMemory(pData, new short[] {type}, 2);
487         COM.MoveMemory(pData + 8, new int[]{byRefPtr}, 4);
488         return;
489     }
490
491     switch (type) {
492         case COM.VT_EMPTY :
493         case COM.VT_NULL :
494             COM.MoveMemory(pData, new short[] {type}, 2);
495             break;
496         case COM.VT_BOOL :
497             COM.MoveMemory(pData, new short[] {type}, 2);
498             COM.MoveMemory(pData + 8, new int[]{(booleanData) ? COM.VARIANT_TRUE : COM.VARIANT_FALSE}, 2);
499             break;
500         case COM.VT_I1 :
501             COM.MoveMemory(pData, new short[] {type}, 2);
502             COM.MoveMemory(pData + 8, new byte[]{byteData}, 1);
503             break;
504         case COM.VT_I2 :
505             COM.MoveMemory(pData, new short[] {type}, 2);
506             COM.MoveMemory(pData + 8, new short[]{shortData}, 2);
507             break;
508         case COM.VT_I4 :
509             COM.MoveMemory(pData, new short[] {type}, 2);
510             COM.MoveMemory(pData + 8, new int[]{intData}, 4);
511             break;
512         case COM.VT_I8 :
513             COM.MoveMemory(pData, new short[] {type}, 2);
514             COM.MoveMemory(pData + 8, new long[]{longData}, 8);
515         case COM.VT_UI2 :
516             COM.MoveMemory(pData, new short[] {type}, 2);
517             COM.MoveMemory(pData + 8, new char[]{charData}, 2);
518             break;
519         case COM.VT_R4 :
520             COM.MoveMemory(pData, new short[] {type}, 2);
521             COM.MoveMemory(pData + 8, new float[]{floatData}, 4);
522             break;
523         case COM.VT_R8 :
524             COM.MoveMemory(pData, new short[] {type}, 2);
525             COM.MoveMemory(pData + 8, new double[]{doubleData}, 8);
526             break;
527         case COM.VT_DISPATCH :
528             dispatchData.AddRef();
529             COM.MoveMemory(pData, new short[] {type}, 2);
530             COM.MoveMemory(pData + 8, new int[]{dispatchData.getAddress()}, 4);
531             break;
532         case COM.VT_UNKNOWN :
533             unknownData.AddRef();
534             COM.MoveMemory(pData, new short[] {type}, 2);
535             COM.MoveMemory(pData + 8, new int[]{unknownData.getAddress()}, 4);
536             break;
537         case COM.VT_BSTR :
538             COM.MoveMemory(pData, new short[] {type}, 2);
539             char[] data = (stringData+"\0").toCharArray();
540             int ptr = COM.SysAllocString(data);
541             COM.MoveMemory(pData + 8, new int[] {ptr}, 4);
542             break;
543     
544         default :
545             OLE.error(SWT.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 SWTException <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 == COM.VT_EMPTY) {
564         OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
565     }
566     if (type == COM.VT_R8) {
567         return doubleData;
568     }
569     
570     // try to coerce the value to the desired type
571
int oldPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
572     int newPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
573     try {
574         getData(oldPtr);
575         int result = COM.VariantChangeType(newPtr, oldPtr, (short) 0, COM.VT_R8);
576         if (result != COM.S_OK)
577             OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
578         Variant doubleVar = new Variant();
579         doubleVar.setData(newPtr);
580         return doubleVar.getDouble();
581     } finally {
582         COM.VariantClear(oldPtr);
583         OS.GlobalFree(oldPtr);
584         COM.VariantClear(newPtr);
585         OS.GlobalFree(newPtr);
586     }
587 }
588
589 /**
590  * Returns the Java float represented by this Variant.
591  *
592  * <p>If this Variant does not contain a Java float, an attempt is made to
593  * coerce the Variant type into a Java float. If this fails, an error is thrown.
594  *
595  * @return the Java float represented by this Variant
596  *
597  * @exception SWTException <ul>
598  * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a float</li>
599  * </ul>
600  */

601 public float getFloat() {
602     if (type == COM.VT_EMPTY) {
603         OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
604     }
605     if (type == COM.VT_R4) {
606         return floatData;
607     }
608
609     // try to coerce the value to the desired type
610
int oldPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
611     int newPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
612     try {
613         getData(oldPtr);
614         int result = COM.VariantChangeType(newPtr, oldPtr, (short) 0, COM.VT_R4);
615         if (result != COM.S_OK)
616             OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
617         Variant floatVar = new Variant();
618         floatVar.setData(newPtr);
619         return floatVar.getFloat();
620     } finally {
621         COM.VariantClear(oldPtr);
622         OS.GlobalFree(oldPtr);
623         COM.VariantClear(newPtr);
624         OS.GlobalFree(newPtr);
625     }
626     
627 }
628 /**
629  * Returns the Java int represented by this Variant.
630  *
631  * <p>If this Variant does not contain a Java int, an attempt is made to
632  * coerce the Variant type into a Java int. If this fails, an error is thrown.
633  *
634  * @return the Java int represented by this Variant
635  *
636  * @exception SWTException <ul>
637  * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a int</li>
638  * </ul>
639  */

640 public int getInt() {
641     if (type == COM.VT_EMPTY) {
642         OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
643     }
644     if (type == COM.VT_I4) {
645         return intData;
646     }
647         
648     // try to coerce the value to the desired type
649
int oldPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
650     int newPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
651     try {
652         getData(oldPtr);
653         int result = COM.VariantChangeType(newPtr, oldPtr, (short) 0, COM.VT_I4);
654         if (result != COM.S_OK)
655             OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
656         Variant intVar = new Variant();
657         intVar.setData(newPtr);
658         return intVar.getInt();
659     } finally {
660         COM.VariantClear(oldPtr);
661         OS.GlobalFree(oldPtr);
662         COM.VariantClear(newPtr);
663         OS.GlobalFree(newPtr);
664     }
665 }
666 /**
667  * Returns the Java long represented by this Variant.
668  *
669  * <p>If this Variant does not contain a Java long, an attempt is made to
670  * coerce the Variant type into a Java long. If this fails, an error is thrown.
671  *
672  * @return the Java long represented by this Variant
673  *
674  * @exception SWTException <ul>
675  * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a long</li>
676  * </ul>
677  *
678  * @since 3.2
679  */

680 public long getLong() {
681     if (type == COM.VT_EMPTY) {
682         OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
683     }
684     if (type == COM.VT_I8) {
685         return longData;
686     }
687         
688     // try to coerce the value to the desired type
689
int oldPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
690     int newPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
691     try {
692         getData(oldPtr);
693         int result = COM.VariantChangeType(newPtr, oldPtr, (short) 0, COM.VT_I8);
694         if (result != COM.S_OK)
695             OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
696         Variant longVar = new Variant();
697         longVar.setData(newPtr);
698         return longVar.getLong();
699     } finally {
700         COM.VariantClear(oldPtr);
701         OS.GlobalFree(oldPtr);
702         COM.VariantClear(newPtr);
703         OS.GlobalFree(newPtr);
704     }
705 }
706 /**
707  * Returns the Java short represented by this Variant.
708  *
709  * <p>If this Variant does not contain a Java short, an attempt is made to
710  * coerce the Variant type into a Java short. If this fails, an error is thrown.
711  *
712  * @return the Java short represented by this Variant
713  *
714  * @exception SWTException <ul>
715  * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a short</li>
716  * </ul>
717  */

718 public short getShort() {
719     if (type == COM.VT_EMPTY) {
720         OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
721     }
722     if (type == COM.VT_I2) {
723         return shortData;
724     }
725         
726     // try to coerce the value to the desired type
727
int oldPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
728     int newPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
729     try {
730         getData(oldPtr);
731         int result = COM.VariantChangeType(newPtr, oldPtr, (short) 0, COM.VT_I2);
732         if (result != COM.S_OK)
733             OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
734         Variant shortVar = new Variant();
735         shortVar.setData(newPtr);
736         return shortVar.getShort();
737     } finally {
738         COM.VariantClear(oldPtr);
739         OS.GlobalFree(oldPtr);
740         COM.VariantClear(newPtr);
741         OS.GlobalFree(newPtr);
742     }
743     
744 }
745 /**
746  * Returns the Java String represented by this Variant.
747  *
748  * <p>If this Variant does not contain a Java String, an attempt is made to
749  * coerce the Variant type into a Java String. If this fails, an error is thrown.
750  *
751  * @return the Java String represented by this Variant
752  *
753  * @exception SWTException <ul>
754  * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into a String</li>
755  * </ul>
756  */

757 public String JavaDoc getString() {
758     if (type == COM.VT_EMPTY) {
759         OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
760     }
761     if (type == COM.VT_BSTR) {
762         return stringData;
763     }
764
765     // try to coerce the value to the desired type
766
int oldPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
767     int newPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
768     try {
769         getData(oldPtr);
770         int result = COM.VariantChangeType(newPtr, oldPtr, (short) 0, COM.VT_BSTR);
771         if (result != COM.S_OK)
772             OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
773
774         Variant stringVar = new Variant();
775         stringVar.setData(newPtr);
776         return stringVar.getString();
777             
778     } finally {
779         COM.VariantClear(oldPtr);
780         OS.GlobalFree(oldPtr);
781         COM.VariantClear(newPtr);
782         OS.GlobalFree(newPtr);
783     }
784 }
785 /**
786  * Returns the type of the variant type. This will be an OLE.VT_* value or
787  * a bitwise combination of OLE.VT_* values as in the case of
788  * OLE.VT_BSTR | OLE.VT_BYREF.
789  *
790  * @return the type of the variant data
791  *
792  * @since 2.0
793  */

794 public short getType() {
795     return type;
796 }
797 /**
798  * Returns the IUnknown object represented by this Variant.
799  *
800  * <p>If this Variant does not contain an IUnknown object, an attempt is made to
801  * coerce the Variant type into an IUnknown object. If this fails, an error is
802  * thrown.
803  *
804  * @return the IUnknown object represented by this Variant
805  *
806  * @exception SWTException <ul>
807  * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant can not be coerced into
808  * an IUnknown object</li>
809  * </ul>
810  */

811 public IUnknown getUnknown() {
812     if (type == COM.VT_EMPTY) {
813         OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, -1);
814     }
815     if (type == COM.VT_UNKNOWN) {
816         return unknownData;
817     }
818
819     // try to coerce the value to the desired type
820
int oldPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
821     int newPtr = OS.GlobalAlloc(COM.GMEM_FIXED | COM.GMEM_ZEROINIT, sizeof);
822     Variant unknownVar = null; // GOOGLE: prevent memory leaks
823
try {
824         getData(oldPtr);
825         int result = COM.VariantChangeType(newPtr, oldPtr, (short) 0, COM.VT_UNKNOWN);
826         if (result != COM.S_OK)
827             OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE, result);
828         unknownVar = new Variant();
829         unknownVar.setData(newPtr);
830         return unknownVar.getUnknown();
831     } finally {
832         COM.VariantClear(oldPtr);
833         OS.GlobalFree(oldPtr);
834         COM.VariantClear(newPtr); // Note: This must absolutely be done AFTER the
835
// IUnknown object is created as Variant Clear
836
// will result in a Release being performed on the
837
// Dispatch object
838
OS.GlobalFree(newPtr);
839         // GOOGLE: prevent memory leaks
840
if (unknownVar != null)
841             unknownVar.dispose();
842     }
843 }
844 /**
845  * Update the by reference value of this variant with a new boolean value.
846  *
847  * @param val the new boolean value
848  *
849  * @exception SWTException <ul>
850  * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant is not
851  * a (VT_BYREF | VT_BOOL) object</li>
852  * </ul>
853  *
854  * @since 2.1
855  */

856 public void setByRef(boolean val) {
857     if ((type & COM.VT_BYREF) == 0 || (type & COM.VT_BOOL) == 0) {
858         OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE);
859     }
860     COM.MoveMemory(byRefPtr, new short[]{val ? COM.VARIANT_TRUE : COM.VARIANT_FALSE}, 2);
861 }
862 /**
863  * Update the by reference value of this variant with a new float value.
864  *
865  * @param val the new float value
866  *
867  * @exception SWTException <ul>
868  * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant is not
869  * a (VT_BYREF | VT_R4) object</li>
870  * </ul>
871  *
872  * @since 2.1
873  */

874 public void setByRef(float val) {
875     if ((type & COM.VT_BYREF) == 0 || (type & COM.VT_R4) == 0) {
876         OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE);
877     }
878     COM.MoveMemory(byRefPtr, new float[]{val}, 4);
879 }
880 /**
881  * Update the by reference value of this variant with a new integer value.
882  *
883  * @param val the new integer value
884  *
885  * @exception SWTException <ul>
886  * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant is not a (VT_BYREF | VT_I4) object</li>
887  * </ul>
888  *
889  * @since 2.1
890  */

891 public void setByRef(int val) {
892     if ((type & COM.VT_BYREF) == 0 || (type & COM.VT_I4) == 0) {
893         OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE);
894     }
895     COM.MoveMemory(byRefPtr, new int[]{val}, 4);
896 }
897 /**
898  * Update the by reference value of this variant with a new short value.
899  *
900  * @param val the new short value
901  *
902  * @exception SWTException <ul>
903  * <li>ERROR_CANNOT_CHANGE_VARIANT_TYPE when type of Variant is not a (VT_BYREF | VT_I2) object
904  * </ul>
905  *
906  * @since 2.1
907  */

908 public void setByRef(short val) {
909     if ((type & COM.VT_BYREF) == 0 || (type & COM.VT_I2) == 0) {
910         OLE.error(OLE.ERROR_CANNOT_CHANGE_VARIANT_TYPE);
911     }
912     COM.MoveMemory(byRefPtr, new short[]{val}, 2);
913 }
914
915 void setData(int pData){
916     if (pData == 0) OLE.error(OLE.ERROR_INVALID_ARGUMENT);
917
918     short[] dataType = new short[1];
919     COM.MoveMemory(dataType, pData, 2);
920     type = dataType[0];
921
922     if ((type & COM.VT_BYREF) == COM.VT_BYREF) {
923         int[] newByRefPtr = new int[1];
924         OS.MoveMemory(newByRefPtr, pData + 8, 4);
925         byRefPtr = newByRefPtr[0];
926         return;
927     }
928     
929     switch (type) {
930         case COM.VT_EMPTY :
931         case COM.VT_NULL :
932             break;
933         case COM.VT_BOOL :
934             short[] newBooleanData = new short[1];
935             COM.MoveMemory(newBooleanData, pData + 8, 2);
936             booleanData = (newBooleanData[0] != COM.VARIANT_FALSE);
937             break;
938         case COM.VT_I1 :
939             byte[] newByteData = new byte[1];
940             COM.MoveMemory(newByteData, pData + 8, 1);
941             byteData = newByteData[0];
942             break;
943         case COM.VT_I2 :
944             short[] newShortData = new short[1];
945             COM.MoveMemory(newShortData, pData + 8, 2);
946             shortData = newShortData[0];
947             break;
948         case COM.VT_I4 :
949             int[] newIntData = new int[1];
950             OS.MoveMemory(newIntData, pData + 8, 4);
951             intData = newIntData[0];
952             break;
953         case COM.VT_I8 :
954             long[] newLongData = new long[1];
955             OS.MoveMemory(newLongData, pData + 8, 8);
956             longData = newLongData[0];
957             break;
958         case COM.VT_UI2 :
959             char[] newCharData = new char[1];
960             COM.MoveMemory(newCharData, pData + 8, 2);
961             charData = newCharData[0];
962             break;
963         case COM.VT_R4 :
964             float[] newFloatData = new float[1];
965             COM.MoveMemory(newFloatData, pData + 8, 4);
966             floatData = newFloatData[0];
967             break;
968         case COM.VT_R8 :
969             double[] newDoubleData = new double[1];
970             COM.MoveMemory(newDoubleData, pData + 8, 8);
971             doubleData = newDoubleData[0];
972             break;
973         case COM.VT_DISPATCH : {
974             int[] ppvObject = new int[1];
975             OS.MoveMemory(ppvObject, pData + 8, 4);
976             if (ppvObject[0] == 0) {
977                 type = COM.VT_EMPTY;
978                 break;
979             }
980             dispatchData = new IDispatch(ppvObject[0]);
981             dispatchData.AddRef();
982             break;
983         }
984         case COM.VT_UNKNOWN : {
985             int[] ppvObject = new int[1];
986             OS.MoveMemory(ppvObject, pData + 8, 4);
987             if (ppvObject[0] == 0) {
988                 type = COM.VT_EMPTY;
989                 break;
990             }
991             unknownData = new IUnknown(ppvObject[0]);
992             unknownData.AddRef();
993             break;
994         }
995
996         // GOOGLE: map exception name in IE7 to BSTR
997
case COM.VT_WEIRD_IE7_BSTR :
998             type = COM.VT_BSTR;
999             // intentional fall-through to VT_BSTR case
1000
case COM.VT_BSTR :
1001            // get the address of the memory in which the string resides
1002
int[] hMem = new int[1];
1003            OS.MoveMemory(hMem, pData + 8, 4);
1004            if (hMem[0] == 0) {
1005                type = COM.VT_EMPTY;
1006                break;
1007            }
1008            // Get the size of the string from the OS - the size is expressed in number
1009
// of bytes - each unicode character is 2 bytes.
1010
int size = COM.SysStringByteLen(hMem[0]);
1011            if (size > 0){
1012                // get the unicode character array from the global memory and create a String
1013
char[] buffer = new char[(size + 1) /2]; // add one to avoid rounding errors
1014
COM.MoveMemory(buffer, hMem[0], size);
1015                stringData = new String JavaDoc(buffer);
1016            } else {
1017                stringData = ""; //$NON-NLS-1$
1018
}
1019            break;
1020    
1021        default :
1022            // try coercing it into one of the known forms
1023
int newPData = OS.GlobalAlloc(OS.GMEM_FIXED | OS.GMEM_ZEROINIT, Variant.sizeof);
1024            if (COM.VariantChangeType(newPData, pData, (short) 0, COM.VT_R4) == COM.S_OK) {
1025                setData(newPData);
1026            } else if (COM.VariantChangeType(newPData, pData, (short) 0, COM.VT_I4) == COM.S_OK) {
1027                setData(newPData);
1028            } else if (COM.VariantChangeType(newPData, pData, (short) 0, COM.VT_BSTR) == COM.S_OK) {
1029                setData(newPData);
1030            }
1031            COM.VariantClear(newPData);
1032            OS.GlobalFree(newPData);
1033            break;
1034    }
1035}
1036
1037/**
1038 * Returns a string containing a concise, human-readable
1039 * description of the receiver.
1040 *
1041 * @return a string representation of the Variant
1042 */

1043public String JavaDoc toString () {
1044    switch (type) {
1045        case COM.VT_BOOL :
1046            return "VT_BOOL{"+booleanData+"}";
1047        case COM.VT_I1 :
1048            return "VT_I1{"+byteData+"}";
1049        case COM.VT_I2 :
1050            return "VT_I2{"+shortData+"}";
1051        case COM.VT_I4 :
1052            return "VT_I4{"+intData+"}";
1053        case COM.VT_I8 :
1054            return "VT_I8{"+longData+"}";
1055        case COM.VT_UI2 :
1056            return "VT_UI2{"+charData+"}";
1057        case COM.VT_R4 :
1058            return "VT_R4{"+floatData+"}";
1059        case COM.VT_R8 :
1060            return "VT_R8{"+doubleData+"}";
1061        case COM.VT_BSTR :
1062            return "VT_BSTR{"+stringData+"}";
1063        case COM.VT_DISPATCH :
1064            return "VT_DISPATCH{"+(dispatchData == null ? 0 : dispatchData.getAddress())+"}";
1065        case COM.VT_UNKNOWN :
1066            return "VT_UNKNOWN{"+(unknownData == null ? 0 : unknownData.getAddress())+"}";
1067        case COM.VT_EMPTY :
1068            return "VT_EMPTY";
1069        case COM.VT_NULL :
1070            return "VT_NULL";
1071     }
1072    if ((type & COM.VT_BYREF) != 0) {
1073        return "VT_BYREF|"+(type & ~COM.VT_BYREF)+"{"+byRefPtr+"}";
1074    }
1075    return "Unsupported Type "+type;
1076}
1077}
1078
Popular Tags