| 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.internal_asset; | 5 library barback.asset.internal_asset; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:convert'; | 8 import 'dart:convert'; |
| 9 import 'dart:typed_data'; | 9 import 'dart:typed_data'; |
| 10 | 10 |
| 11 import 'package:async/async.dart'; | 11 import 'package:async/async.dart'; |
| 12 import 'package:collection/collection.dart'; | 12 import 'package:collection/collection.dart'; |
| 13 | 13 |
| 14 import '../serialize.dart'; | 14 import '../serialize.dart'; |
| 15 import '../utils.dart'; | 15 import '../utils.dart'; |
| 16 import '../utils/file_pool.dart'; | 16 import '../utils/file_pool.dart'; |
| 17 import '../utils/stream_replayer.dart'; | 17 import '../utils/stream_replayer.dart'; |
| 18 import 'asset.dart'; | 18 import 'asset.dart'; |
| 19 import 'asset_id.dart'; | 19 import 'asset_id.dart'; |
| 20 | 20 |
| 21 /// Serialize an asset to a form that's safe to send across isolates. | 21 /// Serialize an asset to a form that's safe to send across isolates. |
| 22 Map serializeAsset(Asset asset) { | 22 Map serializeAsset(Asset asset) { |
| 23 var id = serializeId(asset.id); | 23 var id = serializeId(asset.id); |
| 24 if (asset is BinaryAsset) { | 24 if (asset is BinaryAsset) { |
| 25 return { | 25 return {'type': 'binary', 'id': id, 'contents': asset._contents}; |
| 26 'type': 'binary', | |
| 27 'id': id, | |
| 28 'contents': asset._contents | |
| 29 }; | |
| 30 } else if (asset is FileAsset) { | 26 } else if (asset is FileAsset) { |
| 31 return { | 27 return {'type': 'file', 'id': id, 'path': asset._path}; |
| 32 'type': 'file', | |
| 33 'id': id, | |
| 34 'path': asset._path | |
| 35 }; | |
| 36 } else if (asset is StringAsset) { | 28 } else if (asset is StringAsset) { |
| 37 return { | 29 return {'type': 'string', 'id': id, 'contents': asset._contents}; |
| 38 'type': 'string', | |
| 39 'id': id, | |
| 40 'contents': asset._contents | |
| 41 }; | |
| 42 } else { | 30 } else { |
| 43 // [asset] is probably a [StreamAsset], but it's possible that the user has | 31 // [asset] is probably a [StreamAsset], but it's possible that the user has |
| 44 // created a custom subclass, in which case we just serialize the stream | 32 // created a custom subclass, in which case we just serialize the stream |
| 45 // anyway. | 33 // anyway. |
| 46 return { | 34 return { |
| 47 'type': 'stream', | 35 'type': 'stream', |
| 48 'id': id, | 36 'id': id, |
| 49 'stream': serializeStream(asset.read()) | 37 'stream': serializeStream(asset.read()) |
| 50 }; | 38 }; |
| 51 } | 39 } |
| 52 } | 40 } |
| 53 | 41 |
| 54 /// Deserialize an asset from the form returned by [serialize]. | 42 /// Deserialize an asset from the form returned by [serialize]. |
| 55 Asset deserializeAsset(Map asset) { | 43 Asset deserializeAsset(Map asset) { |
| 56 var id = deserializeId(asset['id']); | 44 var id = deserializeId(asset['id']); |
| 57 switch (asset['type']) { | 45 switch (asset['type']) { |
| 58 case 'binary': | 46 case 'binary': |
| 59 return new BinaryAsset( | 47 return new BinaryAsset( |
| 60 id, DelegatingList.typed(asset['contents'] as List)); | 48 id, DelegatingList.typed(asset['contents'] as List)); |
| 61 case 'file': return new FileAsset(id, asset['path']); | 49 case 'file': |
| 62 case 'string': return new StringAsset(id, asset['contents']); | 50 return new FileAsset(id, asset['path']); |
| 51 case 'string': |
| 52 return new StringAsset(id, asset['contents']); |
| 63 case 'stream': | 53 case 'stream': |
| 64 return new StreamAsset( | 54 return new StreamAsset( |
| 65 id, DelegatingStream.typed(deserializeStream(asset['stream']))); | 55 id, DelegatingStream.typed(deserializeStream(asset['stream']))); |
| 66 default: | 56 default: |
| 67 throw new FormatException('Unknown asset type "${asset['type']}".'); | 57 throw new FormatException('Unknown asset type "${asset['type']}".'); |
| 68 } | 58 } |
| 69 } | 59 } |
| 70 | 60 |
| 71 /// An asset whose data is stored in a list of bytes. | 61 /// An asset whose data is stored in a list of bytes. |
| 72 class BinaryAsset implements Asset { | 62 class BinaryAsset implements Asset { |
| 73 final AssetId id; | 63 final AssetId id; |
| 74 | 64 |
| 75 final Uint8List _contents; | 65 final Uint8List _contents; |
| 76 | 66 |
| 77 BinaryAsset(this.id, List<int> contents) | 67 BinaryAsset(this.id, List<int> contents) : _contents = toUint8List(contents); |
| 78 : _contents = toUint8List(contents); | |
| 79 | 68 |
| 80 Future<String> readAsString({Encoding encoding}) { | 69 Future<String> readAsString({Encoding encoding}) { |
| 81 if (encoding == null) encoding = UTF8; | 70 if (encoding == null) encoding = UTF8; |
| 82 | 71 |
| 83 return new Future.value(encoding.decode(_contents)); | 72 return new Future.value(encoding.decode(_contents)); |
| 84 } | 73 } |
| 85 | 74 |
| 86 Stream<List<int>> read() => new Future<List<int>>.value(_contents).asStream(); | 75 Stream<List<int>> read() => new Future<List<int>>.value(_contents).asStream(); |
| 87 | 76 |
| 88 String toString() { | 77 String toString() { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 Future<String> readAsString({Encoding encoding}) => | 135 Future<String> readAsString({Encoding encoding}) => |
| 147 new Future.value(_contents); | 136 new Future.value(_contents); |
| 148 | 137 |
| 149 Stream<List<int>> read() => | 138 Stream<List<int>> read() => |
| 150 new Future<List<int>>.value(UTF8.encode(_contents)).asStream(); | 139 new Future<List<int>>.value(UTF8.encode(_contents)).asStream(); |
| 151 | 140 |
| 152 String toString() { | 141 String toString() { |
| 153 // Don't show the whole string if it's long. | 142 // Don't show the whole string if it's long. |
| 154 var contents = _contents; | 143 var contents = _contents; |
| 155 if (contents.length > 40) { | 144 if (contents.length > 40) { |
| 156 contents = contents.substring(0, 20) + " ... " + | 145 contents = contents.substring(0, 20) + |
| 157 contents.substring(contents.length - 20); | 146 " ... " + |
| 147 contents.substring(contents.length - 20); |
| 158 } | 148 } |
| 159 | 149 |
| 160 contents = _escape(contents); | 150 contents = _escape(contents); |
| 161 return 'String "$contents"'; | 151 return 'String "$contents"'; |
| 162 } | 152 } |
| 163 | 153 |
| 164 String _escape(String string) { | 154 String _escape(String string) { |
| 165 return string | 155 return string |
| 166 .replaceAll("\"", r'\"') | 156 .replaceAll("\"", r'\"') |
| 167 .replaceAll("\n", r"\n") | 157 .replaceAll("\n", r"\n") |
| 168 .replaceAll("\r", r"\r") | 158 .replaceAll("\r", r"\r") |
| 169 .replaceAll("\t", r"\t"); | 159 .replaceAll("\t", r"\t"); |
| 170 } | 160 } |
| 171 } | 161 } |
| 172 | 162 |
| 173 /// An asset whose data is available from a stream. | 163 /// An asset whose data is available from a stream. |
| 174 class StreamAsset implements Asset { | 164 class StreamAsset implements Asset { |
| 175 final AssetId id; | 165 final AssetId id; |
| 176 | 166 |
| 177 /// A stream replayer that records and replays the contents of the input | 167 /// A stream replayer that records and replays the contents of the input |
| 178 /// stream. | 168 /// stream. |
| 179 final StreamReplayer<List<int>> _replayer; | 169 final StreamReplayer<List<int>> _replayer; |
| 180 | 170 |
| 181 StreamAsset(this.id, Stream<List<int>> stream) | 171 StreamAsset(this.id, Stream<List<int>> stream) |
| 182 : _replayer = new StreamReplayer(stream); | 172 : _replayer = new StreamReplayer(stream); |
| 183 | 173 |
| 184 Future<String> readAsString({Encoding encoding}) { | 174 Future<String> readAsString({Encoding encoding}) { |
| 185 if (encoding == null) encoding = UTF8; | 175 if (encoding == null) encoding = UTF8; |
| 186 return _replayer.getReplay().expand((chunk) => chunk).toList() | 176 return _replayer |
| 177 .getReplay() |
| 178 .expand((chunk) => chunk) |
| 179 .toList() |
| 187 .then((bytes) => encoding.decode(bytes)); | 180 .then((bytes) => encoding.decode(bytes)); |
| 188 } | 181 } |
| 189 | 182 |
| 190 Stream<List<int>> read() => _replayer.getReplay(); | 183 Stream<List<int>> read() => _replayer.getReplay(); |
| 191 | 184 |
| 192 String toString() => "Stream"; | 185 String toString() => "Stream"; |
| 193 } | 186 } |
| OLD | NEW |