| Index: runtime/bin/builtin.dart
|
| diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart
|
| index 818acaf7c7ab5ee7b7e3cce51573baac6c2008c5..e3abb9a20da865d742aa7a3aea739efd003078d9 100644
|
| --- a/runtime/bin/builtin.dart
|
| +++ b/runtime/bin/builtin.dart
|
| @@ -4,6 +4,7 @@
|
|
|
| library builtin;
|
| import 'dart:io';
|
| +import 'dart:typed_data';
|
|
|
| // Corelib 'print' implementation.
|
| void _print(arg) {
|
| @@ -35,14 +36,16 @@ _getHttpRequestResponseCode() => _httpRequestResponseCode;
|
| _getHttpRequestStatusString() => _httpRequestStatusString;
|
| _getHttpRequestResponse() => _httpRequestResponse;
|
|
|
| -void _requestCompleted(HttpClientResponseBody body) {
|
| - _httpRequestResponseCode = body.statusCode;
|
| - _httpRequestStatusString = '${body.statusCode} ${body.reasonPhrase}';
|
| +void _requestCompleted(List<int> data, HttpClientResponse response) {
|
| + _httpRequestResponseCode = response.statusCode;
|
| + _httpRequestStatusString = '${response.statusCode} ${response.reasonPhrase}';
|
| _httpRequestResponse = null;
|
| - if (body.statusCode != 200 || body.type == 'json') {
|
| + if (response.statusCode != 200 ||
|
| + (response.headers.contentType != null &&
|
| + response.headers.contentType.mimeType == 'application/json')) {
|
| return;
|
| }
|
| - _httpRequestResponse = body.body;
|
| + _httpRequestResponse = data;
|
| }
|
|
|
|
|
| @@ -61,9 +64,12 @@ void _makeHttpRequest(String uri) {
|
| Uri requestUri = Uri.parse(uri);
|
| _client.getUrl(requestUri)
|
| .then((HttpClientRequest request) => request.close())
|
| - .then(HttpBodyHandler.processResponse)
|
| - .then((HttpClientResponseBody body) {
|
| - _requestCompleted(body);
|
| + .then((HttpClientResponse response) {
|
| + return response
|
| + .fold(new _BufferList(), (b, d) => b..add(d))
|
| + .then((buffer) {
|
| + _requestCompleted(buffer.readBytes(), response);
|
| + });
|
| }).catchError((error) {
|
| _requestFailed(error);
|
| });
|
| @@ -271,3 +277,99 @@ String _filePathFromHttpUri(Uri uri) {
|
| _logResolution('# Path: $uri -> $uri');
|
| return uri.toString();
|
| }
|
| +
|
| +/**
|
| + * Utility class that can fast concatenate [List<int>]s of bytes. Use
|
| + * [readBytes] to get the final buffer.
|
| + */
|
| +// TODO(ajohnsen): Expose in dart:io?
|
| +class _BufferList {
|
| + const int _INIT_SIZE = 1 * 1024;
|
| +
|
| + _BufferList() {
|
| + clear();
|
| + }
|
| +
|
| + int pow2roundup(int x) {
|
| + --x;
|
| + x |= x >> 1;
|
| + x |= x >> 2;
|
| + x |= x >> 4;
|
| + x |= x >> 8;
|
| + x |= x >> 16;
|
| + return x + 1;
|
| + }
|
| +
|
| + /**
|
| + * Adds a new buffer to the list.
|
| + */
|
| + void add(List<int> buffer) {
|
| + int bufferLength = buffer.length;
|
| + int required = _length + bufferLength;
|
| + if (_buffer == null) {
|
| + int size = pow2roundup(required);
|
| + if (size < _INIT_SIZE) size = _INIT_SIZE;
|
| + _buffer = new Uint8List(size);
|
| + } else if (_buffer.length < required) {
|
| + // This will give is a list in the range of 2-4 times larger than
|
| + // required.
|
| + int size = pow2roundup(required) * 2;
|
| + Uint8List newBuffer = new Uint8List(size);
|
| + newBuffer.setRange(0, _buffer.length, _buffer);
|
| + _buffer = newBuffer;
|
| + }
|
| + assert(_buffer.length >= required);
|
| + if (buffer is Uint8List) {
|
| + _buffer.setRange(_length, required, buffer);
|
| + } else {
|
| + for (int i = 0; i < bufferLength; i++) {
|
| + _buffer[_length + i] = buffer[i];
|
| + }
|
| + }
|
| + _length = required;
|
| + }
|
| +
|
| + /**
|
| + * Same as [add].
|
| + */
|
| + void write(List<int> buffer) {
|
| + add(buffer);
|
| + }
|
| +
|
| + /**
|
| + * Read all the bytes from the buffer list. If it's empty, an empty list
|
| + * is returned. A call to [readBytes] will clear the buffer.
|
| + */
|
| + List<int> readBytes() {
|
| + if (_buffer == null) return new Uint8List(0);
|
| + var buffer = new Uint8List.view(_buffer.buffer, 0, _length);
|
| + clear();
|
| + return buffer;
|
| + }
|
| +
|
| + /**
|
| + * Returns the total number of bytes in the buffer.
|
| + */
|
| + int get length => _length;
|
| +
|
| + /**
|
| + * Returns whether the buffer list is empty.
|
| + */
|
| + bool get isEmpty => _length == 0;
|
| +
|
| + /**
|
| + * Returns whether the buffer list is not empty.
|
| + */
|
| + bool get isNotEmpty => !isEmpty;
|
| +
|
| + /**
|
| + * Clears the content of the buffer list.
|
| + */
|
| + void clear() {
|
| + _length = 0;
|
| + _buffer = null;
|
| + }
|
| +
|
| + int _length; // Total number of bytes in the buffer.
|
| + Uint8List _buffer; // Internal buffer.
|
| +}
|
|
|