Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 * @implements {Common.OutputStream} | 5 * @implements {Common.OutputStream} |
| 6 * @implements {Bindings.OutputStreamDelegate} | 6 * @implements {Bindings.OutputStreamDelegate} |
| 7 * @unrestricted | 7 * @unrestricted |
| 8 */ | 8 */ |
| 9 Timeline.TimelineLoader = class { | 9 Timeline.TimelineLoader = class { |
| 10 /** | 10 /** |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 72 } | 72 } |
| 73 | 73 |
| 74 /** | 74 /** |
| 75 * @override | 75 * @override |
| 76 * @param {string} chunk | 76 * @param {string} chunk |
| 77 */ | 77 */ |
| 78 write(chunk) { | 78 write(chunk) { |
| 79 if (!this._client) | 79 if (!this._client) |
| 80 return; | 80 return; |
| 81 this._loadedBytes += chunk.length; | 81 this._loadedBytes += chunk.length; |
| 82 if (!this._firstChunk) | 82 if (this._firstChunk) |
| 83 this._client.loadingStarted(); | |
| 84 else | |
| 83 this._client.loadingProgress(this._totalSize ? this._loadedBytes / this._t otalSize : undefined); | 85 this._client.loadingProgress(this._totalSize ? this._loadedBytes / this._t otalSize : undefined); |
| 84 | 86 |
| 85 if (this._state === Timeline.TimelineLoader.State.Initial) { | 87 if (this._state === Timeline.TimelineLoader.State.Initial) { |
| 86 if (chunk[0] === '{') { | 88 if (chunk.startsWith('{"nodes":[')) { |
| 89 this._state = Timeline.TimelineLoader.State.LoadingCPUProfileFormat; | |
| 90 } else if (chunk[0] === '{') { | |
| 87 this._state = Timeline.TimelineLoader.State.LookingForEvents; | 91 this._state = Timeline.TimelineLoader.State.LookingForEvents; |
| 88 } else if (chunk[0] === '[') { | 92 } else if (chunk[0] === '[') { |
| 89 this._state = Timeline.TimelineLoader.State.ReadingEvents; | 93 this._state = Timeline.TimelineLoader.State.ReadingEvents; |
| 90 } else { | 94 } else { |
| 91 this._reportErrorAndCancelLoading(Common.UIString('Malformed timeline da ta: Unknown JSON format')); | 95 this._reportErrorAndCancelLoading(Common.UIString('Malformed timeline da ta: Unknown JSON format')); |
| 92 return; | 96 return; |
| 93 } | 97 } |
| 94 } | 98 } |
| 95 | 99 |
| 100 if (this._state === Timeline.TimelineLoader.State.LoadingCPUProfileFormat) { | |
| 101 this._buffer += chunk; | |
| 102 return; | |
| 103 } | |
| 104 | |
| 96 if (this._state === Timeline.TimelineLoader.State.LookingForEvents) { | 105 if (this._state === Timeline.TimelineLoader.State.LookingForEvents) { |
| 97 var objectName = '"traceEvents":'; | 106 var objectName = '"traceEvents":'; |
| 98 var startPos = this._buffer.length - objectName.length; | 107 var startPos = this._buffer.length - objectName.length; |
| 99 this._buffer += chunk; | 108 this._buffer += chunk; |
| 100 var pos = this._buffer.indexOf(objectName, startPos); | 109 var pos = this._buffer.indexOf(objectName, startPos); |
| 101 if (pos === -1) | 110 if (pos === -1) |
| 102 return; | 111 return; |
| 103 chunk = this._buffer.slice(pos + objectName.length); | 112 chunk = this._buffer.slice(pos + objectName.length); |
| 104 this._state = Timeline.TimelineLoader.State.ReadingEvents; | 113 this._state = Timeline.TimelineLoader.State.ReadingEvents; |
| 105 } | 114 } |
| 106 | 115 |
| 107 if (this._state !== Timeline.TimelineLoader.State.ReadingEvents) | 116 if (this._state !== Timeline.TimelineLoader.State.ReadingEvents) |
| 108 return; | 117 return; |
| 109 if (this._jsonTokenizer.write(chunk)) | 118 if (this._jsonTokenizer.write(chunk)) |
| 110 return; | 119 return; |
| 111 this._state = Timeline.TimelineLoader.State.SkippingTail; | 120 this._state = Timeline.TimelineLoader.State.SkippingTail; |
| 112 if (this._firstChunk) { | 121 if (this._firstChunk) { |
| 113 this._reportErrorAndCancelLoading(Common.UIString('Malformed timeline inpu t, wrong JSON brackets balance')); | 122 this._reportErrorAndCancelLoading(Common.UIString('Malformed timeline inpu t, wrong JSON brackets balance')); |
| 114 return; | 123 return; |
| 115 } | 124 } |
| 116 } | 125 } |
| 117 | 126 |
| 118 /** | 127 /** |
| 119 * @param {string} data | 128 * @param {string} data |
| 120 */ | 129 */ |
| 121 _writeBalancedJSON(data) { | 130 _writeBalancedJSON(data) { |
| 122 var json = data + ']'; | 131 var json = data + ']'; |
| 123 | 132 |
| 124 if (this._firstChunk) { | 133 if (!this._firstChunk) { |
| 125 this._client.loadingStarted(); | |
| 126 } else { | |
| 127 var commaIndex = json.indexOf(','); | 134 var commaIndex = json.indexOf(','); |
| 128 if (commaIndex !== -1) | 135 if (commaIndex !== -1) |
| 129 json = json.slice(commaIndex + 1); | 136 json = json.slice(commaIndex + 1); |
| 130 json = '[' + json; | 137 json = '[' + json; |
| 131 } | 138 } |
| 132 | 139 |
| 133 var items; | 140 var items; |
| 134 try { | 141 try { |
| 135 items = /** @type {!Array.<!SDK.TracingManager.EventPayload>} */ (JSON.par se(json)); | 142 items = /** @type {!Array.<!SDK.TracingManager.EventPayload>} */ (JSON.par se(json)); |
| 136 } catch (e) { | 143 } catch (e) { |
| 137 this._reportErrorAndCancelLoading(Common.UIString('Malformed timeline data : %s', e.toString())); | 144 this._reportErrorAndCancelLoading(Common.UIString('Malformed timeline data : %s', e.toString())); |
| 138 return; | 145 return; |
| 139 } | 146 } |
| 140 | 147 |
| 141 if (this._firstChunk) { | 148 if (this._firstChunk) { |
| 142 this._firstChunk = false; | 149 this._firstChunk = false; |
| 143 if (this._looksLikeAppVersion(items[0])) { | 150 if (this._looksLikeAppVersion(items[0])) { |
| 144 this._reportErrorAndCancelLoading(Common.UIString('Legacy Timeline forma t is not supported.')); | 151 this._reportErrorAndCancelLoading(Common.UIString('Legacy Timeline forma t is not supported.')); |
| 145 return; | 152 return; |
| 146 } | 153 } |
| 147 } | 154 } |
| 148 | 155 |
| 149 try { | 156 try { |
| 150 this._tracingModel.addEvents(items); | 157 this._tracingModel.addEvents(items); |
| 151 } catch (e) { | 158 } catch (e) { |
| 152 this._reportErrorAndCancelLoading(Common.UIString('Malformed timeline data : %s', e.toString())); | 159 this._reportErrorAndCancelLoading(Common.UIString('Malformed timeline data : %s', e.toString())); |
| 153 return; | |
| 154 } | 160 } |
| 155 } | 161 } |
| 156 | 162 |
| 157 /** | 163 /** |
| 158 * @param {string=} message | 164 * @param {string=} message |
| 159 */ | 165 */ |
| 160 _reportErrorAndCancelLoading(message) { | 166 _reportErrorAndCancelLoading(message) { |
| 161 if (message) | 167 if (message) |
| 162 Common.console.error(message); | 168 Common.console.error(message); |
| 163 this.cancel(); | 169 this.cancel(); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 175 * @override | 181 * @override |
| 176 */ | 182 */ |
| 177 close() { | 183 close() { |
| 178 if (!this._client) | 184 if (!this._client) |
| 179 return; | 185 return; |
| 180 this._client.processingStarted(); | 186 this._client.processingStarted(); |
| 181 setTimeout(() => this._finalizeTrace(), 0); | 187 setTimeout(() => this._finalizeTrace(), 0); |
| 182 } | 188 } |
| 183 | 189 |
| 184 _finalizeTrace() { | 190 _finalizeTrace() { |
| 191 if (this._state === Timeline.TimelineLoader.State.LoadingCPUProfileFormat) { | |
| 192 this._parseCPUProfileFormat(this._buffer); | |
| 193 this._buffer = ''; | |
| 194 } | |
| 185 this._tracingModel.tracingComplete(); | 195 this._tracingModel.tracingComplete(); |
| 186 this._client.loadingComplete(this._tracingModel, this._backingStorage); | 196 this._client.loadingComplete(this._tracingModel, this._backingStorage); |
| 187 } | 197 } |
| 188 | 198 |
| 189 /** | 199 /** |
| 190 * @override | 200 * @override |
| 191 */ | 201 */ |
| 192 onTransferStarted() { | 202 onTransferStarted() { |
| 193 } | 203 } |
| 194 | 204 |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 218 case 'NotReadableError': | 228 case 'NotReadableError': |
| 219 this._reportErrorAndCancelLoading(Common.UIString('File "%s" is not read able', reader.fileName())); | 229 this._reportErrorAndCancelLoading(Common.UIString('File "%s" is not read able', reader.fileName())); |
| 220 break; | 230 break; |
| 221 case 'AbortError': | 231 case 'AbortError': |
| 222 break; | 232 break; |
| 223 default: | 233 default: |
| 224 this._reportErrorAndCancelLoading( | 234 this._reportErrorAndCancelLoading( |
| 225 Common.UIString('An error occurred while reading the file "%s"', rea der.fileName())); | 235 Common.UIString('An error occurred while reading the file "%s"', rea der.fileName())); |
| 226 } | 236 } |
| 227 } | 237 } |
| 238 | |
| 239 /** | |
| 240 * @param {string} text | |
| 241 */ | |
| 242 _parseCPUProfileFormat(text) { | |
| 243 try { | |
| 244 var profile = JSON.parse(text); | |
| 245 var traceEvents = TimelineModel.TimelineJSProfileProcessor.buildTraceProfi leFromCpuProfile(profile); | |
| 246 this._tracingModel.addEvents(traceEvents); | |
|
caseq
2017/03/02 21:27:05
this one could be out of try {}
alph
2017/03/02 22:17:25
Done.
| |
| 247 } catch (e) { | |
| 248 this._reportErrorAndCancelLoading(Common.UIString('Malformed CPU profile f ormat')); | |
| 249 } | |
| 250 } | |
| 228 }; | 251 }; |
| 229 | 252 |
| 230 | 253 |
| 231 Timeline.TimelineLoader.TransferChunkLengthBytes = 5000000; | 254 Timeline.TimelineLoader.TransferChunkLengthBytes = 5000000; |
| 232 | 255 |
| 233 /** | 256 /** |
| 234 * @interface | 257 * @interface |
| 235 */ | 258 */ |
| 236 Timeline.TimelineLoader.Client = function() {}; | 259 Timeline.TimelineLoader.Client = function() {}; |
| 237 | 260 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 252 loadingComplete(tracingModel, backingStorage) {}, | 275 loadingComplete(tracingModel, backingStorage) {}, |
| 253 }; | 276 }; |
| 254 | 277 |
| 255 /** | 278 /** |
| 256 * @enum {symbol} | 279 * @enum {symbol} |
| 257 */ | 280 */ |
| 258 Timeline.TimelineLoader.State = { | 281 Timeline.TimelineLoader.State = { |
| 259 Initial: Symbol('Initial'), | 282 Initial: Symbol('Initial'), |
| 260 LookingForEvents: Symbol('LookingForEvents'), | 283 LookingForEvents: Symbol('LookingForEvents'), |
| 261 ReadingEvents: Symbol('ReadingEvents'), | 284 ReadingEvents: Symbol('ReadingEvents'), |
| 262 SkippingTail: Symbol('SkippingTail') | 285 SkippingTail: Symbol('SkippingTail'), |
| 286 LoadingCPUProfileFormat: Symbol('LoadingCPUProfileFormat') | |
| 263 }; | 287 }; |
| 264 | 288 |
| 265 /** | 289 /** |
| 266 * @implements {Bindings.OutputStreamDelegate} | 290 * @implements {Bindings.OutputStreamDelegate} |
| 267 * @unrestricted | 291 * @unrestricted |
| 268 */ | 292 */ |
| 269 Timeline.TracingTimelineSaver = class { | 293 Timeline.TracingTimelineSaver = class { |
| 270 /** | 294 /** |
| 271 * @override | 295 * @override |
| 272 */ | 296 */ |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 290 * @override | 314 * @override |
| 291 * @param {!Bindings.ChunkedReader} reader | 315 * @param {!Bindings.ChunkedReader} reader |
| 292 * @param {!Event} event | 316 * @param {!Event} event |
| 293 */ | 317 */ |
| 294 onError(reader, event) { | 318 onError(reader, event) { |
| 295 var error = event.target.error; | 319 var error = event.target.error; |
| 296 Common.console.error( | 320 Common.console.error( |
| 297 Common.UIString('Failed to save timeline: %s (%s, %s)', error.message, e rror.name, error.code)); | 321 Common.UIString('Failed to save timeline: %s (%s, %s)', error.message, e rror.name, error.code)); |
| 298 } | 322 } |
| 299 }; | 323 }; |
| OLD | NEW |