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 |