mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-25 01:47:31 +09:00
Issue #1258 - Part 1: Import mailnews, ldap, and mork from comm-esr52.9.1
This commit is contained in:
parent
23e0d82436
commit
e400f4130a
1564 changed files with 510348 additions and 0 deletions
155
mailnews/db/gloda/modules/utils.js
Normal file
155
mailnews/db/gloda/modules/utils.js
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
this.EXPORTED_SYMBOLS = ['GlodaUtils'];
|
||||
|
||||
var Cc = Components.classes;
|
||||
var Ci = Components.interfaces;
|
||||
var Cr = Components.results;
|
||||
var Cu = Components.utils;
|
||||
|
||||
Cu.import("resource:///modules/mailServices.js");
|
||||
|
||||
/**
|
||||
* @namespace A holding place for logic that is not gloda-specific and should
|
||||
* reside elsewhere.
|
||||
*/
|
||||
var GlodaUtils = {
|
||||
|
||||
/**
|
||||
* This Regexp is super-complicated and used at least in two different parts of
|
||||
* the code, so let's expose it from one single location.
|
||||
*/
|
||||
PART_RE: new RegExp("^[^?]+\\?(?:/;section=\\d+\\?)?(?:[^&]+&)*part=([^&]+)(?:&[^&]+)*$"),
|
||||
|
||||
deMime: function gloda_utils_deMime(aString) {
|
||||
return MailServices.mimeConverter.decodeMimeHeader(aString, null, false, true);
|
||||
},
|
||||
|
||||
_headerParser: MailServices.headerParser,
|
||||
|
||||
/**
|
||||
* Parses an RFC 2822 list of e-mail addresses and returns an object with
|
||||
* 4 attributes, as described below. We will use the example of the user
|
||||
* passing an argument of '"Bob Smith" <bob@example.com>'.
|
||||
*
|
||||
* This method (by way of nsIMsgHeaderParser) takes care of decoding mime
|
||||
* headers, but is not aware of folder-level character set overrides.
|
||||
*
|
||||
* count: the number of addresses parsed. (ex: 1)
|
||||
* addresses: a list of e-mail addresses (ex: ["bob@example.com"])
|
||||
* names: a list of names (ex: ["Bob Smith"])
|
||||
* fullAddresses: aka the list of name and e-mail together (ex: ['"Bob Smith"
|
||||
* <bob@example.com>']).
|
||||
*
|
||||
* This method is a convenience wrapper around nsIMsgHeaderParser.
|
||||
*/
|
||||
parseMailAddresses: function gloda_utils_parseMailAddresses(aMailAddresses) {
|
||||
let addresses = {}, names = {}, fullAddresses = {};
|
||||
this._headerParser.parseHeadersWithArray(aMailAddresses, addresses,
|
||||
names, fullAddresses);
|
||||
return {names: names.value, addresses: addresses.value,
|
||||
fullAddresses: fullAddresses.value,
|
||||
count: names.value.length};
|
||||
},
|
||||
|
||||
/**
|
||||
* MD5 hash a string and return the hex-string result. Impl from nsICryptoHash
|
||||
* docs.
|
||||
*/
|
||||
md5HashString: function gloda_utils_md5hash(aString) {
|
||||
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
|
||||
createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||
let trash = {};
|
||||
converter.charset = "UTF-8";
|
||||
let data = converter.convertToByteArray(aString, trash);
|
||||
|
||||
let hasher = Cc['@mozilla.org/security/hash;1'].
|
||||
createInstance(Ci.nsICryptoHash);
|
||||
hasher.init(Ci.nsICryptoHash.MD5);
|
||||
hasher.update(data, data.length);
|
||||
let hash = hasher.finish(false);
|
||||
|
||||
// return the two-digit hexadecimal code for a byte
|
||||
function toHexString(charCode) {
|
||||
return ("0" + charCode.toString(16)).slice(-2);
|
||||
}
|
||||
|
||||
// convert the binary hash data to a hex string.
|
||||
let hex = Object.keys(hash).map(i => toHexString(hash.charCodeAt(i)));
|
||||
return hex.join("");
|
||||
},
|
||||
|
||||
getCardForEmail: function gloda_utils_getCardForEmail(aAddress) {
|
||||
// search through all of our local address books looking for a match.
|
||||
let enumerator = MailServices.ab.directories;
|
||||
let cardForEmailAddress;
|
||||
let addrbook;
|
||||
while (!cardForEmailAddress && enumerator.hasMoreElements())
|
||||
{
|
||||
addrbook = enumerator.getNext().QueryInterface(Ci.nsIAbDirectory);
|
||||
try
|
||||
{
|
||||
cardForEmailAddress = addrbook.cardForEmailAddress(aAddress);
|
||||
if (cardForEmailAddress)
|
||||
return cardForEmailAddress;
|
||||
} catch (ex) {}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
_FORCE_GC_AFTER_NUM_HEADERS: 4096,
|
||||
_headersSeen: 0,
|
||||
/**
|
||||
* As |forceGarbageCollection| says, once XPConnect sees a header, it likes
|
||||
* to hold onto that reference. This method is used to track the number of
|
||||
* headers we have seen and force a GC when we have to.
|
||||
*
|
||||
* Ideally the indexer's idle-biased GC mechanism would take care of all the
|
||||
* GC; we are just a failsafe to make sure that our memory usage is bounded
|
||||
* based on the number of headers we have seen rather than just time.
|
||||
* Since holding onto headers can keep databases around too, this also
|
||||
* helps avoid keeping file handles open, etc.
|
||||
*
|
||||
* |forceGarbageCollection| will zero our tracking variable when a GC happens
|
||||
* so we are informed by the indexer's GC triggering.
|
||||
*
|
||||
* And of course, we don't want to trigger collections willy nilly because
|
||||
* they have a cost even if there is no garbage.
|
||||
*
|
||||
* @param aNumHeadersSeen The number of headers code has seen. A granularity
|
||||
* of hundreds of messages should be fine.
|
||||
*/
|
||||
considerHeaderBasedGC: function(aNumHeadersSeen) {
|
||||
this._headersSeen += aNumHeadersSeen;
|
||||
if (this._headersSeen >= this._FORCE_GC_AFTER_NUM_HEADERS)
|
||||
this.forceGarbageCollection();
|
||||
},
|
||||
|
||||
/**
|
||||
* Force a garbage-collection sweep. Gloda has to force garbage collection
|
||||
* periodically because XPConnect's XPCJSRuntime::DeferredRelease mechanism
|
||||
* can end up holding onto a ridiculously high number of XPConnect objects in
|
||||
* between normal garbage collections. This has mainly posed a problem
|
||||
* because nsAutolock is a jerk in DEBUG builds in 1.9.1, but in theory this
|
||||
* also helps us even out our memory usage.
|
||||
* We also are starting to do this more to try and keep the garbage collection
|
||||
* durations acceptable. We intentionally avoid triggering the cycle
|
||||
* collector in those cases, as we do presume a non-trivial fixed cost for
|
||||
* cycle collection. (And really all we want is XPConnect to not be a jerk.)
|
||||
* This method exists mainly to centralize our GC activities and because if
|
||||
* we do start involving the cycle collector, that is a non-trivial block of
|
||||
* code to copy-and-paste all over the place (at least in a module).
|
||||
*
|
||||
* @param aCycleCollecting Do we need the cycle collector to run? Currently
|
||||
* unused / unimplemented, but we would use
|
||||
* nsIDOMWindowUtils.garbageCollect() to do so.
|
||||
*/
|
||||
forceGarbageCollection:
|
||||
function gloda_utils_garbageCollection(aCycleCollecting) {
|
||||
Cu.forceGC();
|
||||
this._headersSeen = 0;
|
||||
}
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue