| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import "dart:core" hide Resource; |
| 5 import "dart:async" show Future, Stream; | 6 import "dart:async" show Future, Stream; |
| 6 import "dart:convert" show Encoding; | 7 import "dart:convert" show Encoding; |
| 7 import "dart:isolate" show Isolate; | |
| 8 import "loader.dart"; | |
| 9 | 8 |
| 10 /// A resource that can be read into the program. | 9 import "resource_loader.dart"; |
| 11 /// | 10 import "resolve.dart"; |
| 12 /// A resource is data that can be located using a URI and read into | 11 |
| 13 /// the program at runtime. | 12 /// Base resource implementation. |
| 14 /// The URI may use the `package` scheme to read resources provided | 13 class Resource { |
| 15 /// along with package sources. | 14 // Default implementation of a generic `Resource` class. |
| 16 abstract class Resource { | 15 // |
| 17 /// Creates a resource object with the given [uri] as location. | 16 // Actually exposed `Resource` interfaces uses this as implementation, |
| 18 /// | 17 // but expose a different `Resource` class with plaform-dependent statics. |
| 19 /// The [uri] must be either a [Uri] or a string containing a valid URI. | 18 // Requires a loader to be provided. |
| 20 /// If the string is not a valid URI, using any of the functions on | 19 |
| 21 /// the resource object will fail. | 20 /// Loading strategy for the resource. |
| 22 /// | 21 final ResourceLoader _loader; |
| 23 /// The URI may be relative, in which case it will be resolved | 22 |
| 24 /// against [Uri.base] before being used. | 23 /// The URI of the resource. |
| 25 /// | 24 final _uri; |
| 26 /// The URI may use the `package` scheme, which is always supported. | 25 |
| 27 /// Other schemes may also be supported where possible. | 26 const Resource(uri, ResourceLoader loader) |
| 28 /// | 27 : _uri = uri, _loader = loader; |
| 29 /// If [loader] is provided, it is used to load absolute non-package URIs. | |
| 30 /// Package: URIs are resolved to a non-package URI before being loaded, so | |
| 31 /// the loader doesn't have to support package: URIs, nor does it need to | |
| 32 /// support relative URI references. | |
| 33 /// If [loader] is omitted, a default implementation is used which supports | |
| 34 /// as many of `http`, `https`, `file` and `data` as are available on the | |
| 35 /// current platform. | |
| 36 const factory Resource(uri, {ResourceLoader loader}) = _Resource; | |
| 37 | 28 |
| 38 /// The location URI of this resource. | 29 /// The location URI of this resource. |
| 39 /// | 30 /// |
| 40 /// This is a [Uri] of the `uri` parameter given to the constructor. | 31 /// This is a [Uri] of the `uri` parameter given to the constructor. |
| 41 /// If the parameter was a string that did not contain a valid URI, | 32 /// If the parameter was a string that did not contain a valid URI, |
| 42 /// reading `uri` will fail. | 33 /// reading `uri` will fail. |
| 43 Uri get uri; | 34 Uri get uri => (_uri is String) ? Uri.parse(_uri) : (_uri as Uri); |
| 44 | 35 |
| 45 /// Reads the resource content as a stream of bytes. | 36 /// Reads the resource content as a stream of bytes. |
| 46 Stream<List<int>> openRead(); | 37 Stream<List<int>> openRead() async* { |
| 38 Uri uri = await resolveUri(this.uri); |
| 39 yield* _loader.openRead(uri); |
| 40 } |
| 47 | 41 |
| 48 /// Reads the resource content as a single list of bytes. | 42 /// Reads the resource content as a single list of bytes. |
| 49 Future<List<int>> readAsBytes(); | 43 Future<List<int>> readAsBytes() async { |
| 44 Uri uri = await resolveUri(this.uri); |
| 45 return _loader.readAsBytes(uri); |
| 46 } |
| 50 | 47 |
| 51 /// Reads the resource content as a string. | 48 /// Reads the resource content as a string. |
| 52 /// | 49 /// |
| 53 /// The content is decoded into a string using an [Encoding]. | 50 /// The content is decoded into a string using an [Encoding]. |
| 54 /// If no other encoding is provided, it defaults to UTF-8. | 51 /// If no encoding is provided, an encoding is chosen depending on the |
| 55 Future<String> readAsString({Encoding encoding}); | 52 /// protocol and/or available metadata. |
| 56 } | |
| 57 | |
| 58 class _Resource implements Resource { | |
| 59 /// Loading strategy for the resource. | |
| 60 final ResourceLoader _loader; | |
| 61 | |
| 62 /// The URI of the resource. | |
| 63 final _uri; | |
| 64 | |
| 65 const _Resource(uri, {ResourceLoader loader}) | |
| 66 : _uri = uri, _loader = (loader != null) ? loader : const DefaultLoader(); | |
| 67 // TODO: Make this `loader ?? const DefaultLoader()` when ?? is const. | |
| 68 | |
| 69 Uri get uri => (_uri is String) ? Uri.parse(_uri) : (_uri as Uri); | |
| 70 | |
| 71 Stream<List<int>> openRead() async* { | |
| 72 Uri uri = await _resolvedUri; | |
| 73 yield* _loader.openRead(uri); | |
| 74 } | |
| 75 | |
| 76 Future<List<int>> readAsBytes() async { | |
| 77 Uri uri = await _resolvedUri; | |
| 78 return _loader.readAsBytes(uri); | |
| 79 } | |
| 80 | |
| 81 Future<String> readAsString({Encoding encoding}) async { | 53 Future<String> readAsString({Encoding encoding}) async { |
| 82 Uri uri = await _resolvedUri; | 54 Uri uri = await resolveUri(this.uri); |
| 83 return _loader.readAsString(uri, encoding: encoding); | 55 return _loader.readAsString(uri, encoding: encoding); |
| 84 } | 56 } |
| 85 | |
| 86 Future<Uri> get _resolvedUri => resolveUri(uri); | |
| 87 } | 57 } |
| OLD | NEW |