blob: 2dfb1ede7b7488995b5a7759abfd46c49069d0b1 [file] [log] [blame]
Jeff Thompson08ab3cd2012-10-08 02:56:20 -07001var EXPORTED_SYMBOLS = ["ContentChannel"];
2
3const Cc = Components.classes;
4const Ci = Components.interfaces;
5const Cr = Components.results;
6
7Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
8
9/** Create an nsIChannel where asyncOpen calls requestContent(contentListener). When the content
10 is available, call contentListener.onReceivedContent(content, contentType, contentCharset).
11 The content is sent to the listener passed to asyncOpen.
12 */
13function ContentChannel(uri, requestContent) {
14 this.requestContent = requestContent;
15
16 this.done = false;
17
18 this.name = uri;
19 this.loadFlags = 0;
20 this.loadGroup = null;
21 this.status = 200;
22
23 // We don't know these yet.
24 this.contentLength = -1;
25 this.contentType = null;
26 this.contentCharset = null;
27 this.URI = uri;
28 this.originalURI = uri;
29 this.owner = null;
30 this.notificationCallback = null;
31 this.securityInfo = null;
32}
33
34ContentChannel.prototype = {
35 QueryInterface: function(aIID) {
36 if (aIID.equals(Ci.nsISupports))
37 return this;
38
39 if (aIID.equals(Ci.nsIRequest))
40 return this;
41
42 if (aIID.equals(Ci.nsIChannel))
43 return this;
44
45 throw Cr.NS_ERROR_NO_INTERFACE;
46 },
47
48 isPending: function() {
49 return !this.done;
50 },
51
52 cancel: function(aStatus){
53 this.status = aStatus;
54 this.done = true;
55 },
56
57 suspend: function(aStatus){
58 this.status = aStatus;
59 },
60
61 resume: function(aStatus){
62 this.status = aStatus;
63 },
64
65 open: function() {
66 throw Cr.NS_ERROR_NOT_IMPLEMENTED;
67 },
68
69 asyncOpen: function(aListener, aContext) {
70 var thisContentChannel = this;
71 var contentListener = {
72 onReceivedContent : function(content, contentType, contentCharset) {
73 thisContentChannel.contentLength = content.length;
74 thisContentChannel.contentType = contentType;
75 thisContentChannel.contentCharset = contentCharset;
76
77 // Call aListener immediately to send all the content.
78 aListener.onStartRequest(thisContentChannel, aContext);
79
80 var pipe = Cc["@mozilla.org/pipe;1"].createInstance(Ci.nsIPipe);
81 pipe.init(true, true, 0, 0, null);
82 pipe.outputStream.write(content, content.length);
83 pipe.outputStream.close();
84
85 aListener.onDataAvailable(thisContentChannel, aContext, pipe.inputStream, 0, content.length);
86
87 thisContentChannel.done = true;
88 aListener.onStopRequest(thisContentChannel, aContext, thisContentChannel.status);
89 }
90 };
91
92 this.requestContent(contentListener);
93 }
94};