Unverified Commit 9c101515 authored by Martin Kustermann's avatar Martin Kustermann Committed by GitHub

Use utf8.encode() instead of longer const Utf8Encoder.convert() (#130567)

The change in [0] has propagated now everywhere, so we can use
`utf8.encode()` instead of the longer `const Utf8Encoder.convert()`.

Also it cleans up code like

```
  TypedData bytes;
  bytes.buffer.asByteData();
```

as that is not guaranteed to be correct, the correct version would be

```
  TypedData bytes;
  bytes.buffer.asByteData(bytes.offsetInBytes, bytes.lengthInBytes);
```

a shorter hand for that is:

```
  TypedData bytes;
  ByteData.sublistView(bytes);
```

[0] https://github.com/dart-lang/sdk/issues/52801
parent acdd96b2
......@@ -57,11 +57,10 @@ abstract class AssetBundle {
/// Throws an exception if the asset is not found.
///
/// The returned [ByteData] can be converted to a [Uint8List] (a list of bytes)
/// using [ByteData.buffer] to obtain a [ByteBuffer], and then
/// [ByteBuffer.asUint8List] to obtain the byte list. Lists of bytes can be
/// used with APIs that accept [Uint8List] objects, such as
/// [decodeImageFromList], as well as any API that accepts a [List<int>], such
/// as [File.writeAsBytes] or [Utf8Codec.decode] (accessible via [utf8]).
/// using [Uint8List.sublistView]. Lists of bytes can be used with APIs that
/// accept [Uint8List] objects, such as [decodeImageFromList], as well as any
/// API that accepts a [List<int>], such as [File.writeAsBytes] or
/// [Utf8Codec.decode] (accessible via [utf8]).
Future<ByteData> load(String key);
/// Retrieve a binary resource from the asset bundle as an immutable
......@@ -70,7 +69,7 @@ abstract class AssetBundle {
/// Throws an exception if the asset is not found.
Future<ui.ImmutableBuffer> loadBuffer(String key) async {
final ByteData data = await load(key);
return ui.ImmutableBuffer.fromUint8List(data.buffer.asUint8List());
return ui.ImmutableBuffer.fromUint8List(Uint8List.sublistView(data));
}
/// Retrieve a string from the asset bundle.
......@@ -91,7 +90,7 @@ abstract class AssetBundle {
// 50 KB of data should take 2-3 ms to parse on a Moto G4, and about 400 μs
// on a Pixel 4.
if (data.lengthInBytes < 50 * 1024) {
return utf8.decode(data.buffer.asUint8List());
return utf8.decode(Uint8List.sublistView(data));
}
// For strings larger than 50 KB, run the computation in an isolate to
// avoid causing main thread jank.
......@@ -99,7 +98,7 @@ abstract class AssetBundle {
}
static String _utf8decode(ByteData data) {
return utf8.decode(data.buffer.asUint8List());
return utf8.decode(Uint8List.sublistView(data));
}
/// Retrieve a string from the asset bundle, parse it with the given function,
......@@ -161,7 +160,7 @@ class NetworkAssetBundle extends AssetBundle {
]);
}
final Uint8List bytes = await consolidateHttpClientResponseBytes(response);
return bytes.buffer.asByteData();
return ByteData.sublistView(bytes);
}
// TODO(ianh): Once the underlying network logic learns about caching, we
......@@ -308,7 +307,7 @@ abstract class CachingAssetBundle extends AssetBundle {
@override
Future<ui.ImmutableBuffer> loadBuffer(String key) async {
final ByteData data = await load(key);
return ui.ImmutableBuffer.fromUint8List(data.buffer.asUint8List());
return ui.ImmutableBuffer.fromUint8List(Uint8List.sublistView(data));
}
}
......@@ -316,10 +315,10 @@ abstract class CachingAssetBundle extends AssetBundle {
class PlatformAssetBundle extends CachingAssetBundle {
@override
Future<ByteData> load(String key) {
final Uint8List encoded = utf8.encoder.convert(Uri(path: Uri.encodeFull(key)).path);
final Uint8List encoded = utf8.encode(Uri(path: Uri.encodeFull(key)).path);
final Future<ByteData>? future = ServicesBinding.instance.defaultBinaryMessenger.send(
'flutter/assets',
encoded.buffer.asByteData(),
ByteData.sublistView(encoded),
)?.then((ByteData? asset) {
if (asset == null) {
throw FlutterError.fromParts(<DiagnosticsNode>[
......@@ -342,7 +341,7 @@ class PlatformAssetBundle extends CachingAssetBundle {
Future<ui.ImmutableBuffer> loadBuffer(String key) async {
if (kIsWeb) {
final ByteData bytes = await load(key);
return ui.ImmutableBuffer.fromUint8List(bytes.buffer.asUint8List());
return ui.ImmutableBuffer.fromUint8List(Uint8List.sublistView(bytes));
}
bool debugUsePlatformChannel = false;
assert(() {
......@@ -358,7 +357,7 @@ class PlatformAssetBundle extends CachingAssetBundle {
}());
if (debugUsePlatformChannel) {
final ByteData bytes = await load(key);
return ui.ImmutableBuffer.fromUint8List(bytes.buffer.asUint8List());
return ui.ImmutableBuffer.fromUint8List(Uint8List.sublistView(bytes));
}
try {
return await ui.ImmutableBuffer.fromAsset(key);
......
......@@ -50,7 +50,7 @@ class StringCodec implements MessageCodec<String> {
if (message == null) {
return null;
}
return utf8.decoder.convert(message.buffer.asUint8List(message.offsetInBytes, message.lengthInBytes));
return utf8.decode(Uint8List.sublistView(message));
}
@override
......@@ -58,8 +58,7 @@ class StringCodec implements MessageCodec<String> {
if (message == null) {
return null;
}
final Uint8List encoded = utf8.encoder.convert(message);
return encoded.buffer.asByteData();
return ByteData.sublistView(utf8.encode(message));
}
}
......@@ -415,7 +414,7 @@ class StandardMessageCodec implements MessageCodec<Object?> {
if (char <= 0x7f) {
asciiBytes[i] = char;
} else {
utf8Bytes = utf8.encoder.convert(value.substring(i));
utf8Bytes = utf8.encode(value.substring(i));
utf8Offset = i;
break;
}
......
......@@ -6176,7 +6176,7 @@ class RawImage extends LeafRenderObjectWidget {
/// @override
/// Future<ByteData> load(String key) async {
/// if (key == 'resources/test') {
/// return ByteData.view(Uint8List.fromList(utf8.encode('Hello World!')).buffer);
/// return ByteData.sublistView(utf8.encode('Hello World!'));
/// }
/// return ByteData(0);
/// }
......
......@@ -16,17 +16,16 @@ class TestAssetBundle extends CachingAssetBundle {
Future<ByteData> load(String key) async {
loadCallCount[key] = (loadCallCount[key] ?? 0) + 1;
if (key == 'AssetManifest.json') {
return ByteData.view(Uint8List.fromList(const Utf8Encoder().convert('{"one": ["one"]}')).buffer);
return ByteData.sublistView(utf8.encode('{"one": ["one"]}'));
}
if (key == 'AssetManifest.bin') {
return const StandardMessageCodec().encodeMessage(<String, Object>{
'one': <Object>[]
})!;
return const StandardMessageCodec()
.encodeMessage(<String, Object>{'one': <Object>[]})!;
}
if (key == 'counter') {
return ByteData.view(Uint8List.fromList(const Utf8Encoder().convert(loadCallCount[key]!.toString())).buffer);
return ByteData.sublistView(utf8.encode(loadCallCount[key]!.toString()));
}
if (key == 'one') {
......
......@@ -89,7 +89,7 @@ void main() {
int flutterAssetsCallCount = 0;
binding.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', (ByteData? message) async {
flutterAssetsCallCount += 1;
return Uint8List.fromList('test_asset_data'.codeUnits).buffer.asByteData();
return ByteData.sublistView(utf8.encode('test_asset_data'));
});
await rootBundle.loadString('test_asset');
......
......@@ -3,7 +3,6 @@
// found in the LICENSE file.
import 'dart:convert';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
import 'package:flutter/scheduler.dart';
......@@ -14,15 +13,11 @@ class TestChannelBuffersFlutterBinding extends BindingBase with SchedulerBinding
void main() {
ByteData makeByteData(String str) {
final List<int> list = utf8.encode(str);
final ByteBuffer buffer = list is Uint8List ? list.buffer : Uint8List.fromList(list).buffer;
return ByteData.view(buffer);
return ByteData.sublistView(utf8.encode(str));
}
String getString(ByteData data) {
final ByteBuffer buffer = data.buffer;
final List<int> list = buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
return utf8.decode(list);
return utf8.decode(Uint8List.sublistView(data));
}
test('does drain channel buffers', () async {
......
......@@ -4,7 +4,6 @@
import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
......@@ -13,10 +12,7 @@ void main() {
TestWidgetsFlutterBinding.ensureInitialized();
ByteData makeByteData(String str) {
final List<int> list = utf8.encode(str);
final ByteBuffer buffer =
list is Uint8List ? list.buffer : Uint8List.fromList(list).buffer;
return ByteData.view(buffer);
return ByteData.sublistView(utf8.encode(str));
}
test('default binary messenger calls callback once', () async {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment