2323 */
2424package com .sun .jna .platform .win32 .COM .util ;
2525
26- import com .sun .jna .platform .win32 .OaIdl .DATE ;
27- import com .sun .jna .platform .win32 .OaIdl .VARIANT_BOOL ;
2826import com .sun .jna .platform .win32 .OleAuto ;
2927import com .sun .jna .platform .win32 .Variant ;
3028import java .lang .reflect .InvocationHandler ;
3634import com .sun .jna .platform .win32 .WinDef ;
3735import com .sun .jna .platform .win32 .Variant .VARIANT ;
3836import com .sun .jna .platform .win32 .WTypes .BSTR ;
39- import com .sun .jna .platform .win32 .WinDef .BOOL ;
40- import com .sun .jna .platform .win32 .WinDef .BYTE ;
41- import com .sun .jna .platform .win32 .WinDef .CHAR ;
42- import com .sun .jna .platform .win32 .WinDef .LONG ;
43- import com .sun .jna .platform .win32 .WinDef .SHORT ;
4437import com .sun .jna .platform .win32 .OaIdl ;
45- import com .sun .jna .platform .win32 .OaIdl .SAFEARRAY ;
4638import static com .sun .jna .platform .win32 .Variant .VT_ARRAY ;
4739import static com .sun .jna .platform .win32 .Variant .VT_BOOL ;
4840import static com .sun .jna .platform .win32 .Variant .VT_BSTR ;
7062import static com .sun .jna .platform .win32 .Variant .VT_UNKNOWN ;
7163import static com .sun .jna .platform .win32 .Variant .VT_VARIANT ;
7264import com .sun .jna .platform .win32 .WinDef .PVOID ;
65+ import java .lang .reflect .Constructor ;
7366
7467/**
7568 * This class is considered internal to the package.
@@ -78,42 +71,26 @@ class Convert {
7871 /**
7972 * Convert a java value into a VARIANT suitable for passing in a COM
8073 * invocation.
81- *
74+ *
8275 * <p><i>Implementation notes</i></p>
83- *
76+ *
8477 * <ul>
8578 * <li>VARIANTs are not rewrapped, but passed through unmodified</li>
8679 * <li>A string is wrapped into a BSTR, that is wrapped into the VARIANT.
8780 * The string is allocated as native memory by the VARIANT constructor.
8881 * The BSTR needs to be freed by {@link com.sun.jna.platform.win32.OleAuto#SysFreeString}.</li>
8982 * </ul>
90- *
83+ *
9184 * @param value to be wrapped
9285 * @return wrapped VARIANT
9386 */
9487 public static VARIANT toVariant (Object value ) {
95- if (value instanceof VARIANT ) {
88+ if (value instanceof VARIANT ) {
9689 return (VARIANT ) value ;
97- } else if (value instanceof BSTR ) {
98- return new VARIANT ((BSTR ) value );
99- } else if (value instanceof VARIANT_BOOL ) {
100- return new VARIANT ((VARIANT_BOOL ) value );
101- } else if (value instanceof BOOL ) {
102- return new VARIANT ((BOOL ) value );
103- } else if (value instanceof LONG ) {
104- return new VARIANT ((LONG ) value );
105- } else if (value instanceof SHORT ) {
106- return new VARIANT ((SHORT ) value );
107- } else if (value instanceof DATE ) {
108- return new VARIANT ((DATE ) value );
109- } else if (value instanceof BYTE ) {
110- return new VARIANT ((BYTE ) value );
11190 } else if (value instanceof Byte ) {
11291 return new VARIANT ((Byte ) value );
11392 } else if (value instanceof Character ) {
11493 return new VARIANT ((Character ) value );
115- } else if (value instanceof CHAR ) {
116- return new VARIANT ((CHAR ) value );
11794 } else if (value instanceof Short ) {
11895 return new VARIANT ((Short ) value );
11996 } else if (value instanceof Integer ) {
@@ -132,27 +109,42 @@ public static VARIANT toVariant(Object value) {
132109 return new VARIANT ((com .sun .jna .platform .win32 .COM .IDispatch ) value );
133110 } else if (value instanceof Date ) {
134111 return new VARIANT ((Date ) value );
135- } else if (value instanceof Proxy ) {
112+ } else if (value instanceof Proxy ) {
136113 InvocationHandler ih = Proxy .getInvocationHandler (value );
137114 ProxyObject pobj = (ProxyObject ) ih ;
138115 return new VARIANT (pobj .getRawDispatch ());
139116 } else if (value instanceof IComEnum ) {
140117 IComEnum enm = (IComEnum ) value ;
141118 return new VARIANT (new WinDef .LONG (enm .getValue ()));
142- } else if (value instanceof SAFEARRAY ) {
143- return new VARIANT ((SAFEARRAY ) value );
144- } else {
145- return null ;
146- }
147- }
148-
119+ } else {
120+ Constructor <VARIANT > constructor = null ;
121+ if (value != null ) {
122+ for (Constructor <VARIANT > m : (Constructor <VARIANT >[]) VARIANT .class .getConstructors ()) {
123+ if (m .getParameterCount () > 0
124+ && m .getParameterTypes ()[0 ].isAssignableFrom (value .getClass ())) {
125+ constructor = m ;
126+ }
127+ }
128+ }
129+
130+ if (constructor != null ) {
131+ try {
132+ return constructor .newInstance (value );
133+ } catch (Exception ex ) {
134+ throw new RuntimeException (ex );
135+ }
136+ }
137+ return null ;
138+ }
139+ }
140+
149141 public static Object toJavaObject (VARIANT value , Class <?> targetClass , ObjectFactory factory , boolean addReference , boolean freeValue ) {
150- if (null ==value
151- || value .getVarType ().intValue () == VT_EMPTY
142+ if (null ==value
143+ || value .getVarType ().intValue () == VT_EMPTY
152144 || value .getVarType ().intValue () == VT_NULL ) {
153145 return null ;
154146 }
155-
147+
156148 if (targetClass != null && (!targetClass .isAssignableFrom (Object .class ))) {
157149 if (targetClass .isAssignableFrom (value .getClass ())) {
158150 return value ;
@@ -163,86 +155,67 @@ public static Object toJavaObject(VARIANT value, Class<?> targetClass, ObjectFac
163155 return vobj ;
164156 }
165157 }
166-
158+
167159 VARIANT inputValue = value ;
168-
160+
169161 if (value .getVarType ().intValue () == (VT_BYREF | VT_VARIANT )) {
170162 value = (VARIANT ) value .getValue ();
171163 }
172-
164+
173165 // Passing null or Object.class as targetClass switch to default
174166 // handling
175167 if (targetClass == null || (targetClass .isAssignableFrom (Object .class ))) {
176-
168+
177169 targetClass = null ;
178-
170+
179171 int varType = value .getVarType ().intValue ();
180-
172+
181173 switch (value .getVarType ().intValue ()) {
182174 case VT_UI1 :
183175 case VT_I1 :
184- case VT_BYREF | VT_UI1 :
185- case VT_BYREF | VT_I1 :
186176 targetClass = Byte .class ;
187177 break ;
188178 case VT_I2 :
189- case VT_BYREF | VT_I2 :
190179 targetClass = Short .class ;
191180 break ;
192181 case VT_UI2 :
193- case VT_BYREF | VT_UI2 :
194182 targetClass = Character .class ;
195183 break ;
196184 case VT_INT :
197185 case VT_UINT :
198186 case VT_UI4 :
199187 case VT_I4 :
200- case VT_BYREF | VT_I4 :
201- case VT_BYREF | VT_UI4 :
202- case VT_BYREF | VT_INT :
203- case VT_BYREF | VT_UINT :
204188 targetClass = Integer .class ;
205189 break ;
206190 case VT_UI8 :
207191 case VT_I8 :
208- case VT_BYREF | VT_I8 :
209- case VT_BYREF | VT_UI8 :
210192 targetClass = Long .class ;
211193 break ;
212194 case VT_R4 :
213- case VT_BYREF | VT_R4 :
214195 targetClass = Float .class ;
215196 break ;
216197 case VT_R8 :
217- case VT_BYREF | VT_R8 :
218198 targetClass = Double .class ;
219199 break ;
220200 case VT_BOOL :
221- case VT_BYREF | VT_BOOL :
222201 targetClass = Boolean .class ;
223202 break ;
224203 case VT_ERROR :
225- case VT_BYREF | VT_ERROR :
226204 targetClass = WinDef .SCODE .class ;
227205 break ;
228206 case VT_CY :
229- case VT_BYREF | VT_CY :
230207 targetClass = OaIdl .CURRENCY .class ;
231208 break ;
232209 case VT_DATE :
233- case VT_BYREF | VT_DATE :
234210 targetClass = Date .class ;
235211 break ;
236212 case VT_BSTR :
237- case VT_BYREF | VT_BSTR :
238213 targetClass = String .class ;
239214 break ;
240215 case VT_UNKNOWN :
241- case VT_BYREF | VT_UNKNOWN :
242216 targetClass = com .sun .jna .platform .win32 .COM .IUnknown .class ;
243217 break ;
244218 case VT_DISPATCH :
245- case VT_BYREF | VT_DISPATCH :
246219 targetClass = IDispatch .class ;
247220 break ;
248221 case VT_BYREF | VT_VARIANT :
@@ -261,7 +234,7 @@ public static Object toJavaObject(VARIANT value, Class<?> targetClass, ObjectFac
261234 }
262235 }
263236 }
264-
237+
265238 Object result ;
266239 if (Byte .class .equals (targetClass ) || byte .class .equals (targetClass )) {
267240 result = value .byteValue ();
@@ -308,14 +281,14 @@ public static Object toJavaObject(VARIANT value, Class<?> targetClass, ObjectFac
308281 if (IComEnum .class .isAssignableFrom (targetClass )) {
309282 result = targetClass .cast (Convert .toComEnum ((Class <? extends IComEnum >) targetClass , result ));
310283 }
311-
284+
312285 if (freeValue ) {
313286 free (inputValue , result );
314287 }
315-
288+
316289 return result ;
317290 }
318-
291+
319292 public static <T extends IComEnum > T toComEnum (Class <T > enumType , Object value ) {
320293 try {
321294 Method m = enumType .getMethod ("values" );
@@ -332,13 +305,13 @@ public static <T extends IComEnum> T toComEnum(Class<T> enumType, Object value)
332305 }
333306 return null ;
334307 }
335-
308+
336309 /**
337310 * Free the contents of the supplied VARIANT.
338- *
311+ *
339312 * <p>This method is a companion to {@link #toVariant}. Primary usage is
340313 * to free BSTRs contained in VARIANTs.</p>
341- *
314+ *
342315 * @param variant to be cleared
343316 * @param javaType type before/after conversion
344317 */
@@ -352,13 +325,13 @@ public static void free(VARIANT variant, Class<?> javaType) {
352325 }
353326 }
354327 }
355-
328+
356329 /**
357330 * Free the contents of the supplied VARIANT.
358- *
331+ *
359332 * <p>This method is a companion to {@link #toVariant}. Primary usage is
360333 * to free BSTRs contained in VARIANTs.</p>
361- *
334+ *
362335 * @param variant to be cleared
363336 * @param value value before/after conversion
364337 */
0 commit comments