-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
OaIdl.java
2008 lines (1707 loc) · 64.1 KB
/
OaIdl.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* The contents of this file is dual-licensed under 2
* alternative Open Source/Free licenses: LGPL 2.1 or later and
* Apache License 2.0. (starting with JNA version 4.0.0).
*
* You can freely decide which license you want to apply to
* the project.
*
* You may obtain a copy of the LGPL License at:
*
* http://www.gnu.org/licenses/licenses.html
*
* A copy is also included in the downloadable source code package
* containing JNA, in file "LGPL2.1".
*
* You may obtain a copy of the Apache License at:
*
* http://www.apache.org/licenses/
*
* A copy is also included in the downloadable source code package
* containing JNA, in file "AL2.0".
*/
package com.sun.jna.platform.win32;
import static com.sun.jna.platform.win32.Variant.VT_BOOL;
import static com.sun.jna.platform.win32.Variant.VT_BSTR;
import static com.sun.jna.platform.win32.Variant.VT_CY;
import static com.sun.jna.platform.win32.Variant.VT_DATE;
import static com.sun.jna.platform.win32.Variant.VT_DECIMAL;
import static com.sun.jna.platform.win32.Variant.VT_DISPATCH;
import static com.sun.jna.platform.win32.Variant.VT_ERROR;
import static com.sun.jna.platform.win32.Variant.VT_I1;
import static com.sun.jna.platform.win32.Variant.VT_I2;
import static com.sun.jna.platform.win32.Variant.VT_I4;
import static com.sun.jna.platform.win32.Variant.VT_INT;
import static com.sun.jna.platform.win32.Variant.VT_R4;
import static com.sun.jna.platform.win32.Variant.VT_R8;
import static com.sun.jna.platform.win32.Variant.VT_RECORD;
import static com.sun.jna.platform.win32.Variant.VT_UI1;
import static com.sun.jna.platform.win32.Variant.VT_UI2;
import static com.sun.jna.platform.win32.Variant.VT_UI4;
import static com.sun.jna.platform.win32.Variant.VT_UINT;
import static com.sun.jna.platform.win32.Variant.VT_UNKNOWN;
import static com.sun.jna.platform.win32.Variant.VT_VARIANT;
import java.io.Closeable;
import java.util.Date;
import com.sun.jna.IntegerType;
import com.sun.jna.Memory;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.Structure.FieldOrder;
import com.sun.jna.Union;
import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR;
import com.sun.jna.platform.win32.Guid.GUID;
import com.sun.jna.platform.win32.Variant.VARIANT;
import com.sun.jna.platform.win32.Variant.VariantArg;
import com.sun.jna.platform.win32.WTypes.BSTR;
import com.sun.jna.platform.win32.WTypes.LPOLESTR;
import com.sun.jna.platform.win32.WTypes.VARTYPE;
import com.sun.jna.platform.win32.WinDef.BYTE;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinDef.DWORDByReference;
import com.sun.jna.platform.win32.WinDef.LCID;
import com.sun.jna.platform.win32.WinDef.LONG;
import com.sun.jna.platform.win32.WinDef.LONGLONG;
import com.sun.jna.platform.win32.WinDef.PVOID;
import com.sun.jna.platform.win32.WinDef.SCODE;
import com.sun.jna.platform.win32.WinDef.SHORT;
import com.sun.jna.platform.win32.WinDef.ULONG;
import com.sun.jna.platform.win32.WinDef.ULONGLONG;
import com.sun.jna.platform.win32.WinDef.USHORT;
import com.sun.jna.platform.win32.WinDef.WORD;
import com.sun.jna.platform.win32.COM.COMUtils;
import com.sun.jna.platform.win32.COM.Dispatch;
import com.sun.jna.platform.win32.COM.TypeComp;
import com.sun.jna.platform.win32.COM.Unknown;
import com.sun.jna.ptr.ByReference;
import com.sun.jna.ptr.PointerByReference;
/**
* The Interface OaIdl.
*/
public interface OaIdl {
// The DATE Type is defined in localtime and the java Date type always contains
// a a timezone offset, so the difference has to be calculated and can't be
// predetermined
public static final long DATE_OFFSET = new Date(1899 - 1900, 12 - 1, 30, 0, 0, 0).getTime();
/**
* The Class EXCEPINFO.
*/
@FieldOrder({"wCode", "wReserved", "bstrSource", "bstrDescription",
"bstrHelpFile", "dwHelpContext", "pvReserved", "pfnDeferredFillIn",
"scode"})
public static class EXCEPINFO extends Structure {
/**
* The Class ByReference.
*/
public static class ByReference extends EXCEPINFO implements
Structure.ByReference {
}
/** The w code. */
public WORD wCode;
/** The w reserved. */
public WORD wReserved;
/** The bstr source. */
public BSTR bstrSource;
/** The bstr description. */
public BSTR bstrDescription;
/** The bstr help file. */
public BSTR bstrHelpFile;
/** The dw help context. */
public DWORD dwHelpContext;
/** The pv reserved. */
public PVOID pvReserved;
/** The pfn deferred fill in. */
public EXCEPINFO.ByReference pfnDeferredFillIn;
/** The scode. */
public SCODE scode;
/**
* Instantiates a new excepinfo.
*/
public EXCEPINFO() {
super();
}
/**
* Instantiates a new excepinfo.
*
* @param p
* the p
*/
public EXCEPINFO(Pointer p) {
super(p);
}
}
public static class VARIANT_BOOL extends IntegerType {
private static final long serialVersionUID = 1L;
public static final int SIZE = 2;
public VARIANT_BOOL() {
this(0);
}
public VARIANT_BOOL(long value) {
super(2, value);
}
public VARIANT_BOOL(boolean value) {
this(value ? 0xFFFF : 0x0000);
}
public boolean booleanValue() {
return shortValue() != 0x0000;
}
}
public static class _VARIANT_BOOL extends VARIANT_BOOL {
private static final long serialVersionUID = 1L;
public _VARIANT_BOOL() {
this(0);
}
public _VARIANT_BOOL(long value) {
super(value);
}
}
public static class VARIANT_BOOLByReference extends ByReference {
public VARIANT_BOOLByReference() {
this(new VARIANT_BOOL(0));
}
public VARIANT_BOOLByReference(VARIANT_BOOL value) {
super(VARIANT_BOOL.SIZE);
setValue(value);
}
public void setValue(VARIANT_BOOL value) {
getPointer().setShort(0, value.shortValue());
}
public VARIANT_BOOL getValue() {
return new VARIANT_BOOL(getPointer().getShort(0));
}
@Override
public String toString() {
return super.toString(getValue());
}
}
public static class _VARIANT_BOOLByReference extends ByReference {
public _VARIANT_BOOLByReference() {
this(new VARIANT_BOOL(0));
}
public _VARIANT_BOOLByReference(VARIANT_BOOL value) {
super(VARIANT_BOOL.SIZE);
setValue(value);
}
public void setValue(VARIANT_BOOL value) {
getPointer().setShort(0, value.shortValue());
}
public VARIANT_BOOL getValue() {
return new VARIANT_BOOL(getPointer().getShort(0));
}
@Override
public String toString() {
return super.toString(getValue());
}
}
@FieldOrder({"date"})
public static class DATE extends Structure {
private final static long MICRO_SECONDS_PER_DAY = 24L * 60L * 60L * 1000L;
public static class ByReference extends DATE implements
Structure.ByReference {
}
public double date;
public DATE() {
super();
}
public DATE(double date) {
this.date = date;
}
public DATE(Date javaDate) {
setFromJavaDate(javaDate);
}
public Date getAsJavaDate() {
long days = (((long) this.date) * MICRO_SECONDS_PER_DAY) + DATE_OFFSET;
double timePart = 24 * Math.abs(this.date - ((long) this.date));
int hours = (int) timePart;
timePart = 60 * (timePart - ((int) timePart));
int minutes = (int) timePart;
timePart = 60 * (timePart - ((int) timePart));
int seconds = (int) timePart;
timePart = 1000 * (timePart - ((int) timePart));
int milliseconds = (int) timePart;
Date baseDate = new Date(days);
baseDate.setHours(hours);
baseDate.setMinutes(minutes);
baseDate.setSeconds(seconds);
baseDate.setTime(baseDate.getTime() + milliseconds);
return baseDate;
}
public void setFromJavaDate(Date javaDate) {
double msSinceOrigin = javaDate.getTime() - DATE_OFFSET;
double daysAsFract = msSinceOrigin / MICRO_SECONDS_PER_DAY;
Date dayDate = new Date(javaDate.getTime());
dayDate.setHours(0);
dayDate.setMinutes(0);
dayDate.setSeconds(0);
dayDate.setTime(dayDate.getTime() / 1000 * 1000); // Clear milliseconds
double integralPart = Math.floor(daysAsFract);
double fractionalPart = Math.signum(daysAsFract) * ((javaDate.getTime() - dayDate.getTime()) / (24d * 60 * 60 * 1000));
this.date = integralPart + fractionalPart;
}
}
/**
* The Class DISPID.
*/
public static class DISPID extends LONG {
private static final long serialVersionUID = 1L;
public DISPID() {
this(0);
}
public DISPID(int value) {
super(value);
}
}
public static class DISPIDByReference extends ByReference {
public DISPIDByReference() {
this(new DISPID(0));
}
public DISPIDByReference(DISPID value) {
super(DISPID.SIZE);
setValue(value);
}
public void setValue(DISPID value) {
getPointer().setInt(0, value.intValue());
}
public DISPID getValue() {
return new DISPID(getPointer().getInt(0));
}
@Override
public String toString() {
return super.toString(getValue());
}
}
public static class MEMBERID extends DISPID {
private static final long serialVersionUID = 1L;
public MEMBERID() {
this(0);
}
public MEMBERID(int value) {
super(value);
}
}
public static class MEMBERIDByReference extends ByReference {
public MEMBERIDByReference() {
this(new MEMBERID(0));
}
public MEMBERIDByReference(MEMBERID value) {
super(MEMBERID.SIZE);
setValue(value);
}
public void setValue(MEMBERID value) {
getPointer().setInt(0, value.intValue());
}
public MEMBERID getValue() {
return new MEMBERID(getPointer().getInt(0));
}
@Override
public String toString() {
return super.toString(getValue());
}
}
// The Collect property. You use this property if the method you are calling
// through Invoke is an accessor function.
/** The Constant DISPID_COLLECT. */
public final static DISPID DISPID_COLLECT = new DISPID(-8);
// The C++ constructor function for the object.
/** The Constant DISPID_CONSTRUCTOR. */
public final static DISPID DISPID_CONSTRUCTOR = new DISPID(-6);
// The C++ destructor function for the object.
/** The Constant DISPID_DESTRUCTOR. */
public final static DISPID DISPID_DESTRUCTOR = new DISPID(-7);
// The Evaluate method. This method is implicitly invoked when the ActiveX
// client encloses the arguments in square brackets. For example, the
// following two lines are equivalent:
/** The Constant DISPID_EVALUATE. */
public final static DISPID DISPID_EVALUATE = new DISPID(-5);
// The _NewEnum property. This special, restricted property is required for
// collection objects. It returns an enumerator object that supports
// IEnumVARIANT, and should have the restricted attribute specified.
/** The Constant DISPID_NEWENUM. */
public final static DISPID DISPID_NEWENUM = new DISPID(-4);
// The parameter that receives the value of an assignment in a PROPERTYPUT.
/** The Constant DISPID_PROPERTYPUT. */
public final static DISPID DISPID_PROPERTYPUT = new DISPID(-3);
// The value returned by IDispatch::GetIDsOfNames to indicate that a member
// or parameter name was not found.
/** The Constant DISPID_UNKNOWN. */
public final static DISPID DISPID_UNKNOWN = new DISPID(-1);
// The default member for the object. This property or method is invoked
// when an ActiveX client specifies the object name without a property or
// method.
/** The Constant DISPID_VALUE. */
public final static DISPID DISPID_VALUE = new DISPID(0);
public final static MEMBERID MEMBERID_NIL = new MEMBERID(
DISPID_UNKNOWN.intValue());
/** An array that is allocated on the stack. */
public final static int FADF_AUTO = 0x0001;
/** An array that is statically allocated. */
public final static int FADF_STATIC = 0x0002;
/** An array that is embedded in a structure. */
public final static int FADF_EMBEDDED = 0x0004;
/** An array that may not be resized or reallocated. */
public final static int FADF_FIXEDSIZE = 0x0010;
/**
* An array that contains records. When set, there will be a pointer to the
* IRecordInfo interface at negative offset 4 in the array descriptor.
*/
public final static int FADF_RECORD = 0x0020;
/**
* An array that has an IID identifying interface. When set, there will be a
* GUID at negative offset 16 in the safe array descriptor. Flag is set only
* when FADF_DISPATCH or FADF_UNKNOWN is also set.
*/
public final static int FADF_HAVEIID = 0x0040;
/**
* An array that has a variant type. The variant type can be retrieved with
* SafeArrayGetVartype.
*/
public final static int FADF_HAVEVARTYPE = 0x0080;
/** An array of BSTRs. */
public final static int FADF_BSTR = 0x0100;
/** An array of IUnknown*. */
public final static int FADF_UNKNOWN = 0x0200;
/** An array of IDispatch*. */
public final static int FADF_DISPATCH = 0x0400;
/** An array of VARIANTs. */
public final static int FADF_VARIANT = 0x0800;
/** Bits reserved for future use. */
public final static int FADF_RESERVED = 0xF008;
@FieldOrder({"value"})
public static class TYPEKIND extends Structure {
public static class ByReference extends TYPEKIND implements
Structure.ByReference {
public ByReference() {
}
public ByReference(int value) {
super(value);
}
public ByReference(TYPEKIND typekind) {
super(typekind.getPointer());
value = typekind.value;
}
}
public int value;
public TYPEKIND() {
super();
}
public TYPEKIND(int value) {
this.value = value;
}
public TYPEKIND(Pointer pointer) {
super(pointer);
this.read();
}
// / <i>native declaration : line 4</i>
public static final int TKIND_ENUM = 0;
// / <i>native declaration : line 5</i>
public static final int TKIND_RECORD = TYPEKIND.TKIND_ENUM + 1;
// / <i>native declaration : line 6</i>
public static final int TKIND_MODULE = TYPEKIND.TKIND_RECORD + 1;
// / <i>native declaration : line 7</i>
public static final int TKIND_INTERFACE = TYPEKIND.TKIND_MODULE + 1;
// / <i>native declaration : line 8</i>
public static final int TKIND_DISPATCH = TYPEKIND.TKIND_INTERFACE + 1;
// / <i>native declaration : line 9</i>
public static final int TKIND_COCLASS = TYPEKIND.TKIND_DISPATCH + 1;
// / <i>native declaration : line 10</i>
public static final int TKIND_ALIAS = TYPEKIND.TKIND_COCLASS + 1;
// / <i>native declaration : line 11</i>
public static final int TKIND_UNION = TYPEKIND.TKIND_ALIAS + 1;
// / <i>native declaration : line 12</i>
public static final int TKIND_MAX = TYPEKIND.TKIND_UNION + 1;
}
@FieldOrder({"value"})
public static class DESCKIND extends Structure {
public static class ByReference extends DESCKIND implements
Structure.ByReference {
}
public int value;
public DESCKIND() {
super();
}
public DESCKIND(int value) {
this.value = value;
}
public DESCKIND(Pointer pointer) {
super(pointer);
this.read();
}
// / <i>native declaration : line 4</i>
public static final int DESCKIND_NONE = 0;
// / <i>native declaration : line 5</i>
public static final int DESCKIND_FUNCDESC = DESCKIND.DESCKIND_NONE + 1;
// / <i>native declaration : line 6</i>
public static final int DESCKIND_VARDESC = DESCKIND.DESCKIND_FUNCDESC + 1;
// / <i>native declaration : line 7</i>
public static final int DESCKIND_TYPECOMP = DESCKIND.DESCKIND_VARDESC + 1;
// / <i>native declaration : line 8</i>
public static final int DESCKIND_IMPLICITAPPOBJ = DESCKIND.DESCKIND_TYPECOMP + 1;
// / <i>native declaration : line 9</i>
public static final int DESCKIND_MAX = DESCKIND.DESCKIND_IMPLICITAPPOBJ + 1;
}
/**
* Implementation of SAFEARRAY. Implements Closable, which in this case
* delegates to destroy, to free native memory on close.
*
* <p>VARTYPE for the SAFEARRAY can be:</p>
*
* <ul>
* <li>VT_BOOL</li>
* <li>VT_BSTR</li>
* <li>VT_CY</li>
* <li>VT_DATE</li>
* <li>VT_DECIMAL</li>
* <li>VT_DISPATCH</li>
* <li>VT_ERROR</li>
* <li>VT_I1</li>
* <li>VT_I2</li>
* <li>VT_I4</li>
* <li>VT_INT</li>
* <li>VT_R4</li>
* <li>VT_R8</li>
* <li>VT_RECORD</li>
* <li>VT_UI1</li>
* <li>VT_UI2</li>
* <li>VT_UI4</li>
* <li>VT_UINT</li>
* <li>VT_UNKNOWN</li>
* <li>VT_VARIANT</li>
* </ul>
*
* <p>General comment: All indices in the helper methods use java int.</p>
*
* <p>The native type for the indices is LONG, which is defined as:</p>
*
* <blockquote>A 32-bit signed integer. The range is �2147483648 through 2147483647 decimal.</blockquote>
*/
@FieldOrder({"cDims", "fFeatures", "cbElements", "cLocks", "pvData", "rgsabound"})
public static class SAFEARRAY extends Structure implements Closeable {
public static class ByReference extends SAFEARRAY implements
Structure.ByReference {
}
public USHORT cDims;
public USHORT fFeatures;
public ULONG cbElements;
public ULONG cLocks;
public PVOID pvData;
/** The rgsabound. */
public SAFEARRAYBOUND[] rgsabound = { new SAFEARRAYBOUND() };
public SAFEARRAY() {
super();
}
public SAFEARRAY(Pointer pointer) {
super(pointer);
this.read();
}
@Override
public void read() {
super.read();
if(cDims.intValue() > 0) {
rgsabound = (SAFEARRAYBOUND[]) rgsabound[0].toArray(cDims.intValue());
} else {
rgsabound = new SAFEARRAYBOUND[]{ new SAFEARRAYBOUND() };
}
}
/**
* Create a SAFEARRAY with supplied VARIANT as element type.
*
* <p>
* This helper creates a basic SAFEARRAY with a base type of VT_VARIANT.
* The array will have as many dimensions as parameters are passed in.
* The lowerbound for each dimension is set to zero, the count to the
* parameter value.</p>
*
* @param size array of dimension size
* @return SAFEARRAYWrapper or {@code NULL} if creation fails.
*/
public static SAFEARRAY.ByReference createSafeArray(int... size) {
return createSafeArray(new WTypes.VARTYPE(Variant.VT_VARIANT), size);
}
/**
* Create a SAFEARRAY with supplied element type.
*
* <p>
* The array will have as many dimensions as parameters are passed in.
* The lowerbound for each dimension is set to zero, the count to the
* parameter value.</p>
*
* @param vartype type of array contents (see Variant.VT_* constants)
* @param size array of dimension size
* @return SAFEARRAYWrapper or {@code NULL} if creation fails.
*/
public static SAFEARRAY.ByReference createSafeArray(VARTYPE vartype, int... size) {
OaIdl.SAFEARRAYBOUND[] rgsabound = (OaIdl.SAFEARRAYBOUND[]) new OaIdl.SAFEARRAYBOUND().toArray(size.length);
for (int i = 0; i < size.length; i++) {
rgsabound[i].lLbound = new WinDef.LONG(0);
rgsabound[i].cElements = new WinDef.ULONG(size[size.length - i - 1]);
}
SAFEARRAY.ByReference data = OleAuto.INSTANCE.SafeArrayCreate(vartype, new WinDef.UINT(size.length), rgsabound);
return data;
}
/**
* Set value at {@code indices} in {@code array} to arg.
*
* <p>
* The supplied argument is copied into the array. If the value is no
* longer needed, it needs to be freed if not handled automatically.</p>
*
* @param indices the index, order follows java/C convention
* @param arg the arg
*/
public void putElement(Object arg, int... indices) {
WinDef.LONG[] paramIndices = new WinDef.LONG[indices.length];
for (int i = 0; i < indices.length; i++) {
paramIndices[i] = new WinDef.LONG(indices[indices.length - i - 1]);
}
WinNT.HRESULT hr;
Memory mem;
switch (getVarType().intValue()) {
case VT_BOOL:
mem = new Memory(2);
if(arg instanceof Boolean) {
mem.setShort(0, (short) (((Boolean) arg) ? 0xFFFF : 0) );
} else {
mem.setShort(0, (short) (((Number) arg).intValue() > 0 ? 0xFFFF : 0));
}
hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem);
COMUtils.checkRC(hr);
break;
case VT_UI1:
case VT_I1:
mem = new Memory(1);
mem.setByte(0, ((Number) arg).byteValue());
hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem);
COMUtils.checkRC(hr);
break;
case VT_UI2:
case VT_I2:
mem = new Memory(2);
mem.setShort(0, ((Number) arg).shortValue());
hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem);
COMUtils.checkRC(hr);
break;
case VT_UI4:
case VT_UINT:
case VT_I4:
case VT_INT:
mem = new Memory(4);
mem.setInt(0, ((Number) arg).intValue());
hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem);
COMUtils.checkRC(hr);
break;
case VT_ERROR:
mem = new Memory(4);
mem.setInt(0, ((Number) arg).intValue());
hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem);
COMUtils.checkRC(hr);
break;
case VT_R4:
mem = new Memory(4);
mem.setFloat(0, ((Number) arg).floatValue());
hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem);
COMUtils.checkRC(hr);
break;
case VT_R8:
mem = new Memory(8);
mem.setDouble(0, ((Number) arg).doubleValue());
hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem);
COMUtils.checkRC(hr);
break;
case VT_DATE:
mem = new Memory(8);
mem.setDouble(0, ((DATE) arg).date);
hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem);
COMUtils.checkRC(hr);
break;
case VT_BSTR:
if(arg instanceof String) {
BSTR bstr = OleAuto.INSTANCE.SysAllocString((String) arg);
hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, bstr.getPointer());
OleAuto.INSTANCE.SysFreeString(bstr);
COMUtils.checkRC(hr);
} else {
hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, ((BSTR) arg).getPointer());
COMUtils.checkRC(hr);
}
break;
case VT_VARIANT:
hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, ((VARIANT) arg).getPointer());
COMUtils.checkRC(hr);
break;
case VT_UNKNOWN:
hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, ((Unknown) arg).getPointer());
COMUtils.checkRC(hr);
break;
case VT_DISPATCH:
hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, ((Dispatch) arg).getPointer());
COMUtils.checkRC(hr);
break;
case VT_CY:
hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, ((CURRENCY) arg).getPointer());
COMUtils.checkRC(hr);
break;
case VT_DECIMAL:
hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, ((DECIMAL) arg).getPointer());
COMUtils.checkRC(hr);
break;
case VT_RECORD:
default:
throw new IllegalStateException("Can't parse array content - type not supported: " + getVarType().intValue());
}
}
/**
* Retrieve the value at the referenced index from the SAFEARRAY.
*
* <p>The function creates a copy of the value. The values are
* allocated with native functions and need to be freed accordingly.</p>
*
* @param indices the index, order follows java/C convention
* @return the variant
*/
public Object getElement(int... indices) {
WinDef.LONG[] paramIndices = new WinDef.LONG[indices.length];
for (int i = 0; i < indices.length; i++) {
paramIndices[i] = new WinDef.LONG(indices[indices.length - i - 1]);
}
Object result;
WinNT.HRESULT hr;
Memory mem;
PointerByReference pbr;
switch (getVarType().intValue()) {
case VT_BOOL:
mem = new Memory(2);
hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem);
COMUtils.checkRC(hr);
result = mem.getShort(0) != 0;
break;
case VT_UI1:
case VT_I1:
mem = new Memory(1);
hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem);
COMUtils.checkRC(hr);
result = mem.getByte(0);
break;
case VT_UI2:
case VT_I2:
mem = new Memory(2);
hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem);
COMUtils.checkRC(hr);
result = mem.getShort(0);
break;
case VT_UI4:
case VT_UINT:
case VT_I4:
case VT_INT:
mem = new Memory(4);
hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem);
COMUtils.checkRC(hr);
result = mem.getInt(0);
break;
case VT_ERROR:
mem = new Memory(4);
hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem);
COMUtils.checkRC(hr);
result = new SCODE(mem.getInt(0));
break;
case VT_R4:
mem = new Memory(4);
hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem);
COMUtils.checkRC(hr);
result = mem.getFloat(0);
break;
case VT_R8:
mem = new Memory(8);
hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem);
COMUtils.checkRC(hr);
result = mem.getDouble(0);
break;
case VT_DATE:
mem = new Memory(8);
hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem);
COMUtils.checkRC(hr);
result = new DATE(mem.getDouble(0));
break;
case VT_BSTR:
pbr = new PointerByReference();
hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, pbr.getPointer());
COMUtils.checkRC(hr);
BSTR bstr = new BSTR(pbr.getValue());
result = bstr.getValue();
OleAuto.INSTANCE.SysFreeString(bstr);
break;
case VT_VARIANT:
VARIANT holder = new Variant.VARIANT();
hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, holder.getPointer());
COMUtils.checkRC(hr);
result = holder;
break;
case VT_UNKNOWN:
pbr = new PointerByReference();
hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, pbr.getPointer());
COMUtils.checkRC(hr);
result = new Unknown(pbr.getValue());
break;
case VT_DISPATCH:
pbr = new PointerByReference();
hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, pbr.getPointer());
COMUtils.checkRC(hr);
result = new Dispatch(pbr.getValue());
break;
case VT_CY:
CURRENCY currency = new CURRENCY();
hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, currency.getPointer());
COMUtils.checkRC(hr);
result = currency;
break;
case VT_DECIMAL:
DECIMAL decimal = new DECIMAL();
hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, decimal.getPointer());
COMUtils.checkRC(hr);
result = decimal;
break;
case VT_RECORD:
default:
throw new IllegalStateException("Can't parse array content - type not supported: " + getVarType().intValue());
}
return result;
}
/**
* Retrieve pointer to data element from array.
*
* <p>
* Caller is responsible for (un)locking the array via
* {@link OleAuto#SafeArrayLock} and {@link OleAuto#SafeArrayUnlock} or
* the helper methods: {@link SAFEARRAY#lock} and
* {@link SAFEARRAY#unlock}.</p>
*
* @param indices the index, order follows java/C convention
* @return the pointer to the data element
*/
public Pointer ptrOfIndex(int... indices) {
WinDef.LONG[] paramIndices = new WinDef.LONG[indices.length];
for (int i = 0; i < indices.length; i++) {
paramIndices[i] = new WinDef.LONG(indices[indices.length - i - 1]);
}
PointerByReference pbr = new PointerByReference();
WinNT.HRESULT hr = OleAuto.INSTANCE.SafeArrayPtrOfIndex(this, paramIndices, pbr);
COMUtils.checkRC(hr);
return pbr.getValue();
}
/**
* Destroy the underlying SAFEARRAY and free memory
*/
public void destroy() {
WinNT.HRESULT res = OleAuto.INSTANCE.SafeArrayDestroy(this);
COMUtils.checkRC(res);
}
/**
* Implemented to satisfy Closeable interface, delegates to destroy.
*/
@Override
public void close() {
destroy();
}
/**
* Retrieve lower bound for the selected dimension.
*
* <p>As in the all the accessor functions, that index is converted to
* java conventions.</p>
*
* @param dimension zerobased index
* @return lower bound for the selected dimension
*/
public int getLBound(int dimension) {
int targetDimension = getDimensionCount() - dimension;
WinDef.LONGByReference bound = new WinDef.LONGByReference();
WinNT.HRESULT res = OleAuto.INSTANCE.SafeArrayGetLBound(this, new WinDef.UINT(targetDimension), bound);
COMUtils.checkRC(res);
return bound.getValue().intValue();
}
/**
* Retrieve upper bound for the selected dimension.
*
* <p>As in the all the accessor functions, that index is converted to
* java conventions.</p>
*
* @param dimension zerobased index
* @return upper bound for the selected dimension
*/
public int getUBound(int dimension) {
int targetDimension = getDimensionCount() - dimension;
WinDef.LONGByReference bound = new WinDef.LONGByReference();
WinNT.HRESULT res = OleAuto.INSTANCE.SafeArrayGetUBound(this, new WinDef.UINT(targetDimension), bound);
COMUtils.checkRC(res);
return bound.getValue().intValue();
}
/**
* Return number of dimensions of the SAFEARRAY
*
* @return number of dimensions of the SAFEARRAY
*/
public int getDimensionCount() {
return OleAuto.INSTANCE.SafeArrayGetDim(this).intValue();
}
/**
* Lock array and retrieve pointer to data
*
* @return Pointer to arraydata
*/
public Pointer accessData() {
PointerByReference pbr = new PointerByReference();
WinNT.HRESULT hr = OleAuto.INSTANCE.SafeArrayAccessData(this, pbr);
COMUtils.checkRC(hr);
return pbr.getValue();
}
/**
* Unlock array and invalidate the pointer retrieved via
* SafeArrayAccessData
*/
public void unaccessData() {
WinNT.HRESULT hr = OleAuto.INSTANCE.SafeArrayUnaccessData(this);
COMUtils.checkRC(hr);
}
/**
* Increments the lock count of an array, and places a pointer to the
* array data in pvData of the array descriptor.
*/
public void lock() {
WinNT.HRESULT res = OleAuto.INSTANCE.SafeArrayLock(this);
COMUtils.checkRC(res);
}
/**
* Decrements the lock count of an array so it can be freed or resized
*/
public void unlock() {
WinNT.HRESULT res = OleAuto.INSTANCE.SafeArrayUnlock(this);