OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | |
3 * | |
4 * Redistribution and use in source and binary forms, with or without | |
5 * modification, are permitted provided that the following conditions are | |
6 * met: | |
7 * | |
8 * * Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * * Redistributions in binary form must reproduce the above | |
11 * copyright notice, this list of conditions and the following disclaimer | |
12 * in the documentation and/or other materials provided with the | |
13 * distribution. | |
14 * * Neither the name of Google Inc. nor the names of its | |
15 * contributors may be used to endorse or promote products derived from | |
16 * this software without specific prior written permission. | |
17 * | |
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
29 */ | |
30 | |
31 window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileS
ystem; | |
32 | |
33 /** | |
34 * @constructor | |
35 * @param {!string} dirPath | |
36 * @param {!string} name | |
37 * @param {!function(?WebInspector.TempFile)} callback | |
38 */ | |
39 WebInspector.TempFile = function(dirPath, name, callback) | |
40 { | |
41 this._fileEntry = null; | |
42 this._writer = null; | |
43 | |
44 /** | |
45 * @param {!FileSystem} fs | |
46 * @this {WebInspector.TempFile} | |
47 */ | |
48 function didInitFs(fs) | |
49 { | |
50 fs.root.getDirectory(dirPath, { create: true }, didGetDir.bind(this), er
rorHandler); | |
51 } | |
52 | |
53 /** | |
54 * @param {!DirectoryEntry} dir | |
55 * @this {WebInspector.TempFile} | |
56 */ | |
57 function didGetDir(dir) | |
58 { | |
59 dir.getFile(name, { create: true }, didCreateFile.bind(this), errorHandl
er); | |
60 } | |
61 | |
62 /** | |
63 * @param {!FileEntry} fileEntry | |
64 * @this {WebInspector.TempFile} | |
65 */ | |
66 function didCreateFile(fileEntry) | |
67 { | |
68 this._fileEntry = fileEntry; | |
69 fileEntry.createWriter(didCreateWriter.bind(this), errorHandler); | |
70 } | |
71 | |
72 /** | |
73 * @param {!FileWriter} writer | |
74 * @this {WebInspector.TempFile} | |
75 */ | |
76 function didCreateWriter(writer) | |
77 { | |
78 /** | |
79 * @this {WebInspector.TempFile} | |
80 */ | |
81 function didTruncate(e) | |
82 { | |
83 this._writer = writer; | |
84 writer.onwrite = null; | |
85 writer.onerror = null; | |
86 callback(this); | |
87 } | |
88 | |
89 function onTruncateError(e) | |
90 { | |
91 WebInspector.console.error("Failed to truncate temp file " + e.code
+ " : " + e.message); | |
92 callback(null); | |
93 } | |
94 | |
95 if (writer.length) { | |
96 writer.onwrite = didTruncate.bind(this); | |
97 writer.onerror = onTruncateError; | |
98 writer.truncate(0); | |
99 } else { | |
100 this._writer = writer; | |
101 callback(this); | |
102 } | |
103 } | |
104 | |
105 function errorHandler(e) | |
106 { | |
107 WebInspector.console.error("Failed to create temp file " + e.code + " :
" + e.message); | |
108 callback(null); | |
109 } | |
110 | |
111 /** | |
112 * @this {WebInspector.TempFile} | |
113 */ | |
114 function didClearTempStorage() | |
115 { | |
116 window.requestFileSystem(window.TEMPORARY, 10, didInitFs.bind(this), err
orHandler); | |
117 } | |
118 WebInspector.TempFile._ensureTempStorageCleared(didClearTempStorage.bind(thi
s)); | |
119 } | |
120 | |
121 WebInspector.TempFile.prototype = { | |
122 /** | |
123 * @param {!string} data | |
124 * @param {!function(boolean)} callback | |
125 */ | |
126 write: function(data, callback) | |
127 { | |
128 var blob = new Blob([data], {type: 'text/plain'}); | |
129 this._writer.onerror = function(e) | |
130 { | |
131 WebInspector.console.error("Failed to write into a temp file: " + e.
message); | |
132 callback(false); | |
133 } | |
134 this._writer.onwrite = function(e) | |
135 { | |
136 callback(true); | |
137 } | |
138 this._writer.write(blob); | |
139 }, | |
140 | |
141 finishWriting: function() | |
142 { | |
143 this._writer = null; | |
144 }, | |
145 | |
146 /** | |
147 * @param {function(?string)} callback | |
148 */ | |
149 read: function(callback) | |
150 { | |
151 /** | |
152 * @param {!File} file | |
153 */ | |
154 function didGetFile(file) | |
155 { | |
156 var reader = new FileReader(); | |
157 | |
158 /** | |
159 * @this {FileReader} | |
160 */ | |
161 reader.onloadend = function(e) | |
162 { | |
163 callback(/** @type {?string} */ (this.result)); | |
164 } | |
165 reader.onerror = function(error) | |
166 { | |
167 WebInspector.console.error("Failed to read from temp file: " + e
rror.message); | |
168 } | |
169 reader.readAsText(file); | |
170 } | |
171 function didFailToGetFile(error) | |
172 { | |
173 WebInspector.console.error("Failed to load temp file: " + error.mess
age); | |
174 callback(null); | |
175 } | |
176 this._fileEntry.file(didGetFile, didFailToGetFile); | |
177 }, | |
178 | |
179 /** | |
180 * @param {!WebInspector.OutputStream} outputStream | |
181 * @param {!WebInspector.OutputStreamDelegate} delegate | |
182 */ | |
183 writeToOutputSteam: function(outputStream, delegate) | |
184 { | |
185 /** | |
186 * @param {!File} file | |
187 */ | |
188 function didGetFile(file) | |
189 { | |
190 var reader = new WebInspector.ChunkedFileReader(file, 10*1000*1000,
delegate); | |
191 reader.start(outputStream); | |
192 } | |
193 | |
194 function didFailToGetFile(error) | |
195 { | |
196 WebInspector.console.error("Failed to load temp file: " + error.mess
age); | |
197 outputStream.close(); | |
198 } | |
199 | |
200 this._fileEntry.file(didGetFile, didFailToGetFile); | |
201 }, | |
202 | |
203 remove: function() | |
204 { | |
205 if (this._fileEntry) | |
206 this._fileEntry.remove(function() {}); | |
207 } | |
208 } | |
209 | |
210 /** | |
211 * @constructor | |
212 * @param {!string} dirPath | |
213 * @param {!string} name | |
214 */ | |
215 WebInspector.BufferedTempFileWriter = function(dirPath, name) | |
216 { | |
217 this._chunks = []; | |
218 this._tempFile = null; | |
219 this._isWriting = false; | |
220 this._finishCallback = null; | |
221 this._isFinished = false; | |
222 new WebInspector.TempFile(dirPath, name, this._didCreateTempFile.bind(this))
; | |
223 } | |
224 | |
225 WebInspector.BufferedTempFileWriter.prototype = { | |
226 /** | |
227 * @param {!string} data | |
228 */ | |
229 write: function(data) | |
230 { | |
231 if (!this._chunks) | |
232 return; | |
233 if (this._finishCallback) | |
234 throw new Error("No writes are allowed after close."); | |
235 this._chunks.push(data); | |
236 if (this._tempFile && !this._isWriting) | |
237 this._writeNextChunk(); | |
238 }, | |
239 | |
240 /** | |
241 * @param {!function(?WebInspector.TempFile)} callback | |
242 */ | |
243 close: function(callback) | |
244 { | |
245 this._finishCallback = callback; | |
246 if (this._isFinished) | |
247 callback(this._tempFile); | |
248 else if (!this._isWriting && !this._chunks.length) | |
249 this._notifyFinished(); | |
250 }, | |
251 | |
252 _didCreateTempFile: function(tempFile) | |
253 { | |
254 this._tempFile = tempFile; | |
255 if (!tempFile) { | |
256 this._chunks = null; | |
257 this._notifyFinished(); | |
258 return; | |
259 } | |
260 if (this._chunks.length) | |
261 this._writeNextChunk(); | |
262 }, | |
263 | |
264 _writeNextChunk: function() | |
265 { | |
266 var chunkSize = 0; | |
267 var endIndex = 0; | |
268 for (; endIndex < this._chunks.length; endIndex++) { | |
269 chunkSize += this._chunks[endIndex].length; | |
270 if (chunkSize > 10 * 1000 * 1000) | |
271 break; | |
272 } | |
273 var chunk = this._chunks.slice(0, endIndex + 1).join(""); | |
274 this._chunks.splice(0, endIndex + 1); | |
275 this._isWriting = true; | |
276 this._tempFile.write(chunk, this._didWriteChunk.bind(this)); | |
277 }, | |
278 | |
279 _didWriteChunk: function(success) | |
280 { | |
281 this._isWriting = false; | |
282 if (!success) { | |
283 this._tempFile = null; | |
284 this._chunks = null; | |
285 this._notifyFinished(); | |
286 return; | |
287 } | |
288 if (this._chunks.length) | |
289 this._writeNextChunk(); | |
290 else if (this._finishCallback) | |
291 this._notifyFinished(); | |
292 }, | |
293 | |
294 _notifyFinished: function() | |
295 { | |
296 this._isFinished = true; | |
297 if (this._tempFile) | |
298 this._tempFile.finishWriting(); | |
299 if (this._finishCallback) | |
300 this._finishCallback(this._tempFile); | |
301 } | |
302 } | |
303 | |
304 /** | |
305 * @constructor | |
306 */ | |
307 WebInspector.TempStorageCleaner = function() | |
308 { | |
309 this._worker = new SharedWorker("temp_storage_shared_worker/TempStorageShare
dWorker.js", "TempStorage"); | |
310 this._callbacks = []; | |
311 this._worker.port.onmessage = this._handleMessage.bind(this); | |
312 this._worker.port.onerror = this._handleError.bind(this); | |
313 } | |
314 | |
315 WebInspector.TempStorageCleaner.prototype = { | |
316 /** | |
317 * @param {!function()} callback | |
318 */ | |
319 ensureStorageCleared: function(callback) | |
320 { | |
321 if (this._callbacks) | |
322 this._callbacks.push(callback); | |
323 else | |
324 callback(); | |
325 }, | |
326 | |
327 _handleMessage: function(event) | |
328 { | |
329 if (event.data.type === "tempStorageCleared") { | |
330 if (event.data.error) | |
331 WebInspector.console.error(event.data.error); | |
332 this._notifyCallbacks(); | |
333 } | |
334 }, | |
335 | |
336 _handleError: function(event) | |
337 { | |
338 WebInspector.console.error(WebInspector.UIString("Failed to clear temp s
torage: %s", event.data)); | |
339 this._notifyCallbacks(); | |
340 }, | |
341 | |
342 _notifyCallbacks: function() | |
343 { | |
344 var callbacks = this._callbacks; | |
345 this._callbacks = null; | |
346 for (var i = 0; i < callbacks.length; i++) | |
347 callbacks[i](); | |
348 } | |
349 } | |
350 | |
351 /** | |
352 * @param {!function()} callback | |
353 */ | |
354 WebInspector.TempFile._ensureTempStorageCleared = function(callback) | |
355 { | |
356 if (!WebInspector.TempFile._storageCleaner) | |
357 WebInspector.TempFile._storageCleaner = new WebInspector.TempStorageClea
ner(); | |
358 WebInspector.TempFile._storageCleaner.ensureStorageCleared(callback); | |
359 } | |
OLD | NEW |