Index: mojo/public/dart/src/drain_data.dart |
diff --git a/mojo/public/dart/src/drain_data.dart b/mojo/public/dart/src/drain_data.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..40f2a49f2fa22992918dfcc7e14e110b787ccfd7 |
--- /dev/null |
+++ b/mojo/public/dart/src/drain_data.dart |
@@ -0,0 +1,69 @@ |
+// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+part of core; |
+ |
+class DataPipeDrainer { |
+ MojoDataPipeConsumer _consumer; |
+ MojoHandle _handle; |
+ List<ByteData> _dataList; |
+ int _dataSize; |
+ |
+ DataPipeDrainer(this._consumer) { |
+ _handle = new MojoHandle(_consumer.handle); |
+ _dataList = new List(); |
+ _dataSize = 0; |
+ } |
+ |
+ MojoResult _doRead() { |
+ ByteData thisRead = _consumer.beginRead(); |
+ if (thisRead == null) { |
+ throw 'Data pipe beginRead failed: ${_consumer.status}'; |
+ } |
+ _dataList.add(thisRead); |
+ _dataSize += thisRead.lengthInBytes; |
+ return _consumer.endRead(thisRead.lengthInBytes); |
+ } |
+ |
+ ByteData _concatData() { |
+ var data = new ByteData(_dataSize); |
+ int end = 0; |
+ for (var chunk in _dataList) { |
+ data.buffer.asUint8List().setRange( |
+ end, end + chunk.lengthInBytes, chunk.buffer.asUint8List()); |
+ end += chunk.lengthInBytes; |
+ } |
+ return data; |
+ } |
+ |
+ Future<ByteData> drain() { |
+ var completer = new Completer(); |
+ _handle.listen((List<int> event) { |
+ var mojoSignals = new MojoHandleSignals(event[1]); |
+ if (mojoSignals.isReadable) { |
+ var result = _doRead(); |
+ if (!result.isOk) { |
+ _handle.close(); |
+ _handle = null; |
+ completer.complete(_concatData()); |
+ } else { |
+ _handle.enableReadEvents(); |
+ } |
+ } else if (mojoSignals.isPeerClosed) { |
+ _handle.close(); |
+ _handle = null; |
+ completer.complete(_concatData()); |
+ } else { |
+ throw 'Unexpected handle event: $mojoSignals'; |
+ } |
+ }); |
+ return completer.future; |
+ } |
+ |
+ static Future<ByteData> drainHandle(MojoHandle handle) { |
+ var consumer = new MojoDataPipeConsumer(handle); |
+ var drainer = new DataPipeDrainer(consumer); |
+ return drainer.drain(); |
+ } |
+} |