| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library barback.asset; | 5 library barback.asset; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:io'; | 8 import 'dart:io'; |
| 9 import 'dart:utf'; |
| 9 | 10 |
| 10 import 'asset_id.dart'; | 11 import 'asset_id.dart'; |
| 12 import 'utils.dart'; |
| 11 | 13 |
| 12 /// A blob of content. | 14 /// A blob of content. |
| 13 /// | 15 /// |
| 14 /// Assets may come from the file system, or as the output of a [Transformer]. | 16 /// Assets may come from the file system, or as the output of a [Transformer]. |
| 15 /// They are identified by [AssetId]. | 17 /// They are identified by [AssetId]. |
| 16 abstract class Asset { | 18 abstract class Asset { |
| 17 /// The ID for this asset. | 19 /// The ID for this asset. |
| 18 final AssetId id; | 20 final AssetId id; |
| 19 | 21 |
| 20 Asset(this.id); | 22 Asset(this.id); |
| 21 | 23 |
| 22 factory Asset.fromFile(AssetId id, File file) { | 24 factory Asset.fromBytes(AssetId id, List<int> bytes) => |
| 23 return new _FileAsset(id, file); | 25 new _BinaryAsset(id, bytes); |
| 26 |
| 27 factory Asset.fromFile(AssetId id, File file) => |
| 28 new _FileAsset(id, file); |
| 29 |
| 30 factory Asset.fromString(AssetId id, String content) => |
| 31 new _StringAsset(id, content); |
| 32 |
| 33 factory Asset.fromPath(AssetId id, String path) => |
| 34 new _FileAsset(id, new File(path)); |
| 35 |
| 36 /// Returns the contents of the asset as a string. |
| 37 /// |
| 38 /// If the asset was created from a [String] the original string is always |
| 39 /// returned and [encoding] is ignored. Otherwise, the binary data of the |
| 40 /// asset is decoded using [encoding], which defaults to [Encoding.UTF_8]. |
| 41 Future<String> readAsString({Encoding encoding}); |
| 42 |
| 43 /// Streams the binary contents of the asset. |
| 44 /// |
| 45 /// If the asset was created from a [String], this returns its UTF-8 encoding. |
| 46 Stream<List<int>> read(); |
| 47 } |
| 48 |
| 49 /// An asset whose data is stored in a list of bytes. |
| 50 class _BinaryAsset extends Asset { |
| 51 final List<int> _contents; |
| 52 |
| 53 _BinaryAsset(AssetId id, this._contents) |
| 54 : super(id); |
| 55 |
| 56 Future<String> readAsString({Encoding encoding}) { |
| 57 if (encoding == null) encoding = Encoding.UTF_8; |
| 58 |
| 59 // TODO(rnystrom): When #6284 is fixed, just use that. Until then, only |
| 60 // UTF-8 is supported. :( |
| 61 if (encoding != Encoding.UTF_8) { |
| 62 throw new UnsupportedError( |
| 63 "${encoding.name} is not a supported encoding."); |
| 64 } |
| 65 |
| 66 return new Future.value(decodeUtf8(_contents)); |
| 24 } | 67 } |
| 25 | 68 |
| 26 factory Asset.fromString(AssetId id, String content) { | 69 Stream<List<int>> read() => new Future<List<int>>.value(_contents).asStream(); |
| 27 return new _StringAsset(id, content); | 70 |
| 71 String toString() { |
| 72 var buffer = new StringBuffer(); |
| 73 buffer.write("Bytes ["); |
| 74 |
| 75 // Don't show the whole list if it's long. |
| 76 if (_contents.length > 11) { |
| 77 for (var i = 0; i < 5; i++) { |
| 78 buffer.write(byteToHex(_contents[i])); |
| 79 buffer.write(" "); |
| 80 } |
| 81 |
| 82 buffer.write("..."); |
| 83 |
| 84 for (var i = _contents.length - 5; i < _contents.length; i++) { |
| 85 buffer.write(" "); |
| 86 buffer.write(byteToHex(_contents[i])); |
| 87 } |
| 88 } else { |
| 89 for (var i = 0; i < _contents.length; i++) { |
| 90 if (i > 0) buffer.write(" "); |
| 91 buffer.write(byteToHex(_contents[i])); |
| 92 } |
| 93 } |
| 94 |
| 95 buffer.write("]"); |
| 96 return buffer.toString(); |
| 28 } | 97 } |
| 29 | |
| 30 factory Asset.fromPath(AssetId id, String path) { | |
| 31 return new _FileAsset(id, new File(path)); | |
| 32 } | |
| 33 | |
| 34 // TODO(rnystrom): This prevents users from defining their own | |
| 35 // implementations of Asset. Use serialization package instead. | |
| 36 factory Asset.deserialize(data) { | |
| 37 // TODO(rnystrom): Handle errors. | |
| 38 var id = new AssetId.parse(data[1]); | |
| 39 switch (data[0]) { | |
| 40 case "file": return new _FileAsset(id, new File(data[2])); break; | |
| 41 case "string": return new _StringAsset(id, data[2]); break; | |
| 42 } | |
| 43 } | |
| 44 | |
| 45 /// Returns the contents of the asset as a string. | |
| 46 // TODO(rnystrom): Figure out how binary assets should be handled. | |
| 47 Future<String> readAsString(); | |
| 48 | |
| 49 /// Streams the contents of the asset. | |
| 50 Stream<List<int>> read(); | |
| 51 | |
| 52 /// Serializes this [Asset] to an object that can be sent across isolates | |
| 53 /// and passed to [deserialize]. | |
| 54 Object serialize(); | |
| 55 } | 98 } |
| 56 | 99 |
| 57 /// An asset backed by a file on the local file system. | 100 /// An asset backed by a file on the local file system. |
| 58 class _FileAsset extends Asset { | 101 class _FileAsset extends Asset { |
| 59 final File _file; | 102 final File _file; |
| 60 _FileAsset(AssetId id, this._file) | 103 _FileAsset(AssetId id, this._file) |
| 61 : super(id); | 104 : super(id); |
| 62 | 105 |
| 63 Future<String> readAsString() => _file.readAsString(); | 106 Future<String> readAsString({Encoding encoding}) { |
| 107 if (encoding == null) encoding = Encoding.UTF_8; |
| 108 return _file.readAsString(encoding: encoding); |
| 109 } |
| 110 |
| 64 Stream<List<int>> read() => _file.openRead(); | 111 Stream<List<int>> read() => _file.openRead(); |
| 65 | 112 |
| 66 String toString() => 'File "${_file.path}"'; | 113 String toString() => 'File "${_file.path}"'; |
| 67 | |
| 68 Object serialize() => ["file", id.serialize(), _file.path]; | |
| 69 } | 114 } |
| 70 | 115 |
| 71 /// An asset whose data is stored in a string. | 116 /// An asset whose data is stored in a string. |
| 72 // TODO(rnystrom): Have something similar for in-memory binary assets. | |
| 73 class _StringAsset extends Asset { | 117 class _StringAsset extends Asset { |
| 74 final String _contents; | 118 final String _contents; |
| 75 | 119 |
| 76 _StringAsset(AssetId id, this._contents) | 120 _StringAsset(AssetId id, this._contents) |
| 77 : super(id); | 121 : super(id); |
| 78 | 122 |
| 79 Future<String> readAsString() => new Future.value(_contents); | 123 Future<String> readAsString({Encoding encoding}) => |
| 124 new Future.value(_contents); |
| 80 | 125 |
| 81 // TODO(rnystrom): Implement this and handle encoding. | 126 Stream<List<int>> read() => |
| 82 Stream<List<int>> read() => throw new UnimplementedError(); | 127 new Future<List<int>>.value(encodeUtf8(_contents)).asStream(); |
| 83 | 128 |
| 84 String toString() { | 129 String toString() { |
| 85 // Don't show the whole string if it's long. | 130 // Don't show the whole string if it's long. |
| 86 var contents = _contents; | 131 var contents = _contents; |
| 87 if (contents.length > 40) { | 132 if (contents.length > 40) { |
| 88 contents = contents.substring(0, 20) + " ... " + | 133 contents = contents.substring(0, 20) + " ... " + |
| 89 contents.substring(contents.length - 20); | 134 contents.substring(contents.length - 20); |
| 90 } | 135 } |
| 91 | 136 |
| 92 contents = _escape(contents); | 137 contents = _escape(contents); |
| 93 return 'String "$contents"'; | 138 return 'String "$contents"'; |
| 94 } | 139 } |
| 95 | 140 |
| 96 Object serialize() => ["string", id.serialize(), _contents]; | |
| 97 | |
| 98 String _escape(String string) { | 141 String _escape(String string) { |
| 99 return string | 142 return string |
| 100 .replaceAll("\"", r'\"') | 143 .replaceAll("\"", r'\"') |
| 101 .replaceAll("\n", r"\n") | 144 .replaceAll("\n", r"\n") |
| 102 .replaceAll("\r", r"\r") | 145 .replaceAll("\r", r"\r") |
| 103 .replaceAll("\t", r"\t"); | 146 .replaceAll("\t", r"\t"); |
| 104 } | 147 } |
| 105 } | 148 } |
| OLD | NEW |