@@ -127,6 +127,17 @@ public interface ByValue { }
127
127
*/
128
128
public interface ByReference { }
129
129
130
+ private static class PointerTracking {
131
+
132
+ private final Pointer pointer ;
133
+ private final Object value ;
134
+
135
+ PointerTracking (Pointer pointer , Object value ) {
136
+ this .pointer = pointer ;
137
+ this .value = value ;
138
+ }
139
+ }
140
+
130
141
/** Use the platform default alignment. */
131
142
public static final int ALIGN_DEFAULT = 0 ;
132
143
/** No alignment, place all fields on nearest 1-byte boundary */
@@ -157,7 +168,7 @@ public interface ByReference { }
157
168
private Map <String , StructField > structFields ;
158
169
// Keep track of native C strings which have been allocated,
159
170
// corresponding to String fields of this Structure
160
- private final Map <String , Object > nativeStrings = new HashMap <String , Object >( );
171
+ private final Map <String , PointerTracking > nativeStrings = new HashMap <String , PointerTracking >( 8 );
161
172
private TypeMapper typeMapper ;
162
173
// This field is accessed by native code
163
174
private long typeInfo ;
@@ -343,14 +354,15 @@ void useMemory(Pointer m, int offset, boolean force) {
343
354
this .memory .write (0 , buf , 0 , buf .length );
344
355
}
345
356
else {
346
- // Ensure our memory pointer is initialized, even if we can't
347
- // yet figure out a proper size/layout
348
- this .memory = m .share (offset );
349
357
if (size == CALCULATE_SIZE ) {
350
358
size = calculateSize (false );
351
359
}
352
360
if (size != CALCULATE_SIZE ) {
353
361
this .memory = m .share (offset , size );
362
+ } else {
363
+ // Ensure our memory pointer is initialized, even if we can't
364
+ // yet figure out a proper size/layout
365
+ this .memory = m .share (offset );
354
366
}
355
367
}
356
368
this .array = null ;
@@ -508,8 +520,9 @@ public boolean add(Structure o) {
508
520
if (!contains (o )) {
509
521
ensureCapacity (count +1 );
510
522
elements [count ++] = o ;
523
+ return true ;
511
524
}
512
- return true ;
525
+ return false ;
513
526
}
514
527
private int indexOf (Structure s1 ) {
515
528
for (int i =0 ;i < count ;i ++) {
@@ -579,10 +592,9 @@ public void read() {
579
592
ensureAllocated ();
580
593
581
594
// Avoid redundant reads
582
- if (busy ().contains (this )) {
595
+ if (! busy ().add (this )) {
583
596
return ;
584
597
}
585
- busy ().add (this );
586
598
if (this instanceof Structure .ByReference ) {
587
599
reading ().put (getPointer (), this );
588
600
}
@@ -593,7 +605,7 @@ public void read() {
593
605
}
594
606
finally {
595
607
busy ().remove (this );
596
- if (reading ().get (getPointer ()) == this ) {
608
+ if (this instanceof Structure . ByReference && reading ().get (getPointer ()) == this ) {
597
609
reading ().remove (getPointer ());
598
610
}
599
611
}
@@ -740,8 +752,7 @@ protected Object readField(StructField structField) {
740
752
741
753
if (fieldType .equals (String .class )
742
754
|| fieldType .equals (WString .class )) {
743
- nativeStrings .put (structField .name + ".ptr" , memory .getPointer (offset ));
744
- nativeStrings .put (structField .name + ".val" , result );
755
+ nativeStrings .put (structField .name , new PointerTracking (memory .getPointer (offset ), result ));
745
756
}
746
757
747
758
// Update the value on the Java field
@@ -769,10 +780,9 @@ public void write() {
769
780
}
770
781
771
782
// Avoid redundant writes
772
- if (busy ().contains (this )) {
783
+ if (! busy ().add (this )) {
773
784
return ;
774
785
}
775
- busy ().add (this );
776
786
try {
777
787
// Write all fields, except those marked 'volatile'
778
788
for (StructField sf : fields ().values ()) {
@@ -845,23 +855,21 @@ protected void writeField(StructField structField) {
845
855
if (value != null ) {
846
856
// If we've already allocated a native string here, and the
847
857
// string value is unchanged, leave it alone
848
- if ( nativeStrings .containsKey (structField .name + ".ptr" )
849
- && value .equals (nativeStrings . get ( structField . name + ".val" ) )) {
858
+ PointerTracking tracking = nativeStrings .get (structField .name );
859
+ if ( tracking != null && value .equals (tracking . value )) {
850
860
return ;
851
861
}
852
862
NativeString nativeString = wide
853
863
? new NativeString (value .toString (), true )
854
864
: new NativeString (value .toString (), encoding );
855
865
// Keep track of allocated C strings to avoid
856
866
// premature garbage collection of the memory.
857
- nativeStrings .put (structField .name , nativeString );
867
+ nativeStrings .put (structField .name , new PointerTracking ( nativeString . getPointer (), nativeString ) );
858
868
value = nativeString .getPointer ();
859
869
}
860
870
else {
861
871
nativeStrings .remove (structField .name );
862
872
}
863
- nativeStrings .remove (structField .name + ".ptr" );
864
- nativeStrings .remove (structField .name + ".val" );
865
873
}
866
874
867
875
try {
0 commit comments