Extending Name class
It is now possible to add a Name object to another (or the same) Name
object, appending all name components of the source Name to the
destination Name.
diff --git a/js/Name.js b/js/Name.js
index 4d8a64c..37ef47f 100644
--- a/js/Name.js
+++ b/js/Name.js
@@ -3,20 +3,20 @@
* 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.
+ * 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.createNameArray(_components);
}
- else if(typeof _components === 'object'){
+ else if(typeof _components === 'object'){
if(LOG>4)console.log('Content Name Array '+_components);
this.components = [];
for (var i = 0; i < _components.length; ++i)
@@ -48,7 +48,7 @@
// Omit the leading protocol such as ndn:
name = name.substr(iColon + 1, name.length - iColon - 1).trim();
}
-
+
if (name[0] == '/') {
if (name.length >= 2 && name[1] == '/') {
// Strip the authority following "//".
@@ -64,15 +64,15 @@
}
var array = name.split('/');
-
+
// Unescape the components.
for (var i = 0; i < array.length; ++i) {
var component = Name.fromEscapedString(array[i]);
-
+
if (component == null) {
// Ignore the illegal componenent. This also gets rid of a trailing '/'.
array.splice(i, 1);
- --i;
+ --i;
continue;
}
else
@@ -86,19 +86,19 @@
Name.prototype.from_ccnb = function(/*XMLDecoder*/ decoder) {
decoder.readStartElement(this.getElementLabel());
-
+
this.components = new Array(); //new ArrayList<byte []>();
while (decoder.peekStartElement(CCNProtocolDTags.Component)) {
this.add(decoder.readBinaryElement(CCNProtocolDTags.Component));
}
-
+
decoder.readEndElement();
};
Name.prototype.to_ccnb = function(/*XMLEncoder*/ encoder) {
-
- if( this.components ==null )
+
+ if( this.components ==null )
throw new Error("CANNOT ENCODE EMPTY CONTENT NAME");
encoder.writeStartElement(this.getElementLabel());
@@ -121,37 +121,54 @@
*/
Name.prototype.add = function(component){
var result;
- if(typeof component == 'string')
+ if(typeof component == 'string') {
result = DataUtils.stringToUtf8Array(component);
- else if(typeof component == 'object' && component instanceof Uint8Array)
+ this.components.push (result);
+ }
+ else if(typeof component == 'object' && component instanceof Uint8Array) {
result = new Uint8Array(component);
- else if(typeof component == 'object' && component instanceof ArrayBuffer) {
+ this.components.push (result);
+ }
+ else if(typeof component == 'object' && component instanceof ArrayBuffer) {
// Make a copy. Don't use ArrayBuffer.slice since it isn't always supported.
result = new Uint8Array(new ArrayBuffer(component.byteLength));
result.set(new Uint8Array(component));
+ this.components.push(result);
}
- else if(typeof component == 'object')
+ else if(typeof component == 'object' && component instanceof Name) {
+ components = component;
+ if (this == component) {
+ components = new Name (component.components); // special case, when we need to create a copy
+ }
+ for(var i = 0; i < components.components.length; ++i) {
+ result = new Uint8Array (components.components[i]);
+ this.components.push (result);
+ }
+ }
+ else if(typeof component == 'object') {
// Assume component is a byte array. We can't check instanceof Array because
// this doesn't work in JavaScript if the array comes from a different module.
result = new Uint8Array(component);
- else
- throw new Error("Cannot add Name element at index " + this.components.length +
- ": Invalid type");
-
- return this.components.push(result);
+ this.components.push(result);
+ }
+ else
+ throw new Error("Cannot add Name element at index " + this.components.length +
+ ": Invalid type");
+
+ return this;
};
// Return the escaped name string according to "CCNx URI Scheme".
-Name.prototype.to_uri = function() {
+Name.prototype.to_uri = function() {
if (this.components.length == 0)
return "/";
-
+
var result = "";
-
+
for(var i = 0; i < this.components.length; ++i)
result += "/"+ Name.toEscapedString(this.components[i]);
-
- return result;
+
+ return result;
};
/*
@@ -180,14 +197,14 @@
var component = this.components[i];
if (component.length <= 0)
continue;
-
- if (component[0] == 0 || component[0] == 0xC0 || component[0] == 0xC1 ||
+
+ if (component[0] == 0 || component[0] == 0xC0 || component[0] == 0xC1 ||
(component[0] >= 0xF5 && component[0] <= 0xFF))
continue;
-
+
return i;
}
-
+
return -1;
}
@@ -197,18 +214,18 @@
Name.prototype.equalsName = function(name) {
if (this.components.length != name.components.length)
return false;
-
+
// Start from the last component because they are more likely to differ.
for (var i = this.components.length - 1; i >= 0; --i) {
if (!DataUtils.arraysEqual(this.components[i], name.components[i]))
return false;
}
-
+
return true;
}
/*
- * Find the last component in name that has a ContentDigest and return the digest value as Uint8Array,
+ * Find the last component in name that has a ContentDigest and return the digest value as Uint8Array,
* or null if not found. See Name.getComponentContentDigestValue.
*/
Name.prototype.getContentDigestValue = function() {
@@ -217,7 +234,7 @@
if (digestValue != null)
return digestValue;
}
-
+
return null;
}
@@ -227,10 +244,10 @@
* A ContentDigest component is Name.ContentDigestPrefix + 32 bytes + Name.ContentDigestSuffix.
*/
Name.getComponentContentDigestValue = function(component) {
- var digestComponentLength = Name.ContentDigestPrefix.length + 32 + Name.ContentDigestSuffix.length;
+ var digestComponentLength = Name.ContentDigestPrefix.length + 32 + Name.ContentDigestSuffix.length;
// Check for the correct length and equal ContentDigestPrefix and ContentDigestSuffix.
if (component.length == digestComponentLength &&
- DataUtils.arraysEqual(component.subarray(0, Name.ContentDigestPrefix.length),
+ DataUtils.arraysEqual(component.subarray(0, Name.ContentDigestPrefix.length),
Name.ContentDigestPrefix) &&
DataUtils.arraysEqual(component.subarray
(component.length - Name.ContentDigestSuffix.length, component.length),
@@ -240,7 +257,7 @@
return null;
}
-// Meta GUID "%C1.M.G%C1" + ContentDigest with a 32 byte BLOB.
+// Meta GUID "%C1.M.G%C1" + ContentDigest with a 32 byte BLOB.
Name.ContentDigestPrefix = new Uint8Array([0xc1, 0x2e, 0x4d, 0x2e, 0x47, 0xc1, 0x01, 0xaa, 0x02, 0x85]);
Name.ContentDigestSuffix = new Uint8Array([0x00]);
@@ -268,7 +285,7 @@
var value = component[i];
// Check for 0-9, A-Z, a-z, (+), (-), (.), (_)
if (value >= 0x30 && value <= 0x39 || value >= 0x41 && value <= 0x5a ||
- value >= 0x61 && value <= 0x7a || value == 0x2b || value == 0x2d ||
+ value >= 0x61 && value <= 0x7a || value == 0x2b || value == 0x2d ||
value == 0x2e || value == 0x5f)
result += String.fromCharCode(value);
else
@@ -284,9 +301,9 @@
*/
Name.fromEscapedString = function(escapedString) {
var component = unescape(escapedString.trim());
-
+
if (component.match(/[^.]/) == null) {
- // Special case for component of only periods.
+ // Special case for component of only periods.
if (component.length <= 2)
// Zero, one or two periods is illegal. Ignore this componenent to be
// consistent with the C implementation.