Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 define('data_receiver', [ | 5 define('data_receiver', [ |
| 6 'async_waiter', | 6 'async_waiter', |
| 7 'device/serial/data_stream.mojom', | 7 'device/serial/data_stream.mojom', |
| 8 'device/serial/data_stream_serialization.mojom', | |
| 8 'mojo/public/js/bindings/core', | 9 'mojo/public/js/bindings/core', |
| 9 'mojo/public/js/bindings/router', | 10 'mojo/public/js/bindings/router', |
| 10 ], function(asyncWaiter, dataStream, core, router) { | 11 ], function(asyncWaiter, dataStream, serialization, core, router) { |
| 11 /** | 12 /** |
| 12 * @module data_receiver | 13 * @module data_receiver |
| 13 */ | 14 */ |
| 14 | 15 |
| 15 /** | 16 /** |
| 16 * @typedef module:data_receiver~PendingError | |
| 17 * @type {Object} | |
| 18 * @property {number} error - the error | |
| 19 * @property {number} offset - the location of the error | |
| 20 * @private | |
| 21 */ | |
| 22 | |
| 23 /** | |
| 24 * A pending receive operation. | 17 * A pending receive operation. |
| 25 * @constructor | 18 * @constructor |
| 26 * @alias module:data_receiver~PendingReceive | 19 * @alias module:data_receiver~PendingReceive |
| 27 * @private | 20 * @private |
| 28 */ | 21 */ |
| 29 function PendingReceive() { | 22 function PendingReceive() { |
| 30 /** | 23 /** |
| 31 * The promise that will be resolved or rejected when this receive completes | 24 * The promise that will be resolved or rejected when this receive completes |
| 32 * or fails, respectively. | 25 * or fails, respectively. |
| 33 * @type {Promise.<ArrayBuffer>} | 26 * @type {Promise.<ArrayBuffer>} |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 62 * Dispatches received data to the promise returned by | 55 * Dispatches received data to the promise returned by |
| 63 * [getPromise]{@link module:data_receiver.PendingReceive#getPromise}. | 56 * [getPromise]{@link module:data_receiver.PendingReceive#getPromise}. |
| 64 * @param {ArrayBuffer} data The data to dispatch. | 57 * @param {ArrayBuffer} data The data to dispatch. |
| 65 */ | 58 */ |
| 66 PendingReceive.prototype.dispatchData = function(data) { | 59 PendingReceive.prototype.dispatchData = function(data) { |
| 67 this.dataCallback_(data); | 60 this.dataCallback_(data); |
| 68 }; | 61 }; |
| 69 | 62 |
| 70 /** | 63 /** |
| 71 * Dispatches an error if the offset of the error has been reached. | 64 * Dispatches an error if the offset of the error has been reached. |
| 72 * @param {module:data_receiver~PendingError} error The error to dispatch. | 65 * @param {module:device/serial/data_stream_serialization~PendingReceiveError} |
| 66 * error The error to dispatch. | |
| 73 * @param {number} bytesReceived The number of bytes that have been received. | 67 * @param {number} bytesReceived The number of bytes that have been received. |
| 74 */ | 68 */ |
| 75 PendingReceive.prototype.dispatchError = function(error, bytesReceived) { | 69 PendingReceive.prototype.dispatchError = function(error, bytesReceived) { |
| 76 if (bytesReceived != error.offset) | 70 if (bytesReceived != error.offset) |
| 77 return false; | 71 return false; |
| 78 | 72 |
| 79 var e = new Error(); | 73 var e = new Error(); |
| 80 e.error = error.error; | 74 e.error = error.error; |
| 81 this.errorCallback_(e); | 75 this.errorCallback_(e); |
| 82 return true; | 76 return true; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 95 /** | 89 /** |
| 96 * A DataReceiver that receives data from a DataSource. | 90 * A DataReceiver that receives data from a DataSource. |
| 97 * @param {MojoHandle} handle The handle to the DataSource. | 91 * @param {MojoHandle} handle The handle to the DataSource. |
| 98 * @param {number} bufferSize How large a buffer the data pipe should use. | 92 * @param {number} bufferSize How large a buffer the data pipe should use. |
| 99 * @param {number} fatalErrorValue The receive error value to report in the | 93 * @param {number} fatalErrorValue The receive error value to report in the |
| 100 * event of a fatal error. | 94 * event of a fatal error. |
| 101 * @constructor | 95 * @constructor |
| 102 * @alias module:data_receiver.DataReceiver | 96 * @alias module:data_receiver.DataReceiver |
| 103 */ | 97 */ |
| 104 function DataReceiver(handle, bufferSize, fatalErrorValue) { | 98 function DataReceiver(handle, bufferSize, fatalErrorValue) { |
| 99 var dataPipeOptions = { | |
| 100 flags: core.CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, | |
| 101 elementNumBytes: 1, | |
| 102 capacityNumBytes: bufferSize, | |
| 103 }; | |
| 104 var receivePipe = core.createDataPipe(dataPipeOptions); | |
| 105 this.init_( | |
| 106 handle, receivePipe.consumerHandle, fatalErrorValue, 0, null, false); | |
| 107 this.source_.init(receivePipe.producerHandle); | |
| 108 } | |
| 109 | |
| 110 DataReceiver.prototype = | |
| 111 $Object.create(dataStream.DataSourceClientStub.prototype); | |
| 112 | |
| 113 /** | |
| 114 * Closes this DataReceiver. | |
| 115 */ | |
| 116 DataReceiver.prototype.close = function() { | |
| 117 if (this.shutDown_) | |
| 118 return; | |
| 119 this.shutDown_ = true; | |
| 120 this.router_.close(); | |
| 121 this.waiter_.stop(); | |
| 122 core.close(this.receivePipe_); | |
| 123 if (this.receive_) { | |
| 124 this.receive_.dispatchFatalError(this.fatalErrorValue_); | |
| 125 this.receive_ = null; | |
| 126 } | |
| 127 }; | |
| 128 | |
| 129 /** | |
| 130 * Initialize this DataReceiver. | |
| 131 * @param {MojoHandle} source A handle to the DataSource | |
| 132 * @param {MojoHandle} dataPipe A handle to use for receiving data from the | |
| 133 * DataSource. | |
| 134 * @param {number} fatalErrorValue The error to dispatch in the event of a | |
| 135 * fatal error. | |
| 136 * @param {number} bytesReceived The number of bytes already received. | |
| 137 * @param | |
| 138 * {module:device/serial/data_stream_serialization~PendingReceiveError?} | |
| 139 * pendingError The pending error if there is one. | |
| 140 * @param {boolean} paused Whether the DataSource is paused. | |
| 141 * @private | |
| 142 */ | |
| 143 DataReceiver.prototype.init_ = function( | |
| 144 source, dataPipe, fatalErrorValue, bytesReceived, pendingError, paused) { | |
|
raymes
2014/09/23 03:20:57
Is this valid JS style? In C++ we would put 1 arg
Sam McNally
2014/09/23 03:47:24
Not sure - clang format is happy with it, but I th
Ken Rockot(use gerrit already)
2014/09/24 16:08:02
Either one is fine for Google JS style. See the fi
| |
| 105 /** | 145 /** |
| 106 * The [Router]{@link module:mojo/public/js/bindings/router.Router} for the | 146 * The [Router]{@link module:mojo/public/js/bindings/router.Router} for the |
| 107 * connection to the DataSource. | 147 * connection to the DataSource. |
| 108 * @private | 148 * @private |
| 109 */ | 149 */ |
| 110 this.router_ = new router.Router(handle); | 150 this.router_ = new router.Router(source); |
| 111 /** | 151 /** |
| 112 * The connection to the DataSource. | 152 * The connection to the DataSource. |
| 113 * @private | 153 * @private |
| 114 */ | 154 */ |
| 115 this.source_ = new dataStream.DataSourceProxy(this.router_); | 155 this.source_ = new dataStream.DataSourceProxy(this.router_); |
| 116 this.router_.setIncomingReceiver(this); | 156 this.router_.setIncomingReceiver(this); |
| 117 var dataPipeOptions = { | |
| 118 flags: core.CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, | |
| 119 elementNumBytes: 1, | |
| 120 capacityNumBytes: bufferSize, | |
| 121 }; | |
| 122 var receivePipe = core.createDataPipe(dataPipeOptions); | |
| 123 this.source_.init(receivePipe.producerHandle); | |
| 124 /** | 157 /** |
| 125 * The handle to the data pipe to use for receiving data. | 158 * The handle to the data pipe to use for receiving data. |
| 126 * @private | 159 * @private |
| 127 */ | 160 */ |
| 128 this.receivePipe_ = receivePipe.consumerHandle; | 161 this.receivePipe_ = dataPipe; |
| 129 /** | 162 /** |
| 130 * The current receive operation. | 163 * The current receive operation. |
| 131 * @type {module:data_receiver~PendingReceive} | 164 * @type {module:data_receiver~PendingReceive} |
| 132 * @private | 165 * @private |
| 133 */ | 166 */ |
| 134 this.receive_ = null; | 167 this.receive_ = null; |
| 135 /** | 168 /** |
| 136 * The error to be dispatched in the event of a fatal error. | 169 * The error to be dispatched in the event of a fatal error. |
| 137 * @type {number} | 170 * @type {number} |
| 138 * @private | 171 * @private |
| 139 */ | 172 */ |
| 140 this.fatalErrorValue_ = fatalErrorValue; | 173 this.fatalErrorValue_ = fatalErrorValue; |
| 141 /** | 174 /** |
| 142 * The async waiter used to wait for | 175 * The async waiter used to wait for |
| 143 * {@link module:data_receiver.DataReceiver#receivePipe_} to be readable. | 176 * {@link module:data_receiver.DataReceiver#receivePipe_} to be readable. |
| 144 * @type module:async_waiter.AsyncWaiter | 177 * @type module:async_waiter.AsyncWaiter |
| 145 * @private | 178 * @private |
| 146 */ | 179 */ |
| 147 this.waiter_ = new asyncWaiter.AsyncWaiter(this.receivePipe_, | 180 this.waiter_ = new asyncWaiter.AsyncWaiter(this.receivePipe_, |
| 148 core.HANDLE_SIGNAL_READABLE, | 181 core.HANDLE_SIGNAL_READABLE, |
| 149 this.onHandleReady_.bind(this)); | 182 this.onHandleReady_.bind(this)); |
| 150 /** | 183 /** |
| 151 * The number of bytes received from the DataSource. | 184 * The number of bytes received from the DataSource. |
| 152 * @type {number} | 185 * @type {number} |
| 153 * @private | 186 * @private |
| 154 */ | 187 */ |
| 155 this.bytesReceived_ = 0; | 188 this.bytesReceived_ = bytesReceived; |
| 156 /** | 189 /** |
| 157 * The pending error if there is one. | 190 * The pending error if there is one. |
| 158 * @type module:data_receiver~PendingError | 191 * @type module:device/serial/data_stream_serialization~PendingReceiveError |
| 159 * @private | 192 * @private |
| 160 */ | 193 */ |
| 161 this.pendingError_ = null; | 194 this.pendingError_ = pendingError; |
| 162 /** | 195 /** |
| 163 * Whether the DataSource is paused. | 196 * Whether the DataSource is paused. |
| 164 * @type {boolean} | 197 * @type {boolean} |
| 165 * @private | 198 * @private |
| 166 */ | 199 */ |
| 167 this.paused_ = false; | 200 this.paused_ = paused; |
| 168 /** | 201 /** |
| 169 * Whether this DataReceiver has shut down. | 202 * Whether this DataReceiver has shut down. |
| 170 * @type {boolean} | 203 * @type {boolean} |
| 171 * @private | 204 * @private |
| 172 */ | 205 */ |
| 173 this.shutDown_ = false; | 206 this.shutDown_ = false; |
| 174 } | 207 }; |
| 175 | |
| 176 DataReceiver.prototype = | |
| 177 $Object.create(dataStream.DataSourceClientStub.prototype); | |
| 178 | 208 |
| 179 /** | 209 /** |
| 180 * Closes this DataReceiver. | 210 * Serializes this DataReceiver. |
| 211 * This will cancel a receive if one is in progress. | |
| 212 * @return {Promise.<?SerializedDataReceiver>} A promise that will resolve to | |
| 213 * the serialization of this DataReceiver. If this DataReceiver has shut | |
| 214 * down, the promise will resolve to null. | |
| 181 */ | 215 */ |
| 182 DataReceiver.prototype.close = function() { | 216 DataReceiver.prototype.serialize = function() { |
| 183 if (this.shutDown_) | 217 if (this.shutDown_) |
| 184 return; | 218 return Promise.resolve(null); |
| 185 this.shutDown_ = true; | 219 |
| 186 this.router_.close(); | |
| 187 this.waiter_.stop(); | 220 this.waiter_.stop(); |
| 188 core.close(this.receivePipe_); | |
| 189 if (this.receive_) { | 221 if (this.receive_) { |
| 190 this.receive_.dispatchFatalError(this.fatalErrorValue_); | 222 this.receive_.dispatchFatalError(this.fatalErrorValue_); |
| 191 this.receive_ = null; | 223 this.receive_ = null; |
| 192 } | 224 } |
| 225 var serialized = new serialization.SerializedDataReceiver(); | |
| 226 serialized.source = this.router_.connector_.handle_; | |
| 227 serialized.data_pipe = this.receivePipe_; | |
| 228 serialized.fatal_error_value = this.fatalErrorValue_; | |
| 229 serialized.bytes_received = this.bytesReceived_; | |
| 230 serialized.paused = this.paused_; | |
| 231 serialized.pending_error = this.pendingError_; | |
| 232 this.router_.connector_.handle_ = null; | |
| 233 this.router_.close(); | |
| 234 this.shutDown_ = true; | |
| 235 return Promise.resolve(serialized); | |
| 193 }; | 236 }; |
| 194 | 237 |
| 195 /** | 238 /** |
| 239 * Deserializes a SerializedDataReceiver. | |
| 240 * @param {?SerializedDataReceiver} serialized The serialized DataReceiver. | |
| 241 * @return {DataReceiver} The deserialized DataReceiver. | |
| 242 */ | |
| 243 DataReceiver.deserialize = function(serialized) { | |
| 244 var receiver = $Object.create(DataReceiver.prototype); | |
| 245 receiver.deserialize_(serialized); | |
| 246 return receiver; | |
| 247 }; | |
| 248 | |
| 249 /** | |
| 250 * Deserializes a SerializedDataReceiver into this DataReceiver. | |
| 251 * @param {?SerializedDataReceiver} serialized The serialized DataReceiver. | |
| 252 * @private | |
| 253 */ | |
| 254 DataReceiver.prototype.deserialize_ = function(serialized) { | |
| 255 if (!serialized) { | |
| 256 this.shutDown_ = true; | |
| 257 return; | |
| 258 } | |
| 259 this.init_(serialized.source, | |
| 260 serialized.data_pipe, | |
| 261 serialized.fatal_error_value, | |
| 262 serialized.bytes_received, | |
| 263 serialized.pending_error, | |
| 264 serialized.paused); | |
| 265 }; | |
| 266 | |
| 267 /** | |
| 196 * Receive data from the DataSource. | 268 * Receive data from the DataSource. |
| 197 * @return {Promise.<ArrayBuffer>} A promise to the received data. If an error | 269 * @return {Promise.<ArrayBuffer>} A promise to the received data. If an error |
| 198 * occurs, the promise will reject with an Error object with a property | 270 * occurs, the promise will reject with an Error object with a property |
| 199 * error containing the error code. | 271 * error containing the error code. |
| 200 * @throws Will throw if this has encountered a fatal error or another receive | 272 * @throws Will throw if this has encountered a fatal error or another receive |
| 201 * is in progress. | 273 * is in progress. |
| 202 */ | 274 */ |
| 203 DataReceiver.prototype.receive = function() { | 275 DataReceiver.prototype.receive = function() { |
| 204 if (this.shutDown_) | 276 if (this.shutDown_) |
| 205 throw new Error('System error'); | 277 throw new Error('DataReceiver has been closed'); |
| 206 if (this.receive_) | 278 if (this.receive_) |
| 207 throw new Error('Receive already in progress.'); | 279 throw new Error('Receive already in progress.'); |
| 208 var receive = new PendingReceive(); | 280 var receive = new PendingReceive(); |
| 209 var promise = receive.getPromise(); | 281 var promise = receive.getPromise(); |
| 210 if (this.pendingError_ && | 282 if (this.pendingError_ && |
| 211 receive.dispatchError(this.pendingError_, this.bytesReceived_)) { | 283 receive.dispatchError(this.pendingError_, this.bytesReceived_)) { |
| 212 this.pendingError_ = null; | 284 this.pendingError_ = null; |
| 213 this.paused_ = true; | 285 this.paused_ = true; |
| 214 return promise; | 286 return promise; |
| 215 } | 287 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 249 /** | 321 /** |
| 250 * Invoked by the DataSource when an error is encountered. | 322 * Invoked by the DataSource when an error is encountered. |
| 251 * @param {number} offset The location at which the error occurred. | 323 * @param {number} offset The location at which the error occurred. |
| 252 * @param {number} error The error that occurred. | 324 * @param {number} error The error that occurred. |
| 253 * @private | 325 * @private |
| 254 */ | 326 */ |
| 255 DataReceiver.prototype.onError = function(offset, error) { | 327 DataReceiver.prototype.onError = function(offset, error) { |
| 256 if (this.shutDown_) | 328 if (this.shutDown_) |
| 257 return; | 329 return; |
| 258 | 330 |
| 259 /** | 331 var pendingError = new serialization.PendingReceiveError(); |
| 260 * @type module:data_receiver~PendingError | 332 pendingError.error = error; |
| 261 */ | 333 pendingError.offset = offset; |
| 262 var pendingError = { | |
| 263 error: error, | |
| 264 offset: offset, | |
| 265 }; | |
| 266 if (this.receive_ && | 334 if (this.receive_ && |
| 267 this.receive_.dispatchError(pendingError, this.bytesReceived_)) { | 335 this.receive_.dispatchError(pendingError, this.bytesReceived_)) { |
| 268 this.receive_ = null; | 336 this.receive_ = null; |
| 269 this.waiter_.stop(); | 337 this.waiter_.stop(); |
| 270 this.paused_ = true; | 338 this.paused_ = true; |
| 271 return; | 339 return; |
| 272 } | 340 } |
| 273 this.pendingError_ = pendingError; | 341 this.pendingError_ = pendingError; |
| 274 }; | 342 }; |
| 275 | 343 |
| 276 return {DataReceiver: DataReceiver}; | 344 return {DataReceiver: DataReceiver}; |
| 277 }); | 345 }); |
| OLD | NEW |