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', 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 'device/serial/data_stream_serialization.mojom', 903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 'mojo/public/js/bindings/core', 1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 'mojo/public/js/bindings/router', 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci], function(asyncWaiter, dataStream, serialization, core, router) { 1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @module data_receiver 1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * A pending receive operation. 1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @constructor 1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @alias module:data_receiver~PendingReceive 2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) function PendingReceive() { 2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The promise that will be resolved or rejected when this receive completes 2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * or fails, respectively. 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @type {!Promise.<ArrayBuffer>} 2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.promise_ = new Promise(function(resolve, reject) { 3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The callback to call with the data received on success. 3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @type {Function} 3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.dataCallback_ = resolve; 3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The callback to call with the error on failure. 3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @type {Function} 3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.errorCallback_ = reject; 4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }.bind(this)); 4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * Returns the promise that will be resolved when this operation completes or 4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * rejected if an error occurs. 4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @return {Promise.<ArrayBuffer>} A promise to the data received. 4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) PendingReceive.prototype.getPromise = function() { 5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return this.promise_; 5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }; 5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * Dispatches received data to the promise returned by 5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * [getPromise]{@link module:data_receiver.PendingReceive#getPromise}. 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {!ArrayBuffer} data The data to dispatch. 5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) PendingReceive.prototype.dispatchData = function(data) { 6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.dataCallback_(data); 6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }; 6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * Dispatches an error if the offset of the error has been reached. 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {!PendingReceiveError} error The error to dispatch. 6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {number} bytesReceived The number of bytes that have been received. 6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) PendingReceive.prototype.dispatchError = function(error, bytesReceived) { 6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (bytesReceived != error.offset) 7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return false; 7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) var e = new Error(); 7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) e.error = error.error; 7403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.errorCallback_(e); 7503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return true; 7603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }; 7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 7803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * Unconditionally dispatches an error. 8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {number} error The error to dispatch. 8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 8203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) PendingReceive.prototype.dispatchFatalError = function(error) { 8303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) var e = new Error(); 8403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) e.error = error; 8503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.errorCallback_(e); 8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }; 8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 8903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * A DataReceiver that receives data from a DataSource. 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {!MojoHandle} handle The handle to the DataSource. 9103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {number} bufferSize How large a buffer the data pipe should use. 9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {number} fatalErrorValue The receive error value to report in the 9303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * event of a fatal error. 9403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @constructor 9503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @alias module:data_receiver.DataReceiver 9603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) function DataReceiver(handle, bufferSize, fatalErrorValue) { 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci var dataPipeOptions = { 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci flags: core.CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci elementNumBytes: 1, 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci capacityNumBytes: bufferSize, 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }; 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci var receivePipe = core.createDataPipe(dataPipeOptions); 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.init_( 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci handle, receivePipe.consumerHandle, fatalErrorValue, 0, null, false); 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.source_.init(receivePipe.producerHandle); 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DataReceiver.prototype = 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci $Object.create(dataStream.DataSourceClientStub.prototype); 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * Closes this DataReceiver. 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci */ 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DataReceiver.prototype.close = function() { 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (this.shutDown_) 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.shutDown_ = true; 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.router_.close(); 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.waiter_.stop(); 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci core.close(this.receivePipe_); 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (this.receive_) { 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.receive_.dispatchFatalError(this.fatalErrorValue_); 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.receive_ = null; 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }; 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * Initialize this DataReceiver. 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {!MojoHandle} source A handle to the DataSource 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {!MojoHandle} dataPipe A handle to use for receiving data from the 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * DataSource. 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {number} fatalErrorValue The error to dispatch in the event of a 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * fatal error. 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {number} bytesReceived The number of bytes already received. 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {PendingReceiveError} pendingError The pending error if there is 1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * one. 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {boolean} paused Whether the DataSource is paused. 1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @private 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci */ 1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DataReceiver.prototype.init_ = function(source, 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci dataPipe, 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci fatalErrorValue, 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bytesReceived, 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pendingError, 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci paused) { 14703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The [Router]{@link module:mojo/public/js/bindings/router.Router} for the 14903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * connection to the DataSource. 15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.router_ = new router.Router(source); 15303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 15403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The connection to the DataSource. 15503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 15603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 15703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.source_ = new dataStream.DataSourceProxy(this.router_); 15803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.router_.setIncomingReceiver(this); 15903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 16003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The handle to the data pipe to use for receiving data. 16103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 16203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.receivePipe_ = dataPipe; 16403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 16503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The current receive operation. 16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @type {module:data_receiver~PendingReceive} 16703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 16803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 16903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.receive_ = null; 17003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 17103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The error to be dispatched in the event of a fatal error. 1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @const {number} 17303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 17403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 17503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.fatalErrorValue_ = fatalErrorValue; 17603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 17703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The async waiter used to wait for 1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * |[receivePipe_]{@link module:data_receiver.DataReceiver#receivePipe_}| to 1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * be readable. 1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @type {!module:async_waiter.AsyncWaiter} 18103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 18203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 18303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.waiter_ = new asyncWaiter.AsyncWaiter(this.receivePipe_, 18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) core.HANDLE_SIGNAL_READABLE, 18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.onHandleReady_.bind(this)); 18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The number of bytes received from the DataSource. 18803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @type {number} 18903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 19003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.bytesReceived_ = bytesReceived; 19203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 19303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * The pending error if there is one. 1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @type {PendingReceiveError} 19503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 19603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.pendingError_ = pendingError; 19803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 19903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * Whether the DataSource is paused. 20003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @type {boolean} 20103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 20203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.paused_ = paused; 20403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 20503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * Whether this DataReceiver has shut down. 20603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @type {boolean} 20703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 20803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 20903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.shutDown_ = false; 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }; 21103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 21203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * Serializes this DataReceiver. 2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * This will cancel a receive if one is in progress. 2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @return {!Promise.<SerializedDataReceiver>} A promise that will resolve to 2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * the serialization of this DataReceiver. If this DataReceiver has shut 2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * down, the promise will resolve to null. 21803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DataReceiver.prototype.serialize = function() { 22003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (this.shutDown_) 2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return Promise.resolve(null); 2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 22303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.waiter_.stop(); 22403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (this.receive_) { 22503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.receive_.dispatchFatalError(this.fatalErrorValue_); 22603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.receive_ = null; 22703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci var serialized = new serialization.SerializedDataReceiver(); 2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci serialized.source = this.router_.connector_.handle_; 2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci serialized.data_pipe = this.receivePipe_; 2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci serialized.fatal_error_value = this.fatalErrorValue_; 2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci serialized.bytes_received = this.bytesReceived_; 2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci serialized.paused = this.paused_; 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci serialized.pending_error = this.pendingError_; 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.router_.connector_.handle_ = null; 2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.router_.close(); 2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.shutDown_ = true; 2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return Promise.resolve(serialized); 2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }; 2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** 2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * Deserializes a SerializedDataReceiver. 2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {SerializedDataReceiver} serialized The serialized DataReceiver. 2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @return {!DataReceiver} The deserialized DataReceiver. 2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci */ 2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DataReceiver.deserialize = function(serialized) { 2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci var receiver = $Object.create(DataReceiver.prototype); 2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci receiver.deserialize_(serialized); 2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return receiver; 2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci }; 2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** 2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * Deserializes a SerializedDataReceiver into this DataReceiver. 2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {SerializedDataReceiver} serialized The serialized DataReceiver. 2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @private 2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci */ 2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DataReceiver.prototype.deserialize_ = function(serialized) { 2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!serialized) { 2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.shutDown_ = true; 2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this.init_(serialized.source, 2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci serialized.data_pipe, 2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci serialized.fatal_error_value, 2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci serialized.bytes_received, 2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci serialized.pending_error, 2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci serialized.paused); 26803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }; 26903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 27003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 27103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * Receive data from the DataSource. 27203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @return {Promise.<ArrayBuffer>} A promise to the received data. If an error 27303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * occurs, the promise will reject with an Error object with a property 27403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * error containing the error code. 27503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @throws Will throw if this has encountered a fatal error or another receive 27603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * is in progress. 27703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 27803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DataReceiver.prototype.receive = function() { 27903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (this.shutDown_) 2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci throw new Error('DataReceiver has been closed'); 28103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (this.receive_) 28203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) throw new Error('Receive already in progress.'); 28303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) var receive = new PendingReceive(); 28403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) var promise = receive.getPromise(); 28503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (this.pendingError_ && 28603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) receive.dispatchError(this.pendingError_, this.bytesReceived_)) { 28703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.pendingError_ = null; 28803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.paused_ = true; 28903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return promise; 29003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 29103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (this.paused_) { 29203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.source_.resume(); 29303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.paused_ = false; 29403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 29503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.receive_ = receive; 29603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.waiter_.start(); 29703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return promise; 29803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }; 29903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 30003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * Invoked when 3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * |[receivePipe_]{@link module:data_receiver.DataReceiver#receivePipe_}| is 3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * ready to read. Reads from the data pipe if the wait is successful. 30403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {number} waitResult The result of the asynchronous wait. 30503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 30603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 30703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DataReceiver.prototype.onHandleReady_ = function(waitResult) { 30803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (waitResult != core.RESULT_OK || !this.receive_) { 30903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.close(); 31003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 31103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 31203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) var result = core.readData(this.receivePipe_, core.READ_DATA_FLAG_NONE); 31303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (result.result == core.RESULT_OK) { 31403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // TODO(sammc): Handle overflow in the same fashion as the C++ receiver. 31503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.bytesReceived_ += result.buffer.byteLength; 31603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.receive_.dispatchData(result.buffer); 31703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.receive_ = null; 31803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } else if (result.result == core.RESULT_SHOULD_WAIT) { 31903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.waiter_.start(); 32003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } else { 32103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.close(); 32203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 32303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }; 32403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 32503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) /** 32603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * Invoked by the DataSource when an error is encountered. 32703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {number} offset The location at which the error occurred. 32803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @param {number} error The error that occurred. 32903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) * @private 33003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) */ 33103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DataReceiver.prototype.onError = function(offset, error) { 33203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (this.shutDown_) 33303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 33403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci var pendingError = new serialization.PendingReceiveError(); 3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pendingError.error = error; 3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pendingError.offset = offset; 33803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (this.receive_ && 33903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.receive_.dispatchError(pendingError, this.bytesReceived_)) { 34003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.receive_ = null; 34103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.waiter_.stop(); 34203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.paused_ = true; 34303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 34403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 34503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) this.pendingError_ = pendingError; 34603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) }; 34703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 34803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return {DataReceiver: DataReceiver}; 34903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}); 350