data: Optimize Data signing
As of this commit, KeyChain::sign pre-allocates EncodingBuffer, requests
unsigned portion of Data using Data::wireEncode(EncodingBuffer, true),
and then appends the resulting signature and prepends Data packet
header. This way there is no extra memory allocation after Data packet
is signed.
Change-Id: I670e9a2f1d6f5e9b049f41b47f011af384f32c95
diff --git a/src/interest.cpp b/src/interest.cpp
index 9e5b129..590d527 100644
--- a/src/interest.cpp
+++ b/src/interest.cpp
@@ -108,6 +108,124 @@
return true;
}
+template<bool T>
+size_t
+Interest::wireEncode(EncodingImpl<T>& block) const
+{
+ size_t totalLength = 0;
+
+ // Interest ::= INTEREST-TYPE TLV-LENGTH
+ // Name
+ // Selectors?
+ // Nonce
+ // Scope?
+ // InterestLifetime?
+
+ // (reverse encoding)
+
+ // InterestLifetime
+ if (getInterestLifetime() >= time::milliseconds::zero() &&
+ getInterestLifetime() != DEFAULT_INTEREST_LIFETIME)
+ {
+ totalLength += prependNonNegativeIntegerBlock(block,
+ Tlv::InterestLifetime,
+ getInterestLifetime().count());
+ }
+
+ // Scope
+ if (getScope() >= 0)
+ {
+ totalLength += prependNonNegativeIntegerBlock(block, Tlv::Scope, getScope());
+ }
+
+ // Nonce
+ getNonce(); // to ensure that Nonce is properly set
+ totalLength += block.prependBlock(m_nonce);
+
+ // Selectors
+ if (hasSelectors())
+ {
+ totalLength += getSelectors().wireEncode(block);
+ }
+
+ // Name
+ totalLength += getName().wireEncode(block);
+
+ totalLength += block.prependVarNumber(totalLength);
+ totalLength += block.prependVarNumber(Tlv::Interest);
+ return totalLength;
+}
+
+const Block&
+Interest::wireEncode() const
+{
+ if (m_wire.hasWire())
+ return m_wire;
+
+ EncodingEstimator estimator;
+ size_t estimatedSize = wireEncode(estimator);
+
+ EncodingBuffer buffer(estimatedSize, 0);
+ wireEncode(buffer);
+
+ // to ensure that Nonce block points to the right memory location
+ const_cast<Interest*>(this)->wireDecode(buffer.block());
+
+ return m_wire;
+}
+
+void
+Interest::wireDecode(const Block& wire)
+{
+ m_wire = wire;
+ m_wire.parse();
+
+ // Interest ::= INTEREST-TYPE TLV-LENGTH
+ // Name
+ // Selectors?
+ // Nonce
+ // Scope?
+ // InterestLifetime?
+
+ if (m_wire.type() != Tlv::Interest)
+ throw Tlv::Error("Unexpected TLV number when decoding Interest");
+
+ // Name
+ m_name.wireDecode(m_wire.get(Tlv::Name));
+
+ // Selectors
+ Block::element_const_iterator val = m_wire.find(Tlv::Selectors);
+ if (val != m_wire.elements_end())
+ {
+ m_selectors.wireDecode(*val);
+ }
+ else
+ m_selectors = Selectors();
+
+ // Nonce
+ m_nonce = m_wire.get(Tlv::Nonce);
+
+ // Scope
+ val = m_wire.find(Tlv::Scope);
+ if (val != m_wire.elements_end())
+ {
+ m_scope = readNonNegativeInteger(*val);
+ }
+ else
+ m_scope = -1;
+
+ // InterestLifetime
+ val = m_wire.find(Tlv::InterestLifetime);
+ if (val != m_wire.elements_end())
+ {
+ m_interestLifetime = time::milliseconds(readNonNegativeInteger(*val));
+ }
+ else
+ {
+ m_interestLifetime = DEFAULT_INTEREST_LIFETIME;
+ }
+}
+
std::ostream&
operator<<(std::ostream& os, const Interest& interest)
{