encoding: reorganize Block class code
* Improve Doxygen.
* Consolidate and simplify constructors.
* Reorder class methods in cpp file to match hpp.
* Make operator== and operator!= non-member functions.
* Improve exception messages.
* Update code style.
refs #4171
Change-Id: I4cc0393f43a24a500b0efff90108ad1b42f5fa47
diff --git a/src/encoding/block.cpp b/src/encoding/block.cpp
index 16c05c5..82b1110 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-2016 Regents of the University of California.
+/*
+ * Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -23,10 +23,9 @@
#include "block.hpp"
#include "block-helpers.hpp"
-
-#include "tlv.hpp"
-#include "encoding-buffer.hpp"
#include "buffer-stream.hpp"
+#include "encoding-buffer.hpp"
+#include "tlv.hpp"
#include <boost/lexical_cast.hpp>
#include <boost/asio/buffer.hpp>
@@ -45,176 +44,122 @@
const size_t MAX_SIZE_OF_BLOCK_FROM_STREAM = MAX_NDN_PACKET_SIZE;
+// ---- constructor, creation, assignment ----
+
Block::Block()
: m_type(std::numeric_limits<uint32_t>::max())
+ , m_size(0)
{
}
Block::Block(const EncodingBuffer& buffer)
- : m_buffer(const_cast<EncodingBuffer&>(buffer).getBuffer())
- , m_begin(buffer.begin())
- , m_end(buffer.end())
- , m_size(m_end - m_begin)
-{
- m_value_begin = m_begin;
- m_value_end = m_end;
-
- m_type = tlv::readType(m_value_begin, m_value_end);
- uint64_t length = tlv::readVarNumber(m_value_begin, m_value_end);
- if (length != static_cast<uint64_t>(m_value_end - m_value_begin))
- {
- BOOST_THROW_EXCEPTION(tlv::Error("TLV length doesn't match buffer length"));
- }
-}
-
-Block::Block(const ConstBufferPtr& wire,
- uint32_t type,
- const Buffer::const_iterator& begin, const Buffer::const_iterator& end,
- const Buffer::const_iterator& valueBegin, const Buffer::const_iterator& valueEnd)
- : m_buffer(wire)
- , m_type(type)
- , m_begin(begin)
- , m_end(end)
- , m_size(m_end - m_begin)
- , m_value_begin(valueBegin)
- , m_value_end(valueEnd)
+ : Block(const_cast<EncodingBuffer&>(buffer).getBuffer(), buffer.begin(), buffer.end(), true)
{
}
Block::Block(const ConstBufferPtr& buffer)
- : m_buffer(buffer)
- , m_begin(m_buffer->begin())
- , m_end(m_buffer->end())
- , m_size(m_end - m_begin)
+ : Block(buffer, buffer->begin(), buffer->end(), true)
{
- m_value_begin = m_begin;
- m_value_end = m_end;
-
- m_type = tlv::readType(m_value_begin, m_value_end);
-
- uint64_t length = tlv::readVarNumber(m_value_begin, m_value_end);
- if (length != static_cast<uint64_t>(m_value_end - m_value_begin))
- {
- BOOST_THROW_EXCEPTION(tlv::Error("TLV length doesn't match buffer length"));
- }
}
-Block::Block(const ConstBufferPtr& buffer,
- const Buffer::const_iterator& begin, const Buffer::const_iterator& end,
- bool verifyLength/* = true*/)
- : m_buffer(buffer)
+Block::Block(ConstBufferPtr buffer, Buffer::const_iterator begin, Buffer::const_iterator end,
+ bool verifyLength)
+ : m_buffer(std::move(buffer))
, m_begin(begin)
, m_end(end)
+ , m_valueBegin(m_begin)
+ , m_valueEnd(m_end)
, m_size(m_end - m_begin)
{
- m_value_begin = m_begin;
- m_value_end = m_end;
+ if (m_buffer->size() == 0) {
+ BOOST_THROW_EXCEPTION(std::invalid_argument("buffer is empty"));
+ }
- m_type = tlv::readType(m_value_begin, m_value_end);
- uint64_t length = tlv::readVarNumber(m_value_begin, m_value_end);
- if (verifyLength) {
- if (length != static_cast<uint64_t>(std::distance(m_value_begin, m_value_end))) {
- BOOST_THROW_EXCEPTION(tlv::Error("TLV length doesn't match buffer length"));
- }
+ const uint8_t* bufferBegin = &m_buffer->front();
+ const uint8_t* bufferEnd = bufferBegin + m_buffer->size();
+ if (&*begin < bufferBegin || &*begin > bufferEnd ||
+ &*end < bufferBegin || &*end > bufferEnd) {
+ BOOST_THROW_EXCEPTION(std::invalid_argument("begin/end iterators points out of the buffer"));
+ }
+
+ m_type = tlv::readType(m_valueBegin, m_valueEnd);
+ uint64_t length = tlv::readVarNumber(m_valueBegin, m_valueEnd);
+ // m_valueBegin now points to TLV-VALUE
+
+ if (verifyLength && length != static_cast<uint64_t>(m_valueEnd - m_valueBegin)) {
+ BOOST_THROW_EXCEPTION(Error("TLV-LENGTH doesn't match buffer size"));
}
}
-Block::Block(const Block& block,
- const Buffer::const_iterator& begin, const Buffer::const_iterator& end,
- bool verifyLength/* = true*/)
- : m_buffer(block.m_buffer)
+Block::Block(const Block& block, Buffer::const_iterator begin, Buffer::const_iterator end,
+ bool verifyLength)
+ : Block(block.m_buffer, begin, end, verifyLength)
+{
+}
+
+Block::Block(ConstBufferPtr buffer, uint32_t type,
+ Buffer::const_iterator begin, Buffer::const_iterator end,
+ Buffer::const_iterator valueBegin, Buffer::const_iterator valueEnd)
+ : m_buffer(std::move(buffer))
, m_begin(begin)
, m_end(end)
+ , m_valueBegin(valueBegin)
+ , m_valueEnd(valueEnd)
+ , m_type(type)
, m_size(m_end - m_begin)
{
- if (!(m_buffer->begin() <= begin && begin <= m_buffer->end()) ||
- !(m_buffer->begin() <= end && end <= m_buffer->end())) {
- BOOST_THROW_EXCEPTION(Error("begin/end iterators do not point to the underlying buffer of the block"));
- }
-
- m_value_begin = m_begin;
- m_value_end = m_end;
-
- m_type = tlv::readType(m_value_begin, m_value_end);
- uint64_t length = tlv::readVarNumber(m_value_begin, m_value_end);
- if (verifyLength) {
- if (length != static_cast<uint64_t>(std::distance(m_value_begin, m_value_end))) {
- BOOST_THROW_EXCEPTION(tlv::Error("TLV length doesn't match buffer length"));
- }
- }
}
-Block::Block(const uint8_t* buffer, size_t maxlength)
+Block::Block(const uint8_t* buf, size_t bufSize)
{
- const uint8_t* tmp_begin = buffer;
- const uint8_t* tmp_end = buffer + maxlength;
+ const uint8_t* pos = buf;
+ const uint8_t* const end = buf + bufSize;
- m_type = tlv::readType(tmp_begin, tmp_end);
- uint64_t length = tlv::readVarNumber(tmp_begin, tmp_end);
+ m_type = tlv::readType(pos, end);
+ uint64_t length = tlv::readVarNumber(pos, end);
+ // pos now points to TLV-VALUE
- if (length > static_cast<uint64_t>(tmp_end - tmp_begin))
- {
- BOOST_THROW_EXCEPTION(tlv::Error("Not enough data in the buffer to fully parse TLV"));
- }
+ if (length > static_cast<uint64_t>(end - pos)) {
+ BOOST_THROW_EXCEPTION(tlv::Error("Not enough data in the buffer to fully parse TLV"));
+ }
+ size_t typeLengthSize = pos - buf;
+ m_size = typeLengthSize + length;
- m_buffer = make_shared<Buffer>(buffer, (tmp_begin - buffer) + length);
-
+ m_buffer = make_shared<Buffer>(buf, m_size);
m_begin = m_buffer->begin();
- m_end = m_buffer->end();
- m_size = m_end - m_begin;
-
- m_value_begin = m_buffer->begin() + (tmp_begin - buffer);
- m_value_end = m_buffer->end();
+ m_end = m_valueEnd = m_buffer->end();
+ m_valueBegin = m_begin + typeLengthSize;
}
-Block::Block(const void* bufferX, size_t maxlength)
+Block::Block(const void* buf, size_t bufSize)
+ : Block(reinterpret_cast<const uint8_t*>(buf), bufSize)
{
- const uint8_t* buffer = reinterpret_cast<const uint8_t*>(bufferX);
-
- const uint8_t* tmp_begin = buffer;
- const uint8_t* tmp_end = buffer + maxlength;
-
- m_type = tlv::readType(tmp_begin, tmp_end);
- uint64_t length = tlv::readVarNumber(tmp_begin, tmp_end);
-
- if (length > static_cast<uint64_t>(tmp_end - tmp_begin))
- {
- BOOST_THROW_EXCEPTION(tlv::Error("Not enough data in the buffer to fully parse TLV"));
- }
-
- m_buffer = make_shared<Buffer>(buffer, (tmp_begin - buffer) + length);
-
- m_begin = m_buffer->begin();
- m_end = m_buffer->end();
- m_size = m_end - m_begin;
-
- m_value_begin = m_buffer->begin() + (tmp_begin - buffer);
- m_value_end = m_buffer->end();
}
Block::Block(uint32_t type)
: m_type(type)
+ , m_size(tlv::sizeOfVarNumber(m_type) + tlv::sizeOfVarNumber(0))
{
}
-Block::Block(uint32_t type, const ConstBufferPtr& value)
- : m_buffer(value)
- , m_type(type)
+Block::Block(uint32_t type, ConstBufferPtr value)
+ : m_buffer(std::move(value))
, m_begin(m_buffer->end())
, m_end(m_buffer->end())
- , m_value_begin(m_buffer->begin())
- , m_value_end(m_buffer->end())
+ , m_valueBegin(m_buffer->begin())
+ , m_valueEnd(m_buffer->end())
+ , m_type(type)
{
m_size = tlv::sizeOfVarNumber(m_type) + tlv::sizeOfVarNumber(value_size()) + value_size();
}
Block::Block(uint32_t type, const Block& value)
: m_buffer(value.m_buffer)
- , m_type(type)
, m_begin(m_buffer->end())
, m_end(m_buffer->end())
- , m_value_begin(value.begin())
- , m_value_end(value.end())
+ , m_valueBegin(value.begin())
+ , m_valueEnd(value.end())
+ , m_type(type)
{
m_size = tlv::sizeOfVarNumber(m_type) + tlv::sizeOfVarNumber(value_size()) + value_size();
}
@@ -229,11 +174,13 @@
uint64_t length = tlv::readVarNumber(begin, end);
if (length == 0) {
- return makeEmptyBlock(type);
+ // XXX An extra octet is incorrectly consumed from istream (#4180)
+ return Block(type);
}
- if (length > MAX_SIZE_OF_BLOCK_FROM_STREAM)
- BOOST_THROW_EXCEPTION(tlv::Error("Length of block from stream is too large"));
+ if (length > MAX_SIZE_OF_BLOCK_FROM_STREAM) {
+ BOOST_THROW_EXCEPTION(tlv::Error("TLV-LENGTH from stream exceeds limit"));
+ }
// We may still have some problem here, if some exception happens,
// we may completely lose all the bytes extracted from the stream.
@@ -252,225 +199,78 @@
std::tuple<bool, Block>
Block::fromBuffer(ConstBufferPtr buffer, size_t offset)
{
- Buffer::const_iterator tempBegin = buffer->begin() + offset;
+ const Buffer::const_iterator begin = buffer->begin() + offset;
+ Buffer::const_iterator pos = begin;
- uint32_t type;
- bool isOk = tlv::readType(tempBegin, buffer->end(), type);
- if (!isOk)
+ uint32_t type = 0;
+ bool isOk = tlv::readType(pos, buffer->end(), type);
+ if (!isOk) {
return std::make_tuple(false, Block());
-
- uint64_t length;
- isOk = tlv::readVarNumber(tempBegin, buffer->end(), length);
- if (!isOk)
+ }
+ uint64_t length = 0;
+ isOk = tlv::readVarNumber(pos, buffer->end(), length);
+ if (!isOk) {
return std::make_tuple(false, Block());
+ }
+ // pos now points to TLV-VALUE
- if (length > static_cast<uint64_t>(buffer->end() - tempBegin))
+ if (length > static_cast<uint64_t>(buffer->end() - pos)) {
return std::make_tuple(false, Block());
+ }
- return std::make_tuple(true, Block(buffer, type,
- buffer->begin() + offset, tempBegin + length,
- tempBegin, tempBegin + length));
+ return std::make_tuple(true, Block(buffer, type, begin, pos + length, pos, pos + length));
}
std::tuple<bool, Block>
-Block::fromBuffer(const uint8_t* buffer, size_t maxSize)
+Block::fromBuffer(const uint8_t* buf, size_t bufSize)
{
- const uint8_t* tempBegin = buffer;
- const uint8_t* tempEnd = buffer + maxSize;
+ const uint8_t* pos = buf;
+ const uint8_t* const end = buf + bufSize;
uint32_t type = 0;
- bool isOk = tlv::readType(tempBegin, tempEnd, type);
- if (!isOk)
+ bool isOk = tlv::readType(pos, end, type);
+ if (!isOk) {
return std::make_tuple(false, Block());
-
- uint64_t length;
- isOk = tlv::readVarNumber(tempBegin, tempEnd, length);
- if (!isOk)
+ }
+ uint64_t length = 0;
+ isOk = tlv::readVarNumber(pos, end, length);
+ if (!isOk) {
return std::make_tuple(false, Block());
+ }
+ // pos now points to TLV-VALUE
- if (length > static_cast<uint64_t>(tempEnd - tempBegin))
+ if (length > static_cast<uint64_t>(end - pos)) {
return std::make_tuple(false, Block());
+ }
- BufferPtr sharedBuffer = make_shared<Buffer>(buffer, tempBegin + length);
- return std::make_tuple(true,
- Block(sharedBuffer, type,
- sharedBuffer->begin(), sharedBuffer->end(),
- sharedBuffer->begin() + (tempBegin - buffer), sharedBuffer->end()));
+ size_t typeLengthSize = pos - buf;
+ auto b = make_shared<Buffer>(buf, pos + length);
+ return std::make_tuple(true, Block(b, type, b->begin(), b->end(),
+ b->begin() + typeLengthSize, b->end()));
+}
+
+// ---- wire format ----
+
+bool
+Block::hasWire() const
+{
+ return m_buffer != nullptr && m_begin != m_end;
}
void
Block::reset()
{
- m_buffer.reset(); // reset of the shared_ptr
- m_subBlocks.clear(); // remove all parsed subelements
+ this->resetWire();
m_type = std::numeric_limits<uint32_t>::max();
- m_begin = m_end = m_value_begin = m_value_end = Buffer::const_iterator();
+ m_elements.clear();
}
void
Block::resetWire()
{
- m_buffer.reset(); // reset of the shared_ptr
- // keep subblocks
-
- // keep type
- m_begin = m_end = m_value_begin = m_value_end = Buffer::const_iterator();
-}
-
-void
-Block::parse() const
-{
- if (!m_subBlocks.empty() || value_size() == 0)
- return;
-
- Buffer::const_iterator begin = value_begin();
- Buffer::const_iterator end = value_end();
-
- while (begin != end)
- {
- Buffer::const_iterator element_begin = begin;
-
- uint32_t type = tlv::readType(begin, end);
- uint64_t length = tlv::readVarNumber(begin, end);
-
- if (length > static_cast<uint64_t>(end - begin))
- {
- m_subBlocks.clear();
- BOOST_THROW_EXCEPTION(tlv::Error("TLV length exceeds buffer length"));
- }
- Buffer::const_iterator element_end = begin + length;
-
- m_subBlocks.push_back(Block(m_buffer,
- type,
- element_begin, element_end,
- begin, element_end));
-
- begin = element_end;
- // don't do recursive parsing, just the top level
- }
-}
-
-void
-Block::encode()
-{
- if (hasWire())
- return;
-
- OBufferStream os;
- tlv::writeVarNumber(os, type());
-
- if (hasValue())
- {
- tlv::writeVarNumber(os, value_size());
- os.write(reinterpret_cast<const char*>(value()), value_size());
- }
- else if (m_subBlocks.size() == 0)
- {
- tlv::writeVarNumber(os, 0);
- }
- else
- {
- size_t valueSize = 0;
- for (element_const_iterator i = m_subBlocks.begin(); i != m_subBlocks.end(); ++i) {
- valueSize += i->size();
- }
-
- tlv::writeVarNumber(os, valueSize);
-
- for (element_const_iterator i = m_subBlocks.begin(); i != m_subBlocks.end(); ++i) {
- if (i->hasWire())
- os.write(reinterpret_cast<const char*>(i->wire()), i->size());
- else if (i->hasValue()) {
- tlv::writeVarNumber(os, i->type());
- tlv::writeVarNumber(os, i->value_size());
- os.write(reinterpret_cast<const char*>(i->value()), i->value_size());
- }
- else
- BOOST_THROW_EXCEPTION(Error("Underlying value buffer is empty"));
- }
- }
-
- // now assign correct block
-
- m_buffer = os.buf();
- m_begin = m_buffer->begin();
- m_end = m_buffer->end();
- m_size = m_end - m_begin;
-
- m_value_begin = m_buffer->begin();
- m_value_end = m_buffer->end();
-
- tlv::readType(m_value_begin, m_value_end);
- tlv::readVarNumber(m_value_begin, m_value_end);
-}
-
-const Block&
-Block::get(uint32_t type) const
-{
- element_const_iterator it = this->find(type);
- if (it != m_subBlocks.end())
- return *it;
-
- BOOST_THROW_EXCEPTION(Error("(Block::get) Requested a non-existed type [" +
- boost::lexical_cast<std::string>(type) + "] from Block"));
-}
-
-Block::element_const_iterator
-Block::find(uint32_t type) const
-{
- return std::find_if(m_subBlocks.begin(), m_subBlocks.end(),
- [type] (const Block& subBlock) { return subBlock.type() == type; });
-}
-
-void
-Block::remove(uint32_t type)
-{
- resetWire();
-
- auto it = std::remove_if(m_subBlocks.begin(), m_subBlocks.end(),
- [type] (const Block& subBlock) { return subBlock.type() == type; });
- m_subBlocks.resize(it - m_subBlocks.begin());
-}
-
-Block
-Block::blockFromValue() const
-{
- if (value_size() == 0)
- BOOST_THROW_EXCEPTION(Error("Underlying value buffer is empty"));
-
- Buffer::const_iterator begin = value_begin(),
- end = value_end();
-
- Buffer::const_iterator element_begin = begin;
-
- uint32_t type = tlv::readType(begin, end);
- uint64_t length = tlv::readVarNumber(begin, end);
-
- if (length != static_cast<uint64_t>(end - begin))
- BOOST_THROW_EXCEPTION(tlv::Error("TLV length mismatches buffer length"));
-
- return Block(m_buffer,
- type,
- element_begin, end,
- begin, end);
-}
-
-Block::operator boost::asio::const_buffer() const
-{
- return boost::asio::const_buffer(wire(), size());
-}
-
-bool
-Block::empty() const
-{
- return m_type == std::numeric_limits<uint32_t>::max();
-}
-
-bool
-Block::hasWire() const
-{
- return m_buffer && (m_begin != m_end);
+ m_buffer.reset(); // discard underlying buffer by resetting shared_ptr
+ m_begin = m_end = m_valueBegin = m_valueEnd = Buffer::const_iterator();
}
Buffer::const_iterator
@@ -495,7 +295,7 @@
Block::wire() const
{
if (!hasWire())
- BOOST_THROW_EXCEPTION(Error("(Block::wire) Underlying wire buffer is empty"));
+ BOOST_THROW_EXCEPTION(Error("Underlying wire buffer is empty"));
return &*m_begin;
}
@@ -503,35 +303,144 @@
size_t
Block::size() const
{
- if (hasWire() || hasValue()) {
- return m_size;
- }
- else
+ if (empty()) {
BOOST_THROW_EXCEPTION(Error("Block size cannot be determined (undefined block size)"));
+ }
+
+ return m_size;
}
-bool
-Block::hasValue() const
-{
- return static_cast<bool>(m_buffer);
-}
+// ---- value ----
const uint8_t*
Block::value() const
{
- if (!hasValue())
- return 0;
-
- return &*m_value_begin;
+ return hasValue() ? &*m_valueBegin : nullptr;
}
size_t
Block::value_size() const
{
- if (!hasValue())
- return 0;
+ return hasValue() ? m_valueEnd - m_valueBegin : 0;
+}
- return m_value_end - m_value_begin;
+Block
+Block::blockFromValue() const
+{
+ if (!hasValue())
+ BOOST_THROW_EXCEPTION(Error("Block has no TLV-VALUE"));
+
+ return Block(*this, m_valueBegin, m_valueEnd, true);
+}
+
+// ---- sub elements ----
+
+void
+Block::parse() const
+{
+ if (!m_elements.empty() || value_size() == 0)
+ return;
+
+ Buffer::const_iterator begin = value_begin();
+ Buffer::const_iterator end = value_end();
+
+ while (begin != end) {
+ Buffer::const_iterator pos = begin;
+
+ uint32_t type = tlv::readType(pos, end);
+ uint64_t length = tlv::readVarNumber(pos, end);
+ if (length > static_cast<uint64_t>(end - pos)) {
+ m_elements.clear();
+ BOOST_THROW_EXCEPTION(Error("TLV-LENGTH of sub-element of type " + to_string(type) +
+ " exceeds TLV-VALUE boundary of parent block"));
+ }
+ // pos now points to TLV-VALUE of sub element
+
+ Buffer::const_iterator subEnd = pos + length;
+ m_elements.emplace_back(m_buffer, type, begin, subEnd, pos, subEnd);
+
+ begin = subEnd;
+ }
+}
+
+void
+Block::encode()
+{
+ if (hasWire())
+ return;
+
+ OBufferStream os;
+ tlv::writeVarNumber(os, type());
+
+ if (hasValue()) {
+ tlv::writeVarNumber(os, value_size());
+ os.write(reinterpret_cast<const char*>(value()), value_size());
+ }
+ else if (m_elements.size() == 0) {
+ tlv::writeVarNumber(os, 0);
+ }
+ else {
+ size_t valueSize = 0;
+ for (element_const_iterator i = m_elements.begin(); i != m_elements.end(); ++i) {
+ valueSize += i->size();
+ }
+
+ tlv::writeVarNumber(os, valueSize);
+
+ for (element_const_iterator i = m_elements.begin(); i != m_elements.end(); ++i) {
+ if (i->hasWire())
+ os.write(reinterpret_cast<const char*>(i->wire()), i->size());
+ else if (i->hasValue()) {
+ tlv::writeVarNumber(os, i->type());
+ tlv::writeVarNumber(os, i->value_size());
+ os.write(reinterpret_cast<const char*>(i->value()), i->value_size());
+ }
+ else
+ BOOST_THROW_EXCEPTION(Error("Underlying value buffer is empty"));
+ }
+ }
+
+ // now assign correct block
+
+ m_buffer = os.buf();
+ m_begin = m_buffer->begin();
+ m_end = m_buffer->end();
+ m_size = m_end - m_begin;
+
+ m_valueBegin = m_buffer->begin();
+ m_valueEnd = m_buffer->end();
+
+ tlv::readType(m_valueBegin, m_valueEnd);
+ tlv::readVarNumber(m_valueBegin, m_valueEnd);
+}
+
+const Block&
+Block::get(uint32_t type) const
+{
+ auto it = this->find(type);
+ if (it != m_elements.end()) {
+ return *it;
+ }
+
+ BOOST_THROW_EXCEPTION(Error("No sub-element of type " + to_string(type) +
+ " is found in block of type " + to_string(m_type)));
+}
+
+Block::element_const_iterator
+Block::find(uint32_t type) const
+{
+ return std::find_if(m_elements.begin(), m_elements.end(),
+ [type] (const Block& subBlock) { return subBlock.type() == type; });
+}
+
+void
+Block::remove(uint32_t type)
+{
+ resetWire();
+
+ auto it = std::remove_if(m_elements.begin(), m_elements.end(),
+ [type] (const Block& subBlock) { return subBlock.type() == type; });
+ m_elements.resize(it - m_elements.begin());
}
Block::element_iterator
@@ -540,11 +449,11 @@
resetWire();
#ifdef NDN_CXX_HAVE_VECTOR_INSERT_ERASE_CONST_ITERATOR
- return m_subBlocks.erase(position);
+ return m_elements.erase(position);
#else
- element_iterator it = m_subBlocks.begin();
- std::advance(it, std::distance(m_subBlocks.cbegin(), position));
- return m_subBlocks.erase(it);
+ element_iterator it = m_elements.begin();
+ std::advance(it, std::distance(m_elements.cbegin(), position));
+ return m_elements.erase(it);
#endif
}
@@ -554,13 +463,13 @@
resetWire();
#ifdef NDN_CXX_HAVE_VECTOR_INSERT_ERASE_CONST_ITERATOR
- return m_subBlocks.erase(first, last);
+ return m_elements.erase(first, last);
#else
- element_iterator itStart = m_subBlocks.begin();
- element_iterator itEnd = m_subBlocks.begin();
- std::advance(itStart, std::distance(m_subBlocks.cbegin(), first));
- std::advance(itEnd, std::distance(m_subBlocks.cbegin(), last));
- return m_subBlocks.erase(itStart, itEnd);
+ element_iterator itStart = m_elements.begin();
+ element_iterator itEnd = m_elements.begin();
+ std::advance(itStart, std::distance(m_elements.cbegin(), first));
+ std::advance(itEnd, std::distance(m_elements.cbegin(), last));
+ return m_elements.erase(itStart, itEnd);
#endif
}
@@ -568,7 +477,7 @@
Block::push_back(const Block& element)
{
resetWire();
- m_subBlocks.push_back(element);
+ m_elements.push_back(element);
}
Block::element_iterator
@@ -577,43 +486,27 @@
resetWire();
#ifdef NDN_CXX_HAVE_VECTOR_INSERT_ERASE_CONST_ITERATOR
- return m_subBlocks.insert(pos, element);
+ return m_elements.insert(pos, element);
#else
- element_iterator it = m_subBlocks.begin();
- std::advance(it, std::distance(m_subBlocks.cbegin(), pos));
- return m_subBlocks.insert(it, element);
+ element_iterator it = m_elements.begin();
+ std::advance(it, std::distance(m_elements.cbegin(), pos));
+ return m_elements.insert(it, element);
#endif
}
-Block::element_const_iterator
-Block::elements_begin() const
-{
- return m_subBlocks.begin();
-}
+// ---- misc ----
-Block::element_const_iterator
-Block::elements_end() const
+Block::operator boost::asio::const_buffer() const
{
- return m_subBlocks.end();
-}
-
-size_t
-Block::elements_size() const
-{
- return m_subBlocks.size();
+ return boost::asio::const_buffer(wire(), size());
}
bool
-Block::operator!=(const Block& other) const
+operator==(const Block& lhs, const Block& rhs)
{
- return !this->operator==(other);
-}
-
-bool
-Block::operator==(const Block& other) const
-{
- return this->size() == other.size() &&
- std::equal(this->begin(), this->end(), other.begin());
+ return lhs.type() == rhs.type() &&
+ lhs.value_size() == rhs.value_size() &&
+ ::memcmp(lhs.value(), rhs.value(), lhs.value_size()) == 0;
}
} // namespace ndn