Bug 1140652 - deduplicate reading and saving a string into a file (usually a JSON structure). r=mkmelin, r=IanN, a=Ratty for SeaMonkey CLOSED TREE

This commit is contained in:
aceman 2015-04-17 00:19:20 +02:00
Родитель 8a66d3e203
Коммит 1ba7a770bf
8 изменённых файлов: 119 добавлений и 207 удалений

Просмотреть файл

@ -6,6 +6,7 @@ Components.utils.import("resource:///modules/folderUtils.jsm");
Components.utils.import("resource:///modules/iteratorUtils.jsm");
Components.utils.import("resource:///modules/mailServices.js");
Components.utils.import("resource:///modules/MailUtils.js");
Components.utils.import("resource:///modules/IOUtils.js");
Components.utils.import("resource://gre/modules/Services.jsm");
const kDefaultMode = "all";
@ -159,23 +160,8 @@ let gFolderTreeView = {
if (aJSONFile) {
// Parse our persistent-open-state json file
let file = Services.dirsvc.get("ProfD", Ci.nsIFile);
file.append(aJSONFile);
if (file.exists()) {
let data = "";
let fstream = Cc["@mozilla.org/network/file-input-stream;1"]
.createInstance(Ci.nsIFileInputStream);
let sstream = Cc["@mozilla.org/scriptableinputstream;1"]
.createInstance(Ci.nsIScriptableInputStream);
fstream.init(file, -1, 0, 0);
sstream.init(fstream);
while (sstream.available())
data += sstream.read(4096);
sstream.close();
fstream.close();
let data = IOUtils.loadFileToString(aJSONFile);
if (data) {
try {
this._persistOpenMap = JSON.parse(data);
} catch (x) {
@ -213,17 +199,7 @@ let gFolderTreeView = {
if (aJSONFile) {
// Write out our json file...
let data = JSON.stringify(this._persistOpenMap);
let file = Services.dirsvc.get("ProfD", Ci.nsIFile);
file.append(aJSONFile);
let foStream = Cc["@mozilla.org/network/safe-file-output-stream;1"]
.createInstance(Ci.nsIFileOutputStream);
foStream.init(file, 0x02 | 0x08 | 0x20, parseInt("0666", 8), 0);
// safe-file-output-stream appears to throw an error if it doesn't write everything at once
// so we won't worry about looping to deal with partial writes
foStream.write(data, data.length);
foStream.QueryInterface(Ci.nsISafeOutputStream).finish();
foStream.close();
IOUtils.saveStringToFile(aJSONFile, data);
}
},

Просмотреть файл

@ -16,7 +16,6 @@ const Cu = Components.utils;
const nsIMFNService = Ci.nsIMsgFolderNotificationService;
Cu.import("resource:///modules/IOUtils.js");
Cu.import("resource:///modules/errUtils.js");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource:///modules/mailServices.js");

Просмотреть файл

@ -18,6 +18,7 @@ const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource:///modules/mailServices.js");
Cu.import("resource:///modules/IOUtils.js");
var MailMigrator = {
/**
@ -271,29 +272,12 @@ var MailMigrator = {
// Add an expanded entry for All Address Books.
if (currentUIVersion < 10) {
let PERMS_FILE = parseInt("0644", 8);
let file = Services.dirsvc.get("ProfD", Ci.nsIFile);
file.append("directoryTree.json");
let data = "";
const DIR_TREE_FILE = "directoryTree.json";
// If the file exists, read its contents, prepend the "All ABs" URI
// and save it, else, just write the "All ABs" URI to the file.
if (file.exists()) {
let fstream = Cc["@mozilla.org/network/file-input-stream;1"]
.createInstance(Ci.nsIFileInputStream);
let sstream = Cc["@mozilla.org/scriptableinputstream;1"]
.createInstance(Ci.nsIScriptableInputStream);
fstream.init(file, -1, 0, 0);
sstream.init(fstream);
while (sstream.available()) {
data += sstream.read(4096);
}
sstream.close();
fstream.close();
}
if (data == "[]") {
let data = IOUtils.loadFileToString(DIR_TREE_FILE);
if (!data || data == "[]") {
data = "";
} else if (data.length > 0) {
data = data.substring(1, data.length - 1);
@ -302,13 +286,7 @@ var MailMigrator = {
data = "[" + "\"moz-abdirectory://?\"" +
((data.length > 0) ? ("," + data) : "") + "]";
let foStream = Cc["@mozilla.org/network/safe-file-output-stream;1"]
.createInstance(Ci.nsIFileOutputStream);
foStream.init(file, 0x02 | 0x08 | 0x20, PERMS_FILE, 0);
foStream.write(data, data.length);
foStream.QueryInterface(Ci.nsISafeOutputStream).finish();
foStream.close();
IOUtils.saveStringToFile(DIR_TREE_FILE, data);
}
// Several Latin language groups were consolidated into x-western.

Просмотреть файл

@ -6,6 +6,7 @@
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource:///modules/mailServices.js");
Components.utils.import("resource:///modules/IOUtils.js");
var gDirTree;
var abList = 0;
@ -27,7 +28,6 @@ const kCollectedAddressbookURI = "moz-abmdbdirectory://history.mab";
// blank.
let defaultPhotoURI = "";
const PERMS_FILE = parseInt("0644", 8);
const PERMS_DIRECTORY = parseInt("0755", 8);
// Controller object for Dir Pane
@ -778,41 +778,6 @@ function getPhotoURI(aPhotoName) {
return Services.io.newFileURI(file).spec;
}
/**
* Saves the given input stream to a file.
*
* @param aIStream The input stream to save.
* @param aFile The file to which the stream is saved.
*/
function saveStreamToFile(aIStream, aFile) {
if (!(aIStream instanceof Components.interfaces.nsIInputStream))
throw "Invalid stream passed to saveStreamToFile";
if (!(aFile instanceof Components.interfaces.nsIFile))
throw "Invalid file passed to saveStreamToFile";
// Write the input stream to the file
var fstream = Components.classes["@mozilla.org/network/safe-file-output-stream;1"]
.createInstance(Components.interfaces.nsIFileOutputStream);
var buffer = Components.classes["@mozilla.org/network/buffered-output-stream;1"]
.createInstance(Components.interfaces.nsIBufferedOutputStream);
fstream.init(aFile, 0x04 | 0x08 | 0x20, PERMS_FILE, 0); // write, create, truncate
buffer.init(fstream, 8192);
buffer.writeFrom(aIStream, aIStream.available());
// Close the output streams
if (buffer instanceof Components.interfaces.nsISafeOutputStream)
buffer.finish();
else
buffer.close();
if (fstream instanceof Components.interfaces.nsISafeOutputStream)
fstream.finish();
else
fstream.close();
// Close the input stream
aIStream.close();
return aFile;
}
/**
* Copies the photo at the given URI in a folder named "Photos" in the current
* profile folder.
@ -840,7 +805,7 @@ function storePhoto(aUri)
// Get the photo file
file = makePhotoFile(file, findPhotoExt(channel));
return saveStreamToFile(istream, file);
return IOUtils.saveStreamToFile(istream, file);
}
/**

Просмотреть файл

@ -9,6 +9,7 @@
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource:///modules/mailServices.js");
Components.utils.import("resource:///modules/IOUtils.js");
// Tree Sort helper methods.
const AB_ORDER = ["aab", "pab", "mork", "ldap", "mapi+other", "anyab", "cab"];
@ -145,60 +146,26 @@ function directoryTreeView() {}
directoryTreeView.prototype = {
__proto__: new PROTO_TREE_VIEW(),
PERMS_FILE: parseInt("0644", 8),
hasRemoteAB: false,
init: function dtv_init(aTree, aJSONFile) {
const Cc = Components.classes;
const Ci = Components.interfaces;
if (aJSONFile) {
// Parse our persistent-open-state json file
let file = Services.dirsvc.get("ProfD", Ci.nsIFile);
file.append(aJSONFile);
if (file.exists()) {
let data = "";
let fstream = Cc["@mozilla.org/network/file-input-stream;1"]
.createInstance(Ci.nsIFileInputStream);
let sstream = Cc["@mozilla.org/scriptableinputstream;1"]
.createInstance(Ci.nsIScriptableInputStream);
fstream.init(file, -1, 0, 0);
sstream.init(fstream);
while (sstream.available()) {
data += sstream.read(4096);
}
sstream.close();
fstream.close();
let data = IOUtils.loadFileToString(aJSONFile);
if (data)
this._persistOpenMap = JSON.parse(data);
}
}
this._rebuild();
aTree.view = this;
},
shutdown: function dtv_shutdown(aJSONFile) {
const Cc = Components.classes;
const Ci = Components.interfaces;
// Write out the persistOpenMap to our JSON file
if (aJSONFile) {
// Write out our json file...
let data = JSON.stringify(this._persistOpenMap);
let file = Services.dirsvc.get("ProfD", Ci.nsIFile);
file.append(aJSONFile);
let foStream = Cc["@mozilla.org/network/safe-file-output-stream;1"]
.createInstance(Ci.nsIFileOutputStream);
foStream.init(file, 0x02 | 0x08 | 0x20, PERMS_FILE, 0);
foStream.write(data, data.length);
foStream.QueryInterface(Ci.nsISafeOutputStream).finish();
foStream.close();
IOUtils.saveStringToFile(aJSONFile, data);
}
},
@ -231,9 +198,6 @@ directoryTreeView.prototype = {
var oldCount = this._rowMap.length;
this._rowMap = [];
const Cc = Components.classes;
const Ci = Components.interfaces;
var dirEnum = MailServices.ab.directories;
// Make an entry for All Address Books.

Просмотреть файл

@ -2,36 +2,49 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var EXPORTED_SYMBOLS = ["IOUtils"];
const EXPORTED_SYMBOLS = ["IOUtils"];
Components.utils.import("resource://gre/modules/Services.jsm");
const Cc = Components.classes;
const Ci = Components.interfaces;
const kStringBlockSize = 4096;
const kStreamBlockSize = 8192;
var IOUtils =
{
/**
* Read a file containing ASCII text into a string.
*
* @param aFile An nsIFile representing the file to read.
* @param aFile An nsIFile representing the file to read or a string containing
* the file name of a file under user's profile.
* @returns A string containing the contents of the file, presumed to be ASCII
* text.
* text. If the file didn't exist, returns null.
*/
loadFileToString: function IOUtils_loadFileToString(aFile) {
loadFileToString: function(aFile) {
let file;
if (!(aFile instanceof Ci.nsIFile)) {
file = Services.dirsvc.get("ProfD", Ci.nsIFile);
file.append(aFile);
} else {
file = aFile;
}
if (!file.exists())
return null;
let fstream = Cc["@mozilla.org/network/file-input-stream;1"]
.createInstance(Ci.nsIFileInputStream);
fstream.init(aFile, -1, 0, 0);
// PR_RDONLY
fstream.init(file, 0x01, 0, 0);
let sstream = Cc["@mozilla.org/scriptableinputstream;1"]
.createInstance(Ci.nsIScriptableInputStream);
sstream.init(fstream);
let data = "";
let str = sstream.read(4096);
while (str.length > 0) {
data += str;
str = sstream.read(4096);
while (sstream.available()) {
data += sstream.read(kStringBlockSize);
}
sstream.close();
@ -41,11 +54,83 @@ var IOUtils =
},
/**
* This is provided by the JS component loader.
* Save a string containing ASCII text into a file. The file will be overwritten
* and contain only the given text.
*
* @param aFile An nsIFile representing the file to write or a string containing
* the file name of a file under user's profile.
* @param aData The string to write.
* @param aPerms The octal file permissions for the created file. If unset
* the default of 0600 is used.
*/
btoa: btoa,
saveStringToFile: function(aFile, aData, aPerms = 0o600) {
let file;
if (!(aFile instanceof Ci.nsIFile)) {
file = Services.dirsvc.get("ProfD", Ci.nsIFile);
file.append(aFile);
} else {
file = aFile;
}
getPhysicalMemorySize: function IOUtils_getPhysicalMemorySize() {
let foStream = Cc["@mozilla.org/network/safe-file-output-stream;1"]
.createInstance(Ci.nsIFileOutputStream);
// PR_WRONLY + PR_CREATE_FILE + PR_TRUNCATE
foStream.init(file, 0x02 | 0x08 | 0x20, aPerms, 0);
// safe-file-output-stream appears to throw an error if it doesn't write everything at once
// so we won't worry about looping to deal with partial writes.
// In case we try to use this function for big files where buffering
// is needed we could use the implementation in saveStreamToFile().
foStream.write(aData, aData.length);
foStream.QueryInterface(Ci.nsISafeOutputStream).finish();
foStream.close();
},
/**
* Saves the given input stream to a file.
*
* @param aIStream The input stream to save.
* @param aFile The file to which the stream is saved.
* @param aPerms The octal file permissions for the created file. If unset
* the default of 0600 is used.
*/
saveStreamToFile: function(aIStream, aFile, aPerms = 0o600) {
if (!(aIStream instanceof Ci.nsIInputStream))
throw new Error("Invalid stream passed to saveStreamToFile");
if (!(aFile instanceof Ci.nsIFile))
throw new Error("Invalid file passed to saveStreamToFile");
let fstream = Cc["@mozilla.org/network/safe-file-output-stream;1"]
.createInstance(Ci.nsIFileOutputStream);
let buffer = Cc["@mozilla.org/network/buffered-output-stream;1"]
.createInstance(Ci.nsIBufferedOutputStream);
// Write the input stream to the file.
// PR_WRITE + PR_CREATE + PR_TRUNCATE
fstream.init(aFile, 0x04 | 0x08 | 0x20, aPerms, 0);
buffer.init(fstream, kStreamBlockSize);
buffer.writeFrom(aIStream, aIStream.available());
// Close the output streams.
if (buffer instanceof Components.interfaces.nsISafeOutputStream)
buffer.finish();
else
buffer.close();
if (fstream instanceof Components.interfaces.nsISafeOutputStream)
fstream.finish();
else
fstream.close();
// Close the input stream.
aIStream.close();
return aFile;
},
/**
* Returns size of system memory.
*/
getPhysicalMemorySize: function() {
return Services.sysinfo.getPropertyAsInt64("memsize");
},
};

Просмотреть файл

@ -4,6 +4,7 @@
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource:///modules/mailServices.js");
Components.utils.import("resource:///modules/IOUtils.js");
var gDirTree = 0;
var abList = null;
@ -658,41 +659,6 @@ function getPhotoURI(aPhotoName) {
return Services.io.newFileURI(file).spec;
}
/**
* Saves the given input stream to a file.
*
* @param aIStream The input stream to save.
* @param aFile The file to which the stream is saved.
*/
function saveStreamToFile(aIStream, aFile) {
if (!(aIStream instanceof Components.interfaces.nsIInputStream))
throw "Invalid stream passed to saveStreamToFile";
if (!(aFile instanceof Components.interfaces.nsIFile))
throw "Invalid file passed to saveStreamToFile";
// Write the input stream to the file
var fstream = Components.classes["@mozilla.org/network/safe-file-output-stream;1"]
.createInstance(Components.interfaces.nsIFileOutputStream);
var buffer = Components.classes["@mozilla.org/network/buffered-output-stream;1"]
.createInstance(Components.interfaces.nsIBufferedOutputStream);
fstream.init(aFile, 0x04 | 0x08 | 0x20, parseInt("0600", 8), 0); // write, create, truncate
buffer.init(fstream, 8192);
buffer.writeFrom(aIStream, aIStream.available());
// Close the output streams
if (buffer instanceof Components.interfaces.nsISafeOutputStream)
buffer.finish();
else
buffer.close();
if (fstream instanceof Components.interfaces.nsISafeOutputStream)
fstream.finish();
else
fstream.close();
// Close the input stream
aIStream.close();
return aFile;
}
/**
* Copies the photo at the given URI in a folder named "Photos" in the current
* profile folder.
@ -719,7 +685,7 @@ function storePhoto(aUri) {
// Get the photo file
file = makePhotoFile(file, findPhotoExt(channel));
return saveStreamToFile(istream, file);
return IOUtils.saveStreamToFile(istream, file);
}
/**

Просмотреть файл

@ -7,6 +7,8 @@
* depends on jsTreeView.js being loaded before this script is loaded.
*/
Components.utils.import("resource:///modules/IOUtils.js");
/**
* Each abDirTreeItem corresponds to one row in the tree view.
*/
@ -90,24 +92,8 @@ directoryTreeView.prototype =
{
if (aJSONFile) {
// Parse our persistent-open-state json file
let file = Services.dirsvc.get("ProfD", Components.interfaces.nsIFile);
file.append(aJSONFile);
if (file.exists())
{
let data = "";
let fstream = Components.classes["@mozilla.org/network/file-input-stream;1"]
.createInstance(Components.interfaces.nsIFileInputStream);
let sstream = Components.classes["@mozilla.org/scriptableinputstream;1"]
.createInstance(Components.interfaces.nsIScriptableInputStream);
fstream.init(file, -1, 0, 0);
sstream.init(fstream);
while (sstream.available())
data += sstream.read(4096);
sstream.close();
fstream.close();
let data = IOUtils.loadFileToString(aJSONFile);
if (data) {
this._persistOpenMap = JSON.parse(data);
}
}
@ -123,14 +109,7 @@ directoryTreeView.prototype =
{
// Write out our json file...
let data = JSON.stringify(this._persistOpenMap);
let file = Services.dirsvc.get("ProfD", Components.interfaces.nsIFile);
file.append(aJSONFile);
let foStream = Components.classes["@mozilla.org/network/safe-file-output-stream;1"]
.createInstance(Components.interfaces.nsIFileOutputStream);
foStream.init(file, 0x02 | 0x08 | 0x20, parseInt("0666", 8), 0);
foStream.write(data, data.length);
foStream.QueryInterface(Components.interfaces.nsISafeOutputStream).finish();
foStream.close();
IOUtils.saveStringToFile(aJSONFile, data);
}
},