data_receiver.js revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// found in the LICENSE file. 403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)define('data_receiver', [ 603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 'async_waiter', 703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 'device/serial/data_stream.mojom', 803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 'mojo/public/js/bindings/core', 903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 'mojo/public/js/bindings/router', 1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)], function(asyncWaiter, dataStream, core, router) { 1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @module data_receiver 1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @typedef module:data_receiver~PendingError 1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @type {Object} 1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @property {number} error - the error 1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @property {number} offset - the location of the error 2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * A pending receive operation. 2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @constructor 2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @alias module:data_receiver~PendingReceive 2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) function PendingReceive() { 3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The promise that will be resolved or rejected when this receive completes 3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * or fails, respectively. 3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @type {Promise.<ArrayBuffer>} 3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.promise_ = new Promise(function(resolve, reject) { 3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The callback to call with the data received on success. 3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @type {Function} 4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.dataCallback_ = resolve; 4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The callback to call with the error on failure. 4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @type {Function} 4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.errorCallback_ = reject; 4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }.bind(this)); 5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * Returns the promise that will be resolved when this operation completes or 5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * rejected if an error occurs. 5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @return {Promise.<ArrayBuffer>} A promise to the data received. 5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) PendingReceive.prototype.getPromise = function() { 5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return this.promise_; 5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }; 6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * Dispatches received data to the promise returned by 6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * [getPromise]{@link module:data_receiver.PendingReceive#getPromise}. 6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {ArrayBuffer} data The data to dispatch. 6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) PendingReceive.prototype.dispatchData = function(data) { 6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.dataCallback_(data); 6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }; 6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * Dispatches an error if the offset of the error has been reached. 7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {module:data_receiver~PendingError} error The error to dispatch. 7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {number} bytesReceived The number of bytes that have been received. 7403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 7503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) PendingReceive.prototype.dispatchError = function(error, bytesReceived) { 7603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (bytesReceived != error.offset) 7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return false; 7803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) var e = new Error(); 8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) e.error = error.error; 8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.errorCallback_(e); 8203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return true; 8303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }; 8403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 8503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * Unconditionally dispatches an error. 8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {number} error The error to dispatch. 8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 8903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) PendingReceive.prototype.dispatchFatalError = function(error) { 9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) var e = new Error(); 9103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) e.error = error; 9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.errorCallback_(e); 9303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }; 9403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 9503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 9603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * A DataReceiver that receives data from a DataSource. 9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {MojoHandle} handle The handle to the DataSource. 9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {number} bufferSize How large a buffer the data pipe should use. 9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {number} fatalErrorValue The receive error value to report in the 10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * event of a fatal error. 10103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @constructor 10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @alias module:data_receiver.DataReceiver 10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) function DataReceiver(handle, bufferSize, fatalErrorValue) { 10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 10603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The [Router]{@link module:mojo/public/js/bindings/router.Router} for the 10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * connection to the DataSource. 10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.router_ = new router.Router(handle); 11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 11203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The connection to the DataSource. 11303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 11403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.source_ = new dataStream.DataSourceProxy(this.router_); 11603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.router_.setIncomingReceiver(this); 11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) var dataPipeOptions = { 11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) flags: core.CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, 11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) elementNumBytes: 1, 12003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) capacityNumBytes: bufferSize, 12103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }; 12203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) var receivePipe = core.createDataPipe(dataPipeOptions); 12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.source_.init(receivePipe.producerHandle); 12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The handle to the data pipe to use for receiving data. 12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 12803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.receivePipe_ = receivePipe.consumerHandle; 12903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The current receive operation. 13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @type {module:data_receiver~PendingReceive} 13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.receive_ = null; 13503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The error to be dispatched in the event of a fatal error. 13703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @type {number} 13803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 13903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.fatalErrorValue_ = fatalErrorValue; 14103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 14203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The async waiter used to wait for 14303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * {@link module:data_receiver.DataReceiver#receivePipe_} to be readable. 14403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @type module:async_waiter.AsyncWaiter 14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 14603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 14703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.waiter_ = new asyncWaiter.AsyncWaiter(this.receivePipe_, 14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) core.HANDLE_SIGNAL_READABLE, 14903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.onHandleReady_.bind(this)); 15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The number of bytes received from the DataSource. 15203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @type {number} 15303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 15403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 15503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.bytesReceived_ = 0; 15603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 15703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The pending error if there is one. 15803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @type module:data_receiver~PendingError 15903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 16003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 16103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.pendingError_ = null; 16203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 16303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * Whether the DataSource is paused. 16403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @type {boolean} 16503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 16703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.paused_ = false; 16803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 16903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * Whether this DataReceiver has shut down. 17003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @type {boolean} 17103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 17203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 17303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.shutDown_ = false; 17403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 17503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 17603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DataReceiver.prototype = 17703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) $Object.create(dataStream.DataSourceClientStub.prototype); 17803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 17903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 18003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * Closes this DataReceiver. 18103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 18203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DataReceiver.prototype.close = function() { 18303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (this.shutDown_) 18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.shutDown_ = true; 18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.router_.close(); 18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.waiter_.stop(); 18803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) core.close(this.receivePipe_); 18903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (this.receive_) { 19003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.receive_.dispatchFatalError(this.fatalErrorValue_); 19103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.receive_ = null; 19203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 19303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }; 19403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 19503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 19603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * Receive data from the DataSource. 19703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @return {Promise.<ArrayBuffer>} A promise to the received data. If an error 19803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * occurs, the promise will reject with an Error object with a property 19903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * error containing the error code. 20003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @throws Will throw if this has encountered a fatal error or another receive 20103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * is in progress. 20203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 20303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DataReceiver.prototype.receive = function() { 20403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (this.shutDown_) 20503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) throw new Error('System error'); 20603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (this.receive_) 20703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) throw new Error('Receive already in progress.'); 20803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) var receive = new PendingReceive(); 20903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) var promise = receive.getPromise(); 21003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (this.pendingError_ && 21103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) receive.dispatchError(this.pendingError_, this.bytesReceived_)) { 21203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.pendingError_ = null; 21303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.paused_ = true; 21403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return promise; 21503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 21603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (this.paused_) { 21703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.source_.resume(); 21803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.paused_ = false; 21903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 22003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.receive_ = receive; 22103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.waiter_.start(); 22203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return promise; 22303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }; 22403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 22503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 22603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * Invoked when |handle_| is ready to read. Reads from the data pipe if the 22703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * wait is successful. 22803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {number} waitResult The result of the asynchronous wait. 22903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 23003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 23103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DataReceiver.prototype.onHandleReady_ = function(waitResult) { 23203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (waitResult != core.RESULT_OK || !this.receive_) { 23303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.close(); 23403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 23503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 23603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) var result = core.readData(this.receivePipe_, core.READ_DATA_FLAG_NONE); 23703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (result.result == core.RESULT_OK) { 23803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // TODO(sammc): Handle overflow in the same fashion as the C++ receiver. 23903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.bytesReceived_ += result.buffer.byteLength; 24003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.receive_.dispatchData(result.buffer); 24103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.receive_ = null; 24203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } else if (result.result == core.RESULT_SHOULD_WAIT) { 24303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.waiter_.start(); 24403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } else { 24503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.close(); 24603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 24703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }; 24803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 24903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 25003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * Invoked by the DataSource when an error is encountered. 25103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {number} offset The location at which the error occurred. 25203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {number} error The error that occurred. 25303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 25403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 25503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DataReceiver.prototype.onError = function(offset, error) { 25603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (this.shutDown_) 25703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 25803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 25903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 26003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @type module:data_receiver~PendingError 26103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 26203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) var pendingError = { 26303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) error: error, 26403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) offset: offset, 26503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }; 26603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (this.receive_ && 26703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.receive_.dispatchError(pendingError, this.bytesReceived_)) { 26803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.receive_ = null; 26903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.waiter_.stop(); 27003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.paused_ = true; 27103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 27203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 27303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.pendingError_ = pendingError; 27403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }; 27503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 27603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return {DataReceiver: DataReceiver}; 27703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}); 278