blob: 12badcf7b06942017c6341745c922cc01c9f5677 [file] [log] [blame]
/*
* @author: ucla-cs
* See COPYING for copyright and distribution information.
*/
var EXPORTED_SYMBOLS = ["ContentChannel"];
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
/** Create an nsIChannel where asyncOpen calls requestContent(contentListener). When the content
is available, call contentListener.onReceivedContent(content, contentType, contentCharset),
which sends the content to the listener passed to asyncOpen and returns after calling its
onStopRequest.
*/
function ContentChannel(uri, requestContent) {
this.requestContent = requestContent;
this.done = false;
this.name = uri.spec;
// This is set by the caller of asyncOpen.
this.loadFlags = 0;
this.loadGroup = null;
this.status = 200;
// We don't know these yet.
this.contentLength = -1;
this.contentType = null;
this.contentCharset = null;
this.URI = uri;
this.originalURI = uri;
this.owner = null;
this.notificationCallback = null;
this.securityInfo = null;
}
ContentChannel.prototype = {
QueryInterface: function(aIID) {
if (aIID.equals(Ci.nsISupports))
return this;
if (aIID.equals(Ci.nsIRequest))
return this;
if (aIID.equals(Ci.nsIChannel))
return this;
throw Cr.NS_ERROR_NO_INTERFACE;
},
isPending: function() {
return !this.done;
},
cancel: function(aStatus){
this.status = aStatus;
this.done = true;
},
suspend: function(aStatus){
this.status = aStatus;
},
resume: function(aStatus){
this.status = aStatus;
},
open: function() {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
},
asyncOpen: function(aListener, aContext) {
try {
var thisContentChannel = this;
var threadManager = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager);
var callingThread = threadManager.currentThread;
var contentListener = {
onReceivedContent : function(content, contentType, contentCharset) {
thisContentChannel.contentLength = content.length;
thisContentChannel.contentType = contentType;
thisContentChannel.contentCharset = contentCharset;
var pipe = Cc["@mozilla.org/pipe;1"].createInstance(Ci.nsIPipe);
pipe.init(true, true, 0, 0, null);
pipe.outputStream.write(content, content.length);
pipe.outputStream.close();
// nsIChannel requires us to call aListener on its calling thread.
// Set dispatch flags to 1 to wait for it to finish.
callingThread.dispatch({
run: function() {
aListener.onStartRequest(thisContentChannel, aContext);
aListener.onDataAvailable(thisContentChannel, aContext,
pipe.inputStream, 0, content.length);
thisContentChannel.done = true;
aListener.onStopRequest(thisContentChannel, aContext,
thisContentChannel.status);
}
}, 1);
}
};
this.requestContent(contentListener);
} catch (ex) {
dump("ContentChannel.asyncOpen exception: " + ex + "\n");
}
}
};