OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 /** | |
6 * @constructor | |
7 * @implements {WebInspector.OutputStream} | |
8 * @param {!WebInspector.TimelineModel} model | |
9 * @param {!WebInspector.Progress} progress | |
10 * @param {function()=} canceledCallback | |
11 */ | |
12 WebInspector.TimelineLoader = function(model, progress, canceledCallback) | |
13 { | |
14 this._model = model; | |
15 | |
16 this._canceledCallback = canceledCallback; | |
17 this._progress = progress; | |
18 this._progress.setTitle(WebInspector.UIString("Loading")); | |
19 this._progress.setTotalWork(WebInspector.TimelineLoader._totalProgress); // Unknown, will loop the values. | |
20 | |
21 this._state = WebInspector.TimelineLoader.State.Initial; | |
22 this._buffer = ""; | |
23 this._firstChunk = true; | |
24 this._wasCanceledOnce = false; | |
25 | |
26 this._loadedBytes = 0; | |
27 this._jsonTokenizer = new WebInspector.TextUtils.BalancedJSONTokenizer(this. _writeBalancedJSON.bind(this), true); | |
28 } | |
29 | |
30 /** | |
31 * @param {!WebInspector.TimelineModel} model | |
32 * @param {!Blob} file | |
33 * @param {!WebInspector.Progress} progress | |
34 */ | |
35 WebInspector.TimelineLoader.loadFromFile = function(model, file, progress) | |
36 { | |
37 var delegate = new WebInspector.TimelineModelLoadFromFileDelegate(model, pro gress); | |
38 var fileReader = WebInspector.TimelineLoader._createFileReader(file, delegat e); | |
39 var loader = new WebInspector.TimelineLoader(model, new WebInspector.Progres sProxy(null), fileReader.cancel.bind(fileReader)); | |
40 fileReader.start(loader); | |
41 } | |
42 | |
43 /** | |
44 * @param {!WebInspector.TimelineModel} model | |
45 * @param {string} url | |
46 * @param {!WebInspector.Progress} progress | |
47 */ | |
48 WebInspector.TimelineLoader.loadFromURL = function(model, url, progress) | |
49 { | |
50 var stream = new WebInspector.TimelineLoader(model, progress); | |
51 WebInspector.ResourceLoader.loadAsStream(url, null, stream); | |
52 } | |
53 | |
54 WebInspector.TimelineLoader._createFileReader = function(file, delegate) | |
alph
2016/02/27 00:29:20
annotate plz
| |
55 { | |
56 return new WebInspector.ChunkedFileReader(file, WebInspector.TimelineModel.T ransferChunkLengthBytes, delegate); | |
57 } | |
58 | |
59 | |
60 WebInspector.TimelineLoader._totalProgress = 100000; | |
61 | |
62 WebInspector.TimelineLoader.State = { | |
63 Initial: "Initial", | |
alph
2016/02/27 00:29:20
symbols?
| |
64 LookingForEvents: "LookingForEvents", | |
65 ReadingEvents: "ReadingEvents" | |
66 } | |
67 | |
68 WebInspector.TimelineLoader.prototype = { | |
69 /** | |
70 * @override | |
71 * @param {string} chunk | |
72 */ | |
73 write: function(chunk) | |
74 { | |
75 this._loadedBytes += chunk.length; | |
76 if (this._progress.isCanceled() && !this._wasCanceledOnce) { | |
77 this._wasCanceled = true; | |
78 this._reportErrorAndCancelLoading(); | |
79 return; | |
80 } | |
81 this._progress.setWorked(this._loadedBytes % WebInspector.TimelineLoader ._totalProgress, | |
82 WebInspector.UIString("Loaded %s", Number.bytes ToString(this._loadedBytes))); | |
83 if (this._state === WebInspector.TimelineLoader.State.Initial) { | |
84 if (chunk[0] === "{") | |
85 this._state = WebInspector.TimelineLoader.State.LookingForEvents ; | |
86 else if (chunk[0] === "[") | |
87 this._state = WebInspector.TimelineLoader.State.ReadingEvents; | |
88 else { | |
89 this._reportErrorAndCancelLoading(WebInspector.UIString("Malform ed timeline data: Unknown JSON format")); | |
90 return; | |
91 } | |
92 } | |
93 | |
94 if (this._state === WebInspector.TimelineLoader.State.LookingForEvents) { | |
95 var objectName = "\"traceEvents\":"; | |
96 var startPos = this._buffer.length - objectName.length; | |
97 this._buffer += chunk; | |
98 var pos = this._buffer.indexOf(objectName, startPos); | |
99 if (pos === -1) | |
100 return; | |
101 chunk = this._buffer.slice(pos + objectName.length) | |
102 this._state = WebInspector.TimelineLoader.State.ReadingEvents; | |
103 } | |
104 | |
105 this._jsonTokenizer.write(chunk); | |
106 }, | |
107 | |
108 /** | |
109 * @param {string} data | |
110 */ | |
111 _writeBalancedJSON: function(data) | |
112 { | |
113 var json = data + "]"; | |
114 | |
115 if (this._firstChunk) { | |
116 this._model.startCollectingTraceEvents(true); | |
117 } else { | |
118 var commaIndex = json.indexOf(","); | |
119 if (commaIndex !== -1) | |
120 json = json.slice(commaIndex + 1); | |
121 json = "[" + json; | |
122 } | |
123 | |
124 var items; | |
125 try { | |
126 items = /** @type {!Array.<!WebInspector.TracingManager.EventPayload >} */ (JSON.parse(json)); | |
127 } catch (e) { | |
128 this._reportErrorAndCancelLoading(WebInspector.UIString("Malformed t imeline data: %s", e.toString())); | |
129 return; | |
130 } | |
131 | |
132 if (this._firstChunk) { | |
133 this._firstChunk = false; | |
134 if (this._looksLikeAppVersion(items[0])) { | |
135 this._reportErrorAndCancelLoading(WebInspector.UIString("Legacy Timeline format is not supported.")); | |
136 return; | |
137 } | |
138 } | |
139 | |
140 try { | |
141 this._model.traceEventsCollected(items); | |
142 } catch(e) { | |
143 this._reportErrorAndCancelLoading(WebInspector.UIString("Malformed t imeline data: %s", e.toString())); | |
144 return; | |
145 } | |
146 }, | |
147 | |
148 /** | |
149 * @param {string=} message | |
150 */ | |
151 _reportErrorAndCancelLoading: function(message) | |
152 { | |
153 if (message) | |
154 WebInspector.console.error(message); | |
155 this._model.tracingComplete(); | |
156 this._model.reset(); | |
157 if (this._canceledCallback) | |
158 this._canceledCallback(); | |
159 this._progress.done(); | |
160 }, | |
161 | |
162 _looksLikeAppVersion: function(item) | |
alph
2016/02/27 00:29:20
annotate
| |
163 { | |
164 return typeof item === "string" && item.indexOf("Chrome") !== -1; | |
165 }, | |
166 | |
167 /** | |
168 * @override | |
169 */ | |
170 close: function() | |
171 { | |
172 this._model._loadedFromFile = true; | |
173 this._model.tracingComplete(); | |
174 if (this._progress) | |
175 this._progress.done(); | |
176 } | |
177 } | |
178 | |
179 /** | |
180 * @constructor | |
181 * @implements {WebInspector.OutputStreamDelegate} | |
182 * @param {!WebInspector.TimelineModel} model | |
183 * @param {!WebInspector.Progress} progress | |
184 */ | |
185 WebInspector.TimelineModelLoadFromFileDelegate = function(model, progress) | |
186 { | |
187 this._model = model; | |
188 this._progress = progress; | |
189 } | |
190 | |
191 WebInspector.TimelineModelLoadFromFileDelegate.prototype = { | |
192 /** | |
193 * @override | |
194 */ | |
195 onTransferStarted: function() | |
196 { | |
197 this._progress.setTitle(WebInspector.UIString("Loading\u2026")); | |
198 }, | |
199 | |
200 /** | |
201 * @override | |
202 * @param {!WebInspector.ChunkedReader} reader | |
203 */ | |
204 onChunkTransferred: function(reader) | |
205 { | |
206 if (this._progress.isCanceled()) { | |
207 reader.cancel(); | |
208 this._progress.done(); | |
209 this._model.reset(); | |
210 return; | |
211 } | |
212 | |
213 var totalSize = reader.fileSize(); | |
214 if (totalSize) { | |
215 this._progress.setTotalWork(totalSize); | |
216 this._progress.setWorked(reader.loadedSize()); | |
217 } | |
218 }, | |
219 | |
220 /** | |
221 * @override | |
222 */ | |
223 onTransferFinished: function() | |
224 { | |
225 this._progress.done(); | |
226 }, | |
227 | |
228 /** | |
229 * @override | |
230 * @param {!WebInspector.ChunkedReader} reader | |
231 * @param {!Event} event | |
232 */ | |
233 onError: function(reader, event) | |
234 { | |
235 this._progress.done(); | |
236 this._model.reset(); | |
237 switch (event.target.error.code) { | |
238 case FileError.NOT_FOUND_ERR: | |
239 WebInspector.console.error(WebInspector.UIString("File \"%s\" not fo und.", reader.fileName())); | |
240 break; | |
241 case FileError.NOT_READABLE_ERR: | |
242 WebInspector.console.error(WebInspector.UIString("File \"%s\" is not readable", reader.fileName())); | |
243 break; | |
244 case FileError.ABORT_ERR: | |
245 break; | |
246 default: | |
247 WebInspector.console.error(WebInspector.UIString("An error occurred while reading the file \"%s\"", reader.fileName())); | |
248 } | |
249 } | |
250 } | |
251 | |
252 /** | |
253 * @constructor | |
254 * @param {!WebInspector.OutputStream} stream | |
255 * @implements {WebInspector.OutputStreamDelegate} | |
256 */ | |
257 WebInspector.TracingTimelineSaver = function(stream) | |
258 { | |
259 this._stream = stream; | |
260 } | |
261 | |
262 WebInspector.TracingTimelineSaver.prototype = { | |
263 /** | |
264 * @override | |
265 */ | |
266 onTransferStarted: function() | |
267 { | |
268 this._stream.write("["); | |
269 }, | |
270 | |
271 /** | |
272 * @override | |
273 */ | |
274 onTransferFinished: function() | |
275 { | |
276 this._stream.write("]"); | |
277 }, | |
278 | |
279 /** | |
280 * @override | |
281 * @param {!WebInspector.ChunkedReader} reader | |
282 */ | |
283 onChunkTransferred: function(reader) { }, | |
284 | |
285 /** | |
286 * @override | |
287 * @param {!WebInspector.ChunkedReader} reader | |
288 * @param {!Event} event | |
289 */ | |
290 onError: function(reader, event) { } | |
291 } | |
OLD | NEW |