Make add check for string, byte array, etc. If a component is a string, encode as UTF8. Implement getPrefix and getComponent. Added test-name.html to test these functions.
diff --git a/js/Name.js b/js/Name.js
index 7c4e05a..c177f61 100644
--- a/js/Name.js
+++ b/js/Name.js
@@ -1,53 +1,40 @@
/*
- * @author: Meki Cheraoui
+ * @author: Meki Cheraoui, Jeff Thompson
* See COPYING for copyright and distribution information.
* This class represents a Name as an array of components where each is a byte array.
*/
-
+/*
+ * Create a new Name from _components.
+ * If _components is a string, parse it as a URI. Otherwise it is an array of components
+ * where each is a string, byte array, ArrayBuffer or Uint8Array.
+ * Convert and store as an array of Uint8Array.
+ * If a component is a string, encode as utf8.
+ */
var Name = function Name(_components){
-
- if( typeof _components == 'string') {
-
+ if( typeof _components == 'string') {
if(LOG>3)console.log('Content Name String '+_components);
- this.components = Name.makeBlob(Name.createNameArray(_components));
+ this.components = Name.createNameArray(_components);
}
- else if(typeof _components === 'object' && _components instanceof Array ){
-
+ else if(typeof _components === 'object'){
if(LOG>4)console.log('Content Name Array '+_components);
- this.components = Name.makeBlob(_components);
-
+ this.components = [];
+ for (var i = 0; i < _components.length; ++i)
+ this.add(_components[i]);
}
- else if(_components==null){
+ else if(_components==null)
this.components =[];
- }
- else{
-
+ else
if(LOG>1)console.log("NO CONTENT NAME GIVEN");
-
- }
};
Name.prototype.getName = function() {
return this.to_uri();
};
-Name.makeBlob=function(name){
-
- var blobArrays = new Array(name.length);
-
- for(var i=0;i<name.length;i++){
- if(typeof name[i] == 'string')
- blobArrays[i]= DataUtils.toNumbersFromString(name[i]);
- else if(typeof name[i] == 'object')
- blobArrays[i]= name[i] ;
- else
- if(LOG>4)console.log('NAME COMPONENT INVALID');
- }
-
- return blobArrays;
-};
-
+/* Parse name as a URI and return an array of Uint8Array components.
+ *
+ */
Name.createNameArray = function(name) {
name = name.trim();
if (name.length <= 0)
@@ -97,6 +84,9 @@
}
else
array[i] = component;
+
+ // Change the component to Uint8Array now.
+ array[i] = DataUtils.toNumbersFromString(array[i]);
}
return array;
@@ -133,8 +123,27 @@
return CCNProtocolDTags.Name;
};
-Name.prototype.add = function(param){
- return this.components.push(param);
+/*
+ * component is a string, byte array, ArrayBuffer or Uint8Array.
+ * Convert to Uint8Array and add to this Name.
+ * If a component is a string, encode as utf8.
+ * Return the converted value.
+ */
+Name.prototype.add = function(component){
+ var result = null;
+ if(typeof component == 'string')
+ result = DataUtils.stringToUtf8Array(component);
+ else if(typeof component == 'object' && component instanceof Array)
+ result = new Uint8Array(component);
+ else if(typeof component == 'object' && component instanceof Uint8Array)
+ result = new Uint8Array(component);
+ else if(typeof component == 'object' && component instanceof ArrayBuffer)
+ // Make a copy.
+ result = new Uint8Array(component.slice(0, component.byteLength));
+ else
+ if(LOG>4)console.log('NAME COMPONENT INVALID');
+
+ return this.components.push(result);
};
// Return the escaped name string according to "CCNx URI Scheme". Does not include "ccnx:".
@@ -147,6 +156,22 @@
return result;
};
+/*
+ * Return a new Name with the first nComponents components of this Name.
+ */
+Name.prototype.getPrefix = function(nComponents) {
+ return new Name(this.components.slice(0, nComponents));
+}
+
+/*
+ * Return a new ArrayBuffer of the component at i.
+ */
+Name.prototype.getComponent = function(i) {
+ var result = new ArrayBuffer(this.components[i].length);
+ new Uint8Array(result).set(this.components[i]);
+ return result;
+}
+
/**
* Return component as an escaped string according to "CCNx URI Scheme".
* We can't use encodeURIComponent because that doesn't encode all the characters we want to.
diff --git a/js/testing/test-encode-decode-ContentObject-bis.html b/js/testing/test-encode-decode-ContentObject-bis.html
deleted file mode 100644
index df3e700..0000000
--- a/js/testing/test-encode-decode-ContentObject-bis.html
+++ /dev/null
@@ -1,210 +0,0 @@
-<?xml version = "1.0" encoding="utf-8" ?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-"DTD/xhtml1-strict.dtd">
-<html xmlns = "http://www.w3.org/1999/xhtml">
-
-<head>
- <title>NDN Request Example</title>
-
- <script type="text/javascript" src="../Helper.js"></script>
-
- <script type="text/javascript">
-
- function encode(){
- var contentname = new Name( Name.createNameArray(document.getElementById('contentname').value) );
-
- var content = document.getElementById('content').value;
-
- var signedInfo = new SignedInfo();
- signedInfo.setFields();
- //var signatureBits = generateSignatureBits(contentname,content,signedInfo);
-
- //witness is null
- var signature = new Signature();
-
-
- var co = new ContentObject(contentname,signedInfo,content,signature);
-
- co.sign();
-
-
- var output = encodeToHexContentObject(co);
-
- document.getElementById('result').innerHTML = output;
-
- }
-
- function decode(){
-
-
-
- var input = document.getElementById('result').innerHTML;
-
-
- var co = decodeHexContentObject(input);
-
- if(LOG>3)console.log('CONTENT OBJECT DECODED');
- if(LOG>3)console.log(co);
-
- ///////////////////////////////////////
-
- var output ="";
-
- if(co==-1)
- output+= "NO CONTENT FOUND"
- else if (co==-2)
- output+= "CONTENT NAME IS EMPTY"
- else{
- if(co.name!=null && co.name.components!=null){
- output+= "NAME: ";
-
- for(var i=0;i<co.name.components.length;i++){
- output+= "/"+ toString(co.name.components[i]);
- }
- output+= "<br />";
- output+= "<br />";
- }
-
- if(co.content !=null){
- output += "CONTENT(ASCII): "+ toString(co.content);
-
- output+= "<br />";
- output+= "<br />";
- }
- if(co.content !=null){
- output += "CONTENT(hex): "+ DataUtils.toHex(co.content);
-
- output+= "<br />";
- output+= "<br />";
- }
- if(co.signature !=null && co.signature.signature!=null){
-
- output += "SIGNATURE(hex): "+ DataUtils.toHex(co.signature.signature);
-
- output+= "<br />";
- output+= "<br />";
- }
- if(co.signedInfo !=null && co.signedInfo.publisher!=null && co.signedInfo.publisher.publisherPublicKeyDigest!=null){
-
- output += "Publisher Public Key Digest(hex): "+ DataUtils.toHex(co.signedInfo.publisher.publisherPublicKeyDigest);
-
- output+= "<br />";
- output+= "<br />";
- }
- if(co.signedInfo !=null && co.signedInfo.timestamp!=null){
-
- output += "TimeStamp(hex): "+ co.signedInfo.timestamp.date;
-
- output+= "<br />";
- output+= "<br />";
- }
- if(co.signedInfo!=null && co.signedInfo.locator!=null && co.signedInfo.locator.publicKey!=null){
-
- var publickey = rstr2b64(toString(co.signedInfo.locator.publicKey));
- var publickeyHex = DataUtils.toHex(co.signedInfo.locator.publicKey).toLowerCase();
- var publickeyString = toString(co.signedInfo.locator.publicKey);
-
- var signature = DataUtils.toHex(co.signature.signature).toLowerCase();
-
-
- var input = toString(co.rawSignatureData);
-
-
- output += "DER Certificate: "+publickey ;
-
- output+= "<br />";
- output+= "<br />";
-
-
-
- if(LOG>2) console.log(" ContentName + SignedInfo + Content = "+input);
- if(LOG>2) console.log(" PublicKey = "+publickey );
- if(LOG>2) console.log(" PublicKeyHex = "+publickeyHex );
- if(LOG>2) console.log(" PublicKeyString = "+publickeyString );
-
- if(LOG>2) console.log(" Signature "+signature );
- if(LOG>2) console.log(" Signature NOW IS" );
- if(LOG>2) console.log(co.signature.signature);
-
-
- var x509 = new X509();
-
- x509.readCertPEM(publickey);
-
-
- //x509.readCertPEMWithoutRSAInit(publickey);
-
- var result = x509.subjectPublicKeyRSA.verifyString(input, signature);
- console.log('result is '+result);
- /*var rsakey = new RSAKey();
-
- var kp = publickeyHex.slice(56,314);
-
- output += "PUBLISHER KEY(hex): "+kp ;
-
- output+= "<br />";
- output+= "<br />";
-
- console.log('kp is '+kp);
-
- var exp = publickeyHex.slice(318,324);
-
- console.log('kp size is '+kp.length );
- output += "exponent: "+exp ;
-
- output+= "<br />";
- output+= "<br />";
-
- console.log('exp is '+exp);
-
-
- rsakey.setPublic(kp,exp);
-
- var result = rsakey.verifyString(input, signature);*/
-
- if(result)
- output += 'SIGNATURE VALID';
- else
- output += 'SIGNATURE INVALID';
-
-
-
-
- //output += "VALID: "+ toHex(co.signedInfo.locator.publicKey);
-
- output+= "<br />";
- output+= "<br />";
-
-
- if(LOG>4) console.log('str'[1]);
- }
- }
-
- document.getElementById('result').innerHTML = output;
-
- }
-
- </script>
-
-</head>
-<body >
- <form>
-
- Please Enter a Content Name:<br />
-
- <input id="contentname" type="text" name="CONTENTNAME" value="/PARC/abc" />
-
- Please Enter the Content:<br />
-
- <textarea id="content" cols="40" rows="5" name="CONTENT" value="SUCCESS" >SUCCESS!</textarea>
-
- </form>
- <button onclick="encode()">Encode</button>
- <button onclick="decode()">Decode</button>
-
-
-
- <p id="result"></p>
-
-</body>
-</html>
\ No newline at end of file
diff --git a/js/testing/test-name.html b/js/testing/test-name.html
new file mode 100644
index 0000000..713423b
--- /dev/null
+++ b/js/testing/test-name.html
@@ -0,0 +1,110 @@
+<?xml version = "1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"DTD/xhtml1-strict.dtd">
+<html xmlns = "http://www.w3.org/1999/xhtml">
+
+<head>
+ <title>NDN Name</title>
+
+ <script type="text/javascript" src="../Helper.js"></script>
+
+ <script type="text/javascript">
+
+function testName() {
+ var result = document.getElementById('result');
+ result.innerHTML = "";
+
+ var comp1 = new Uint8Array(1);
+ comp1.set(['.'.charCodeAt(0)]);
+
+ var ab2 = new ArrayBuffer(4);
+ var comp2 = new Uint8Array(ab2);
+ comp2.set([0x00, 0x01, 0x02, 0x03]);
+
+ // \u00E9 is e with accent.
+ var entree = "entr\u00E9e";
+
+ // When Name constructor is passed an array, each item is a name component represented with ArrayBuffer,
+ // typed array, or string (parsed as UTF-8)
+ var name1 = new Name([entree, comp1, ab2]);
+ var name1Uri = name1.to_uri();
+ var name1UriExpected = "/entr%C3%A9e/..../%00%01%02%03";
+ result.innerHTML += "Name from '" + entree + "', Uint8Array of '.' and ArrayBuffer of 0,1,2,3:<br>";
+ if (name1Uri == name1UriExpected)
+ result.innerHTML += "SUCCESS: " + name1Uri + ".<br>";
+ else
+ result.innerHTML += "ERROR: got " + name1Uri + ", expected " + name1UriExpected + " .<br>";
+
+ result.innerHTML += "Compare with same Name from '" + entree + "', '.' and ArrayBuffer:<br>";
+ // Equivalent with name1
+ var name2 = new Name([entree, ".", comp2]);
+ if (name2.components.length != name1.components.length)
+ result.innerHTML += "ERROR: Got name with " + name2.components.length +
+ " components, expected " + name1.components.length + ".<br>";
+ else {
+ var allEqual = true;
+ for (var i = 0; i < name1.components.length; ++i) {
+ if (!DataUtils.arraysEqual(name1.components[i], name2.components[i])) {
+ allEqual = false;
+ result.innerHTML += "ERROR: Names differ at component at index " + i + ".<br>";
+ }
+ }
+ if (allEqual)
+ result.innerHTML += "SUCCESS: Names are equal.<br>";
+ }
+
+ result.innerHTML += "Compare with same Name from URI:<br>";
+ // Equivalent with name1; when Name constructor is passed a string, it is treated as a URI
+ var name3 = new Name("/entr%C3%A9e/..../%00%01%02%03");
+ if (name3.components.length != name1.components.length)
+ result.innerHTML += "ERROR: Got name with " + name3.components.length +
+ " components, expected " + name1.components.length + ".<br>";
+ else {
+ var allEqual = true;
+ for (var i = 0; i < name1.components.length; ++i) {
+ if (!DataUtils.arraysEqual(name1.components[i], name3.components[i])) {
+ allEqual = false;
+ result.innerHTML += "ERROR: Names differ at component at index " + i + ".<br>";
+ }
+ }
+ if (allEqual)
+ result.innerHTML += "SUCCESS: Names are equal.<br>";
+ }
+
+ result.innerHTML += "Compare with Name prefix of first 2 components:<br>";
+ // Returns new Name([entree, "."])
+ var name4 = name2.getPrefix(2);
+ if (name4.components.length != 2)
+ result.innerHTML += "ERROR: Got name with " + name4.components.length +
+ " components, expected 2.<br>";
+ else {
+ var allEqual = true;
+ for (var i = 0; i < name4.components.length; ++i) {
+ if (!DataUtils.arraysEqual(name1.components[i], name4.components[i])) {
+ allEqual = false;
+ result.innerHTML += "ERROR: Names differ at component at index " + i + ".<br>";
+ }
+ }
+ if (allEqual)
+ result.innerHTML += "SUCCESS: First 2 components are equal: " + name4.to_uri() + " .<br>";
+ }
+
+ result.innerHTML += "Check with Name component at index 2:<br>";
+ // Returns ArrayBuffer of "%00%01%02%03"
+ var component2Out = new Uint8Array(name1.getComponent(2));
+ if (DataUtils.arraysEqual(component2Out, comp2))
+ result.innerHTML += "SUCCESS: Components at index 2 are equal.<br>";
+ else
+ result.innerHTML += "ERROR: Components at index 2 are different.<br>";
+}
+
+ </script>
+
+</head>
+<body >
+ <button onclick="testName()">Test</button>
+
+ <p id="result"></p>
+
+</body>
+</html>