encoding: provide FormattedOutputFunction for Block
refs #2225
Change-Id: Ie38539ff93293b3919789043b01e09b573fb619a
diff --git a/src/encoding/block.cpp b/src/encoding/block.cpp
index 691bbdf..2113064 100644
--- a/src/encoding/block.cpp
+++ b/src/encoding/block.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2017 Regents of the University of California.
+ * Copyright (c) 2013-2018 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -25,6 +25,7 @@
#include "buffer-stream.hpp"
#include "encoding-buffer.hpp"
#include "tlv.hpp"
+#include "../util/string-helper.hpp"
#include <boost/asio/buffer.hpp>
#include <boost/range/adaptor/reversed.hpp>
@@ -379,12 +380,19 @@
return m_size;
}
+ size_t len = encodeValue(estimator);
+ len += estimator.prependVarNumber(len);
+ len += estimator.prependVarNumber(m_type);
+ return len;
+}
+
+size_t
+Block::encodeValue(EncodingEstimator& estimator) const
+{
size_t len = 0;
for (const Block& element : m_elements | boost::adaptors::reversed) {
len += element.encode(estimator);
}
- len += estimator.prependVarNumber(len);
- len += estimator.prependVarNumber(m_type);
return len;
}
@@ -509,4 +517,31 @@
std::memcmp(lhs.value(), rhs.value(), lhs.value_size()) == 0);
}
+std::ostream&
+operator<<(std::ostream& os, const Block& block)
+{
+ auto oldFmt = os.flags(std::ios_base::dec);
+
+ if (block.empty()) {
+ os << "[invalid]";
+ }
+ else if (!block.m_elements.empty()) {
+ EncodingEstimator estimator;
+ size_t tlvLength = block.encodeValue(estimator);
+ os << block.type() << '[' << tlvLength << "]={";
+ std::copy(block.elements_begin(), block.elements_end(), make_ostream_joiner(os, ','));
+ os << '}';
+ }
+ else if (block.value_size() > 0) {
+ os << block.type() << '[' << block.value_size() << "]=";
+ printHex(os, block.value(), block.value_size(), true);
+ }
+ else {
+ os << block.type() << "[empty]";
+ }
+
+ os.flags(oldFmt);
+ return os;
+}
+
} // namespace ndn
diff --git a/src/encoding/block.hpp b/src/encoding/block.hpp
index 2e0601d..63f3677 100644
--- a/src/encoding/block.hpp
+++ b/src/encoding/block.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2017 Regents of the University of California.
+ * Copyright (c) 2013-2018 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -384,6 +384,11 @@
size_t
encode(EncodingEstimator& estimator) const;
+ /** @brief Estimate TLV-LENGTH as if sub elements are encoded into TLV-VALUE
+ */
+ size_t
+ encodeValue(EncodingEstimator& estimator) const;
+
/** @brief Encode sub elements into TLV-VALUE and prepend Block to encoder
* @post TLV-VALUE contains sub elements from elements()
* @post internal buffer and iterators point to Encoder's buffer
@@ -420,6 +425,18 @@
* This field is valid only if parse() has been executed.
*/
mutable element_container m_elements;
+
+ /** @brief Print @p block to @p os.
+ *
+ * Default-constructed block is printed as: `[invalid]`.
+ * Zero-length block is printed as: `TT[empty]`, where TT is TLV-TYPE in decimal.
+ * Non-zero-length block on which @c Block::parse is not called is printed as: `TT[LL]=VVVV`,
+ * where LL is TLV-LENGTH in decimal, and VVVV is TLV-VALUE is hexadecimal.
+ * Block on which @c Block::parse has been called in printed as: `TT[LL]={SUB,SUB}`,
+ * where SUB is a sub-element printed using this format.
+ */
+ friend std::ostream&
+ operator<<(std::ostream& os, const Block& block);
};
/** @brief Compare whether two Blocks have same TLV-TYPE, TLV-LENGTH, and TLV-VALUE