Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / devtools / front_end / TempFile.js
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.webkitRequestFileSystem;
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), errorHandler);
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), errorHandler);
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.log("Failed to truncate temp file " + e.code + " : " + e.message,
92                              WebInspector.ConsoleMessage.MessageLevel.Error);
93             callback(null);
94         }
95
96         if (writer.length) {
97             writer.onwrite = didTruncate.bind(this);
98             writer.onerror = onTruncateError;
99             writer.truncate(0);
100         } else {
101             this._writer = writer;
102             callback(this);
103         }
104     }
105
106     function errorHandler(e)
107     {
108         WebInspector.console.log("Failed to create temp file " + e.code + " : " + e.message,
109                          WebInspector.ConsoleMessage.MessageLevel.Error);
110         callback(null);
111     }
112
113     /**
114      * @this {WebInspector.TempFile}
115      */
116     function didClearTempStorage()
117     {
118         window.requestFileSystem(window.TEMPORARY, 10, didInitFs.bind(this), errorHandler);
119     }
120     WebInspector.TempFile._ensureTempStorageCleared(didClearTempStorage.bind(this));
121 }
122
123 WebInspector.TempFile.prototype = {
124     /**
125      * @param {!string} data
126      * @param {!function(boolean)} callback
127      */
128     write: function(data, callback)
129     {
130         var blob = new Blob([data], {type: 'text/plain'});
131         this._writer.onerror = function(e)
132         {
133             WebInspector.console.log("Failed to write into a temp file: " + e.message,
134                              WebInspector.ConsoleMessage.MessageLevel.Error);
135             callback(false);
136         }
137         this._writer.onwrite = function(e)
138         {
139             callback(true);
140         }
141         this._writer.write(blob);
142     },
143
144     finishWriting: function()
145     {
146         this._writer = null;
147     },
148
149     /**
150      * @param {function(?string)} callback
151      */
152     read: function(callback)
153     {
154         /**
155          * @param {!File} file
156          */
157         function didGetFile(file)
158         {
159             var reader = new FileReader();
160
161             /**
162              * @this {FileReader}
163              */
164             reader.onloadend = function(e)
165             {
166                 callback(/** @type {?string} */ (this.result));
167             }
168             reader.onerror = function(error)
169             {
170                 WebInspector.console.log("Failed to read from temp file: " + error.message,
171                                  WebInspector.ConsoleMessage.MessageLevel.Error);
172             }
173             reader.readAsText(file);
174         }
175         function didFailToGetFile(error)
176         {
177             WebInspector.console.log("Failed to load temp file: " + error.message,
178                               WebInspector.ConsoleMessage.MessageLevel.Error);
179             callback(null);
180         }
181         this._fileEntry.file(didGetFile, didFailToGetFile);
182     },
183
184     /**
185      * @param {!WebInspector.OutputStream} outputStream
186      * @param {!WebInspector.OutputStreamDelegate} delegate
187      */
188     writeToOutputSteam: function(outputStream, delegate)
189     {
190         /**
191          * @param {!File} file
192          */
193         function didGetFile(file)
194         {
195             var reader = new WebInspector.ChunkedFileReader(file, 10*1000*1000, delegate);
196             reader.start(outputStream);
197         }
198
199         function didFailToGetFile(error)
200         {
201             WebInspector.console.log("Failed to load temp file: " + error.message,
202                              WebInspector.ConsoleMessage.MessageLevel.Error);
203             outputStream.close();
204         }
205
206         this._fileEntry.file(didGetFile, didFailToGetFile);
207     },
208
209     remove: function()
210     {
211         if (this._fileEntry)
212             this._fileEntry.remove(function() {});
213     }
214 }
215
216 /**
217  * @constructor
218  * @param {!string} dirPath
219  * @param {!string} name
220  */
221 WebInspector.BufferedTempFileWriter = function(dirPath, name)
222 {
223     this._chunks = [];
224     this._tempFile = null;
225     this._isWriting = false;
226     this._finishCallback = null;
227     this._isFinished = false;
228     new WebInspector.TempFile(dirPath, name, this._didCreateTempFile.bind(this));
229 }
230
231 WebInspector.BufferedTempFileWriter.prototype = {
232     /**
233      * @param {!string} data
234      */
235     write: function(data)
236     {
237         if (!this._chunks)
238             return;
239         if (this._finishCallback)
240             throw new Error("Now writes are allowed after close.");
241         this._chunks.push(data);
242         if (this._tempFile && !this._isWriting)
243             this._writeNextChunk();
244     },
245
246     /**
247      * @param {!function(?WebInspector.TempFile)} callback
248      */
249     close: function(callback)
250     {
251         this._finishCallback = callback;
252         if (this._isFinished)
253             callback(this._tempFile);
254         else if (!this._isWriting && !this._chunks.length)
255             this._notifyFinished();
256     },
257
258     _didCreateTempFile: function(tempFile)
259     {
260         this._tempFile = tempFile;
261         if (!tempFile) {
262             this._chunks = null;
263             this._notifyFinished();
264             return;
265         }
266         if (this._chunks.length)
267             this._writeNextChunk();
268     },
269
270     _writeNextChunk: function()
271     {
272         var chunkSize = 0;
273         var endIndex = 0;
274         for (; endIndex < this._chunks.length; endIndex++) {
275             chunkSize += this._chunks[endIndex].length;
276             if (chunkSize > 10 * 1000 * 1000)
277                 break;
278         }
279         var chunk = this._chunks.slice(0, endIndex + 1).join("");
280         this._chunks.splice(0, endIndex + 1);
281         this._isWriting = true;
282         this._tempFile.write(chunk, this._didWriteChunk.bind(this));
283     },
284
285     _didWriteChunk: function(success)
286     {
287         this._isWriting = false;
288         if (!success) {
289             this._tempFile = null;
290             this._chunks = null;
291             this._notifyFinished();
292             return;
293         }
294         if (this._chunks.length)
295             this._writeNextChunk();
296         else if (this._finishCallback)
297             this._notifyFinished();
298     },
299
300     _notifyFinished: function()
301     {
302         this._isFinished = true;
303         if (this._tempFile)
304             this._tempFile.finishWriting();
305         if (this._finishCallback)
306             this._finishCallback(this._tempFile);
307     }
308 }
309
310 /**
311  * @constructor
312  */
313 WebInspector.TempStorageCleaner = function()
314 {
315     this._worker = new SharedWorker("TempStorageSharedWorker.js", "TempStorage");
316     this._callbacks = [];
317     this._worker.port.onmessage = this._handleMessage.bind(this);
318     this._worker.port.onerror = this._handleError.bind(this);
319 }
320
321 WebInspector.TempStorageCleaner.prototype = {
322     /**
323      * @param {!function()} callback
324      */
325     ensureStorageCleared: function(callback)
326     {
327         if (this._callbacks)
328             this._callbacks.push(callback);
329         else
330             callback();
331     },
332
333     _handleMessage: function(event)
334     {
335         if (event.data.type === "tempStorageCleared") {
336             if (event.data.error)
337                 WebInspector.console.log(event.data.error, WebInspector.ConsoleMessage.MessageLevel.Error);
338             this._notifyCallbacks();
339         }
340     },
341
342     _handleError: function(event)
343     {
344         WebInspector.console.log(WebInspector.UIString("Failed to clear temp storage: %s", event.data),
345                          WebInspector.ConsoleMessage.MessageLevel.Error);
346         this._notifyCallbacks();
347     },
348
349     _notifyCallbacks: function()
350     {
351         var callbacks = this._callbacks;
352         this._callbacks = null;
353         for (var i = 0; i < callbacks.length; i++)
354             callbacks[i]();
355     }
356 }
357
358 /**
359  * @param {!function()} callback
360  */
361 WebInspector.TempFile._ensureTempStorageCleared = function(callback)
362 {
363     if (!WebInspector.TempFile._storageCleaner)
364         WebInspector.TempFile._storageCleaner = new WebInspector.TempStorageCleaner();
365     WebInspector.TempFile._storageCleaner.ensureStorageCleared(callback);
366 }