In Interest.matches_name used to match interests in the PITTable, added a check for minSuffixComponents, maxSuffixComponents and exclude.
This helps to call the correct closure callback.
diff --git a/js/tools/build/ndn-js-uncomp.js b/js/tools/build/ndn-js-uncomp.js
index 469a0e5..bb22c6a 100644
--- a/js/tools/build/ndn-js-uncomp.js
+++ b/js/tools/build/ndn-js-uncomp.js
@@ -1431,8 +1431,26 @@
};
+/*
+ * Return true if this.name.match(name) and the name conforms to the interest selectors.
+ */
Interest.prototype.matches_name = function(/*Name*/ name) {
- return this.name.match(name);
+ if (!this.name.match(name))
+ return false;
+
+ if (this.minSuffixComponents != null &&
+ // Add 1 for the implicit digest.
+ !(name.components.length + 1 - this.name.components.length >= this.minSuffixComponents))
+ return false;
+ if (this.maxSuffixComponents != null &&
+ // Add 1 for the implicit digest.
+ !(name.components.length + 1 - this.name.components.length <= this.maxSuffixComponents))
+ return false;
+ if (this.exclude != null && name.components.length > this.name.components.length &&
+ this.exclude.matches(name.components[this.name.components.length]))
+ return false;
+
+ return true;
}
/*
@@ -1487,7 +1505,9 @@
encoder.writeEndElement();
};
-// Return a string with elements separated by "," and Exclude.ANY shown as "*".
+/*
+ * Return a string with elements separated by "," and Exclude.ANY shown as "*".
+ */
Exclude.prototype.to_uri = function() {
if (this.values == null || this.values.length == 0)
return "";
@@ -1504,6 +1524,81 @@
}
return result;
};
+
+/*
+ * Return true if the component matches any of the exclude criteria.
+ */
+Exclude.prototype.matches = function(/*Uint8Array*/ component) {
+ for (var i = 0; i < this.values.length; ++i) {
+ if (this.values[i] == Exclude.ANY) {
+ var lowerBound = null;
+ if (i > 0)
+ lowerBound = this.values[i - 1];
+
+ // Find the upper bound, possibly skipping over multiple ANY in a row.
+ var iUpperBound;
+ var upperBound = null;
+ for (iUpperBound = i + 1; iUpperBound < this.values.length; ++iUpperBound) {
+ if (this.values[iUpperBound] != Exclude.ANY) {
+ upperBound = this.values[iUpperBound];
+ break;
+ }
+ }
+
+ // If lowerBound != null, we already checked component equals lowerBound on the last pass.
+ // If upperBound != null, we will check component equals upperBound on the next pass.
+ if (upperBound != null) {
+ if (lowerBound != null) {
+ if (Exclude.compareComponents(component, lowerBound) > 0 &&
+ Exclude.compareComponents(component, upperBound) < 0)
+ return true;
+ }
+ else {
+ if (Exclude.compareComponents(component, upperBound) < 0)
+ return true;
+ }
+
+ // Make i equal iUpperBound on the next pass.
+ i = iUpperBound - 1;
+ }
+ else {
+ if (lowerBound != null) {
+ if (Exclude.compareComponents(component, lowerBound) > 0)
+ return true;
+ }
+ else
+ // this.values has only ANY.
+ return true;
+ }
+ }
+ else {
+ if (DataUtils.arraysEqual(component, this.values[i]))
+ return true;
+ }
+ }
+
+ return false;
+};
+
+/*
+ * Return -1 if component1 is less than component2, 1 if greater or 0 if equal.
+ * A component is less if it is shorter, otherwise if equal length do a byte comparison.
+ */
+Exclude.compareComponents = function(/*Uint8Array*/ component1, /*Uint8Array*/ component2) {
+ if (component1.length < component2.length)
+ return -1;
+ if (component1.length > component2.length)
+ return 1;
+
+ for (var i = 0; i < component1.length; ++i) {
+ if (component1[i] < component2[i])
+ return -1;
+ if (component1[i] > component2[i])
+ return 1;
+ }
+
+ return 0;
+};
/**
* @author: Meki Cheraoui
* See COPYING for copyright and distribution information.
@@ -7544,10 +7639,11 @@
this.timerID = -1; // Timer ID
};
-// Return the longest entry from NDN.PITTable that matches name.
+/*
+ * Return the entry from NDN.PITTable where the name conforms to the interest selectors, and
+ * the interest name is the longest that matches name.
+ */
NDN.getEntryForExpressedInterest = function(/*Name*/ name) {
- // TODO: handle multiple matches? Maybe not from registerPrefix because multiple ContentObject
- // could be sent for one Interest?
var result = null;
for (var i = 0; i < NDN.PITTable.length; i++) {
diff --git a/js/tools/build/ndn-js.js b/js/tools/build/ndn-js.js
index b1a9e17..e6a4ef6 100644
--- a/js/tools/build/ndn-js.js
+++ b/js/tools/build/ndn-js.js
@@ -52,10 +52,12 @@
a.peekStartElement(CCNProtocolDTags.InterestLifetime)&&(this.interestLifetime=1E3*DataUtils.bigEndianToUnsignedInt(a.readBinaryElement(CCNProtocolDTags.InterestLifetime))/4096);a.peekStartElement(CCNProtocolDTags.Nonce)&&(this.nonce=a.readBinaryElement(CCNProtocolDTags.Nonce));a.readEndElement()};
Interest.prototype.to_ccnb=function(a){a.writeStartElement(CCNProtocolDTags.Interest);this.name.to_ccnb(a);null!=this.minSuffixComponents&&a.writeElement(CCNProtocolDTags.MinSuffixComponents,this.minSuffixComponents);null!=this.maxSuffixComponents&&a.writeElement(CCNProtocolDTags.MaxSuffixComponents,this.maxSuffixComponents);null!=this.publisherPublicKeyDigest&&this.publisherPublicKeyDigest.to_ccnb(a);null!=this.exclude&&this.exclude.to_ccnb(a);null!=this.childSelector&&a.writeElement(CCNProtocolDTags.ChildSelector,
this.childSelector);this.DEFAULT_ANSWER_ORIGIN_KIND!=this.answerOriginKind&&null!=this.answerOriginKind&&a.writeElement(CCNProtocolDTags.AnswerOriginKind,this.answerOriginKind);null!=this.scope&&a.writeElement(CCNProtocolDTags.Scope,this.scope);null!=this.interestLifetime&&a.writeElement(CCNProtocolDTags.InterestLifetime,DataUtils.nonNegativeIntToBigEndian(4096*(this.interestLifetime/1E3)));null!=this.nonce&&a.writeElement(CCNProtocolDTags.Nonce,this.nonce);a.writeEndElement()};
-Interest.prototype.matches_name=function(a){return this.name.match(a)};var Exclude=function(a){this.values=a||[]};Exclude.ANY="*";
+Interest.prototype.matches_name=function(a){return!this.name.match(a)||null!=this.minSuffixComponents&&!(a.components.length+1-this.name.components.length>=this.minSuffixComponents)||null!=this.maxSuffixComponents&&!(a.components.length+1-this.name.components.length<=this.maxSuffixComponents)||null!=this.exclude&&a.components.length>this.name.components.length&&this.exclude.matches(a.components[this.name.components.length])?!1:!0};var Exclude=function(a){this.values=a||[]};Exclude.ANY="*";
Exclude.prototype.from_ccnb=function(a){for(a.readStartElement(CCNProtocolDTags.Exclude);;)if(a.peekStartElement(CCNProtocolDTags.Component))this.values.push(a.readBinaryElement(CCNProtocolDTags.Component));else if(a.peekStartElement(CCNProtocolDTags.Any))a.readStartElement(CCNProtocolDTags.Any),a.readEndElement(),this.values.push(Exclude.ANY);else if(a.peekStartElement(CCNProtocolDTags.Bloom))a.readBinaryElement(CCNProtocolDTags.Bloom),this.values.push(Exclude.ANY);else break;a.readEndElement()};
Exclude.prototype.to_ccnb=function(a){if(!(null==this.values||0==this.values.length)){a.writeStartElement(CCNProtocolDTags.Exclude);for(var b=0;b<this.values.length;++b)this.values[b]==Exclude.ANY?(a.writeStartElement(CCNProtocolDTags.Any),a.writeEndElement()):a.writeElement(CCNProtocolDTags.Component,this.values[b]);a.writeEndElement()}};
Exclude.prototype.to_uri=function(){if(null==this.values||0==this.values.length)return"";for(var a="",b=0;b<this.values.length;++b)0<b&&(a+=","),a=this.values[b]==Exclude.ANY?a+"*":a+Name.toEscapedString(this.values[b]);return a};
+Exclude.prototype.matches=function(a){for(var b=0;b<this.values.length;++b)if(this.values[b]==Exclude.ANY){var c=null;0<b&&(c=this.values[b-1]);var d,e=null;for(d=b+1;d<this.values.length;++d)if(this.values[d]!=Exclude.ANY){e=this.values[d];break}if(null!=e){if(null!=c){if(0<Exclude.compareComponents(a,c)&&0>Exclude.compareComponents(a,e))return!0}else if(0>Exclude.compareComponents(a,e))return!0;b=d-1}else if(null!=c){if(0<Exclude.compareComponents(a,c))return!0}else return!0}else if(DataUtils.arraysEqual(a,
+this.values[b]))return!0;return!1};Exclude.compareComponents=function(a,b){if(a.length<b.length)return-1;if(a.length>b.length)return 1;for(var c=0;c<a.length;++c){if(a[c]<b[c])return-1;if(a[c]>b[c])return 1}return 0};
var Key=function(){},KeyLocatorType={KEY:1,CERTIFICATE:2,KEYNAME:3},KeyLocator=function(a,b){this.type=b;b==KeyLocatorType.KEYNAME?(3<LOG&&console.log("KeyLocator: SET KEYNAME"),this.keyName=a):b==KeyLocatorType.KEY?(3<LOG&&console.log("KeyLocator: SET KEY"),this.publicKey=a):b==KeyLocatorType.CERTIFICATE&&(3<LOG&&console.log("KeyLocator: SET CERTIFICATE"),this.certificate=a)};
KeyLocator.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());if(a.peekStartElement(CCNProtocolDTags.Key)){try{this.publicKey=encodedKey=a.readBinaryElement(CCNProtocolDTags.Key),this.type=KeyLocatorType.KEY,4<LOG&&console.log("PUBLIC KEY FOUND: "+this.publicKey)}catch(b){throw Error("Cannot parse key: ",b);}if(null==this.publicKey)throw Error("Cannot parse key: ");}else if(a.peekStartElement(CCNProtocolDTags.Certificate)){try{this.certificate=encodedCert=a.readBinaryElement(CCNProtocolDTags.Certificate),
this.type=KeyLocatorType.CERTIFICATE,4<LOG&&console.log("CERTIFICATE FOUND: "+this.certificate)}catch(c){throw Error("Cannot decode certificate: "+c);}if(null==this.certificate)throw Error("Cannot parse certificate! ");}else this.type=KeyLocatorType.KEYNAME,this.keyName=new KeyName,this.keyName.from_ccnb(a);a.readEndElement()};