blob: 5fe86aa71c09bfe56d6593d0ba40f19f5ce6907a [file] [log] [blame]
Jeff Thompson745026e2012-10-13 12:49:20 -07001/*
2 * @author: ucla-cs
3 * See COPYING for copyright and distribution information.
4 * Implement getAsync and putAsync used by NDN using nsISocketTransportService.
5 * This is used inside Firefox XPCOM modules.
Jeff Thompson08ab3cd2012-10-08 02:56:20 -07006 */
7
8// Assume already imported the following:
9// Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
10// Components.utils.import("resource://gre/modules/NetUtil.jsm");
11
Jeff Thompson6aa338a2012-10-13 23:58:02 -070012/** Send outputData to host:port, read the entire response and call listener.onReceivedData(data)
13 * where data is a byte array.
14 * Code derived from http://stackoverflow.com/questions/7816386/why-nsiscriptableinputstream-is-not-working .
Jeff Thompson08ab3cd2012-10-08 02:56:20 -070015 */
16function readAllFromSocket(host, port, outputData, listener) {
17 var transportService = Components.classes["@mozilla.org/network/socket-transport-service;1"].getService
18 (Components.interfaces.nsISocketTransportService);
19 var pump = Components.classes["@mozilla.org/network/input-stream-pump;1"].createInstance
20 (Components.interfaces.nsIInputStreamPump);
21 var transport = transportService.createTransport(null, 0, host, port, null);
22 var outStream = transport.openOutputStream(1, 0, 0);
23 outStream.write(outputData, outputData.length);
24 outStream.flush();
25 var inStream = transport.openInputStream(0, 0, 0);
26 var dataListener = {
Jeff Thompson6aa338a2012-10-13 23:58:02 -070027 data: [],
Jeff Thompsondad617b2012-10-14 17:11:41 -070028 structureDecoder: new BinaryXMLStructureDecoder(),
Jeff Thompson08ab3cd2012-10-08 02:56:20 -070029 calledOnReceivedData: false,
Jeff Thompson6aa338a2012-10-13 23:58:02 -070030 debugNOnDataAvailable: 0,
Jeff Thompson08ab3cd2012-10-08 02:56:20 -070031
32 onStartRequest: function (request, context) {
33 },
34 onStopRequest: function (request, context, status) {
35 inStream.close();
36 outStream.close();
37 if (!this.calledOnReceivedData) {
38 this.calledOnReceivedData = true;
39 listener.onReceivedData(this.data);
40 }
41 },
42 onDataAvailable: function (request, context, _inputStream, offset, count) {
Jeff Thompsondad617b2012-10-14 17:11:41 -070043 if (this.calledOnReceivedData)
44 // Already finished. Ignore extra data.
45 return;
46
Jeff Thompson08ab3cd2012-10-08 02:56:20 -070047 try {
Jeff Thompson6aa338a2012-10-13 23:58:02 -070048 this.debugNOnDataAvailable += 1;
Jeff Thompson08ab3cd2012-10-08 02:56:20 -070049 // Ignore _inputStream and use inStream.
50 // Use readInputStreamToString to handle binary data.
Jeff Thompson6aa338a2012-10-13 23:58:02 -070051 var rawData = NetUtil.readInputStreamToString(inStream, count);
Jeff Thompson6aa338a2012-10-13 23:58:02 -070052 this.data = this.data.concat(DataUtils.toNumbersFromString(rawData));
Jeff Thompson08ab3cd2012-10-08 02:56:20 -070053
Jeff Thompsondad617b2012-10-14 17:11:41 -070054 // Scan the input to check if a whole ccnb object has been read.
55 if (this.structureDecoder.findElementEnd(this.data))
56 // Finish.
57 this.onStopRequest();
Jeff Thompson08ab3cd2012-10-08 02:56:20 -070058 } catch (ex) {
Jeff Thompson34419762012-10-15 22:24:12 -070059 dump("readAllFromSocket.onDataAvailable exception: " + ex + "\n");
Jeff Thompson08ab3cd2012-10-08 02:56:20 -070060 }
61 }
62 };
63
64 pump.init(inStream, -1, -1, 0, 0, true);
65 pump.asyncRead(dataListener, null);
66}
Jeff Thompson97f27432012-10-16 00:28:03 -070067