name: accommodate typed components in getSuccessor
refs #4570
Change-Id: I8dae1c983663f1d04fbb2e2b82d9fe1e9b4aabda
diff --git a/src/name-component.cpp b/src/name-component.cpp
index 893a852..cb87c8b 100644
--- a/src/name-component.cpp
+++ b/src/name-component.cpp
@@ -398,13 +398,40 @@
return std::memcmp(value(), other.value(), value_size());
}
+static Component
+getDigestSuccessor(const Component& comp)
+{
+ size_t totalLength = 0;
+ EncodingBuffer encoder(comp.size(), 0);
+
+ bool isOverflow = true;
+ size_t i = comp.value_size();
+ for (; isOverflow && i > 0; i--) {
+ uint8_t newValue = static_cast<uint8_t>((comp.value()[i - 1] + 1) & 0xFF);
+ totalLength += encoder.prependByte(newValue);
+ isOverflow = (newValue == 0);
+ }
+ totalLength += encoder.prependByteArray(comp.value(), i);
+
+ if (isOverflow) {
+ return Component(comp.type() + 1);
+ }
+
+ encoder.prependVarNumber(totalLength);
+ encoder.prependVarNumber(comp.type());
+ return encoder.block();
+}
+
Component
Component::getSuccessor() const
{
+ if (isImplicitSha256Digest()) {
+ return getDigestSuccessor(*this);
+ }
+
size_t totalLength = 0;
- EncodingBuffer encoder(size() + 1, 1); // + 1 in case there is an overflow
- // in unlikely case TLV length increases,
- // EncodingBuffer will take care of that
+ EncodingBuffer encoder(size() + 9, 9);
+ // leave room for additional byte when TLV-VALUE overflows, and for TLV-LENGTH size increase
bool isOverflow = true;
size_t i = value_size();
@@ -416,7 +443,7 @@
totalLength += encoder.prependByteArray(value(), i);
if (isOverflow) {
- // new name components has to be extended
+ // new name component has to be extended
totalLength += encoder.appendByte(0);
}
diff --git a/src/name-component.hpp b/src/name-component.hpp
index 1f5e16c..47b6b93 100644
--- a/src/name-component.hpp
+++ b/src/name-component.hpp
@@ -566,6 +566,26 @@
return compare(other) > 0;
}
+ /**
+ * @brief Get the successor of this name component.
+ *
+ * The successor of a name component is defined as follows:
+ *
+ * C represents the set of name components, and X,Y ∈ C.
+ * Operator < is defined by canonical order on C.
+ * Y is the successor of X, if (a) X < Y, and (b) ∄ Z ∈ C s.t. X < Z < Y.
+ *
+ * In plain words, successor of a name component is the next possible name component.
+ *
+ * Examples:
+ *
+ * - successor of `sha256digest=0000000000000000000000000000000000000000000000000000000000000000`
+ * is `sha256digest=0000000000000000000000000000000000000000000000000000000000000001`.
+ * - successor of `sha256digest=ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`
+ * is `2=...`.
+ * - successor of `A` is `B`.
+ * - successor of `%FF` is `%00%00`.
+ */
Component
getSuccessor() const;
diff --git a/src/name.cpp b/src/name.cpp
index 7bbcc2b..bee3b04 100644
--- a/src/name.cpp
+++ b/src/name.cpp
@@ -242,10 +242,7 @@
Name::getSuccessor() const
{
if (empty()) {
- static uint8_t firstValue[] {0};
- Name firstName;
- firstName.append(firstValue, 1);
- return firstName;
+ return Name("/sha256digest=0000000000000000000000000000000000000000000000000000000000000000");
}
return getPrefix(-1).append(get(-1).getSuccessor());
diff --git a/src/name.hpp b/src/name.hpp
index ad64424..0936d3f 100644
--- a/src/name.hpp
+++ b/src/name.hpp
@@ -486,10 +486,14 @@
*
* Examples:
*
- * - successor for / is /%00
- * - successor for /%00%01/%01%02 is /%00%01/%01%03
- * - successor for /%00%01/%01%FF is /%00%01/%02%00
- * - successor for /%00%01/%FF%FF is /%00%01/%00%00%00
+ * - successor of `/` is
+ * `/sha256digest=0000000000000000000000000000000000000000000000000000000000000000`.
+ * - successor of `/sha256digest=0000000000000000000000000000000000000000000000000000000000000000`
+ * is `/sha256digest=0000000000000000000000000000000000000000000000000000000000000001`.
+ * - successor of `/sha256digest=ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`
+ * is `/2=...`.
+ * - successor of `/P/A` is `/P/B`.
+ * - successor of `/Q/%FF` is `/Q/%00%00`.
*
* @return a new Name containing the successor
*/