// Copyright (c) 2019, 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. // VMOptions=--enable-isolate-groups --experimental-enable-isolate-groups-jit // VMOptions=--no-enable-isolate-groups import "dart:async"; import "dart:collection"; import "dart:isolate"; import "dart:typed_data"; import "package:expect/expect.dart"; const large = 2 * 1024 * 1024; void child(replyPort) { print("Child start"); print("Child ByteData"); dynamic x = new ByteData(large); for (int i = 0; i < 4; i++) { x.setInt8(i, i); } replyPort.send(TransferableTypedData.fromList([x.buffer.asUint8List()])); print("Child Uint8List"); x = new Uint8List(large); for (int i = 0; i < 4; i++) { x[i] = i; } replyPort.send(TransferableTypedData.fromList([x])); print("Child Uint8List.view"); x = new Uint8List.view(x.buffer, 1, 2); replyPort.send(TransferableTypedData.fromList([x])); print("Child Int8List"); x = new Int8List(large); for (int i = 0; i < 4; i++) { x[i] = i; } replyPort.send(TransferableTypedData.fromList([x])); print("Child Uint16List"); x = new Uint16List(large); for (int i = 0; i < 4; i++) { x[i] = i; } replyPort.send(TransferableTypedData.fromList([x])); print("Child Int16List"); x = new Int16List(large); for (int i = 0; i < 4; i++) { x[i] = i; } replyPort.send(TransferableTypedData.fromList([x])); print("Child Uint32List"); x = new Uint32List(large); for (int i = 0; i < 4; i++) { x[i] = i; } replyPort.send(TransferableTypedData.fromList([x])); print("Child Int32List"); x = new Int32List(large); for (int i = 0; i < 4; i++) { x[i] = i; } replyPort.send(TransferableTypedData.fromList([x])); print("Child Uint64List"); x = new Uint64List(large); for (int i = 0; i < 4; i++) { x[i] = i; } replyPort.send(TransferableTypedData.fromList([x])); print("Child Int64List"); x = new Int64List(large); for (int i = 0; i < 4; i++) { x[i] = i; } replyPort.send(TransferableTypedData.fromList([x])); print("Child two Uint8Lists"); x = new Uint8List(large); for (int i = 0; i < 4; i++) { x[i] = i; } replyPort.send([ TransferableTypedData.fromList([x]), TransferableTypedData.fromList([x]) ]); print("Child same Uint8List twice - materialize first"); x = new Uint8List(large); for (int i = 0; i < 4; i++) { x[i] = i; } var tr = TransferableTypedData.fromList([x]); replyPort.send([tr, tr]); print("Child same Uint8List twice - materialize second"); x = new Uint8List(large); for (int i = 0; i < 4; i++) { x[i] = i; } tr = TransferableTypedData.fromList([x]); replyPort.send([tr, tr]); print("Child done"); } Future main(List args) async { print("Parent start"); ReceivePort port = new ReceivePort(); Isolate.spawn(child, port.sendPort); StreamIterator incoming = new StreamIterator(port); print("Parent ByteData"); Expect.isTrue(await incoming.moveNext()); dynamic x = incoming.current.materialize().asByteData(); Expect.isTrue(x is ByteData); Expect.equals(large, x.length); for (int i = 0; i < 4; i++) { Expect.equals(i, x.getUint8(i)); } print("Parent Uint8List"); Expect.isTrue(await incoming.moveNext()); x = incoming.current.materialize(); Expect.isTrue(x is ByteBuffer); x = x.asUint8List(); Expect.equals(large, x.length); for (int i = 0; i < 4; i++) { Expect.equals(i, x[i]); } print("Parent Uint8List view"); Expect.isTrue(await incoming.moveNext()); x = incoming.current.materialize().asUint8List(); Expect.equals(1, x[0]); Expect.equals(2, x[1]); print("Parent Int8"); Expect.isTrue(await incoming.moveNext()); x = incoming.current.materialize().asInt8List(); Expect.equals(large, x.length); for (int i = 0; i < 4; i++) { Expect.equals(i, x[i]); } print("Parent Uint16"); Expect.isTrue(await incoming.moveNext()); x = incoming.current.materialize().asUint16List(); Expect.equals(large, x.length); for (int i = 0; i < 4; i++) { Expect.equals(i, x[i]); } print("Parent Int16"); Expect.isTrue(await incoming.moveNext()); x = incoming.current.materialize().asInt16List(); Expect.equals(large, x.length); for (int i = 0; i < 4; i++) { Expect.equals(i, x[i]); } print("Parent Uint32"); Expect.isTrue(await incoming.moveNext()); x = incoming.current.materialize().asUint32List(); Expect.equals(large, x.length); for (int i = 0; i < 4; i++) { Expect.equals(i, x[i]); } print("Parent Int32"); Expect.isTrue(await incoming.moveNext()); x = incoming.current.materialize().asInt32List(); Expect.equals(large, x.length); for (int i = 0; i < 4; i++) { Expect.equals(i, x[i]); } print("Parent Uint64"); Expect.isTrue(await incoming.moveNext()); x = incoming.current.materialize().asUint64List(); Expect.equals(large, x.length); for (int i = 0; i < 4; i++) { Expect.equals(i, x[i]); } print("Parent Int64"); Expect.isTrue(await incoming.moveNext()); x = incoming.current.materialize().asInt64List(); Expect.equals(large, x.length); for (int i = 0; i < 4; i++) { Expect.equals(i, x[i]); } print("Parent two Uint8Lists"); Expect.isTrue(await incoming.moveNext()); final x1 = incoming.current[0].materialize().asUint8List(); final x2 = incoming.current[1].materialize().asUint8List(); Expect.equals(large, x1.length); Expect.equals(large, x2.length); for (int i = 0; i < 4; i++) { Expect.equals(i, x1[i]); Expect.equals(i, x2[i]); } print("Parent same Uint8Lists twice, materialize first"); Expect.isTrue(await incoming.moveNext()); final tr0 = incoming.current[0].materialize().asUint8List(); Expect.throwsArgumentError(() => incoming.current[1].materialize()); Expect.equals(large, tr0.length); for (int i = 0; i < 4; i++) { Expect.equals(i, tr0[i]); } print("Parent same Uint8Lists twice, materialize second"); Expect.isTrue(await incoming.moveNext()); final tr1 = incoming.current[1].materialize().asUint8List(); Expect.throwsArgumentError(() => incoming.current[0].materialize()); Expect.equals(large, tr1.length); for (int i = 0; i < 4; i++) { Expect.equals(i, tr1[i]); } port.close(); print("Parent done"); testCreateMaterializeInSameIsolate(); testIterableToList(); testUserExtendedList(); } testCreateMaterializeInSameIsolate() { // Test same-isolate operation of TransferableTypedData. final Uint8List bytes = new Uint8List(large); for (int i = 0; i < bytes.length; ++i) { bytes[i] = i % 256; } final tr = TransferableTypedData.fromList([bytes]); Expect.listEquals(bytes, tr.materialize().asUint8List()); } testIterableToList() { // Test that iterable.toList() can be used as an argument. final list1 = Uint8List(10); for (int i = 0; i < list1.length; i++) { list1[i] = i; } final list2 = Uint8List(20); for (int i = 0; i < list2.length; i++) { list2[i] = i + list1.length; } final map = {list1: true, list2: true}; Iterable iterable = map.keys; final result = TransferableTypedData.fromList(iterable.toList()) .materialize() .asUint8List(); for (int i = 0; i < result.length; i++) { Expect.equals(i, result[i]); } } class MyList extends ListBase { List _source; MyList(this._source); int get length => _source.length; void set length(int length) { _source.length = length; } E operator [](int index) => _source[index]; void operator []=(int index, E value) { _source[index] = value; } } testUserExtendedList() { final list = MyList([Uint8List(10)]); TransferableTypedData.fromList(list); }