5
5
// ignore_for_file: unnecessary_cast, overridden_fields
6
6
7
7
import 'dart:ffi' ;
8
+ import 'dart:typed_data' ;
8
9
9
10
import 'package:collection/collection.dart' ;
10
11
import 'package:ffi/ffi.dart' ;
@@ -131,39 +132,57 @@ class JArray<E> extends JObject {
131
132
132
133
extension NativeArray <E extends JPrimitive > on JArray <E > {
133
134
void _allocate <T extends NativeType >(
134
- int size ,
135
+ int byteCount ,
135
136
void Function (Pointer <T > ptr) use,
136
137
) {
137
138
using ((arena) {
138
- final ptr = arena.allocate <T >(size );
139
+ final ptr = arena.allocate <T >(byteCount );
139
140
use (ptr);
140
141
}, malloc);
141
142
}
142
143
}
143
144
145
+ extension on Allocator {
146
+ Pointer <NativeFinalizerFunction >? get _nativeFree {
147
+ return switch (this ) {
148
+ malloc => malloc.nativeFree,
149
+ calloc => calloc.nativeFree,
150
+ _ => null ,
151
+ };
152
+ }
153
+ }
154
+
144
155
extension BoolArray on JArray <jboolean> {
145
156
bool operator [](int index) {
146
157
return _elementAt (index, JniCallType .booleanType).boolean;
147
158
}
148
159
149
160
void operator []= (int index, bool value) {
150
161
RangeError .checkValidIndex (index, this );
151
- _allocate <JBooleanMarker >(sizeOf <JBooleanMarker >(), (ptr) {
152
- ptr.value = value ? 1 : 0 ;
153
- Jni .env.SetBooleanArrayRegion (reference.pointer, index, 1 , ptr);
154
- });
162
+ Jni .accessors
163
+ .setBooleanArrayElement (reference.pointer, index, value ? 1 : 0 );
164
+ }
165
+
166
+ Uint8List getRange (int start, int end, {Allocator allocator = malloc}) {
167
+ RangeError .checkValidRange (start, end, length);
168
+ final rangeLength = end - start;
169
+ final buffer = allocator
170
+ .allocate <JBooleanMarker >(sizeOf <JBooleanMarker >() * rangeLength);
171
+ Jni .env
172
+ .GetBooleanArrayRegion (reference.pointer, start, rangeLength, buffer);
173
+ return buffer.asTypedList (rangeLength, finalizer: allocator._nativeFree);
155
174
}
156
175
157
176
void setRange (int start, int end, Iterable <bool > iterable,
158
177
[int skipCount = 0 ]) {
159
178
RangeError .checkValidRange (start, end, length);
160
- final size = end - start;
161
- final it = iterable.skip (skipCount).take (size );
162
- _allocate <JBooleanMarker >(sizeOf <JBooleanMarker >() * size , (ptr) {
179
+ final rangeLength = end - start;
180
+ final it = iterable.skip (skipCount).take (rangeLength );
181
+ _allocate <JBooleanMarker >(sizeOf <JBooleanMarker >() * rangeLength , (ptr) {
163
182
it.forEachIndexed ((index, element) {
164
183
ptr[index] = element ? 1 : 0 ;
165
184
});
166
- Jni .env.SetBooleanArrayRegion (reference.pointer, start, size , ptr);
185
+ Jni .env.SetBooleanArrayRegion (reference.pointer, start, rangeLength , ptr);
167
186
});
168
187
}
169
188
}
@@ -175,51 +194,61 @@ extension ByteArray on JArray<jbyte> {
175
194
176
195
void operator []= (int index, int value) {
177
196
RangeError .checkValidIndex (index, this );
178
- _allocate <JByteMarker >(sizeOf <JByteMarker >(), (ptr) {
179
- ptr.value = value;
180
- Jni .env.SetByteArrayRegion (reference.pointer, index, 1 , ptr);
181
- });
197
+ Jni .accessors.setByteArrayElement (reference.pointer, index, value).check ();
198
+ }
199
+
200
+ Int8List getRange (int start, int end, {Allocator allocator = malloc}) {
201
+ RangeError .checkValidRange (start, end, length);
202
+ final rangeLength = end - start;
203
+ final buffer = allocator <JByteMarker >(rangeLength);
204
+ Jni .env.GetByteArrayRegion (reference.pointer, start, rangeLength, buffer);
205
+ return buffer.asTypedList (rangeLength, finalizer: allocator._nativeFree);
182
206
}
183
207
184
208
void setRange (int start, int end, Iterable <int > iterable,
185
209
[int skipCount = 0 ]) {
186
210
RangeError .checkValidRange (start, end, length);
187
- final size = end - start;
188
- final it = iterable.skip (skipCount).take (size);
189
- _allocate <JByteMarker >(sizeOf <JByteMarker >() * size, (ptr) {
190
- it.forEachIndexed ((index, element) {
191
- ptr[index] = element;
192
- });
193
- Jni .env.SetByteArrayRegion (reference.pointer, start, size, ptr);
211
+ final rangeLength = end - start;
212
+ _allocate <JByteMarker >(sizeOf <JByteMarker >() * rangeLength, (ptr) {
213
+ ptr
214
+ .asTypedList (rangeLength)
215
+ .setRange (0 , rangeLength, iterable, skipCount);
216
+ Jni .env.SetByteArrayRegion (reference.pointer, start, rangeLength, ptr);
194
217
});
195
218
}
196
219
}
197
220
221
+ /// `JArray<jchar>` is a 16-bit integer array.
222
+ ///
223
+ /// Due to variable length encoding, the number of code units is not equal to
224
+ /// the number of characters.
198
225
extension CharArray on JArray <jchar> {
199
- String operator [](int index) {
200
- return String .fromCharCode (
201
- _elementAt (index, JniCallType .charType).char,
202
- );
226
+ int operator [](int index) {
227
+ return _elementAt (index, JniCallType .charType).char;
203
228
}
204
229
205
- void operator []= (int index, String value) {
230
+ void operator []= (int index, int value) {
206
231
RangeError .checkValidIndex (index, this );
207
- _allocate <JCharMarker >(sizeOf <JCharMarker >(), (ptr) {
208
- ptr.value = value.codeUnits.first;
209
- Jni .env.SetCharArrayRegion (reference.pointer, index, 1 , ptr);
210
- });
232
+ Jni .accessors.setCharArrayElement (reference.pointer, index, value).check ();
233
+ }
234
+
235
+ Uint16List getRange (int start, int end, {Allocator allocator = malloc}) {
236
+ RangeError .checkValidRange (start, end, length);
237
+ final rangeLength = end - start;
238
+ final buffer = allocator <JCharMarker >(rangeLength);
239
+ Jni .env.GetCharArrayRegion (reference.pointer, start, rangeLength, buffer);
240
+ return buffer.asTypedList (rangeLength, finalizer: allocator._nativeFree);
211
241
}
212
242
213
- void setRange (int start, int end, Iterable <String > iterable,
243
+ void setRange (int start, int end, Iterable <int > iterable,
214
244
[int skipCount = 0 ]) {
215
245
RangeError .checkValidRange (start, end, length);
216
- final size = end - start;
217
- final it = iterable.skip (skipCount).take (size);
218
- _allocate <JCharMarker >(sizeOf <JCharMarker >() * size, (ptr) {
219
- it.forEachIndexed ((index, element) {
220
- ptr[index] = element.codeUnits.first;
221
- });
222
- Jni .env.SetCharArrayRegion (reference.pointer, start, size, ptr);
246
+ final rangeLength = end - start;
247
+ _allocate <JCharMarker >(sizeOf <JCharMarker >() * rangeLength, (ptr) {
248
+ ptr
249
+ .asTypedList (rangeLength)
250
+ .setRange (0 , rangeLength, iterable, skipCount);
251
+ Jni .env.SetCharArrayRegion (reference.pointer, start, rangeLength, ptr);
223
252
});
224
253
}
225
254
}
@@ -231,22 +260,26 @@ extension ShortArray on JArray<jshort> {
231
260
232
261
void operator []= (int index, int value) {
233
262
RangeError .checkValidIndex (index, this );
234
- _allocate <JShortMarker >(sizeOf <JShortMarker >(), (ptr) {
235
- ptr.value = value;
236
- Jni .env.SetShortArrayRegion (reference.pointer, index, 1 , ptr);
237
- });
263
+ Jni .accessors.setShortArrayElement (reference.pointer, index, value).check ();
264
+ }
265
+
266
+ Int16List getRange (int start, int end, {Allocator allocator = malloc}) {
267
+ RangeError .checkValidRange (start, end, length);
268
+ final rangeLength = end - start;
269
+ final buffer = allocator <JShortMarker >(rangeLength);
270
+ Jni .env.GetShortArrayRegion (reference.pointer, start, rangeLength, buffer);
271
+ return buffer.asTypedList (rangeLength, finalizer: allocator._nativeFree);
238
272
}
239
273
240
274
void setRange (int start, int end, Iterable <int > iterable,
241
275
[int skipCount = 0 ]) {
242
276
RangeError .checkValidRange (start, end, length);
243
- final size = end - start;
244
- final it = iterable.skip (skipCount).take (size);
245
- _allocate <JShortMarker >(sizeOf <JShortMarker >() * size, (ptr) {
246
- it.forEachIndexed ((index, element) {
247
- ptr[index] = element;
248
- });
249
- Jni .env.SetShortArrayRegion (reference.pointer, start, size, ptr);
277
+ final rangeLength = end - start;
278
+ _allocate <JShortMarker >(sizeOf <JShortMarker >() * rangeLength, (ptr) {
279
+ ptr
280
+ .asTypedList (rangeLength)
281
+ .setRange (0 , rangeLength, iterable, skipCount);
282
+ Jni .env.SetShortArrayRegion (reference.pointer, start, rangeLength, ptr);
250
283
});
251
284
}
252
285
}
@@ -258,22 +291,26 @@ extension IntArray on JArray<jint> {
258
291
259
292
void operator []= (int index, int value) {
260
293
RangeError .checkValidIndex (index, this );
261
- _allocate <JIntMarker >(sizeOf <JIntMarker >(), (ptr) {
262
- ptr.value = value;
263
- Jni .env.SetIntArrayRegion (reference.pointer, index, 1 , ptr);
264
- });
294
+ Jni .accessors.setIntArrayElement (reference.pointer, index, value).check ();
295
+ }
296
+
297
+ Int32List getRange (int start, int end, {Allocator allocator = malloc}) {
298
+ RangeError .checkValidRange (start, end, length);
299
+ final rangeLength = end - start;
300
+ final buffer = allocator <JIntMarker >(rangeLength);
301
+ Jni .env.GetIntArrayRegion (reference.pointer, start, rangeLength, buffer);
302
+ return buffer.asTypedList (rangeLength, finalizer: allocator._nativeFree);
265
303
}
266
304
267
305
void setRange (int start, int end, Iterable <int > iterable,
268
306
[int skipCount = 0 ]) {
269
307
RangeError .checkValidRange (start, end, length);
270
- final size = end - start;
271
- final it = iterable.skip (skipCount).take (size);
272
- _allocate <JIntMarker >(sizeOf <JIntMarker >() * size, (ptr) {
273
- it.forEachIndexed ((index, element) {
274
- ptr[index] = element;
275
- });
276
- Jni .env.SetIntArrayRegion (reference.pointer, start, size, ptr);
308
+ final rangeLength = end - start;
309
+ _allocate <JIntMarker >(sizeOf <JIntMarker >() * rangeLength, (ptr) {
310
+ ptr
311
+ .asTypedList (rangeLength)
312
+ .setRange (0 , rangeLength, iterable, skipCount);
313
+ Jni .env.SetIntArrayRegion (reference.pointer, start, rangeLength, ptr);
277
314
});
278
315
}
279
316
}
@@ -285,22 +322,26 @@ extension LongArray on JArray<jlong> {
285
322
286
323
void operator []= (int index, int value) {
287
324
RangeError .checkValidIndex (index, this );
288
- _allocate <JLongMarker >(sizeOf <JLongMarker >(), (ptr) {
289
- ptr.value = value;
290
- Jni .env.SetLongArrayRegion (reference.pointer, index, 1 , ptr);
291
- });
325
+ Jni .accessors.setLongArrayElement (reference.pointer, index, value).check ();
326
+ }
327
+
328
+ Int64List getRange (int start, int end, {Allocator allocator = malloc}) {
329
+ RangeError .checkValidRange (start, end, length);
330
+ final rangeLength = end - start;
331
+ final buffer = allocator <JLongMarker >(rangeLength);
332
+ Jni .env.GetLongArrayRegion (reference.pointer, start, rangeLength, buffer);
333
+ return buffer.asTypedList (rangeLength, finalizer: allocator._nativeFree);
292
334
}
293
335
294
336
void setRange (int start, int end, Iterable <int > iterable,
295
337
[int skipCount = 0 ]) {
296
338
RangeError .checkValidRange (start, end, length);
297
- final size = end - start;
298
- final it = iterable.skip (skipCount).take (size);
299
- _allocate <JLongMarker >(sizeOf <JLongMarker >() * size, (ptr) {
300
- it.forEachIndexed ((index, element) {
301
- ptr[index] = element;
302
- });
303
- Jni .env.SetLongArrayRegion (reference.pointer, start, size, ptr);
339
+ final rangeLength = end - start;
340
+ _allocate <JLongMarker >(sizeOf <JLongMarker >() * rangeLength, (ptr) {
341
+ ptr
342
+ .asTypedList (rangeLength)
343
+ .setRange (0 , rangeLength, iterable, skipCount);
344
+ Jni .env.SetLongArrayRegion (reference.pointer, start, rangeLength, ptr);
304
345
});
305
346
}
306
347
}
@@ -312,22 +353,26 @@ extension FloatArray on JArray<jfloat> {
312
353
313
354
void operator []= (int index, double value) {
314
355
RangeError .checkValidIndex (index, this );
315
- _allocate <JFloatMarker >(sizeOf <JFloatMarker >(), (ptr) {
316
- ptr.value = value;
317
- Jni .env.SetFloatArrayRegion (reference.pointer, index, 1 , ptr);
318
- });
356
+ Jni .accessors.setFloatArrayElement (reference.pointer, index, value).check ();
357
+ }
358
+
359
+ Float32List getRange (int start, int end, {Allocator allocator = malloc}) {
360
+ RangeError .checkValidRange (start, end, length);
361
+ final rangeLength = end - start;
362
+ final buffer = allocator <JFloatMarker >(rangeLength);
363
+ Jni .env.GetFloatArrayRegion (reference.pointer, start, rangeLength, buffer);
364
+ return buffer.asTypedList (rangeLength, finalizer: allocator._nativeFree);
319
365
}
320
366
321
367
void setRange (int start, int end, Iterable <double > iterable,
322
368
[int skipCount = 0 ]) {
323
369
RangeError .checkValidRange (start, end, length);
324
- final size = end - start;
325
- final it = iterable.skip (skipCount).take (size);
326
- _allocate <JFloatMarker >(sizeOf <JFloatMarker >() * size, (ptr) {
327
- it.forEachIndexed ((index, element) {
328
- ptr[index] = element;
329
- });
330
- Jni .env.SetFloatArrayRegion (reference.pointer, start, size, ptr);
370
+ final rangeLength = end - start;
371
+ _allocate <JFloatMarker >(sizeOf <JFloatMarker >() * rangeLength, (ptr) {
372
+ ptr
373
+ .asTypedList (rangeLength)
374
+ .setRange (0 , rangeLength, iterable, skipCount);
375
+ Jni .env.SetFloatArrayRegion (reference.pointer, start, rangeLength, ptr);
331
376
});
332
377
}
333
378
}
@@ -339,22 +384,28 @@ extension DoubleArray on JArray<jdouble> {
339
384
340
385
void operator []= (int index, double value) {
341
386
RangeError .checkValidIndex (index, this );
342
- _allocate <JDoubleMarker >(sizeOf <JDoubleMarker >(), (ptr) {
343
- ptr.value = value;
344
- Jni .env.SetDoubleArrayRegion (reference.pointer, index, 1 , ptr);
345
- });
387
+ Jni .accessors
388
+ .setDoubleArrayElement (reference.pointer, index, value)
389
+ .check ();
390
+ }
391
+
392
+ Float64List getRange (int start, int end, {Allocator allocator = malloc}) {
393
+ RangeError .checkValidRange (start, end, length);
394
+ final rangeLength = end - start;
395
+ final buffer = allocator <JDoubleMarker >(rangeLength);
396
+ Jni .env.GetDoubleArrayRegion (reference.pointer, start, rangeLength, buffer);
397
+ return buffer.asTypedList (rangeLength, finalizer: allocator._nativeFree);
346
398
}
347
399
348
400
void setRange (int start, int end, Iterable <double > iterable,
349
401
[int skipCount = 0 ]) {
350
402
RangeError .checkValidRange (start, end, length);
351
- final size = end - start;
352
- final it = iterable.skip (skipCount).take (size);
353
- _allocate <JDoubleMarker >(sizeOf <JDoubleMarker >() * size, (ptr) {
354
- it.forEachIndexed ((index, element) {
355
- ptr[index] = element;
356
- });
357
- Jni .env.SetDoubleArrayRegion (reference.pointer, start, size, ptr);
403
+ final rangeLength = end - start;
404
+ _allocate <JDoubleMarker >(sizeOf <JDoubleMarker >() * rangeLength, (ptr) {
405
+ ptr
406
+ .asTypedList (rangeLength)
407
+ .setRange (0 , rangeLength, iterable, skipCount);
408
+ Jni .env.SetDoubleArrayRegion (reference.pointer, start, rangeLength, ptr);
358
409
});
359
410
}
360
411
}
@@ -373,8 +424,8 @@ extension ObjectArray<T extends JObject> on JArray<T> {
373
424
374
425
void setRange (int start, int end, Iterable <T > iterable, [int skipCount = 0 ]) {
375
426
RangeError .checkValidRange (start, end, length);
376
- final size = end - start;
377
- final it = iterable.skip (skipCount).take (size );
427
+ final rangeLength = end - start;
428
+ final it = iterable.skip (skipCount).take (rangeLength );
378
429
it.forEachIndexed ((index, element) {
379
430
this [index] = element;
380
431
});
0 commit comments