encoding: Extended version of EncodingBuffer (allow buffer length estimation)
Change-Id: I85bd9f1605340e78035971752f67be22e97ac1d5
diff --git a/src/encoding/encoding-buffer.hpp b/src/encoding/encoding-buffer.hpp
index b3cfa65..8bf6d2c 100644
--- a/src/encoding/encoding-buffer.hpp
+++ b/src/encoding/encoding-buffer.hpp
@@ -23,40 +23,35 @@
namespace ndn {
+namespace encoding {
+const bool Buffer = true;
+const bool Estimator = false;
+} // encoding
+
+template<bool isRealEncoderNotEstimator>
+class EncodingImpl;
+
+typedef EncodingImpl<encoding::Buffer> EncodingBuffer;
+typedef EncodingImpl<encoding::Estimator> EncodingEstimator;
+
/**
* @brief Class representing wire element of the NDN packet
*/
-class EncodingBuffer
+template<>
+class EncodingImpl<encoding::Buffer>
{
public:
- /// @brief Error that can be thrown from the block
- struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
-
- enum
- {
- DefaultBufferSize = 8800,
- BufferReservedSize = 400
- };
-
/**
- * @brief Default constructor to create a fix-sized EncodingBuffer
+ * @brief Constructor to create a EncodingImpl with specified reserved sizes
+ *
+ * The caller should make sure that that reserveFromBack does not exceed totalReserve,
+ * otherwise behavior is undefined.
*/
- EncodingBuffer ()
- : m_buffer (new Buffer ((size_t) DefaultBufferSize))
+ EncodingImpl (size_t totalReserve = 8800,
+ size_t reserveFromBack = 400)
+ : m_buffer (new Buffer (totalReserve))
{
- m_begin = m_end = m_buffer->end () - BufferReservedSize;
- }
-
- /**
- * @brief Constructor to create a EncodingBuffer with user-specified size
- */
- EncodingBuffer (size_t size)
- : m_buffer (new Buffer (size))
- {
- if (size <= BufferReservedSize)
- m_begin = m_end = m_buffer->end ();
- else
- m_begin = m_end = m_buffer->end () - BufferReservedSize;
+ m_begin = m_end = m_buffer->end () - (reserveFromBack < totalReserve ? reserveFromBack : 0);
}
inline size_t
@@ -125,36 +120,93 @@
Buffer::iterator m_end;
};
+
+/**
+ * @brief Class representing wire element of the NDN packet
+ */
+template<>
+class EncodingImpl<encoding::Estimator>
+{
+public:
+ EncodingImpl (size_t totalReserve = 8800,
+ size_t reserveFromBack = 400)
+ {
+ }
+
+ inline size_t
+ size () const;
+
+ inline size_t
+ prependByte (uint8_t val);
+
+ inline size_t
+ prependByteArray (const uint8_t *arr, size_t len);
+
+ inline size_t
+ prependBuffer (const Buffer& arr);
+
+ inline size_t
+ prependNonNegativeInteger (uint64_t varNumber);
+
+ inline size_t
+ prependVarNumber (uint64_t varNumber);
+
+ inline size_t
+ appendByte (uint8_t val);
+
+ inline size_t
+ appendByteArray (const uint8_t *arr, size_t len);
+
+ inline size_t
+ appendBuffer (const Buffer& arr);
+
+ inline size_t
+ appendNonNegativeInteger (uint64_t varNumber);
+
+ inline size_t
+ appendVarNumber (uint64_t varNumber);
+
+private:
+ size_t m_size;
+};
+
+
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
inline size_t
-EncodingBuffer::size () const
+EncodingImpl<encoding::Buffer>::size () const
{
return m_end - m_begin;
}
inline size_t
-EncodingBuffer::capacity () const
+EncodingImpl<encoding::Estimator>::size () const
+{
+ return m_size;
+}
+
+inline size_t
+EncodingImpl<encoding::Buffer>::capacity () const
{
return m_buffer->size ();
}
inline uint8_t*
-EncodingBuffer::buf ()
+EncodingImpl<encoding::Buffer>::buf ()
{
return &(*m_begin);
}
inline const uint8_t*
-EncodingBuffer::buf () const
+EncodingImpl<encoding::Buffer>::buf () const
{
return &(*m_begin);
}
inline void
-EncodingBuffer::resize (size_t sz, bool addInFront)
+EncodingImpl<encoding::Buffer>::resize (size_t sz, bool addInFront)
{
if (addInFront)
{
@@ -185,25 +237,25 @@
}
inline Buffer::iterator
-EncodingBuffer::begin ()
+EncodingImpl<encoding::Buffer>::begin ()
{
return m_begin;
}
inline Buffer::iterator
-EncodingBuffer::end ()
+EncodingImpl<encoding::Buffer>::end ()
{
return m_end;
}
inline Buffer::const_iterator
-EncodingBuffer::begin () const
+EncodingImpl<encoding::Buffer>::begin () const
{
return m_begin;
}
inline Buffer::const_iterator
-EncodingBuffer::end () const
+EncodingImpl<encoding::Buffer>::end () const
{
return m_end;
}
@@ -214,7 +266,7 @@
//////////////////////////////////////////////////////////
inline size_t
-EncodingBuffer::prependByte (uint8_t val)
+EncodingImpl<encoding::Buffer>::prependByte (uint8_t val)
{
if (m_begin == m_buffer->begin ())
resize (m_buffer->size () * 2, true);
@@ -225,7 +277,14 @@
}
inline size_t
-EncodingBuffer::prependByteArray (const uint8_t *arr, size_t len)
+EncodingImpl<encoding::Estimator>::prependByte (uint8_t val)
+{
+ m_size += 1;
+ return 1;
+}
+
+inline size_t
+EncodingImpl<encoding::Buffer>::prependByteArray (const uint8_t *arr, size_t len)
{
if ((m_buffer->begin () + len) > m_begin)
resize (m_buffer->size () * 2 + len, true);
@@ -236,7 +295,14 @@
}
inline size_t
-EncodingBuffer::prependBuffer (const Buffer& arr)
+EncodingImpl<encoding::Estimator>::prependByteArray (const uint8_t *arr, size_t len)
+{
+ m_size += len;
+ return len;
+}
+
+inline size_t
+EncodingImpl<encoding::Buffer>::prependBuffer (const Buffer& arr)
{
if ((m_buffer->begin () + arr.size ()) > m_begin)
resize (m_buffer->size () * 2 + arr.size (), true);
@@ -247,7 +313,14 @@
}
inline size_t
-EncodingBuffer::prependNonNegativeInteger (uint64_t varNumber)
+EncodingImpl<encoding::Estimator>::prependBuffer (const Buffer& arr)
+{
+ m_size += arr.size ();
+ return arr.size ();
+}
+
+inline size_t
+EncodingImpl<encoding::Buffer>::prependNonNegativeInteger (uint64_t varNumber)
{
if (varNumber < 253) {
return prependByte (static_cast<uint8_t> (varNumber));
@@ -267,7 +340,28 @@
}
inline size_t
-EncodingBuffer::prependVarNumber (uint64_t varNumber)
+EncodingImpl<encoding::Estimator>::prependNonNegativeInteger (uint64_t varNumber)
+{
+ if (varNumber < 253) {
+ m_size += 1;
+ return 1;
+ }
+ else if (varNumber <= std::numeric_limits<uint16_t>::max ()) {
+ m_size += 2;
+ return 2;
+ }
+ else if (varNumber <= std::numeric_limits<uint32_t>::max ()) {
+ m_size += 4;
+ return 4;
+ }
+ else {
+ m_size += 8;
+ return 8;
+ }
+}
+
+inline size_t
+EncodingImpl<encoding::Buffer>::prependVarNumber (uint64_t varNumber)
{
if (varNumber < 253) {
prependByte (static_cast<uint8_t> (varNumber));
@@ -293,12 +387,33 @@
}
}
+inline size_t
+EncodingImpl<encoding::Estimator>::prependVarNumber (uint64_t varNumber)
+{
+ if (varNumber < 253) {
+ m_size += 1;
+ return 1;
+ }
+ else if (varNumber <= std::numeric_limits<uint16_t>::max ()) {
+ m_size += 3;
+ return 3;
+ }
+ else if (varNumber <= std::numeric_limits<uint32_t>::max ()) {
+ m_size += 5;
+ return 5;
+ }
+ else {
+ m_size += 9;
+ return 9;
+ }
+}
+
/////////////////////////////////////////////////////////
// Append to the back of the buffer. Resize if needed. //
/////////////////////////////////////////////////////////
inline size_t
-EncodingBuffer::appendByte (uint8_t val)
+EncodingImpl<encoding::Buffer>::appendByte (uint8_t val)
{
if (m_end == m_buffer->end ())
resize (m_buffer->size () * 2, false);
@@ -309,7 +424,13 @@
}
inline size_t
-EncodingBuffer::appendByteArray (const uint8_t *arr, size_t len)
+EncodingImpl<encoding::Estimator>::appendByte (uint8_t val)
+{
+ return 1;
+}
+
+inline size_t
+EncodingImpl<encoding::Buffer>::appendByteArray (const uint8_t *arr, size_t len)
{
if ((m_end + len) > m_buffer->end ())
resize (m_buffer->size () * 2 + len, false);
@@ -320,7 +441,13 @@
}
inline size_t
-EncodingBuffer::appendBuffer (const Buffer& arr)
+EncodingImpl<encoding::Estimator>::appendByteArray (const uint8_t *arr, size_t len)
+{
+ return prependByteArray(arr, len);
+}
+
+inline size_t
+EncodingImpl<encoding::Buffer>::appendBuffer (const Buffer& arr)
{
if ((m_end + arr.size ()) > m_buffer->end ())
resize (m_buffer->size () * 2 + arr.size (), false);
@@ -331,7 +458,13 @@
}
inline size_t
-EncodingBuffer::appendNonNegativeInteger (uint64_t varNumber)
+EncodingImpl<encoding::Estimator>::appendBuffer (const Buffer& arr)
+{
+ return prependBuffer(arr);
+}
+
+inline size_t
+EncodingImpl<encoding::Buffer>::appendNonNegativeInteger (uint64_t varNumber)
{
if (varNumber < 253) {
return appendByte (static_cast<uint8_t> (varNumber));
@@ -351,7 +484,13 @@
}
inline size_t
-EncodingBuffer::appendVarNumber (uint64_t varNumber)
+EncodingImpl<encoding::Estimator>::appendNonNegativeInteger (uint64_t varNumber)
+{
+ return prependNonNegativeInteger(varNumber);
+}
+
+inline size_t
+EncodingImpl<encoding::Buffer>::appendVarNumber (uint64_t varNumber)
{
if (varNumber < 253) {
appendByte (static_cast<uint8_t> (varNumber));
@@ -377,6 +516,12 @@
}
}
+inline size_t
+EncodingImpl<encoding::Estimator>::appendVarNumber (uint64_t varNumber)
+{
+ return prependVarNumber(varNumber);
+}
+
} // ndn
#endif // NDN_ENCODING_BUFFER_HPP