diff --git a/toolkit/components/osfile/osfile_shared.jsm b/toolkit/components/osfile/osfile_shared.jsm index 3103e4d34687..b461724771df 100644 --- a/toolkit/components/osfile/osfile_shared.jsm +++ b/toolkit/components/osfile/osfile_shared.jsm @@ -174,12 +174,7 @@ */ let projectLargeInt = function projectLargeInt(x) { - if (ctypes.Int64.hi(x)) { - throw new Error("Number too large " + x + - "(signed, hi: " + ctypes.Int64.hi(x) + - ", lo:" + ctypes.Int64.lo(x) + ")"); - } - return ctypes.Int64.lo(x); + return parseInt(x.toString(), 10); }; let projectLargeUInt = function projectLargeUInt(x) { if (ctypes.UInt64.hi(x)) { @@ -432,5 +427,75 @@ } }; exports.OS.Shared.declareFFI = declareFFI; + + + /** + * Specific tools that don't really fit anywhere. + */ + let _aux = {}; + exports.OS.Shared._aux = _aux; + + /** + * Utility function shared by implementations of |OS.File.open|: + * extract read/write/trunc/create/existing flags from a |mode| + * object. + * + * @param {*=} mode An object that may contain fields |read|, + * |write|, |truncate|, |create|, |existing|. These fields + * are interpreted only if true-ish. + * @return {{read:bool, write:bool, trunc:bool, create:bool, + * existing:bool}} an object recapitulating the options set + * by |mode|. + * @throws {TypeError} If |mode| contains other fields, or + * if it contains both |create| and |truncate|, or |create| + * and |existing|. + */ + _aux.normalizeOpenMode = function normalizeOpenMode(mode) { + let result = { + read: false, + write: false, + trunc: false, + create: false, + existing: false + }; + for (let key in mode) { + if (!mode[key]) continue; // Only interpret true-ish keys + switch (key) { + case "read": + result.read = true; + break; + case "write": + result.write = true; + break; + case "truncate": // fallthrough + case "trunc": + result.trunc = true; + result.write = true; + break; + case "create": + result.create = true; + result.write = true; + break; + case "existing": // fallthrough + case "exist": + result.existing = true; + break; + default: + throw new TypeError("Mode " + key + " not understood"); + } + } + // Reject opposite modes + if (result.existing && result.create) { + throw new TypeError("Cannot specify both existing:true and create:true"); + } + if (result.trunc && result.create) { + throw new TypeError("Cannot specify both trunc:true and create:true"); + } + // Handle read/write + if (!result.write) { + result.read = true; + } + return result; + }; })(this); }