| Index: pkg/barback/lib/src/internal_asset.dart
|
| diff --git a/pkg/barback/lib/src/asset.dart b/pkg/barback/lib/src/internal_asset.dart
|
| similarity index 56%
|
| copy from pkg/barback/lib/src/asset.dart
|
| copy to pkg/barback/lib/src/internal_asset.dart
|
| index fda813380dc1965b6b901db7e043f531256eed41..85ce4dce6eb994ef217f8defc04f9a7f6ebe9c10 100644
|
| --- a/pkg/barback/lib/src/asset.dart
|
| +++ b/pkg/barback/lib/src/internal_asset.dart
|
| @@ -2,64 +2,79 @@
|
| // 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 barback.asset;
|
| +library barback.internal_asset;
|
|
|
| import 'dart:async';
|
| import 'dart:convert';
|
| import 'dart:io';
|
|
|
| +import 'asset.dart';
|
| import 'asset_id.dart';
|
| import 'file_pool.dart';
|
| +import 'serialize.dart';
|
| import 'stream_replayer.dart';
|
| import 'utils.dart';
|
|
|
| -/// A blob of content.
|
| -///
|
| -/// Assets may come from the file system, or as the output of a [Transformer].
|
| -/// They are identified by [AssetId].
|
| -abstract class Asset {
|
| - /// The ID for this asset.
|
| - final AssetId id;
|
| -
|
| - Asset(this.id);
|
| -
|
| - factory Asset.fromBytes(AssetId id, List<int> bytes) =>
|
| - new _BinaryAsset(id, bytes);
|
| -
|
| - factory Asset.fromFile(AssetId id, File file) =>
|
| - new _FileAsset(id, file);
|
| -
|
| - factory Asset.fromString(AssetId id, String content) =>
|
| - new _StringAsset(id, content);
|
| -
|
| - factory Asset.fromPath(AssetId id, String path) =>
|
| - new _FileAsset(id, new File(path));
|
| -
|
| - /// Creates an asset from a stream.
|
| - ///
|
| - /// This immediately starts draining [stream].
|
| - factory Asset.fromStream(AssetId id, Stream<List<int>> stream) =>
|
| - new _StreamAsset(id, stream);
|
| -
|
| - /// Returns the contents of the asset as a string.
|
| - ///
|
| - /// If the asset was created from a [String] the original string is always
|
| - /// returned and [encoding] is ignored. Otherwise, the binary data of the
|
| - /// asset is decoded using [encoding], which defaults to [UTF8].
|
| - Future<String> readAsString({Encoding encoding});
|
| +/// Serialize an asset to a form that's safe to send across isolates.
|
| +Map serializeAsset(Asset asset) {
|
| + var id = serializeId(asset.id);
|
| + if (asset is BinaryAsset) {
|
| + // If [_contents] is a custom subclass of List, it won't be serializable, so
|
| + // we have to convert it to a built-in [List] first.
|
| + // TODO(nweiz): Send a typed array if that works after issue 14703 is fixed.
|
| + var contents = asset._contents.runtimeType == List ?
|
| + asset._contents : asset._contents.toList();
|
| +
|
| + return {
|
| + 'type': 'binary',
|
| + 'id': id,
|
| + 'contents': contents
|
| + };
|
| + } else if (asset is FileAsset) {
|
| + return {
|
| + 'type': 'file',
|
| + 'id': id,
|
| + 'path': asset._path
|
| + };
|
| + } else if (asset is StringAsset) {
|
| + return {
|
| + 'type': 'string',
|
| + 'id': id,
|
| + 'contents': asset._contents
|
| + };
|
| + } else {
|
| + // [asset] is probably a [StreamAsset], but it's possible that the user has
|
| + // created a custom subclass, in which case we just serialize the stream
|
| + // anyway.
|
| + return {
|
| + 'type': 'stream',
|
| + 'id': id,
|
| + 'stream': serializeStream(asset.read())
|
| + };
|
| + }
|
| +}
|
|
|
| - /// Streams the binary contents of the asset.
|
| - ///
|
| - /// If the asset was created from a [String], this returns its UTF-8 encoding.
|
| - Stream<List<int>> read();
|
| +/// Deserialize an asset from the form returned by [serialize].
|
| +Asset deserializeAsset(Map asset) {
|
| + var id = deserializeId(asset['id']);
|
| + switch (asset['type']) {
|
| + case 'binary': return new BinaryAsset(id, asset['contents']);
|
| + case 'file': return new FileAsset(id, asset['path']);
|
| + case 'string': return new StringAsset(id, asset['contents']);
|
| + case 'stream':
|
| + return new StreamAsset(id, deserializeStream(asset['stream']));
|
| + default:
|
| + throw new FormatException('Unknown asset type "${asset['type']}".');
|
| + }
|
| }
|
|
|
| /// An asset whose data is stored in a list of bytes.
|
| -class _BinaryAsset extends Asset {
|
| +class BinaryAsset implements Asset {
|
| + final AssetId id;
|
| +
|
| final List<int> _contents;
|
|
|
| - _BinaryAsset(AssetId id, this._contents)
|
| - : super(id);
|
| + BinaryAsset(this.id, this._contents);
|
|
|
| Future<String> readAsString({Encoding encoding}) {
|
| if (encoding == null) encoding = UTF8;
|
| @@ -99,31 +114,33 @@ class _BinaryAsset extends Asset {
|
| }
|
|
|
| /// An asset backed by a file on the local file system.
|
| -class _FileAsset extends Asset {
|
| +class FileAsset implements Asset {
|
| + final AssetId id;
|
| +
|
| /// Use a [FilePool] to handle reads so we can try to cope with running out
|
| /// of file descriptors more gracefully.
|
| static final _pool = new FilePool();
|
|
|
| - final File _file;
|
| - _FileAsset(AssetId id, this._file)
|
| - : super(id);
|
| + final String _path;
|
| + FileAsset(this.id, this._path);
|
|
|
| Future<String> readAsString({Encoding encoding}) {
|
| if (encoding == null) encoding = UTF8;
|
| - return _pool.readAsString(_file, encoding);
|
| + return _pool.readAsString(_path, encoding);
|
| }
|
|
|
| - Stream<List<int>> read() => _pool.openRead(_file);
|
| + Stream<List<int>> read() => _pool.openRead(_path);
|
|
|
| - String toString() => 'File "${_file.path}"';
|
| + String toString() => 'File "${_path}"';
|
| }
|
|
|
| /// An asset whose data is stored in a string.
|
| -class _StringAsset extends Asset {
|
| +class StringAsset implements Asset {
|
| + final AssetId id;
|
| +
|
| final String _contents;
|
|
|
| - _StringAsset(AssetId id, this._contents)
|
| - : super(id);
|
| + StringAsset(this.id, this._contents);
|
|
|
| Future<String> readAsString({Encoding encoding}) =>
|
| new Future.value(_contents);
|
| @@ -153,14 +170,15 @@ class _StringAsset extends Asset {
|
| }
|
|
|
| /// An asset whose data is available from a stream.
|
| -class _StreamAsset extends Asset {
|
| +class StreamAsset implements Asset {
|
| + final AssetId id;
|
| +
|
| /// A stream replayer that records and replays the contents of the input
|
| /// stream.
|
| final StreamReplayer<List<int>> _replayer;
|
|
|
| - _StreamAsset(AssetId id, Stream<List<int>> stream)
|
| - : _replayer = new StreamReplayer(stream),
|
| - super(id);
|
| + StreamAsset(this.id, Stream<List<int>> stream)
|
| + : _replayer = new StreamReplayer(stream);
|
|
|
| Future<String> readAsString({Encoding encoding}) {
|
| if (encoding == null) encoding = UTF8;
|
|
|