| 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 |