Skip to content

Commit 4553cde

Browse files
committed
Support data URIs in StandardFileSystem.
Closes #31594 Change-Id: I8dad1429d91cc5934b37cb0be60d1e4039293b71 Reviewed-on: https://dart-review.googlesource.com/33461 Reviewed-by: Peter von der Ahé <[email protected]>
1 parent 9bdcc40 commit 4553cde

File tree

4 files changed

+71
-23
lines changed

4 files changed

+71
-23
lines changed

pkg/front_end/lib/src/api_prototype/standard_file_system.dart

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import 'dart:io' as io;
99

1010
import 'file_system.dart';
1111

12-
/// Concrete implementation of [FileSystem] which performs its operations using
13-
/// I/O.
12+
/// Concrete implementation of [FileSystem] handling standard URI schemes.
13+
///
14+
/// file: URIs are handled using file I/O.
15+
/// data: URIs return their data contents.
1416
///
1517
/// Not intended to be implemented or extended by clients.
1618
class StandardFileSystem implements FileSystem {
@@ -20,28 +22,31 @@ class StandardFileSystem implements FileSystem {
2022

2123
@override
2224
FileSystemEntity entityForUri(Uri uri) {
23-
if (uri.scheme != 'file' && uri.scheme != '') {
25+
if (uri.scheme == 'file' || uri.scheme == '') {
26+
// TODO(askesc): Empty schemes should have been handled elsewhere.
27+
return new _IoFileSystemEntity(Uri.base.resolveUri(uri));
28+
} else if (uri.scheme == 'data') {
29+
return new _DataFileSystemEntity(Uri.base.resolveUri(uri));
30+
} else {
2431
throw new FileSystemException(
25-
uri, 'StandardFileSystem only supports file:* URIs');
32+
uri, 'StandardFileSystem only supports file:* and data:* URIs');
2633
}
27-
return new _StandardFileSystemEntity(Uri.base.resolveUri(uri));
2834
}
2935
}
3036

31-
/// Concrete implementation of [FileSystemEntity] for use by
32-
/// [StandardFileSystem].
33-
class _StandardFileSystemEntity implements FileSystemEntity {
37+
/// Concrete implementation of [FileSystemEntity] for file: URIs.
38+
class _IoFileSystemEntity implements FileSystemEntity {
3439
@override
3540
final Uri uri;
3641

37-
_StandardFileSystemEntity(this.uri);
42+
_IoFileSystemEntity(this.uri);
3843

3944
@override
4045
int get hashCode => uri.hashCode;
4146

4247
@override
4348
bool operator ==(Object other) =>
44-
other is _StandardFileSystemEntity && other.uri == uri;
49+
other is _IoFileSystemEntity && other.uri == uri;
4550

4651
@override
4752
Future<bool> exists() async {
@@ -82,3 +87,33 @@ class _StandardFileSystemEntity implements FileSystemEntity {
8287
return new FileSystemException(uri, message);
8388
}
8489
}
90+
91+
/// Concrete implementation of [FileSystemEntity] for data: URIs.
92+
class _DataFileSystemEntity implements FileSystemEntity {
93+
@override
94+
final Uri uri;
95+
96+
_DataFileSystemEntity(this.uri);
97+
98+
@override
99+
int get hashCode => uri.hashCode;
100+
101+
@override
102+
bool operator ==(Object other) =>
103+
other is _DataFileSystemEntity && other.uri == uri;
104+
105+
@override
106+
Future<bool> exists() async {
107+
return true;
108+
}
109+
110+
@override
111+
Future<List<int>> readAsBytes() async {
112+
return uri.data.contentAsBytes();
113+
}
114+
115+
@override
116+
Future<String> readAsString() async {
117+
return uri.data.contentAsString();
118+
}
119+
}

pkg/front_end/lib/src/testing/hybrid_file_system.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ class HybridFileSystemEntity implements FileSystemEntity {
3737
Future<FileSystemEntity> get delegate async {
3838
if (_delegate != null) return _delegate;
3939
FileSystemEntity entity = _fs.memory.entityForUri(uri);
40-
if (uri.scheme != 'file' || await entity.exists()) {
40+
if ((uri.scheme != 'file' && uri.scheme != 'data') ||
41+
await entity.exists()) {
4142
_delegate = entity;
4243
return _delegate;
4344
}

pkg/front_end/test/standard_file_system_test.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ library front_end.test.standard_file_system_test;
88
import 'dart:async';
99
import 'dart:convert';
1010
import 'dart:io' as io;
11+
import 'dart:math' show Random;
1112

1213
import 'package:front_end/src/api_prototype/file_system.dart';
1314
import 'package:front_end/src/api_prototype/standard_file_system.dart';
@@ -20,6 +21,7 @@ main() {
2021
defineReflectiveTests(StandardFileSystemTest);
2122
defineReflectiveTests(FileTest);
2223
defineReflectiveTests(DirectoryTest);
24+
defineReflectiveTests(DataTest);
2325
});
2426
}
2527

@@ -248,3 +250,23 @@ class _BaseTest {
248250
}
249251
}
250252
}
253+
254+
@reflectiveTest
255+
class DataTest {
256+
test_Data_URIs() async {
257+
String string = "<{[DART]}>";
258+
Uri string_uri = new Uri.dataFromString(string, base64: false);
259+
Uri string_uri_base64 = new Uri.dataFromString(string, base64: true);
260+
261+
Random random = new Random(123);
262+
List<int> bytes = new List.generate(1000, (index) => random.nextInt(256));
263+
Uri bytes_uri = new Uri.dataFromBytes(bytes, percentEncoded: true);
264+
Uri bytes_uri_base64 = new Uri.dataFromBytes(bytes, percentEncoded: false);
265+
266+
StandardFileSystem fs = StandardFileSystem.instance;
267+
expect(string, await fs.entityForUri(string_uri).readAsString());
268+
expect(string, await fs.entityForUri(string_uri_base64).readAsString());
269+
expect(bytes, await fs.entityForUri(bytes_uri).readAsBytes());
270+
expect(bytes, await fs.entityForUri(bytes_uri_base64).readAsBytes());
271+
}
272+
}

runtime/tests/vm/vm.status

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -296,12 +296,7 @@ cc/SourceReport_MultipleReports: Fail
296296
cc/SourceReport_PossibleBreakpoints_Simple: Fail
297297
cc/StackTraceFormat: Fail
298298
cc/UseDartApi: Fail
299-
dart/data_uri_import_test/base64: CompileTimeError
300-
dart/data_uri_import_test/nocharset: CompileTimeError
301-
dart/data_uri_import_test/nomime: CompileTimeError
302-
dart/data_uri_import_test/percentencoded: Fail
303-
dart/data_uri_import_test/wrongmime: CompileTimeError
304-
dart/data_uri_spawn_test: RuntimeError
299+
dart/data_uri_import_test/utf16: MissingRuntimeError # UTF-16 data URIs work in dartk
305300
dart/redirection_type_shuffling_test/00: Crash
306301
dart/redirection_type_shuffling_test/none: Crash
307302
dart/spawn_shutdown_test: SkipSlow
@@ -350,12 +345,7 @@ dart/spawn_infinite_loop_test: Crash
350345
dart/truncating_ints_test: Skip # This test cannot be run in dartkp/legacy mode (gen_kernel does not pass --limit-ints-to-64-bits in legacy mode).
351346

352347
[ $compiler == dartkp && ($runtime == dart_precompiled || $runtime == vm) ]
353-
dart/data_uri_import_test/base64: CompileTimeError
354-
dart/data_uri_import_test/nocharset: CompileTimeError
355-
dart/data_uri_import_test/nomime: CompileTimeError
356-
dart/data_uri_import_test/percentencoded: CompileTimeError
357-
dart/data_uri_import_test/wrongmime: CompileTimeError
358-
dart/data_uri_spawn_test: RuntimeError
348+
dart/data_uri_import_test/utf16: MissingRuntimeError # UTF-16 data URIs work in dartk
359349
dart/redirection_type_shuffling_test: SkipByDesign # Includes dart:mirrors.
360350
dart/spawn_shutdown_test: SkipSlow
361351

0 commit comments

Comments
 (0)