12
12
*/
13
13
package com .sun .jna .platform .win32 .COM .util ;
14
14
15
+ import com .sun .jna .platform .win32 .OaIdl .DATE ;
15
16
import com .sun .jna .platform .win32 .OaIdl .VARIANT_BOOL ;
16
17
import com .sun .jna .platform .win32 .OleAuto ;
17
18
import com .sun .jna .platform .win32 .Variant ;
21
22
import java .lang .reflect .Proxy ;
22
23
import java .util .Date ;
23
24
24
- import com .sun .jna .platform .win32 .WTypes ;
25
25
import com .sun .jna .platform .win32 .WinDef ;
26
26
import com .sun .jna .platform .win32 .Variant .VARIANT ;
27
27
import com .sun .jna .platform .win32 .WTypes .BSTR ;
28
+ import com .sun .jna .platform .win32 .WinDef .BOOL ;
29
+ import com .sun .jna .platform .win32 .WinDef .BYTE ;
30
+ import com .sun .jna .platform .win32 .WinDef .CHAR ;
31
+ import com .sun .jna .platform .win32 .WinDef .LONG ;
32
+ import com .sun .jna .platform .win32 .WinDef .SHORT ;
33
+ import com .sun .jna .platform .win32 .OaIdl ;
34
+ import static com .sun .jna .platform .win32 .Variant .VT_ARRAY ;
35
+ import static com .sun .jna .platform .win32 .Variant .VT_BOOL ;
36
+ import static com .sun .jna .platform .win32 .Variant .VT_BSTR ;
37
+ import static com .sun .jna .platform .win32 .Variant .VT_BYREF ;
38
+ import static com .sun .jna .platform .win32 .Variant .VT_CY ;
39
+ import static com .sun .jna .platform .win32 .Variant .VT_DATE ;
40
+ import static com .sun .jna .platform .win32 .Variant .VT_DECIMAL ;
41
+ import static com .sun .jna .platform .win32 .Variant .VT_DISPATCH ;
42
+ import static com .sun .jna .platform .win32 .Variant .VT_EMPTY ;
43
+ import static com .sun .jna .platform .win32 .Variant .VT_ERROR ;
44
+ import static com .sun .jna .platform .win32 .Variant .VT_I1 ;
45
+ import static com .sun .jna .platform .win32 .Variant .VT_I2 ;
46
+ import static com .sun .jna .platform .win32 .Variant .VT_I4 ;
47
+ import static com .sun .jna .platform .win32 .Variant .VT_I8 ;
48
+ import static com .sun .jna .platform .win32 .Variant .VT_INT ;
49
+ import static com .sun .jna .platform .win32 .Variant .VT_NULL ;
50
+ import static com .sun .jna .platform .win32 .Variant .VT_R4 ;
51
+ import static com .sun .jna .platform .win32 .Variant .VT_R8 ;
52
+ import static com .sun .jna .platform .win32 .Variant .VT_RECORD ;
53
+ import static com .sun .jna .platform .win32 .Variant .VT_SAFEARRAY ;
54
+ import static com .sun .jna .platform .win32 .Variant .VT_UI1 ;
55
+ import static com .sun .jna .platform .win32 .Variant .VT_UI2 ;
56
+ import static com .sun .jna .platform .win32 .Variant .VT_UI4 ;
57
+ import static com .sun .jna .platform .win32 .Variant .VT_UI8 ;
58
+ import static com .sun .jna .platform .win32 .Variant .VT_UINT ;
59
+ import static com .sun .jna .platform .win32 .Variant .VT_UNKNOWN ;
60
+ import static com .sun .jna .platform .win32 .Variant .VT_VARIANT ;
61
+ import com .sun .jna .platform .win32 .WinDef .PVOID ;
28
62
29
63
/**
30
64
* This class is considered internal to the package.
@@ -50,20 +84,42 @@ class Convert {
50
84
public static VARIANT toVariant (Object value ) {
51
85
if (value instanceof VARIANT ) {
52
86
return (VARIANT ) value ;
53
- } else if (value instanceof Boolean ) {
54
- return new VARIANT ((Boolean ) value );
55
- } else if (value instanceof Long ) {
56
- return new VARIANT (new WinDef .LONG ((Long ) value ));
87
+ } else if (value instanceof BSTR ) {
88
+ return new VARIANT ((BSTR ) value );
89
+ } else if (value instanceof VARIANT_BOOL ) {
90
+ return new VARIANT ((VARIANT_BOOL ) value );
91
+ } else if (value instanceof BOOL ) {
92
+ return new VARIANT ((BOOL ) value );
93
+ } else if (value instanceof LONG ) {
94
+ return new VARIANT ((LONG ) value );
95
+ } else if (value instanceof SHORT ) {
96
+ return new VARIANT ((SHORT ) value );
97
+ } else if (value instanceof DATE ) {
98
+ return new VARIANT ((DATE ) value );
99
+ } else if (value instanceof BYTE ) {
100
+ return new VARIANT ((BYTE ) value );
101
+ } else if (value instanceof Byte ) {
102
+ return new VARIANT ((Byte ) value );
103
+ } else if (value instanceof Character ) {
104
+ return new VARIANT ((Character ) value );
105
+ } else if (value instanceof CHAR ) {
106
+ return new VARIANT ((CHAR ) value );
107
+ } else if (value instanceof Short ) {
108
+ return new VARIANT ((Short ) value );
57
109
} else if (value instanceof Integer ) {
58
110
return new VARIANT ((Integer ) value );
59
- } else if (value instanceof Short ) {
60
- return new VARIANT (new WinDef . SHORT (( Short ) value ) );
111
+ } else if (value instanceof Long ) {
112
+ return new VARIANT (( Long ) value );
61
113
} else if (value instanceof Float ) {
62
114
return new VARIANT ((Float ) value );
63
115
} else if (value instanceof Double ) {
64
116
return new VARIANT ((Double ) value );
65
117
} else if (value instanceof String ) {
66
118
return new VARIANT ((String ) value );
119
+ } else if (value instanceof Boolean ) {
120
+ return new VARIANT ((Boolean ) value );
121
+ } else if (value instanceof com .sun .jna .platform .win32 .COM .IDispatch ) {
122
+ return new VARIANT ((com .sun .jna .platform .win32 .COM .IDispatch ) value );
67
123
} else if (value instanceof Date ) {
68
124
return new VARIANT ((Date ) value );
69
125
} else if (value instanceof Proxy ) {
@@ -78,43 +134,171 @@ public static VARIANT toVariant(Object value) {
78
134
}
79
135
}
80
136
81
- public static Object toJavaObject (VARIANT value , Class targetClass ) {
82
- if (null ==value ) {
137
+ public static Object toJavaObject (VARIANT value , Class targetClass , Factory factory , boolean addReference ) {
138
+ if (null ==value
139
+ || value .getVarType ().intValue () == VT_EMPTY
140
+ || value .getVarType ().intValue () == VT_NULL ) {
83
141
return null ;
84
142
}
85
143
144
+ if (targetClass != null
145
+ && (!targetClass .isAssignableFrom (Object .class ))) {
146
+ if (targetClass != null && targetClass .isAssignableFrom (value .getClass ())) {
147
+ return value ;
148
+ }
149
+
150
+ Object vobj = value .getValue ();
151
+ if (vobj != null && (targetClass == null || targetClass .isAssignableFrom (vobj .getClass ()))) {
152
+ return vobj ;
153
+ }
154
+ }
155
+
156
+ if (value .getVarType ().intValue () == (VT_BYREF | VT_VARIANT )) {
157
+ value = (VARIANT ) value .getValue ();
158
+ }
159
+
86
160
// Passing null or Object.class as targetClass switch to default
87
161
// handling
88
- boolean concreteClassRequested = targetClass != null
89
- && (! targetClass .isAssignableFrom (Object .class ));
90
-
91
- if (concreteClassRequested && targetClass .isAssignableFrom (value .getClass ())) {
92
- return value ;
162
+ if (targetClass == null
163
+ || (targetClass .isAssignableFrom (Object .class ))) {
164
+
165
+ targetClass = null ;
166
+
167
+ int varType = value .getVarType ().intValue ();
168
+
169
+ switch (value .getVarType ().intValue ()) {
170
+ case VT_UI1 :
171
+ case VT_I1 :
172
+ case VT_BYREF | VT_UI1 :
173
+ case VT_BYREF | VT_I1 :
174
+ targetClass = Byte .class ;
175
+ break ;
176
+ case VT_I2 :
177
+ case VT_BYREF | VT_I2 :
178
+ targetClass = Short .class ;
179
+ break ;
180
+ case VT_UI2 :
181
+ case VT_BYREF | VT_UI2 :
182
+ targetClass = Character .class ;
183
+ break ;
184
+ case VT_INT :
185
+ case VT_UINT :
186
+ case VT_UI4 :
187
+ case VT_I4 :
188
+ case VT_BYREF | VT_I4 :
189
+ case VT_BYREF | VT_UI4 :
190
+ case VT_BYREF | VT_INT :
191
+ case VT_BYREF | VT_UINT :
192
+ targetClass = Integer .class ;
193
+ break ;
194
+ case VT_UI8 :
195
+ case VT_I8 :
196
+ case VT_BYREF | VT_I8 :
197
+ case VT_BYREF | VT_UI8 :
198
+ targetClass = Long .class ;
199
+ break ;
200
+ case VT_R4 :
201
+ case VT_BYREF | VT_R4 :
202
+ targetClass = Float .class ;
203
+ break ;
204
+ case VT_R8 :
205
+ case VT_BYREF | VT_R8 :
206
+ targetClass = Double .class ;
207
+ break ;
208
+ case VT_BOOL :
209
+ case VT_BYREF | VT_BOOL :
210
+ targetClass = Boolean .class ;
211
+ break ;
212
+ case VT_ERROR :
213
+ case VT_BYREF | VT_ERROR :
214
+ targetClass = WinDef .SCODE .class ;
215
+ break ;
216
+ case VT_CY :
217
+ case VT_BYREF | VT_CY :
218
+ targetClass = OaIdl .CURRENCY .class ;
219
+ break ;
220
+ case VT_DATE :
221
+ case VT_BYREF | VT_DATE :
222
+ targetClass = Date .class ;
223
+ break ;
224
+ case VT_BSTR :
225
+ case VT_BYREF | VT_BSTR :
226
+ targetClass = String .class ;
227
+ break ;
228
+ case VT_UNKNOWN :
229
+ case VT_BYREF | VT_UNKNOWN :
230
+ targetClass = com .sun .jna .platform .win32 .COM .IUnknown .class ;
231
+ break ;
232
+ case VT_DISPATCH :
233
+ case VT_BYREF | VT_DISPATCH :
234
+ targetClass = IDispatch .class ;
235
+ break ;
236
+ case VT_BYREF | VT_VARIANT :
237
+ targetClass = Variant .class ;
238
+ break ;
239
+ case VT_BYREF :
240
+ targetClass = PVOID .class ;
241
+ break ;
242
+ case VT_BYREF | VT_DECIMAL :
243
+ targetClass = OaIdl .DECIMAL .class ;
244
+ break ;
245
+ case VT_RECORD :
246
+ default :
247
+ if ((varType & VT_ARRAY ) > 0
248
+ || ((varType & VT_SAFEARRAY ) > 0 )) {
249
+ targetClass = OaIdl .SAFEARRAY .class ;
250
+ }
251
+ }
93
252
}
94
- Object vobj = value .getValue ();
95
- if (vobj != null && concreteClassRequested && targetClass .isAssignableFrom (vobj .getClass ())) {
96
- return vobj ;
253
+
254
+ Object result ;
255
+ if (Byte .class .equals (targetClass ) || byte .class .equals (targetClass )) {
256
+ result = value .byteValue ();
257
+ } else if (Short .class .equals (targetClass ) || short .class .equals (targetClass )) {
258
+ result = value .shortValue ();
259
+ } else if (Character .class .equals (targetClass ) || char .class .equals (targetClass )) {
260
+ result = (char ) value .intValue ();
261
+ } else if (Integer .class .equals (targetClass ) || int .class .equals (targetClass )) {
262
+ result = value .intValue ();
263
+ } else if (Long .class .equals (targetClass ) || long .class .equals (targetClass ) || IComEnum .class .isAssignableFrom (targetClass )) {
264
+ result = value .longValue ();
265
+ } else if (Float .class .equals (targetClass ) || float .class .equals (targetClass )) {
266
+ result = value .floatValue ();
267
+ } else if (Double .class .equals (targetClass ) || double .class .equals (targetClass )) {
268
+ result = value .doubleValue ();
269
+ } else if (Boolean .class .equals (targetClass ) || boolean .class .equals (targetClass )) {
270
+ result = value .booleanValue ();
271
+ } else if (Date .class .equals (targetClass )) {
272
+ result = value .dateValue ();
273
+ } else if (String .class .equals (targetClass )) {
274
+ result = value .stringValue ();
275
+ } else if (value .getValue () instanceof com .sun .jna .platform .win32 .COM .IDispatch ) {
276
+ com .sun .jna .platform .win32 .COM .IDispatch d = (com .sun .jna .platform .win32 .COM .IDispatch ) value .getValue ();
277
+ Object proxy = factory .createProxy (targetClass , d );
278
+ // must release a COM reference, createProxy adds one, as does the
279
+ // call
280
+ if (!addReference ) {
281
+ int n = d .Release ();
282
+ }
283
+ result = proxy ;
284
+ } else {
285
+ /*
286
+ WinDef.SCODE.class.equals(targetClass)
287
+ || OaIdl.CURRENCY.class.equals(targetClass)
288
+ || OaIdl.DECIMAL.class.equals(targetClass)
289
+ || OaIdl.SAFEARRAY.class.equals(targetClass)
290
+ || com.sun.jna.platform.win32.COM.IUnknown.class.equals(targetClass)
291
+ || Variant.class.equals(targetClass)
292
+ || PVOID.class.equals(targetClass
293
+ */
294
+ result = value .getValue ();
97
295
}
98
- // Handle VARIANTByRef
99
- if (vobj instanceof VARIANT ) {
100
- vobj = ((VARIANT ) vobj ).getValue ();
296
+
297
+ if (IComEnum .class .isAssignableFrom (targetClass )) {
298
+ return targetClass .cast (Convert .toComEnum ((Class <? extends IComEnum >) targetClass , result ));
299
+ } else {
300
+ return result ;
101
301
}
102
- if (vobj instanceof WinDef .BOOL ) {
103
- return ((WinDef .BOOL ) vobj ).booleanValue ();
104
- } else if (vobj instanceof VARIANT_BOOL ) {
105
- return ((VARIANT_BOOL ) vobj ).booleanValue ();
106
- } else if (vobj instanceof WinDef .LONG ) {
107
- return ((WinDef .LONG ) vobj ).longValue ();
108
- } else if (vobj instanceof WinDef .SHORT ) {
109
- return ((WinDef .SHORT ) vobj ).shortValue ();
110
- } else if (vobj instanceof WinDef .UINT ) {
111
- return ((WinDef .UINT ) vobj ).intValue ();
112
- } else if (vobj instanceof WinDef .WORD ) {
113
- return ((WinDef .WORD ) vobj ).intValue ();
114
- } else if (vobj instanceof WTypes .BSTR ) {
115
- return ((WTypes .BSTR ) vobj ).getValue ();
116
- }
117
- return vobj ;
118
302
}
119
303
120
304
public static <T extends IComEnum > T toComEnum (Class <T > enumType , Object value ) {
0 commit comments