encoding: Optimized Data packet encoding, preparation for memory-efficient signing operation
Change-Id: I6eb1f8acef917970790d1f228ade6212c45181fa
refs: #1172
diff --git a/src/data.hpp b/src/data.hpp
index f1b64a3..4c09811 100644
--- a/src/data.hpp
+++ b/src/data.hpp
@@ -37,25 +37,32 @@
Data(const Name& name);
/**
- * @brief The virtual destructor.
+ * @brief The destructor
*/
- inline virtual
+ inline
~Data();
/**
- * @brief Encode this Data for a wire format.
- * @return The encoded byte array.
+ * @brief Fast encoding or block size estimation
*/
- const Block&
- wireEncode() const;
+ template<bool T>
+ inline size_t
+ wireEncode(EncodingImpl<T> &block, bool unsignedPortion = false) const;
/**
- * @brief Decode the input using a particular wire format and update this Data.
- * @param input The input byte array to be decoded.
+ * @brief Encode to a wire format
*/
- void
+ inline const Block&
+ wireEncode() const;
+
+ /**
+ * @brief Decode from the wire format
+ */
+ inline void
wireDecode(const Block &wire);
+ ////////////////////////////////////////////////////////////////////
+
inline const Name&
getName() const;
@@ -68,6 +75,8 @@
inline void
setName(const Name& name);
+ //
+
inline const MetaInfo&
getMetaInfo() const;
@@ -79,13 +88,20 @@
inline void
setMetaInfo(const MetaInfo& metaInfo);
+ //
+
+ ///////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
// MetaInfo proxy methods
+
inline uint32_t
getContentType() const;
inline void
setContentType(uint32_t type);
+
+ //
inline Milliseconds
getFreshnessPeriod() const;
@@ -93,11 +109,18 @@
inline void
setFreshnessPeriod(Milliseconds freshnessPeriod);
+ //
+
inline const name::Component&
getFinalBlockId() const;
inline void
setFinalBlockId(const name::Component& finalBlockId);
+
+ //
+ ///////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////
/**
* @brief Get content Block
@@ -121,6 +144,8 @@
inline void
setContent(const ConstBufferPtr &contentValue);
+
+ //
inline const Signature&
getSignature() const;
@@ -131,10 +156,12 @@
*/
inline void
setSignature(const Signature& signature);
-
+
inline void
setSignatureValue(const Block &value);
+ ///////////////////////////////////////////////////////////////
+
inline uint64_t
getIncomingFaceId() const;
@@ -149,25 +176,25 @@
onChanged();
private:
- Name name_;
- MetaInfo metaInfo_;
- mutable Block content_;
- Signature signature_;
+ Name m_name;
+ MetaInfo m_metaInfo;
+ mutable Block m_content;
+ Signature m_signature;
- mutable Block wire_;
+ mutable Block m_wire;
uint64_t m_incomingFaceId;
};
inline
Data::Data()
- : content_(Tlv::Content) // empty content
+ : m_content(Tlv::Content) // empty content
{
}
inline
Data::Data(const Name& name)
- : name_(name)
+ : m_name(name)
{
}
@@ -176,80 +203,179 @@
{
}
+template<bool T>
+inline size_t
+Data::wireEncode(EncodingImpl<T> &block, bool unsignedPortion/* = false*/) const
+{
+ size_t total_len = 0;
+
+ // Data ::= DATA-TLV TLV-LENGTH
+ // Name
+ // MetaInfo
+ // Content
+ // Signature
+
+ // (reverse encoding)
+
+ if (!unsignedPortion && !m_signature)
+ {
+ throw Error("Requested wire format, but data packet has not been signed yet");
+ }
+
+ if (!unsignedPortion)
+ {
+ // SignatureValue
+ total_len += prependBlock(block, m_signature.getValue());
+ }
+
+ // SignatureInfo
+ total_len += prependBlock(block, m_signature.getInfo());
+
+ // Content
+ total_len += prependBlock(block, getContent());
+
+ // MetaInfo
+ total_len += getMetaInfo().wireEncode(block);
+
+ // Name
+ total_len += getName().wireEncode(block);
+
+ if (!unsignedPortion)
+ {
+ total_len += block.prependVarNumber (total_len);
+ total_len += block.prependVarNumber (Tlv::Data);
+ }
+ return total_len;
+}
+
+inline const Block &
+Data::wireEncode() const
+{
+ if (m_wire.hasWire())
+ return m_wire;
+
+ EncodingEstimator estimator;
+ size_t estimatedSize = wireEncode(estimator);
+
+ EncodingBuffer buffer(estimatedSize, 0);
+ wireEncode(buffer);
+
+ const_cast<Data*>(this)->wireDecode(buffer.block());
+ return m_wire;
+}
+
+/**
+ * Decode the input using a particular wire format and update this Data.
+ * @param input The input byte array to be decoded.
+ */
+void
+Data::wireDecode(const Block &wire)
+{
+ m_wire = wire;
+ m_wire.parse();
+
+ // Data ::= DATA-TLV TLV-LENGTH
+ // Name
+ // MetaInfo
+ // Content
+ // Signature
+
+ // Name
+ m_name.wireDecode(m_wire.get(Tlv::Name));
+
+ // MetaInfo
+ m_metaInfo.wireDecode(m_wire.get(Tlv::MetaInfo));
+
+ // Content
+ m_content = m_wire.get(Tlv::Content);
+
+ ///////////////
+ // Signature //
+ ///////////////
+
+ // SignatureInfo
+ m_signature.setInfo(m_wire.get(Tlv::SignatureInfo));
+
+ // SignatureValue
+ Block::element_const_iterator val = m_wire.find(Tlv::SignatureValue);
+ if (val != m_wire.elements_end())
+ m_signature.setValue(*val);
+}
+
inline const Name&
Data::getName() const
{
- return name_;
+ return m_name;
}
inline void
Data::setName(const Name& name)
{
onChanged();
- name_ = name;
+ m_name = name;
}
inline const MetaInfo&
Data::getMetaInfo() const
{
- return metaInfo_;
+ return m_metaInfo;
}
inline void
Data::setMetaInfo(const MetaInfo& metaInfo)
{
onChanged();
- metaInfo_ = metaInfo;
+ m_metaInfo = metaInfo;
}
inline uint32_t
Data::getContentType() const
{
- return metaInfo_.getType();
+ return m_metaInfo.getType();
}
inline void
Data::setContentType(uint32_t type)
{
onChanged();
- metaInfo_.setType(type);
+ m_metaInfo.setType(type);
}
inline Milliseconds
Data::getFreshnessPeriod() const
{
- return metaInfo_.getFreshnessPeriod();
+ return m_metaInfo.getFreshnessPeriod();
}
inline void
Data::setFreshnessPeriod(Milliseconds freshnessPeriod)
{
onChanged();
- metaInfo_.setFreshnessPeriod(freshnessPeriod);
+ m_metaInfo.setFreshnessPeriod(freshnessPeriod);
}
inline const name::Component&
Data::getFinalBlockId() const
{
- return metaInfo_.getFinalBlockId();
+ return m_metaInfo.getFinalBlockId();
}
inline void
Data::setFinalBlockId(const name::Component& finalBlockId)
{
onChanged();
- metaInfo_.setFinalBlockId(finalBlockId);
+ m_metaInfo.setFinalBlockId(finalBlockId);
}
inline const Block&
Data::getContent() const
{
- if (content_.empty())
- content_ = dataBlock(Tlv::Content, reinterpret_cast<const uint8_t*>(0), 0);
+ if (m_content.empty())
+ m_content = dataBlock(Tlv::Content, reinterpret_cast<const uint8_t*>(0), 0);
- if (!content_.hasWire())
- content_.encode();
- return content_;
+ if (!m_content.hasWire())
+ m_content.encode();
+ return m_content;
}
inline void
@@ -257,7 +383,7 @@
{
onChanged();
- content_ = dataBlock(Tlv::Content, content, contentLength);
+ m_content = dataBlock(Tlv::Content, content, contentLength);
}
inline void
@@ -265,7 +391,7 @@
{
onChanged();
- content_ = Block(Tlv::Content, contentValue); // not real a wire encoding yet
+ m_content = Block(Tlv::Content, contentValue); // not real a wire encoding yet
}
inline void
@@ -274,30 +400,30 @@
onChanged();
if (content.type() == Tlv::Content)
- content_ = content;
+ m_content = content;
else {
- content_ = Block(Tlv::Content, content);
+ m_content = Block(Tlv::Content, content);
}
}
inline const Signature&
Data::getSignature() const
{
- return signature_;
+ return m_signature;
}
inline void
Data::setSignature(const Signature& signature)
{
onChanged();
- signature_ = signature;
+ m_signature = signature;
}
inline void
Data::setSignatureValue(const Block &value)
{
onChanged();
- signature_.setValue(value);
+ m_signature.setValue(value);
}
inline uint64_t
@@ -320,11 +446,21 @@
// !!!Note!!! Signature is not invalidated and it is responsibility of
// the application to do proper re-signing if necessary
- wire_.reset();
+ m_wire.reset();
}
-std::ostream&
-operator << (std::ostream &os, const Data &data);
+inline std::ostream&
+operator << (std::ostream &os, const Data &data)
+{
+ os << "Name: " << data.getName() << "\n";
+ os << "MetaInfo: " << data.getMetaInfo() << "\n";
+ os << "Content: (size: " << data.getContent().value_size() << ")\n";
+ os << "Signature: (type: " << data.getSignature().getType() <<
+ ", value_length: "<< data.getSignature().getValue().value_size() << ")";
+ os << std::endl;
+
+ return os;
+}
} // namespace ndn