Rename NDNSocketTransport.js to XpcomTransport.js and implement expressInterest.
diff --git a/js/NDNSocketTransportService.js b/js/NDNSocketTransportService.js
deleted file mode 100644
index efe3194..0000000
--- a/js/NDNSocketTransportService.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * @author: Jeff Thompson
- * See COPYING for copyright and distribution information.
- * Implement getAsync and putAsync used by NDN using nsISocketTransportService.
- * This is used inside Firefox XPCOM modules.
- */
-
-// Assume already imported the following:
-// Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-// Components.utils.import("resource://gre/modules/NetUtil.jsm");
-
-/** Send outputData (Uint8Array) to host:port, read the entire response and call
- * listener.onReceivedData(data) where data is Uint8Array.
- * Code derived from http://stackoverflow.com/questions/7816386/why-nsiscriptableinputstream-is-not-working .
- */
-function readAllFromSocket(host, port, outputData, listener) {
- var transportService = Components.classes["@mozilla.org/network/socket-transport-service;1"].getService
- (Components.interfaces.nsISocketTransportService);
- var pump = Components.classes["@mozilla.org/network/input-stream-pump;1"].createInstance
- (Components.interfaces.nsIInputStreamPump);
- var transport = transportService.createTransport(null, 0, host, port, null);
- var outStream = transport.openOutputStream(1, 0, 0);
- var rawDataString = DataUtils.toString(outputData);
- outStream.write(rawDataString, rawDataString.length);
- outStream.flush();
- var inStream = transport.openInputStream(0, 0, 0);
- var dataListener = {
- data: new Uint8Array(0),
- structureDecoder: new BinaryXMLStructureDecoder(),
- calledOnReceivedData: false,
-
- onStartRequest: function (request, context) {
- },
- onStopRequest: function (request, context, status) {
- inStream.close();
- outStream.close();
- if (!this.calledOnReceivedData) {
- this.calledOnReceivedData = true;
- listener.onReceivedData(this.data);
- }
- },
- onDataAvailable: function (request, context, _inputStream, offset, count) {
- if (this.calledOnReceivedData)
- // Already finished. Ignore extra data.
- return;
-
- try {
- // Ignore _inputStream and use inStream.
- // Use readInputStreamToString to handle binary data.
- var rawData = NetUtil.readInputStreamToString(inStream, count);
- this.data = DataUtils.concatFromString(this.data, rawData);
-
- // Scan the input to check if a whole ccnb object has been read.
- if (this.structureDecoder.findElementEnd(this.data))
- // Finish.
- this.onStopRequest();
- } catch (ex) {
- dump("readAllFromSocket.onDataAvailable exception: " + ex + "\n");
- }
- }
- };
-
- pump.init(inStream, -1, -1, 0, 0, true);
- pump.asyncRead(dataListener, null);
-}
-
diff --git a/js/XpcomTransport.js b/js/XpcomTransport.js
new file mode 100644
index 0000000..643b918
--- /dev/null
+++ b/js/XpcomTransport.js
@@ -0,0 +1,111 @@
+/*
+ * @author: Jeff Thompson
+ * See COPYING for copyright and distribution information.
+ * Implement getAsync and putAsync used by NDN using nsISocketTransportService.
+ * This is used inside Firefox XPCOM modules.
+ */
+
+// Assume already imported the following:
+// Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+// Components.utils.import("resource://gre/modules/NetUtil.jsm");
+
+var XpcomTransport = function XpcomTransport() {
+};
+
+XpcomTransport.prototype.expressInterest = function(ndn, interest, closure) {
+ var binaryInterest = encodeToBinaryInterest(interest);
+
+ var dataListener = {
+ onReceivedData : function(data) {
+ if (data == null || data == undefined || data.length == 0)
+ dump("NDN.expressInterest: received empty data from socket.\n");
+ else {
+ var decoder = new BinaryXMLDecoder(data);
+ var co = new ContentObject();
+ co.from_ccnb(decoder);
+
+ if(LOG>2) {
+ dump("DECODED CONTENT OBJECT\n");
+ dump(co);
+ dump("\n");
+ }
+
+ // TODO: verify the content object and set kind to UPCALL_CONTENT.
+ var result = closure.upcall(Closure.UPCALL_CONTENT_UNVERIFIED,
+ new UpcallInfo(ndn, interest, 0, co));
+ if (result == Closure.RESULT_OK) {
+ // success
+ }
+ else if (result == Closure.RESULT_ERR)
+ dump("NDN.expressInterest: upcall returned RESULT_ERR.\n");
+ else if (result == Closure.RESULT_REEXPRESS)
+ XpcomTransport.readAllFromSocket(ndn.host, ndn.port, binaryInterest, dataListener);
+ else if (result == Closure.RESULT_VERIFY) {
+ // TODO: force verification of content.
+ }
+ else if (result == Closure.RESULT_FETCHKEY) {
+ // TODO: get the key in the key locator and re-call the interest
+ // with the key available in the local storage.
+ }
+ }
+ }
+ }
+
+ XpcomTransport.readAllFromSocket(ndn.host, ndn.port, binaryInterest, dataListener);
+};
+
+/** Send outputData (Uint8Array) to host:port, read the entire response and call
+ * listener.onReceivedData(data) where data is Uint8Array.
+ * Code derived from http://stackoverflow.com/questions/7816386/why-nsiscriptableinputstream-is-not-working .
+ */
+XpcomTransport.readAllFromSocket = function(host, port, outputData, listener) {
+ var transportService = Components.classes["@mozilla.org/network/socket-transport-service;1"].getService
+ (Components.interfaces.nsISocketTransportService);
+ var pump = Components.classes["@mozilla.org/network/input-stream-pump;1"].createInstance
+ (Components.interfaces.nsIInputStreamPump);
+ var transport = transportService.createTransport(null, 0, host, port, null);
+ var outStream = transport.openOutputStream(1, 0, 0);
+ var rawDataString = DataUtils.toString(outputData);
+ outStream.write(rawDataString, rawDataString.length);
+ outStream.flush();
+ var inStream = transport.openInputStream(0, 0, 0);
+ var dataListener = {
+ data: new Uint8Array(0),
+ structureDecoder: new BinaryXMLStructureDecoder(),
+ calledOnReceivedData: false,
+
+ onStartRequest: function (request, context) {
+ },
+ onStopRequest: function (request, context, status) {
+ inStream.close();
+ outStream.close();
+ if (!this.calledOnReceivedData) {
+ this.calledOnReceivedData = true;
+ listener.onReceivedData(this.data);
+ }
+ },
+ onDataAvailable: function (request, context, _inputStream, offset, count) {
+ if (this.calledOnReceivedData)
+ // Already finished. Ignore extra data.
+ return;
+
+ try {
+ // Ignore _inputStream and use inStream.
+ // Use readInputStreamToString to handle binary data.
+ var rawData = NetUtil.readInputStreamToString(inStream, count);
+ this.data = DataUtils.concatFromString(this.data, rawData);
+
+ // Scan the input to check if a whole ccnb object has been read.
+ if (this.structureDecoder.findElementEnd(this.data))
+ // Finish.
+ this.onStopRequest();
+ } catch (ex) {
+ dump("readAllFromSocket.onDataAvailable exception: " + ex + "\n");
+ }
+ }
+ };
+
+ pump.init(inStream, -1, -1, 0, 0, true);
+ pump.asyncRead(dataListener, null);
+}
+
diff --git a/js/ccnxProtocol.xpi b/js/ccnxProtocol.xpi
index 206ed0e..b8ab92f 100644
--- a/js/ccnxProtocol.xpi
+++ b/js/ccnxProtocol.xpi
Binary files differ
diff --git a/js/ccnxProtocol/components/ccnxProtocolService.js b/js/ccnxProtocol/components/ccnxProtocolService.js
index 95e00bd..f5d526d 100644
--- a/js/ccnxProtocol/components/ccnxProtocolService.js
+++ b/js/ccnxProtocol/components/ccnxProtocolService.js
@@ -1,5 +1,5 @@
/*
- * @author: ucla-cs
+ * @author: Jeff Thompson
* See COPYING for copyright and distribution information.
* This is the ccnx protocol handler for NDN.
* Protocol handling code derived from http://mike.kaply.com/2011/01/18/writing-a-firefox-protocol-handler/
@@ -23,6 +23,7 @@
protocolFlags: nsIProtocolHandler.URI_NORELATIVE |
nsIProtocolHandler.URI_NOAUTH |
nsIProtocolHandler.URI_LOADABLE_BY_ANYONE,
+ transport: new XpcomTransport(),
newURI: function(aSpec, aOriginCharset, aBaseURI)
{
@@ -33,6 +34,8 @@
newChannel: function(aURI)
{
+ var thisCcnxProtocol = this;
+
try {
var trimmedSpec = aURI.spec.trim();
@@ -49,7 +52,9 @@
// TODO: Strip off an ending implicit digest before checking the last component?
var uriEndsWithSegmentNumber = endsWithSegmentNumber(name);
- var ndn = new NDN("lioncub.metwi.ucla.edu");
+ var ndn = new NDN({ host: "lioncub.metwi.ucla.edu", port: 9695,
+ // Use the same transport object each time.
+ getTransport: function() { return thisCcnxProtocol.transport; } });
ndn.expressInterest(name, new ContentClosure
(ndn, contentListener, uriEndsWithSegmentNumber, aURI.originCharset));
};
diff --git a/js/ccnxProtocol/modules/make-ndn-js.jsm.sh b/js/ccnxProtocol/modules/make-ndn-js.jsm.sh
index dbead82..78c52c7 100755
--- a/js/ccnxProtocol/modules/make-ndn-js.jsm.sh
+++ b/js/ccnxProtocol/modules/make-ndn-js.jsm.sh
@@ -2,7 +2,7 @@
cat ndn-js-header.txt \
../../Closure.js emptyLine.txt \
../../NDN.js emptyLine.txt \
- ../../NDNSocketTransportService.js emptyLine.txt \
+ ../../XpcomTransport.js emptyLine.txt \
../../util/CCNProtocolDTags.js emptyLine.txt \
../../util/CCNTime.js emptyLine.txt \
../../Name.js emptyLine.txt \
diff --git a/js/ccnxProtocol/modules/ndn-js-header.txt b/js/ccnxProtocol/modules/ndn-js-header.txt
index f56b59e..0660198 100644
--- a/js/ccnxProtocol/modules/ndn-js-header.txt
+++ b/js/ccnxProtocol/modules/ndn-js-header.txt
@@ -6,7 +6,7 @@
*/
var EXPORTED_SYMBOLS = ["NDN", "Closure", "Name", "Interest", "ContentObject",
- "DataUtils", "MimeTypes"];
+ "DataUtils", "MimeTypes", "XpcomTransport"];
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/NetUtil.jsm");
diff --git a/js/ccnxProtocol/modules/ndn-js.jsm b/js/ccnxProtocol/modules/ndn-js.jsm
index 30641f7..268435c 100644
--- a/js/ccnxProtocol/modules/ndn-js.jsm
+++ b/js/ccnxProtocol/modules/ndn-js.jsm
@@ -6,7 +6,7 @@
*/
var EXPORTED_SYMBOLS = ["NDN", "Closure", "Name", "Interest", "ContentObject",
- "DataUtils", "MimeTypes"];
+ "DataUtils", "MimeTypes", "XpcomTransport"];
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/NetUtil.jsm");
@@ -92,20 +92,32 @@
}
/*
- * @author: ucla-cs
+ * @author: Meki Cherkaoui, Jeff Thompson, Wentao Shang
* See COPYING for copyright and distribution information.
* This class represents the top-level object for communicating with an NDN host.
*/
+var LOG = 3;
+
/**
- * host is default '127.0.0.1'.
- * port is default 9695.
+ * settings is an associative array with the following defaults:
+ * {
+ * host: 'localhost',
+ * port: 9696,
+ * getTransport: function() { return new WebSocketTransport(); }
+ * }
*/
-var NDN = function NDN(host, port){
- this.host = (host || '127.0.0.1');
- this.port = (port || 9695);
+var NDN = function NDN(settings) {
+ settings = (settings || {});
+ this.host = (settings.host || "localhost");
+ this.port = (settings.port || 9696);
+ var getTransport = (settings.getTransport || function() { return new WebSocketTransport(); });
+ this.transport = getTransport();
};
+
+/* Java Socket Bridge and XPCOM transport */
+
NDN.prototype.createRoute = function(host,port){
this.host=host;
this.port=port;
@@ -119,32 +131,32 @@
console.log('INVALID INPUT TO GET');
return null;
}
-
-
+
+
//var array = Name.createNameArray(message);
int = new Interest(new Name(message));
int.InterestLifetime = 4200;
-
+
var hex = encodeToHexInterest(int);
-
+
//var result = get_java_socket_bridge().connectAndStart(ndnurl,ndnport,hex);
-
+
var result = get(this.host,this.port, hex);
if(LOG>0)console.log('BINARY RESPONSE IS ' +result);
-
+
if(result==null || result==undefined || result =="" ){
/*if(result[0] != '0'||result[1]!='4') {
if(LOG>2)console.log('INVALID ANSWER');
}*/
return null;
}
-
+
else{
-
+
co = decodeHexContentObject(result);
if(LOG>2) {
@@ -161,76 +173,76 @@
return null;
}
-
+
}
NDN.prototype.put = function(name,content){
if(this.host!=null && this.port!=null){
-
+
var co = this.get("/%C1.M.S.localhost/%C1.M.SRV/ccnd");
-
+
if(!co || !co.signedInfo || !co.signedInfo.publisher || !co.signedInfo.publisher.publisherPublicKeyDigest){
alert("Cannot contact router");
-
+
return null;
}
-
+
var ccnxnodename = co.signedInfo.publisher.publisherPublicKeyDigest;
-
+
name = name.trim();
-
+
var fe = new ForwardingEntry('selfreg',new Name(name),null, null, 3,2147483647);
-
+
var bytes = encodeForwardingEntry(fe);
-
-
+
+
var si = new SignedInfo();
si.setFields();
-
+
var co = new ContentObject(new Name(),si,bytes,new Signature());
co.sign();
-
+
var coBinary = encodeToBinaryContentObject(co);
-
+
//var ccnxnodename = unescape('%E0%A0%1E%099h%F9t%0C%E7%F46%1B%AB%F5%BB%05%A4%E5Z%AC%A5%E5%8Fs%ED%DE%B8%E0%13%AA%8F');
-
+
var interestName = new Name(['ccnx',ccnxnodename,'selfreg',coBinary]);
int = new Interest(interestName);
int.scope = 1;
-
+
var hex = encodeToHexInterest(int);
console.log('GOING TO PUT INTEREST OBJECT');
-
+
console.log(hex);
-
+
//var result = put(this.host,this.port, hex,name);
-
+
//if(LOG>3)console.log('received interest'); //from host'+ host +':'+port+' with name '+name);
-
+
//if(LOG>3)console.log('DATA ');
-
+
//if(LOG>3)console.log(result);
-
+
//interest = decodeHexInterest(result);
-
+
//console.log('SUCCESSFULLY PARSED INTEREST');
-
+
console.log('CREATING ANSWER');
var si = new SignedInfo();
si.setFields();
-
+
var answer = DataUtils.toNumbersFromString(content);
var co = new ContentObject(new Name(name),si,answer,new Signature());
co.sign();
-
-
+
+
var outputHex = encodeToHexContentObject(co);
-
+
//console.log('SENDING ANSWER');
//return get_java_socket_bridge().putAnswer(outputHex,name);
@@ -264,7 +276,7 @@
return;
}
- interest = new Interest(name);
+ var interest = new Interest(name);
if (template != null) {
interest.minSuffixComponents = template.minSuffixComponents;
interest.maxSuffixComponents = template.maxSuffixComponents;
@@ -278,14 +290,32 @@
else
interest.interestLifetime = 4200;
- var encoder = new BinaryXMLEncoder();
- interest.to_ccnb(encoder);
- var outputData = encoder.getReducedOstream();
- encoder = null;
-
- // Make a local variable so it is not masked by an inner this.
- var ndn = this;
- var dataListener = {
+ this.transport.expressInterest(this, interest, closure);
+};
+
+
+NDN.prototype.registerPrefix = function(name, closure, flag) {
+ return this.transport.registerPrefix(this, name, closure, flag);
+}
+
+/*
+ * @author: Jeff Thompson
+ * See COPYING for copyright and distribution information.
+ * Implement getAsync and putAsync used by NDN using nsISocketTransportService.
+ * This is used inside Firefox XPCOM modules.
+ */
+
+// Assume already imported the following:
+// Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+// Components.utils.import("resource://gre/modules/NetUtil.jsm");
+
+var XpcomTransport = function XpcomTransport() {
+};
+
+XpcomTransport.prototype.expressInterest = function(ndn, interest, closure) {
+ var binaryInterest = encodeToBinaryInterest(interest);
+
+ var dataListener = {
onReceivedData : function(data) {
if (data == null || data == undefined || data.length == 0)
dump("NDN.expressInterest: received empty data from socket.\n");
@@ -299,7 +329,7 @@
dump(co);
dump("\n");
}
-
+
// TODO: verify the content object and set kind to UPCALL_CONTENT.
var result = closure.upcall(Closure.UPCALL_CONTENT_UNVERIFIED,
new UpcallInfo(ndn, interest, 0, co));
@@ -309,7 +339,7 @@
else if (result == Closure.RESULT_ERR)
dump("NDN.expressInterest: upcall returned RESULT_ERR.\n");
else if (result == Closure.RESULT_REEXPRESS)
- readAllFromSocket(ndn.host, ndn.port, outputData, dataListener);
+ XpcomTransport.readAllFromSocket(ndn.host, ndn.port, binaryInterest, dataListener);
else if (result == Closure.RESULT_VERIFY) {
// TODO: force verification of content.
}
@@ -319,30 +349,16 @@
}
}
}
- }
-
- // The application includes a source file that defines readAllFromSocket
- // according to the application's communication method.
- readAllFromSocket(this.host, this.port, outputData, dataListener);
+ }
+
+ XpcomTransport.readAllFromSocket(ndn.host, ndn.port, binaryInterest, dataListener);
};
-
-/*
- * @author: ucla-cs
- * See COPYING for copyright and distribution information.
- * Implement getAsync and putAsync used by NDN using nsISocketTransportService.
- * This is used inside Firefox XPCOM modules.
- */
-
-// Assume already imported the following:
-// Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-// Components.utils.import("resource://gre/modules/NetUtil.jsm");
-
-/** Send outputData (byte array) to host:port, read the entire response and call
- * listener.onReceivedData(data) where data is a byte array.
+/** Send outputData (Uint8Array) to host:port, read the entire response and call
+ * listener.onReceivedData(data) where data is Uint8Array.
* Code derived from http://stackoverflow.com/questions/7816386/why-nsiscriptableinputstream-is-not-working .
*/
-function readAllFromSocket(host, port, outputData, listener) {
+XpcomTransport.readAllFromSocket = function(host, port, outputData, listener) {
var transportService = Components.classes["@mozilla.org/network/socket-transport-service;1"].getService
(Components.interfaces.nsISocketTransportService);
var pump = Components.classes["@mozilla.org/network/input-stream-pump;1"].createInstance
@@ -354,7 +370,7 @@
outStream.flush();
var inStream = transport.openInputStream(0, 0, 0);
var dataListener = {
- data: [],
+ data: new Uint8Array(0),
structureDecoder: new BinaryXMLStructureDecoder(),
calledOnReceivedData: false,
@@ -377,7 +393,7 @@
// Ignore _inputStream and use inStream.
// Use readInputStreamToString to handle binary data.
var rawData = NetUtil.readInputStreamToString(inStream, count);
- this.data = this.data.concat(DataUtils.toNumbersFromString(rawData));
+ this.data = DataUtils.concatFromString(this.data, rawData);
// Scan the input to check if a whole ccnb object has been read.
if (this.structureDecoder.findElementEnd(this.data))
@@ -872,16 +888,29 @@
var n1 = this.encodeObject(this.name);
var n2 = this.encodeObject(this.signedInfo);
var n3 = this.encodeContent();
+ /*console.log('sign: ');
+ console.log(n1);
+ console.log(n2);
+ console.log(n3);*/
- var n = n1.concat(n2,n3);
+ //var n = n1.concat(n2,n3);
+ var tempBuf = new ArrayBuffer(n1.length + n2.length + n3.length);
+ var n = new Uint8Array(tempBuf);
+ //console.log(n);
+ n.set(n1, 0);
+ //console.log(n);
+ n.set(n2, n1.length);
+ //console.log(n);
+ n.set(n3, n1.length + n2.length);
+ //console.log(n);
- if(LOG>2)console.log('Signature Data is (binary) '+n);
+ if(LOG>4)console.log('Signature Data is (binary) '+n);
- if(LOG>2)console.log('Signature Data is (RawString)');
+ if(LOG>4)console.log('Signature Data is (RawString)');
- if(LOG>2)console.log( DataUtils.toString(n) );
+ if(LOG>4)console.log( DataUtils.toString(n) );
- var sig = DataUtils.toString(n);
+ //var sig = DataUtils.toString(n);
var rsa = new RSAKey();
@@ -893,11 +922,11 @@
var hSig = rsa.signByteArrayWithSHA256(n);
- if(LOG>2)console.log('SIGNATURE SAVED IS');
+ if(LOG>4)console.log('SIGNATURE SAVED IS');
- if(LOG>2)console.log(hSig);
+ if(LOG>4)console.log(hSig);
- if(LOG>2)console.log( DataUtils.toNumbers(hSig.trim()));
+ if(LOG>4)console.log( DataUtils.toNumbers(hSig.trim()));
this.signature.signature = DataUtils.toNumbers(hSig.trim());
@@ -930,7 +959,7 @@
ContentObject.prototype.saveRawData = function(bytes){
- var sigBits = bytes.slice(this.startSIG, this.endSIG );
+ var sigBits = bytes.subarray(this.startSIG, this.endSIG);
this.rawSignatureData = sigBits;
};
@@ -1127,8 +1156,8 @@
var publicKeyHex = globalKeyManager.publicKey;
- console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
- console.log(publicKeyHex);
+ if(LOG>4)console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
+ if(LOG>4)console.log(publicKeyHex);
var publicKeyBytes = DataUtils.toNumbers(globalKeyManager.publicKey) ;
@@ -1166,8 +1195,8 @@
//if(LOG>4)console.log('toNumbersFromString(stringCertificate) '+DataUtils.toNumbersFromString(stringCertificate));
- console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
- console.log(publicKeyBytes);
+ if(LOG>4)console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
+ if(LOG>4)console.log(publicKeyBytes);
this.locator = new KeyLocator( publicKeyBytes ,KeyLocatorType.KEY );
@@ -1678,7 +1707,7 @@
this.keyName = _input;
}
else if(_type==KeyLocatorType.KEY){
- console.log('SET KEY');
+ if(LOG>4)console.log('SET KEY');
this.publicKey = _input;
}
else if(_type==KeyLocatorType.CERTIFICATE){
@@ -1750,7 +1779,7 @@
KeyLocator.prototype.to_ccnb = function( encoder) {
- if(LOG>2) console.log('type is is ' + this.type);
+ if(LOG>4) console.log('type is is ' + this.type);
//TODO Check if Name is missing
if (!this.validate()) {
throw new ContentEncodingException("Cannot encode " + this.getClass().getName() + ": field values missing.");
@@ -2295,37 +2324,37 @@
var BinaryXMLEncoder = function BinaryXMLEncoder(){
-
- this.ostream = new Array(10000);
-
-
+ this.ostream = new Uint8Array(10000);
this.offset =0;
-
this.CODEC_NAME = "Binary";
-
};
-BinaryXMLEncoder.prototype.writeUString = function(/*String*/ utf8Content){
+
+BinaryXMLEncoder.prototype.writeUString = function(/*String*/ utf8Content) {
this.encodeUString(this.ostream, utf8Content, XML_UDATA);
};
-BinaryXMLEncoder.prototype.writeBlob = function(/*byte []*/ binaryContent
+
+BinaryXMLEncoder.prototype.writeBlob = function(
+ /*Uint8Array*/ binaryContent
//, /*int*/ offset, /*int*/ length
- ) {
+ ) {
if(LOG >3) console.log(binaryContent);
this.encodeBlob(this.ostream, binaryContent, this.offset, binaryContent.length);
};
-BinaryXMLEncoder.prototype.writeStartElement = function(/*String*/ tag, /*TreeMap<String,String>*/ attributes){
- /*Long*/ dictionaryVal = tag;//stringToTag(tag);
+BinaryXMLEncoder.prototype.writeStartElement = function(
+ /*String*/ tag,
+ /*TreeMap<String,String>*/ attributes
+ ) {
+
+ /*Long*/ dictionaryVal = tag; //stringToTag(tag);
if (null == dictionaryVal) {
-
this.encodeUString(this.ostream, tag, XML_TAG);
-
} else {
this.encodeTypeAndVal(XML_DTAG, dictionaryVal, this.ostream);
}
@@ -2336,14 +2365,13 @@
};
-BinaryXMLEncoder.prototype.writeEndElement = function(){
-
+BinaryXMLEncoder.prototype.writeEndElement = function() {
this.ostream[this.offset] = XML_CLOSE;
- this.offset+= 1;
+ this.offset += 1;
}
+
BinaryXMLEncoder.prototype.writeAttributes = function(/*TreeMap<String,String>*/ attributes) {
-
if (null == attributes) {
return;
}
@@ -2368,10 +2396,9 @@
this.encodeUString(this.ostream, strValue);
}
-
-
}
+
//returns a string
stringToTag = function(/*long*/ tagVal) {
if ((tagVal >= 0) && (tagVal < CCNProtocolDTagsStrings.length)) {
@@ -2403,45 +2430,35 @@
//byte[]
Content,
//TreeMap<String, String>
- attributes) {
-
+ attributes
+ ) {
this.writeStartElement(tag, attributes);
// Will omit if 0-length
if(typeof Content === 'number') {
- if(LOG>4) console.log('GOING TO WRITE THE NUMBER .charCodeAt(0) ' +Content.toString().charCodeAt(0) );
- if(LOG>4) console.log('GOING TO WRITE THE NUMBER ' +Content.toString() );
- if(LOG>4) console.log('type of number is ' +typeof Content.toString() );
-
-
+ if(LOG>4) console.log('GOING TO WRITE THE NUMBER .charCodeAt(0) ' + Content.toString().charCodeAt(0) );
+ if(LOG>4) console.log('GOING TO WRITE THE NUMBER ' + Content.toString() );
+ if(LOG>4) console.log('type of number is ' + typeof Content.toString() );
this.writeUString(Content.toString());
//whatever
-
}
-
else if(typeof Content === 'string'){
- if(LOG>4) console.log('GOING TO WRITE THE STRING ' +Content );
- if(LOG>4) console.log('type of STRING is ' +typeof Content );
+ if(LOG>4) console.log('GOING TO WRITE THE STRING ' + Content );
+ if(LOG>4) console.log('type of STRING is ' + typeof Content );
this.writeUString(Content);
}
-
else{
- //else if(typeof Content === 'string'){
- //console.log('went here');
- //this.writeBlob(Content);
- //}
- if(LOG>4) console.log('GOING TO WRITE A BLOB ' +Content );
- //else if(typeof Content === 'object'){
+ if(LOG>4) console.log('GOING TO WRITE A BLOB ' + Content );
+
this.writeBlob(Content);
- //}
}
this.writeEndElement();
}
-//TODO
+
var TypeAndVal = function TypeAndVal(_type,_val) {
this.type = _type;
@@ -2449,17 +2466,19 @@
};
+
BinaryXMLEncoder.prototype.encodeTypeAndVal = function(
//int
type,
//long
val,
- //byte []
- buf) {
+ //ArrayBufferView
+ ostream
+ ) {
- if(LOG>4)console.log('Encoding type '+ type+ ' and value '+ val);
+ if(LOG>4) console.log('Encoding type '+ type+ ' and value '+ val);
- if(LOG>4) console.log('OFFSET IS ' + this.offset );
+ if(LOG>4) console.log('OFFSET IS ' + this.offset);
if ((type > XML_UDATA) || (type < 0) || (val < 0)) {
throw new Error("Tag and value must be positive, and tag valid.");
@@ -2468,14 +2487,14 @@
// Encode backwards. Calculate how many bytes we need:
var numEncodingBytes = this.numEncodingBytes(val);
- if ((this.offset + numEncodingBytes) > buf.length) {
- throw new Error("Buffer space of " + (buf.length-this.offset) +
+ if ((this.offset + numEncodingBytes) > ostream.length) {
+ throw new Error("Buffer space of " + (ostream.length - this.offset) +
" bytes insufficient to hold " +
numEncodingBytes + " of encoded type and value.");
}
// Bottom 4 bits of val go in last byte with tag.
- buf[this.offset + numEncodingBytes - 1] =
+ ostream[this.offset + numEncodingBytes - 1] =
//(byte)
(BYTE_MASK &
(((XML_TT_MASK & type) |
@@ -2487,9 +2506,8 @@
// is "more" flag.
var i = this.offset + numEncodingBytes - 2;
while ((0 != val) && (i >= this.offset)) {
- buf[i] = //(byte)
- (BYTE_MASK &
- (val & XML_REG_VAL_MASK)); // leave top bit unset
+ ostream[i] = //(byte)
+ (BYTE_MASK & (val & XML_REG_VAL_MASK)); // leave top bit unset
val = val >>> XML_REG_VAL_BITS;
--i;
}
@@ -2502,6 +2520,7 @@
return numEncodingBytes;
};
+
BinaryXMLEncoder.prototype.encodeUString = function(
//OutputStream
ostream,
@@ -2514,23 +2533,15 @@
return;
}
-
- //byte [] data utils
- /*custom*/
- //byte[]
-
if(LOG>3) console.log("The string to write is ");
-
if(LOG>3) console.log(ustring);
//COPY THE STRING TO AVOID PROBLEMS
strBytes = new Array(ustring.length);
-
- var i = 0;
- for( ; i<ustring.length; i++) //in InStr.ToCharArray())
+ for (i = 0; i < ustring.length; i++) //in InStr.ToCharArray())
{
- if(LOG>3)console.log("ustring[" + i + '] = ' + ustring[i]);
+ if(LOG>3) console.log('ustring[' + i + '] = ' + ustring[i]);
strBytes[i] = ustring.charCodeAt(i);
}
@@ -2546,9 +2557,7 @@
if(LOG>3) console.log(strBytes);
this.writeString(strBytes,this.offset);
-
this.offset+= strBytes.length;
-
};
@@ -2556,7 +2565,7 @@
BinaryXMLEncoder.prototype.encodeBlob = function(
//OutputStream
ostream,
- //byte []
+ //Uint8Array
blob,
//int
offset,
@@ -2569,21 +2578,17 @@
if(LOG>4) console.log('LENGTH OF XML_BLOB IS '+length);
+ /*blobCopy = new Array(blob.Length);
- blobCopy = new Array(blob.Length);
- var i = 0;
- for( ;i<blob.length;i++) //in InStr.ToCharArray())
+ for (i = 0; i < blob.length; i++) //in InStr.ToCharArray())
{
blobCopy[i] = blob[i];
- }
+ }*/
- this.encodeTypeAndVal(XML_BLOB, length, ostream,offset);
-
- if (null != blob) {
+ this.encodeTypeAndVal(XML_BLOB, length, ostream, offset);
- this.writeBlobArray(blobCopy,this.offset);
- this.offset += length;
- }
+ this.writeBlobArray(blob, this.offset);
+ this.offset += length;
};
var ENCODING_LIMIT_1_BYTE = ((1 << (XML_TT_VAL_BITS)) - 1);
@@ -2630,13 +2635,10 @@
if(LOG>4)console.log('ENCODING DATE with BINARY VALUE');
if(LOG>4)console.log(binarydate);
-
if(LOG>4)console.log('ENCODING DATE with BINARY VALUE(HEX)');
if(LOG>4)console.log(DataUtils.toHex(binarydate));
-
this.writeElement(tag, binarydate);
-
};
BinaryXMLEncoder.prototype.writeString = function(
@@ -2650,19 +2652,16 @@
if(LOG>4) console.log('GOING TO WRITE A STRING');
if(LOG>4) console.log(input);
- for (var i = 0; i < input.length; i++) {
+ for (i = 0; i < input.length; i++) {
if(LOG>4) console.log('input.charCodeAt(i)=' + input.charCodeAt(i));
this.ostream[this.offset+i] = (input.charCodeAt(i));
}
}
-
else{
-
- if(LOG>4) console.log('GOING TO WRITE A STRING IN BINARY FORM');
- if(LOG>4) console.log(input);
-
- this.writeBlobArray(input);
-
+ if(LOG>4) console.log('GOING TO WRITE A STRING IN BINARY FORM');
+ if(LOG>4) console.log(input);
+
+ this.writeBlobArray(input);
}
/*
else if(typeof input === 'object'){
@@ -2671,26 +2670,24 @@
*/
};
+
BinaryXMLEncoder.prototype.writeBlobArray = function(
- //String
- Blob,
- //CCNTime
+ //Uint8Array
+ blob,
+ //int
offset) {
if(LOG>4) console.log('GOING TO WRITE A BLOB');
- for (var i = 0; i < Blob.length; i++) {
+ /*for (var i = 0; i < Blob.length; i++) {
this.ostream[this.offset+i] = Blob[i];
- }
-
+ }*/
+ this.ostream.set(blob, this.offset);
};
-
BinaryXMLEncoder.prototype.getReducedOstream = function() {
-
- return this.ostream.slice(0,this.offset);
-
+ return this.ostream.subarray(0, this.offset);
};
@@ -3233,12 +3230,11 @@
};
-//byte[]
+//Uint8Array
BinaryXMLDecoder.prototype.decodeBlob = function(
//int
blobLength) {
-
if(null == blobLength){
//TypeAndVal
tv = this.decodeTypeAndVal();
@@ -3256,12 +3252,10 @@
}
//
- //byte []
-
- var bytes = this.istream.slice(this.offset, this.offset+ blobLength);
+ //Uint8Array
+ var bytes = this.istream.subarray(this.offset, this.offset+ blobLength);
this.offset += blobLength;
- //int
return bytes;
};
@@ -3375,9 +3369,6 @@
TypeAndVal.prototype.val = function(){
return this.v;
};
-//TODO
-
-
@@ -3409,13 +3400,14 @@
return strElementText;
};
+
/*
* Set the offset into the input, used for the next read.
*/
BinaryXMLDecoder.prototype.seek = function(
//int
offset) {
- this.offset = offset;
+ this.offset = offset;
}
/*
@@ -3431,7 +3423,6 @@
ContentDecodingException.prototype.name = "ContentDecodingException";
-
/*
* This class uses BinaryXMLDecoder to follow the structure of a ccnb binary element to
* determine its end.
@@ -3764,32 +3755,19 @@
return byteArray;
};
*/
-
-/**
- * Byte Array to Hex String
- */
-DataUtils.byteArrayToHexString = function(byteArray) {
- var str = '';
- for (var i = 0; i < byteArray.length; i++)
- str += byteArray[i] <= 0x7F?
- byteArray[i] === 0x25 ? "%25" : // %
- String.fromCharCode(byteArray[i]) :
- "%" + byteArray[i].toString(16).toUpperCase();
- return decodeURIComponent(str);
-};
-
/**
- * Byte array to Hex String
+ * Uint8Array to Hex String
*/
//http://ejohn.org/blog/numbers-hex-and-colors/
DataUtils.toHex = function(arguments){
- if(LOG>4) console.log('ABOUT TO CONVERT '+ arguments);
- //console.log(arguments);
- var ret = "";
- for ( var i = 0; i < arguments.length; i++ )
- ret += (arguments[i] < 16 ? "0" : "") + arguments[i].toString(16);
- return ret; //.toUpperCase();
+ if (LOG>4) console.log('ABOUT TO CONVERT '+ arguments);
+ //console.log(arguments);
+ var ret = "";
+ for ( var i = 0; i < arguments.length; i++ )
+ ret += (arguments[i] < 16 ? "0" : "") + arguments[i].toString(16);
+ if (LOG>4) console.log('Converted to: ' + ret);
+ return ret; //.toUpperCase();
}
/**
@@ -3805,9 +3783,8 @@
}
/**
- * Byte array to raw string
+ * Uint8Array to raw string.
*/
-//DOES NOT SEEM TO WORK
DataUtils.toString = function(arguments){
//console.log(arguments);
var ret = "";
@@ -3817,15 +3794,16 @@
}
/**
- * Hex String to byte array
+ * Hex String to Uint8Array.
*/
-DataUtils.toNumbers=function( str ){
- if(typeof str =='string'){
- var ret = [];
- str.replace(/(..)/g, function(str){
- ret.push( parseInt( str, 16 ) );
- });
- return ret;
+DataUtils.toNumbers = function(str) {
+ if (typeof str == 'string') {
+ var ret = new Uint8Array(Math.floor(str.length / 2));
+ var i = 0;
+ str.replace(/(..)/g, function(str) {
+ ret[i++] = parseInt(str, 16);
+ });
+ return ret;
}
}
@@ -3843,15 +3821,27 @@
}
/**
- * Raw String to Byte Array
+ * Raw String to Uint8Array.
*/
DataUtils.toNumbersFromString = function( str ){
- var bytes = new Array(str.length);
+ var bytes = new Uint8Array(str.length);
for(var i=0;i<str.length;i++)
bytes[i] = str.charCodeAt(i);
return bytes;
}
+/*
+ * Return a new Uint8Array which is the Uint8Array concatenated with raw String str.
+ */
+DataUtils.concatFromString = function(array, str) {
+ var bytes = new Uint8Array(array.length + str.length);
+ bytes.set(array);
+ for (var i = 0; i < str.length; ++i)
+ bytes[array.length + i] = str.charCodeAt(i);
+ return bytes;
+}
+
+// TODO: Use TextEncoder and return Uint8Array.
DataUtils.encodeUtf8 = function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
@@ -3878,7 +3868,7 @@
return utftext;
};
- // public method for url decoding
+// TODO: Take Uint8Array and use TextDecoder.
DataUtils.decodeUtf8 = function (utftext) {
var string = "";
var i = 0;
@@ -3911,11 +3901,6 @@
return string;
};
- test = function(){
- console.log(DataUtils.decodeUtf8("HELLO.~"));
- return DataUtils.decodeUtf8("HELLO.~");
- }
-
//NOT WORKING
/*
DataUtils.getUTF8StringFromBytes = function(bytes) {
@@ -3972,7 +3957,7 @@
};
/*
- * Convert the big endian byte array to an unsigned int.
+ * Convert the big endian Uint8Array to an unsigned int.
* Don't check for overflow.
*/
DataUtils.bigEndianToUnsignedInt = function(bytes) {
@@ -3985,19 +3970,21 @@
};
/*
- * Convert the int value to a new big endian byte array and return.
- * If value is 0 or negative, return [].
+ * Convert the int value to a new big endian Uint8Array and return.
+ * If value is 0 or negative, return Uint8Array(0).
*/
DataUtils.nonNegativeIntToBigEndian = function(value) {
- var result = [];
if (value <= 0)
- return result;
+ return new Uint8Array(0);
+ // Assume value is not over 64 bits.
+ var result = new Uint8Array(8);
+ var i = 0;
while (value != 0) {
- result.unshift(value & 0xff);
+ result[i++] = value & 0xff;
value >>= 8;
}
- return result;
+ return result.subarray(0, i);
};
var MimeTypes = {
@@ -4550,7 +4537,6 @@
*/
function encodeToHexInterest(interest){
-
var enc = new BinaryXMLEncoder();
interest.to_ccnb(enc);
@@ -4558,18 +4544,28 @@
var hex = DataUtils.toHex(enc.getReducedOstream());
return hex;
-
}
+function encodeToBinaryInterest(interest){
+ var enc = new BinaryXMLEncoder();
+
+ interest.to_ccnb(enc);
+
+ var hex = enc.getReducedOstream();
+
+ return hex;
+}
+
+
function encodeToHexContentObject(co){
var enc = new BinaryXMLEncoder();
co.to_ccnb(enc);
var hex = DataUtils.toHex(enc.getReducedOstream());
-
+
return hex;
@@ -4583,8 +4579,6 @@
var hex = enc.getReducedOstream();
return hex;
-
-
}
function encodeForwardingEntry(co){
@@ -4618,11 +4612,13 @@
}
+
+
function decodeHexInterest(result){
- var numbers = DataUtils.toNumbers(result);
-
+ var numbers = DataUtils.toNumbers(result);
decoder = new BinaryXMLDecoder(numbers);
+
if(LOG>3)console.log('DECODING HEX INTERST \n'+numbers);
var interest = new Interest();
@@ -4637,8 +4633,9 @@
function decodeHexContentObject(result){
var numbers = DataUtils.toNumbers(result);
-
+
decoder = new BinaryXMLDecoder(numbers);
+
if(LOG>3)console.log('DECODED HEX CONTENT OBJECT \n'+numbers);
co = new ContentObject();
@@ -4681,7 +4678,7 @@
output+= "NAME: ";
for(var i=0;i<co.name.components.length;i++){
- output+= "/"+ DataUtils.toString(co.name.components[i]);
+ output+= "/"+ escape(DataUtils.toString(co.name.components[i]));
}
output+= "<br />";
output+= "<br />";
@@ -5592,7 +5589,7 @@
*/
function rstr2binb(input)
{
- console.log('Raw string comming is '+input);
+ //console.log('Raw string comming is '+input);
var output = Array(input.length >> 2);
for(var i = 0; i < output.length; i++)
output[i] = 0;
@@ -5608,7 +5605,7 @@
* @return the array of big-endian words
*/
function byteArray2binb(input){
- console.log("Byte array coming is " + input);
+ //console.log("Byte array coming is " + input);
var output = Array(input.length >> 2);
for(var i = 0; i < output.length; i++)
output[i] = 0;