OLD | NEW |
1 /* | 1 /* |
2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
3 * Copyright (C) 2006-2017 eyeo GmbH | 3 * Copyright (C) 2006-2017 eyeo GmbH |
4 * | 4 * |
5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
8 * | 8 * |
9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 { | 48 { |
49 return new Promise((resolve, reject) => | 49 return new Promise((resolve, reject) => |
50 { | 50 { |
51 let id = ++messageID; | 51 let id = ++messageID; |
52 messageCallbacks.set(id, {resolve, reject}); | 52 messageCallbacks.set(id, {resolve, reject}); |
53 port.postMessage({id, method, args}); | 53 port.postMessage({id, method, args}); |
54 }); | 54 }); |
55 }); | 55 }); |
56 } | 56 } |
57 | 57 |
58 function attachCallback(promise, callback, fallback) | 58 function callLegacy(method, ...args) |
59 { | 59 { |
60 promise.then(result => | 60 return new Promise((resolve, reject) => |
61 { | 61 { |
62 callback(null, result); | 62 LegacyIO[method](...args, (error, result) => |
63 }).catch(error => | 63 { |
64 { | 64 if (error) |
65 if (fallback && error == "NoSuchFile") | 65 reject(error); |
66 fallback(); | 66 else |
67 else | 67 resolve(result); |
68 callback(error); | 68 }); |
69 }); | 69 }); |
70 } | 70 } |
71 | 71 |
| 72 function legacyFile(fileName) |
| 73 { |
| 74 let file = LegacyIO.resolveFilePath("adblockplus"); |
| 75 file.append(fileName); |
| 76 return file; |
| 77 } |
| 78 |
72 exports.IO = | 79 exports.IO = |
73 { | 80 { |
74 resolveFilePath: LegacyIO.resolveFilePath, | 81 /** |
| 82 * @callback TextSink |
| 83 * @param {string} line |
| 84 */ |
75 | 85 |
76 /** | 86 /** |
77 * Reads strings from a file asynchronously, calls listener.process() with | 87 * Reads text lines from a file. |
78 * each line read and with a null parameter once the read operation is done. | 88 * @param {string} fileName |
79 * The callback will be called when the operation is done. | 89 * Name of the file to be read |
| 90 * @param {TextSink} listener |
| 91 * Function that will be called for each line in the file |
| 92 * @return {Promise} |
| 93 * Promise to be resolved or rejected once the operation is completed |
80 */ | 94 */ |
81 readFromFile(/**nsIFile*/ file, /**Object*/ listener, /**Function*/ callback) | 95 readFromFile(fileName, listener) |
82 { | 96 { |
83 attachCallback( | 97 return callWebExt("readFromFile", fileName).then(contents => |
84 callWebExt("readFromFile", file.leafName).then(contents => | 98 { |
| 99 return new Promise((resolve, reject) => |
85 { | 100 { |
86 return new Promise((resolve, reject) => | 101 let lineIndex = 0; |
| 102 |
| 103 function processBatch() |
87 { | 104 { |
88 let lineIndex = 0; | 105 while (lineIndex < contents.length) |
| 106 { |
| 107 listener(contents[lineIndex++]); |
| 108 if (lineIndex % 1000 == 0) |
| 109 { |
| 110 Utils.runAsync(processBatch); |
| 111 return; |
| 112 } |
| 113 } |
| 114 resolve(); |
| 115 } |
89 | 116 |
90 function processBatch() | 117 processBatch(); |
| 118 }); |
| 119 }).catch(error => |
| 120 { |
| 121 if (error == "NoSuchFile") |
| 122 { |
| 123 let wrapper = { |
| 124 process(line) |
91 { | 125 { |
92 while (lineIndex < contents.length) | 126 if (line !== null) |
93 { | 127 listener(line); |
94 listener.process(contents[lineIndex++]); | |
95 if (lineIndex % 1000 == 0) | |
96 { | |
97 Utils.runAsync(processBatch); | |
98 return; | |
99 } | |
100 } | |
101 | |
102 listener.process(null); | |
103 resolve(); | |
104 } | 128 } |
105 | 129 }; |
106 processBatch(); | 130 return callLegacy("readFromFile", legacyFile(fileName), wrapper); |
107 }); | 131 } |
108 }), | 132 throw error; |
109 callback, | 133 }); |
110 () => LegacyIO.readFromFile(file, listener, callback) | |
111 ); | |
112 }, | 134 }, |
113 | 135 |
114 /** | 136 /** |
115 * Writes string data to a file in UTF-8 format asynchronously. The callback | 137 * Writes text lines to a file. |
116 * will be called when the write operation is done. | 138 * @param {string} fileName |
| 139 * Name of the file to be written |
| 140 * @param {Iterable.<string>} data |
| 141 * An array-like or iterable object containing the lines (without line |
| 142 * endings) |
| 143 * @return {Promise} |
| 144 * Promise to be resolved or rejected once the operation is completed |
117 */ | 145 */ |
118 writeToFile(/**nsIFile*/ file, /**Iterator*/ data, /**Function*/ callback) | 146 writeToFile(fileName, data) |
119 { | 147 { |
120 attachCallback( | 148 return callWebExt("writeToFile", fileName, Array.from(data)); |
121 callWebExt("writeToFile", file.leafName, Array.from(data)), | |
122 callback | |
123 ); | |
124 }, | 149 }, |
125 | 150 |
126 /** | 151 /** |
127 * Copies a file asynchronously. The callback will be called when the copy | 152 * Copies a file. |
128 * operation is done. | 153 * @param {string} fromFile |
| 154 * Name of the file to be copied |
| 155 * @param {string} toFile |
| 156 * Name of the file to be written, will be overwritten if exists |
| 157 * @return {Promise} |
| 158 * Promise to be resolved or rejected once the operation is completed |
129 */ | 159 */ |
130 copyFile(/**nsIFile*/ fromFile, /**nsIFile*/ toFile, /**Function*/ callback) | 160 copyFile(fromFile, toFile) |
131 { | 161 { |
132 attachCallback( | 162 return callWebExt("copyFile", fromFile, toFile).catch(error => |
133 callWebExt("copyFile", fromFile.leafName, toFile.leafName), | 163 { |
134 callback, | 164 if (error == "NoSuchFile") |
135 () => LegacyIO.copyFile(fromFile, toFile, callback) | 165 return callLegacy("copyFile", legacyFile(fromFile), legacyFile(toFile)); |
136 ); | 166 throw error; |
| 167 }); |
137 }, | 168 }, |
138 | 169 |
139 /** | 170 /** |
140 * Renames a file within the same directory, will call callback when done. | 171 * Renames a file. |
| 172 * @param {string} fromFile |
| 173 * Name of the file to be renamed |
| 174 * @param {string} newName |
| 175 * New file name, will be overwritten if exists |
| 176 * @return {Promise} |
| 177 * Promise to be resolved or rejected once the operation is completed |
141 */ | 178 */ |
142 renameFile(/**nsIFile*/ fromFile, /**String*/ newName, /**Function*/ callback) | 179 renameFile(fromFile, newName) |
143 { | 180 { |
144 attachCallback( | 181 return callWebExt("renameFile", fromFile, newName).catch(error => |
145 callWebExt("renameFile", fromFile.leafName, newName), | 182 { |
146 callback, | 183 if (error == "NoSuchFile") |
147 () => LegacyIO.renameFile(fromFile, newName, callback) | 184 return callLegacy("renameFile", legacyFile(fromFile), newName); |
148 ); | 185 throw error; |
| 186 }); |
149 }, | 187 }, |
150 | 188 |
151 /** | 189 /** |
152 * Removes a file, will call callback when done. | 190 * Removes a file. |
| 191 * @param {string} fileName |
| 192 * Name of the file to be removed |
| 193 * @return {Promise} |
| 194 * Promise to be resolved or rejected once the operation is completed |
153 */ | 195 */ |
154 removeFile(/**nsIFile*/ file, /**Function*/ callback) | 196 removeFile(fileName) |
155 { | 197 { |
156 attachCallback( | 198 return callWebExt("removeFile", fileName).catch(error => |
157 callWebExt("removeFile", file.leafName), | 199 { |
158 callback, | 200 if (error == "NoSuchFile") |
159 () => LegacyIO.removeFile(file, callback) | 201 return callLegacy("removeFile", legacyFile(fileName)); |
160 ); | 202 throw error; |
| 203 }); |
161 }, | 204 }, |
162 | 205 |
163 /** | 206 /** |
164 * Gets file information such as whether the file exists. | 207 * @typedef StatData |
| 208 * @type {object} |
| 209 * @property {boolean} exists |
| 210 * true if the file exists |
| 211 * @property {number} lastModified |
| 212 * file modification time in milliseconds |
165 */ | 213 */ |
166 statFile(/**nsIFile*/ file, /**Function*/ callback) | 214 |
| 215 /** |
| 216 * Retrieves file metadata. |
| 217 * @param {string} fileName |
| 218 * Name of the file to be looked up |
| 219 * @return {Promise.<StatData>} |
| 220 * Promise to be resolved with file metadata once the operation is |
| 221 * completed |
| 222 */ |
| 223 statFile(fileName) |
167 { | 224 { |
168 attachCallback( | 225 return callWebExt("statFile", fileName).catch(error => |
169 callWebExt("statFile", file.leafName), | 226 { |
170 callback, | 227 if (error == "NoSuchFile") |
171 () => LegacyIO.statFile(file, callback) | 228 return callLegacy("statFile", legacyFile(fileName)); |
172 ); | 229 throw error; |
| 230 }); |
173 } | 231 } |
174 }; | 232 }; |
OLD | NEW |