Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: lib/io.js

Issue 29450608: Issue 5279 - Fix broken I/O in non-Firefox applications (Closed) Base URL: https://hg.adblockplus.org/adblockplus
Patch Set: Created May 29, 2017, 11:54 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 }); 69 });
70 } 70 }
71 71
72 function legacyFile(fileName) 72 function legacyFile(fileName)
73 { 73 {
74 let file = LegacyIO.resolveFilePath("adblockplus"); 74 let file = LegacyIO.resolveFilePath("adblockplus");
75 file.append(fileName); 75 file.append(fileName);
76 return file; 76 return file;
77 } 77 }
78 78
79 let fallback = {
80 readFromFile(fileName, listener)
81 {
82 let wrapper = {
83 process(line)
84 {
85 if (line !== null)
86 listener(line);
87 }
88 };
89 return callLegacy("readFromFile", legacyFile(fileName), wrapper);
90 },
91
92 writeToFile(fileName, data)
93 {
94 return callLegacy("writeToFile", legacyFile(fileName), data);
95 },
96
97 copyFile(fromFile, toFile)
98 {
99 return callLegacy("copyFile", legacyFile(fromFile), legacyFile(toFile));
100 },
101
102 renameFile(fromFile, newName)
103 {
104 return callLegacy("renameFile", legacyFile(fromFile), newName);
105 },
106
107 removeFile(fileName)
108 {
109 return callLegacy("removeFile", legacyFile(fileName));
110 },
111
112 statFile(fileName)
113 {
114 return callLegacy("statFile", legacyFile(fileName));
115 }
116 };
117
79 exports.IO = 118 exports.IO =
80 { 119 {
81 /** 120 /**
82 * @callback TextSink 121 * @callback TextSink
83 * @param {string} line 122 * @param {string} line
84 */ 123 */
85 124
86 /** 125 /**
87 * Reads text lines from a file. 126 * Reads text lines from a file.
88 * @param {string} fileName 127 * @param {string} fileName
(...skipping 20 matching lines...) Expand all
109 { 148 {
110 Utils.runAsync(processBatch); 149 Utils.runAsync(processBatch);
111 return; 150 return;
112 } 151 }
113 } 152 }
114 resolve(); 153 resolve();
115 } 154 }
116 155
117 processBatch(); 156 processBatch();
118 }); 157 });
119 }).catch(error =>
120 {
121 if (error == "NoSuchFile")
122 {
123 let wrapper = {
124 process(line)
125 {
126 if (line !== null)
127 listener(line);
128 }
129 };
130 return callLegacy("readFromFile", legacyFile(fileName), wrapper);
131 }
132 throw error;
133 }); 158 });
134 }, 159 },
135 160
136 /** 161 /**
137 * Writes text lines to a file. 162 * Writes text lines to a file.
138 * @param {string} fileName 163 * @param {string} fileName
139 * Name of the file to be written 164 * Name of the file to be written
140 * @param {Iterable.<string>} data 165 * @param {Iterable.<string>} data
141 * An array-like or iterable object containing the lines (without line 166 * An array-like or iterable object containing the lines (without line
142 * endings) 167 * endings)
143 * @return {Promise} 168 * @return {Promise}
144 * Promise to be resolved or rejected once the operation is completed 169 * Promise to be resolved or rejected once the operation is completed
145 */ 170 */
146 writeToFile(fileName, data) 171 writeToFile(fileName, data)
147 { 172 {
148 return callWebExt("writeToFile", fileName, Array.from(data)); 173 return callWebExt("writeToFile", fileName, Array.from(data));
149 }, 174 },
150 175
151 /** 176 /**
152 * Copies a file. 177 * Copies a file.
153 * @param {string} fromFile 178 * @param {string} fromFile
154 * Name of the file to be copied 179 * Name of the file to be copied
155 * @param {string} toFile 180 * @param {string} toFile
156 * Name of the file to be written, will be overwritten if exists 181 * Name of the file to be written, will be overwritten if exists
157 * @return {Promise} 182 * @return {Promise}
158 * Promise to be resolved or rejected once the operation is completed 183 * Promise to be resolved or rejected once the operation is completed
159 */ 184 */
160 copyFile(fromFile, toFile) 185 copyFile(fromFile, toFile)
161 { 186 {
162 return callWebExt("copyFile", fromFile, toFile).catch(error => 187 return callWebExt("copyFile", fromFile, toFile);
163 {
164 if (error == "NoSuchFile")
165 return callLegacy("copyFile", legacyFile(fromFile), legacyFile(toFile));
166 throw error;
167 });
168 }, 188 },
169 189
170 /** 190 /**
171 * Renames a file. 191 * Renames a file.
172 * @param {string} fromFile 192 * @param {string} fromFile
173 * Name of the file to be renamed 193 * Name of the file to be renamed
174 * @param {string} newName 194 * @param {string} newName
175 * New file name, will be overwritten if exists 195 * New file name, will be overwritten if exists
176 * @return {Promise} 196 * @return {Promise}
177 * Promise to be resolved or rejected once the operation is completed 197 * Promise to be resolved or rejected once the operation is completed
178 */ 198 */
179 renameFile(fromFile, newName) 199 renameFile(fromFile, newName)
180 { 200 {
181 return callWebExt("renameFile", fromFile, newName).catch(error => 201 return callWebExt("renameFile", fromFile, newName);
182 {
183 if (error == "NoSuchFile")
184 return callLegacy("renameFile", legacyFile(fromFile), newName);
185 throw error;
186 });
187 }, 202 },
188 203
189 /** 204 /**
190 * Removes a file. 205 * Removes a file.
191 * @param {string} fileName 206 * @param {string} fileName
192 * Name of the file to be removed 207 * Name of the file to be removed
193 * @return {Promise} 208 * @return {Promise}
194 * Promise to be resolved or rejected once the operation is completed 209 * Promise to be resolved or rejected once the operation is completed
195 */ 210 */
196 removeFile(fileName) 211 removeFile(fileName)
197 { 212 {
198 return callWebExt("removeFile", fileName).catch(error => 213 return callWebExt("removeFile", fileName);
199 {
200 if (error == "NoSuchFile")
201 return callLegacy("removeFile", legacyFile(fileName));
202 throw error;
203 });
204 }, 214 },
205 215
206 /** 216 /**
207 * @typedef StatData 217 * @typedef StatData
208 * @type {object} 218 * @type {object}
209 * @property {boolean} exists 219 * @property {boolean} exists
210 * true if the file exists 220 * true if the file exists
211 * @property {number} lastModified 221 * @property {number} lastModified
212 * file modification time in milliseconds 222 * file modification time in milliseconds
213 */ 223 */
214 224
215 /** 225 /**
216 * Retrieves file metadata. 226 * Retrieves file metadata.
217 * @param {string} fileName 227 * @param {string} fileName
218 * Name of the file to be looked up 228 * Name of the file to be looked up
219 * @return {Promise.<StatData>} 229 * @return {Promise.<StatData>}
220 * Promise to be resolved with file metadata once the operation is 230 * Promise to be resolved with file metadata once the operation is
221 * completed 231 * completed
222 */ 232 */
223 statFile(fileName) 233 statFile(fileName)
224 { 234 {
225 return callWebExt("statFile", fileName).catch(error => 235 return callWebExt("statFile", fileName);
226 {
227 if (error == "NoSuchFile")
228 return callLegacy("statFile", legacyFile(fileName));
229 throw error;
230 });
231 } 236 }
232 }; 237 };
238
239 let {application} = require("info");
240 if (application != "firefox" && application != "fennec2")
241 {
242 // Currently, only Firefox has a working WebExtensions implementation, other
243 // applications should just use the fallback.
244 exports.IO = fallback;
245 }
246 else
247 {
248 for (let name of [
249 "readFromFile", "copyFile", "renameFile", "removeFile", "statFile"
Felix Dahlke 2017/05/29 12:22:30 We could avoid duplication here by iterating over
Wladimir Palant 2017/05/29 12:41:23 Done.
250 ])
251 {
252 // For missing files, fall back to legacy I/O for all methods except
Felix Dahlke 2017/05/29 12:22:30 Nit: I think that comment should move in front of
Wladimir Palant 2017/05/29 12:41:23 Done.
253 // writeToFile()
254 let method = exports.IO[name];
255 let fallbackMethod = fallback[name];
256 exports.IO[name] = (...args) =>
257 {
258 return method(...args).catch(error =>
259 {
260 if (error == "NoSuchFile")
261 return fallbackMethod(...args);
262 throw error;
263 });
264 };
265 }
266 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld