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