Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(306)

Unified Diff: lib/src/resource.dart

Issue 1387163002: Add Resource package. (Closed) Base URL: https://github.com/dart-lang/resource.git@master
Patch Set: Address comments. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/src/loader.dart ('k') | pubspec.yaml » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/resource.dart
diff --git a/lib/src/resource.dart b/lib/src/resource.dart
index 2fef5f6325910a8cb9e4a06c720cbcabe5bc9000..924ec051b364e38c6fa90bd3867704bb2100f69f 100644
--- a/lib/src/resource.dart
+++ b/lib/src/resource.dart
@@ -1,218 +1,87 @@
-// Copyright (c) 2015, 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.
-
-library resoure.resource;
-
-import "dart:async" show Future, Stream;
-import "dart:convert" show Encoding;
-import "dart:isolate" show Isolate;
-import "package_resolver.dart";
-import "io.dart" as io; // Loading strategy. TODO: Be configuration dependent.
-
-/// A strategy for resolving package URIs
-abstract class PackageResolver {
- /// Cache of the current resolver, accessible directly after it has first
- /// been found asynchronously.
- static PackageResolver _current;
-
- /// The package resolution strategy used by the current isolate.
- static final Future<PackageResolver> current = _findIsolateResolution();
-
- PackageResolver();
-
- /// Creates a resolver using a map from package name to package location.
- factory PackageResolver.fromMap(Map<String, Uri> packages) = MapResolver;
-
- /// Creates a resolver using a package root.
- factory PackageResolver.fromRoot(Uri packageRoot) = RootResolver;
-
- /// Resolves a package URI to its location.
- ///
- /// If [uri] does not have `package` as scheme, it is returned again.
- /// Otherwise the package name is looked up, and if found, a location
- /// for the package file is returned.
- Future<Uri> resolve(Uri uri);
-
- /// Returns a [Resource] for the [uri] as resolved by this resolver.
- Resource resource(Uri uri) {
- return new _UriResource(this, uri);
- }
-
- /// Finds the way the current isolate resolves package URIs.
- ///
- /// Is only called once, and when it has been called, the [_current]
- /// resolver is initialized, so [UriResource] will be initialized
- /// with the resolver directly.
- static Future<PackageResolver> _findIsolateResolution() async {
- var pair = await Future.wait([Isolate.packageRoot, Isolate.packageMap]);
- Uri root = pair[0];
- if (root != null) {
- _current = new RootResolver(root);
- } else {
- Map<String, Uri> map = pair[1];
- _current = new MapResolver(map);
- }
- return _current;
- }
-}
-
-/// A resource that can be read into the program.
-///
-/// A resource is data that can be located using a URI and read into
-/// the program at runtime.
-/// The URI may use the `package` scheme to read resources provided
-/// along with package sources.
-abstract class Resource {
- /// Creates a resource object with the given [uri] as location.
- ///
- /// The `uri` is a string containing a valid URI.
- /// If the string is not a valid URI, using any of the functions on
- /// the resource object will fail.
- ///
- /// The URI may be relative, in which case it will be resolved
- /// against [Uri.base] before being used.
- ///
- /// The URI may use the `package` scheme, which is always supported.
- /// Other schemes may also be supported where possible.
- const factory Resource(String uri) = _StringResource;
-
- /// Creates a resource object with the given [uri] as location.
- ///
- /// The URI may be relative, in which case it will be resolved
- /// against [Uri.base] before being used.
- ///
- /// The URI may use the `package` scheme, which is always supported.
- /// Other schemes may also be supported where possible.
- factory Resource.forUri(Uri uri) =>
- new _UriResource(PackageResolver._current, uri);
-
- /// The location `uri` of this resource.
- ///
- /// This is a [Uri] of the `uri` parameter given to the constructor.
- /// If the parameter was not a valid URI, reading `uri` may fail.
- Uri get uri;
-
- Stream<List<int>> openRead();
-
- Future<List<int>> readAsBytes();
-
- /// Read the resource content as a string.
- ///
- /// The content is decoded into a string using an [Encoding].
- /// If no other encoding is provided, it defaults to UTF-8.
- Future<String> readAsString({Encoding encoding});
-}
-
-class _StringResource implements Resource {
- final String _uri;
-
- const _StringResource(String uri) : _uri = uri;
-
- Uri get uri => Uri.parse(_uri);
-
- Stream<List<int>> openRead() {
- return new _UriResource(PackageResolver._current, uri).openRead();
- }
- Future<List<int>> readAsBytes() {
- return new _UriResource(PackageResolver._current, uri).readAsBytes();
- }
- Future<String> readAsString({Encoding encoding}) {
- return new _UriResource(PackageResolver._current, uri)
- .readAsString(encoding: encoding);
- }
-}
-
-class _UriResource implements Resource {
- /// The strategy for resolving package: URIs.
- ///
- /// May be null intially. If so, the [PackageResolver.current] resolver is
- /// used (and cached for later use).
- PackageResolver _resolver;
-
- /// The URI of the resource.
- final Uri uri;
-
- _UriResource(this.resolver, Uri uri);
-
- Stream<List<int>> openRead() async* {
- Uri uri = await _resolve(this.uri);
- return io.readAsStream(uri);
- }
-
- Future<List<int>> readAsBytes() async {
- Uri uri = await _resolve(this.uri);
- return io.readAsBytes(uri);
- }
-
- Future<String> readAsString({Encoding encoding}) async {
- Uri uri = await _resolve(this.uri);
- return io.readAsString(uri, encoding);
- }
-
- static void _checkPackageUri(Uri uri) {
- if (uri.scheme != "package") {
- throw new ArgumentError.value(uri, "Not a package: URI");
- }
- if (uri.hasAuthority) {
- throw new ArgumentError.value(uri,
- "A package: URI must not have an authority part");
- }
- if (uri.path.isEmpty || uri.path.startsWith('/')) {
- throw new ArgumentError.value(uri,
- "A package: URI must have the form "
- "'package:packageName/packagePath'");
- }
- if (uri.hasQuery) {
- throw new ArgumentError.value(uri,
- "A package: URI must not have a query part");
- }
- if (uri.hasFragment) {
- throw new ArgumentError.value(uri,
- "A package: URI must not have a fragment part");
- }
- }
-
- Future<Uri> _resolve(Uri uri) async {
- if (uri.scheme != "package") {
- return Uri.base.resolveUri(uri);
- }
- _checkPackageUri(uri);
- _resolver ??= await PackageResolver._current;
- return _resolver.resolve(uri);
- }
-}
-
-/// A [PackageResolver] based on a packags map.
-class MapResolver extends PackageResolver {
- Map<String, Uri> _mapping;
-
- MapResolver(this._mapping);
-
- Uri resolve(Uri uri) {
- if (uri.scheme != "package") return uri;
- var path = uri.path;
- int slashIndex = path.indexOf('/');
- if (slashIndex <= 0) {
- throw new ArgumentError.value(uri, "Invalid package URI");
- }
- int packageName = path.substring(0, slashIndex);
- var base = _mapping[packageName];
- if (base != null) {
- int packagePath = path.substring(slashIndex + 1);
- return base.resolveUri(new Uri(path: packagePath));
- }
- throw new UnsupportedError("No package named '$packageName' found");
- }
-}
-
-/// A [PackageResolver] based on a package root.
-class RootResolver extends PackageResolver {
- Uri _root;
- RootResolver(this._root);
-
- Uri resolve(Uri uri) {
- if (uri.scheme != "package") return uri;
- return _root.resolve(uri.path);
- }
-}
+// Copyright (c) 2015, 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:async" show Future, Stream;
+import "dart:convert" show Encoding;
+import "dart:isolate" show Isolate;
+import "loader.dart";
+
+/// A resource that can be read into the program.
+///
+/// A resource is data that can be located using a URI and read into
+/// the program at runtime.
+/// The URI may use the `package` scheme to read resources provided
+/// along with package sources.
+abstract class Resource {
+ /// Creates a resource object with the given [uri] as location.
+ ///
+ /// The [uri] must be either a [Uri] or a string containing a valid URI.
+ /// If the string is not a valid URI, using any of the functions on
+ /// the resource object will fail.
+ ///
+ /// The URI may be relative, in which case it will be resolved
+ /// against [Uri.base] before being used.
+ ///
+ /// The URI may use the `package` scheme, which is always supported.
+ /// Other schemes may also be supported where possible.
+ ///
+ /// If [loader] is provided, it is used to load absolute non-package URIs.
+ /// Package: URIs are resolved to a non-package URI before being loaded, so
+ /// the loader doesn't have to support package: URIs, nor does it need to
+ /// support relative URI references.
+ /// If [loader] is omitted, a default implementation is used which supports
+ /// as many of `http`, `https`, `file` and `data` as are available on the
+ /// current platform.
+ const factory Resource(uri, {ResourceLoader loader}) = _Resource;
+
+ /// The location URI of this resource.
+ ///
+ /// This is a [Uri] of the `uri` parameter given to the constructor.
+ /// If the parameter was a string that did not contain a valid URI,
+ /// reading `uri` will fail.
+ Uri get uri;
+
+ /// Reads the resource content as a stream of bytes.
+ Stream<List<int>> openRead();
+
+ /// Reads the resource content as a single list of bytes.
+ Future<List<int>> readAsBytes();
+
+ /// Reads the resource content as a string.
+ ///
+ /// The content is decoded into a string using an [Encoding].
+ /// If no other encoding is provided, it defaults to UTF-8.
+ Future<String> readAsString({Encoding encoding});
+}
+
+class _Resource implements Resource {
+ /// Loading strategy for the resource.
+ final ResourceLoader _loader;
+
+ /// The URI of the resource.
+ final _uri;
+
+ const _Resource(uri, {ResourceLoader loader})
+ : _uri = uri, _loader = (loader != null) ? loader : const DefaultLoader();
+ // TODO: Make this `loader ?? const DefaultLoader()` when ?? is const.
+
+ Uri get uri => (_uri is String) ? Uri.parse(_uri) : (_uri as Uri);
+
+ Stream<List<int>> openRead() async* {
+ Uri uri = await _resolvedUri;
+ yield* _loader.openRead(uri);
+ }
+
+ Future<List<int>> readAsBytes() async {
+ Uri uri = await _resolvedUri;
+ return _loader.readAsBytes(uri);
+ }
+
+ Future<String> readAsString({Encoding encoding}) async {
+ Uri uri = await _resolvedUri;
+ return _loader.readAsString(uri, encoding: encoding);
+ }
+
+ Future<Uri> get _resolvedUri => resolveUri(uri);
+}
« no previous file with comments | « lib/src/loader.dart ('k') | pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698