| // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| import 'dart:io'; | |
| import 'dart:typed_data'; | |
| import 'package:jni/jni.dart'; | |
| import 'package:test/test.dart'; | |
| import 'test_util/test_util.dart'; | |
| void main() { | |
| // Don't forget to initialize JNI. | |
| if (!Platform.isAndroid) { | |
| checkDylibIsUpToDate(); | |
| spawnJvm(); | |
| } | |
| run(testRunner: test); | |
| } | |
| void run({required TestRunnerCallback testRunner}) { | |
| final throwsAJThrowable = throwsA(isA<JThrowable>()); | |
| JByteBuffer testDataBuffer(Arena arena) { | |
| final buffer = JByteBuffer.allocate(3)..releasedBy(arena); | |
| buffer.nextByte = 1; | |
| buffer.nextByte = 2; | |
| buffer.nextByte = 3; | |
| buffer.position = 0; | |
| return buffer; | |
| } | |
| testRunner('wrap whole array', () { | |
| using((arena) { | |
| final array = JByteArray(3)..releasedBy(arena); | |
| array[0] = 1; | |
| array[1] = 2; | |
| array[2] = 3; | |
| final buffer = JByteBuffer.wrap(array)..releasedBy(arena); | |
| expect(buffer, testDataBuffer(arena)); | |
| }); | |
| }); | |
| testRunner('wrap partial array', () { | |
| using((arena) { | |
| final array = JByteArray(3)..releasedBy(arena); | |
| array[0] = 1; | |
| array[1] = 2; | |
| array[2] = 3; | |
| final buffer = JByteBuffer.wrap(array, 1, 1)..releasedBy(arena); | |
| expect(buffer.nextByte, 2); | |
| expect(() => buffer.nextByte, throwsAJThrowable); | |
| }); | |
| }); | |
| testRunner('capacity', () { | |
| using((arena) { | |
| final buffer = testDataBuffer(arena); | |
| expect(buffer.capacity, 3); | |
| }); | |
| }); | |
| testRunner('position', () { | |
| using((arena) { | |
| final buffer = testDataBuffer(arena); | |
| expect(buffer.position, 0); | |
| buffer.position = 2; | |
| expect(buffer.position, 2); | |
| }); | |
| }); | |
| testRunner('limit', () { | |
| using((arena) { | |
| final buffer = testDataBuffer(arena); | |
| expect(buffer.limit, 3); | |
| buffer.limit = 2; | |
| expect(buffer.limit, 2); | |
| }); | |
| }); | |
| testRunner('mark and reset', () { | |
| using((arena) { | |
| final buffer = testDataBuffer(arena); | |
| buffer.position = 1; | |
| buffer.mark(); | |
| buffer.position = 2; | |
| buffer.reset(); | |
| expect(buffer.position, 1); | |
| }); | |
| }); | |
| testRunner('clear', () { | |
| using((arena) { | |
| final buffer = testDataBuffer(arena); | |
| buffer.position = 2; | |
| buffer.limit = 2; | |
| buffer.clear(); | |
| expect(buffer.limit, 3); | |
| expect(buffer.position, 0); | |
| }); | |
| }); | |
| testRunner('flip', () { | |
| using((arena) { | |
| final buffer = testDataBuffer(arena); | |
| buffer.position = 2; | |
| buffer.flip(); | |
| expect(buffer.limit, 2); | |
| expect(buffer.position, 0); | |
| }); | |
| }); | |
| testRunner('rewind', () { | |
| using((arena) { | |
| final buffer = testDataBuffer(arena); | |
| buffer.mark(); | |
| buffer.position = 2; | |
| buffer.rewind(); | |
| expect(buffer.position, 0); | |
| expect(buffer.reset, throwsAJThrowable); | |
| }); | |
| }); | |
| testRunner('remaining and hasRemaining', () { | |
| using((arena) { | |
| final buffer = testDataBuffer(arena); | |
| buffer.position = 2; | |
| expect(buffer.remaining, 1); | |
| expect(buffer.hasRemaining, true); | |
| buffer.position = 3; | |
| expect(buffer.remaining, 0); | |
| expect(buffer.hasRemaining, false); | |
| }); | |
| }); | |
| testRunner('isReadOnly and asReadOnlyBuffer', () { | |
| using((arena) { | |
| final buffer = testDataBuffer(arena); | |
| expect(buffer.isReadOnly, false); | |
| final readOnly = buffer.asReadOnlyBuffer()..releasedBy(arena); | |
| expect(readOnly.isReadOnly, true); | |
| }); | |
| }); | |
| testRunner('hasArray, array and arrayOffset', () { | |
| using((arena) { | |
| final buffer = testDataBuffer(arena); | |
| expect(buffer.hasArray, true); | |
| expect(buffer.arrayOffset, 0); | |
| expect(buffer.array.length, 3); | |
| final directBuffer = JByteBuffer.allocateDirect(3)..releasedBy(arena); | |
| expect(directBuffer.hasArray, false); | |
| }); | |
| }); | |
| testRunner('isDirect', () { | |
| using((arena) { | |
| final buffer = testDataBuffer(arena); | |
| expect(buffer.isDirect, false); | |
| final directBuffer = JByteBuffer.allocateDirect(3)..releasedBy(arena); | |
| expect(directBuffer.isDirect, true); | |
| }); | |
| }); | |
| testRunner('slice', () { | |
| using((arena) { | |
| final buffer = testDataBuffer(arena); | |
| buffer.position = 1; | |
| buffer.limit = 2; | |
| final sliced = buffer.slice()..releasedBy(arena); | |
| expect(sliced.capacity, 1); | |
| expect(sliced.nextByte, 2); | |
| }); | |
| }); | |
| testRunner('duplicate', () { | |
| using((arena) { | |
| final buffer = testDataBuffer(arena); | |
| buffer.position = 1; | |
| buffer.limit = 2; | |
| final duplicate = buffer.duplicate()..releasedBy(arena); | |
| expect(duplicate.capacity, 3); | |
| expect(duplicate.position, 1); | |
| expect(duplicate.limit, 2); | |
| }); | |
| }); | |
| testRunner('asUint8List', () { | |
| using((arena) { | |
| final buffer = testDataBuffer(arena); | |
| expect(buffer.asUint8List, throwsA(isA<StateError>())); | |
| final list = Uint8List.fromList([1, 2, 3]); | |
| final directBuffer = list.toJByteBuffer()..releasedBy(arena); | |
| expect(directBuffer.asUint8List(), list); | |
| }); | |
| }); | |
| testRunner('asUint8List releasing original', () { | |
| using((arena) { | |
| // Used as an example in [JByteBuffer]. | |
| final directBuffer = JByteBuffer.allocateDirect(3); | |
| final data1 = directBuffer.asUint8List(); | |
| directBuffer.nextByte = 42; // No problem! | |
| expect(data1[0], 42); | |
| final data2 = directBuffer.asUint8List(releaseOriginal: true); | |
| expect( | |
| () => directBuffer.nextByte = 42, | |
| throwsA(isA<UseAfterReleaseError>()), | |
| ); | |
| expect(data2[0], 42); | |
| }); | |
| }); | |
| } |