I've run into a weird problem again. I'm scanning through different
mailboxes and examine their messages, retrieving the raw message with
the help of a stream listener. Like following:
//code
emetStreamListener.pushHdr(aMessage);
messageService.CopyMessage(uri, emetStreamListener, false, null,
msgWindow, aurl);
//code
and
//code
var emetStreamListener = {
hdr:[],
bodyAndHdr: "",
pushHdr: function (aHdr) {
this.hdr.push(aHdr);
},
onDataAvailable: function(request, context, inputStream, offset, count)
{
try {
var sis =
Components.classes["@mozilla.org/scriptableinputstream;1"]
.createInstance(Components.interfaces.nsIScriptableInputStream);
sis.init(inputStream);
this.bodyAndHdr += sis.read(count);
}
catch(ex) { dump("StreamListener exception: "+ex.message+"\n"); }
},
onStartRequest: function(request, context)
{
//no function here
},
onStopRequest: function(aRequest, aContext, aStatusCode)
{
var hdr = this.hdr.shift();
emetHandleMessage(hdr,this.bodyAndHdr);
this.bodyAndHdr = ""; // clean up
}
}
//code
This works okay with IMAP boxes, but seems the stream listener gets
confused with POP boxes. The problem is, that when several messages are
processed with this code in POP, the raw messages become garbled
together. In IMAP, the stream listener fetches raw data one by one, but
with the POP box, several instances of the listener seem to get started
at the same time, which causes some weird raw data to be gotten.
I had intended to separate IMAP and POP processing with the following
(gotten from http://simon-cozens.org/programmer/articles/thunderbird-js.pod)
//code
if(aMessage.folder.hasMsgOffline(aMessage.messageKey)) {
emetReadOffline(aMessage);
} else {
emetReadOnline(aMessage);
}
//code
but seems the offline reader is never used (it doesn't use the listener).
As javascript has pretty lousy support for mutex/polling, I am bit stuck
with this one again... Is there way to block starting another listener
until first one is done?
I assume you are using Thunderbird 2 and do not want to require
Thunderbird 3. If this is not the case, Thunderbird 3 has many things
that can probably make your life easier...
I would suggest pausing your enumeration of the messages in a folder
when you decide to stream one. When the streaming completes (as
notified via onStopRequest), you can resume enumeration until you find
another message of interest. (The message enumerator does not have to
be consumed immediately; you can save it to a variable somewhere.)
When you receive the onStopRequest notification, you probably want to
use window.setTimeout to schedule the message enumeration in order to
keep the underlying C/C++ stack reasonable.
Andrew