Index: lib/io.js |
=================================================================== |
--- a/lib/io.js |
+++ b/lib/io.js |
@@ -15,11 +15,23 @@ |
* along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
*/ |
+"use strict"; |
+ |
const keyPrefix = "file:"; |
-function fileToKey(file) |
+function fileToKey(file, chunk) |
{ |
- return keyPrefix + (file instanceof FakeFile ? file.path : file.spec); |
+ let key = keyPrefix; |
+ |
+ if (file instanceof FakeFile) |
+ key += file.path; |
+ else |
+ key += file.spec; |
+ |
+ if (typeof chunk != "undefined") |
+ key += ":" + chunk; |
+ |
+ return key; |
} |
function loadFile(file, successCallback, errorCallback) |
@@ -37,17 +49,23 @@ |
}); |
} |
-function saveFile(file, data, callback) |
-{ |
- ext.storage.set( |
- fileToKey(file), |
- { |
- content: data, |
- lastModified: Date.now() |
- }, |
- callback |
- ); |
-} |
+// Make sure we don't leak chunks when saving smaller files in Edge |
+ext.storage.onChanged.addListener(function(changes, namespace) { |
+ if (namespace != 'local') |
+ return; |
+ |
+ for (key in changes) { |
+ var oldValue = changes[key].oldValue; |
+ var newValue = changes[key].newValue; |
+ if (typeof oldValue == "object" && |
+ typeof oldValue["chunks"] == "number") |
+ { |
+ for (let i = newValue.chunks; i < oldValue.chunks; ++i) |
+ ext.storage.remove(key + ":" + i); |
+ } |
+ } |
+ }); |
+ |
exports.IO = |
{ |
@@ -60,47 +78,79 @@ |
{ |
function onLoaded(entry) |
{ |
- for (let line of entry.content) |
- listener.process(line); |
+ if ("content" in entry) |
+ { |
+ for (let line of entry.content) |
+ listener.process(line); |
- listener.process(null); |
- callback(null); |
+ listener.process(null); |
+ callback(null); |
+ } |
+ else |
+ { |
+ let keys = []; |
+ for (let i = 0; i < entry.chunks; i++) |
+ keys.push(fileToKey(file, i)); |
+ |
+ ext.storage.get(keys, items => |
+ { |
+ for (let key of keys) |
+ for (let line of items[key]) |
+ listener.process(line); |
+ |
+ listener.process(null); |
+ callback(null); |
+ }); |
+ } |
} |
loadFile(file, onLoaded, callback); |
}, |
- |
+ |
writeToFile: function(file, data, callback) |
{ |
- saveFile(file, data, callback); |
- }, |
+ let key = fileToKey(file); |
+ let items = {}; |
+ items[key] = {lastModified: Date.now()}; |
- copyFile: function(fromFile, toFile, callback) |
- { |
- function onLoaded(entry) |
+ // Edge currently has a limitation of how much data can be stored |
+ // using chrome.storage.local.set. The current limit is 1Mb per operation. |
+ // Edge uses 'browser' namespace instead of 'chrome'. |
+ if (typeof browser != "object") |
{ |
- saveFile(toFile, entry.content, callback); |
+ // In Edge strings are stored in UTF-16 format, so 2 bytes per char |
+ // We subtract 1000 bytes for keys and array overhead |
+ let quota = 1024 * 1024 / 2 - 1000; |
+ let chunks = []; |
+ let chunk = []; |
+ let chunkSize = 0; |
+ |
+ for (let line of data) |
+ { |
+ if (line.length + chunkSize > quota) |
+ { |
+ chunks.push(chunk); |
+ chunk = []; |
+ chunkSize = 0; |
+ } |
+ |
+ chunk.push(line); |
+ chunkSize += line.length; |
+ } |
+ chunks.push(chunk); |
+ |
+ if (chunks.length > 1) |
+ { |
+ for (let i = 0; i < chunks.length; i++) |
+ items[fileToKey(file, i)] = chunks[i]; |
+ items[key].chunks = chunks.length; |
+ ext.storage.set(items, callback); |
+ return; |
+ } |
} |
- loadFile(fromFile, onLoaded, callback); |
- }, |
- |
- renameFile: function(fromFile, newName, callback) |
- { |
- function onLoaded() |
- { |
- ext.storage.remove(fileToKey(fromFile), function() |
- { |
- ext.storage.set(keyPrefix + newName, entry, callback); |
- }); |
- } |
- |
- loadFile(fromFile, onLoaded, callback); |
- }, |
- |
- removeFile: function(file, callback) |
- { |
- ext.storage.remove(fileToKey(file), callback); |
+ items[key].content = data; |
+ ext.storage.set(items, callback); |
}, |
statFile: function(file, callback) |
@@ -114,5 +164,5 @@ |
} |
loadFile(file, onLoaded, callback); |
- } |
+ }, |
}; |