blob: 7667fbddb026cd5d90b4b12dda0ae1607035e534 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07002/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 Regents of the University of California.
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -08004 *
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07005 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -08006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070020 *
21 * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080022 */
23
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070024#ifndef NDN_ENCODING_BLOCK_HPP
25#define NDN_ENCODING_BLOCK_HPP
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080026
Alexander Afanasyev19508852014-01-29 01:01:51 -080027#include "../common.hpp"
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080028
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080029#include "buffer.hpp"
30#include "tlv.hpp"
31
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080032namespace ndn {
33
Alexander Afanasyev233750e2014-02-16 00:50:07 -080034template<bool> class EncodingImpl;
35typedef EncodingImpl<true> EncodingBuffer;
36
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080037/**
38 * @brief Class representing wire element of the NDN packet
39 */
40class Block
41{
42public:
Alexander Afanasyev8ea763d2014-02-06 20:32:52 -080043 typedef std::vector<Block> element_container;
44 typedef element_container::iterator element_iterator;
45 typedef element_container::const_iterator element_const_iterator;
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080046
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070047 /// @brief Error that can be thrown from Block
Yingdi Yue52f4ef2014-04-17 19:21:13 -070048 class Error : public Tlv::Error
Alexander Afanasyev937aa782014-03-21 13:17:57 -070049 {
Alexander Afanasyeva465e972014-03-22 17:21:49 -070050 public:
51 explicit
52 Error(const std::string& what)
Yingdi Yue52f4ef2014-04-17 19:21:13 -070053 : Tlv::Error(what)
Alexander Afanasyeva465e972014-03-22 17:21:49 -070054 {
55 }
Alexander Afanasyev937aa782014-03-21 13:17:57 -070056 };
57
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080058 /**
59 * @brief Default constructor to create an empty Block
60 */
61 Block();
62
63 /**
Alexander Afanasyev15151312014-02-16 00:53:51 -080064 * @brief Create block based on EncodingBuffer object
65 */
66 explicit
67 Block(const EncodingBuffer& buffer);
Alexander Afanasyev937aa782014-03-21 13:17:57 -070068
Alexander Afanasyev15151312014-02-16 00:53:51 -080069 /**
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070070 * @brief A helper version of a constructor to create Block from the raw buffer (type
71 * and value-length parsing)
Alexander Afanasyeva465e972014-03-22 17:21:49 -070072 *
73 * This constructor provides ability of implicit conversion from ConstBufferPtr to Block
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080074 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -070075 Block(const ConstBufferPtr& buffer);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080076
77 /**
Alexander Afanasyev187bc482014-02-06 15:04:04 -080078 * @brief Another helper to create block from a buffer, directly specifying boundaries
79 * of the block within the buffer
80 *
81 * This version will automatically detect type and position of the value within the block
82 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -070083 Block(const ConstBufferPtr& buffer,
84 const Buffer::const_iterator& begin, const Buffer::const_iterator& end,
Alexander Afanasyev5964fb72014-02-18 12:42:45 -080085 bool verifyLength = true);
Alexander Afanasyev937aa782014-03-21 13:17:57 -070086
Alexander Afanasyev187bc482014-02-06 15:04:04 -080087 /**
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070088 * @brief A helper version of a constructor to create Block from the raw buffer (type
89 * and value-length parsing)
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080090 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -070091 Block(const uint8_t* buffer, size_t maxlength);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080092
Alexander Afanasyev937aa782014-03-21 13:17:57 -070093 Block(const void* buffer, size_t maxlength);
Yingdi Yu27158392014-01-20 13:04:20 -080094
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080095 /**
96 * @brief Create Block from the wire buffer (no parsing)
97 *
98 * This version of the constructor does not do any parsing
99 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700100 Block(const ConstBufferPtr& wire,
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800101 uint32_t type,
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700102 const Buffer::const_iterator& begin, const Buffer::const_iterator& end,
103 const Buffer::const_iterator& valueBegin, const Buffer::const_iterator& valueEnd);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800104
105 /**
106 * @brief Create Block of a specific type with empty wire buffer
107 */
Alexander Afanasyevf42ce132014-01-07 13:32:30 -0800108 explicit
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800109 Block(uint32_t type);
110
111 /**
112 * @brief Create Block of a specific type with the specified value
113 *
114 * The underlying buffer hold only value, additional operations are needed
115 * to construct wire encoding, one need to prepend the wire buffer with type
116 * and value-length VAR-NUMBERs
117 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700118 Block(uint32_t type, const ConstBufferPtr& value);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800119
120 /**
121 * @brief Create nested Block of a specific type with the specified value
122 *
123 * The underlying buffer hold only value, additional operations are needed
124 * to construct wire encoding, one need to prepend the wire buffer with type
125 * and value-length VAR-NUMBERs
126 */
Alexander Afanasyevf42ce132014-01-07 13:32:30 -0800127 explicit
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700128 Block(uint32_t type, const Block& value);
129
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700130 /*
131 * @brief A helper version of a constructor to create Block from the stream
132 *
133 * @deprecated Use Block::fromStream instead
134 */
135 explicit
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700136 DEPRECATED(Block(std::istream& is))
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700137 {
138 *this = Block::fromStream(is);
139 }
140
141 /*
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700142 * @brief Constructor Block from the stream
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700143 */
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700144 static Block
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700145 fromStream(std::istream& is);
146
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700147 /**
148 * @brief Try to construct block from Buffer, referencing data block pointed by wire
149 *
150 * @throws This method never throws an exception
151 *
152 * @returns true if Block successfully created, false if block cannot be created
153 */
154 static bool
155 fromBuffer(const ConstBufferPtr& wire, size_t offset, Block& block);
156
157 /**
158 * @brief Try to construct block from Buffer, referencing data block pointed by wire
159 *
160 * @throws This method never throws an exception
161 *
162 * @returns true if Block successfully created, false if block cannot be created
163 */
164 static bool
165 fromBuffer(const uint8_t* buffer, size_t maxSize, Block& block);
Alexander Afanasyev196b9aa2014-01-31 17:19:16 -0800166
167 /**
168 * @brief Check if the Block is empty
169 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700170 bool
Alexander Afanasyev196b9aa2014-01-31 17:19:16 -0800171 empty() const;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700172
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800173 /**
174 * @brief Check if the Block has fully encoded wire
175 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700176 bool
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800177 hasWire() const;
178
179 /**
180 * @brief Check if the Block has value block (no type and length are encoded)
181 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700182 bool
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800183 hasValue() const;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700184
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800185 /**
186 * @brief Reset wire buffer of the element
187 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700188 void
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800189 reset();
190
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800191 /**
192 * @brief Reset wire buffer but keep sub elements (if any)
193 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700194 void
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800195 resetWire();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800196
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800197 /**
198 * @brief Parse wire buffer into subblocks
199 *
200 * This method is not really const, but it does not modify any data. It simply
201 * parses contents of the buffer into subblocks
202 */
203 void
204 parse() const;
205
206 /**
207 * @brief Encode subblocks into wire buffer
208 */
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800209 void
210 encode();
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700211
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700212 uint32_t
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800213 type() const;
214
215 /**
216 * @brief Get the first subelement of the requested type
217 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700218 const Block&
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800219 get(uint32_t type) const;
220
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700221 element_const_iterator
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800222 find(uint32_t type) const;
223
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700224 void
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800225 remove(uint32_t type);
226
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700227 element_iterator
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800228 erase(element_iterator position);
229
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700230 element_iterator
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800231 erase(element_iterator first, element_iterator last);
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700232
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700233 void
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700234 push_back(const Block& element);
235
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700236 Buffer::const_iterator
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800237 begin() const;
238
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700239 Buffer::const_iterator
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800240 end() const;
241
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700242 const uint8_t*
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800243 wire() const;
244
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700245 size_t
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800246 size() const;
247
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700248 Buffer::const_iterator
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800249 value_begin() const;
250
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700251 Buffer::const_iterator
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800252 value_end() const;
253
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700254 const uint8_t*
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800255 value() const;
256
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700257 size_t
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800258 value_size() const;
259
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800260 /**
261 * @brief Get all subelements
262 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700263 const element_container&
264 elements() const;
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800265
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700266 element_const_iterator
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800267 elements_begin() const;
268
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700269 element_const_iterator
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800270 elements_end() const;
271
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700272 size_t
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800273 elements_size() const;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700274
Yingdi Yu4270f202014-01-28 14:19:16 -0800275 Block
276 blockFromValue() const;
277
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700278public: // EqualityComparable concept
279 bool
280 operator==(const Block& other) const;
281
282 bool
283 operator!=(const Block& other) const;
284
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800285protected:
286 ConstBufferPtr m_buffer;
287
288 uint32_t m_type;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700289
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800290 Buffer::const_iterator m_begin;
291 Buffer::const_iterator m_end;
292 uint32_t m_size;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700293
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800294 Buffer::const_iterator m_value_begin;
295 Buffer::const_iterator m_value_end;
296
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800297 mutable element_container m_subBlocks;
Alexander Afanasyev233750e2014-02-16 00:50:07 -0800298 friend class EncodingImpl<true>;
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800299};
300
301////////////////////////////////////////////////////////////////////////////////
302////////////////////////////////////////////////////////////////////////////////
303////////////////////////////////////////////////////////////////////////////////
304
305inline bool
Alexander Afanasyev196b9aa2014-01-31 17:19:16 -0800306Block::empty() const
307{
308 return m_type == std::numeric_limits<uint32_t>::max();
309}
310
311
312inline bool
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800313Block::hasWire() const
314{
315 return m_buffer && (m_begin != m_end);
316}
317
318inline bool
319Block::hasValue() const
320{
321 return static_cast<bool>(m_buffer);
322}
323
324inline void
325Block::reset()
326{
327 m_buffer.reset(); // reset of the shared_ptr
328 m_subBlocks.clear(); // remove all parsed subelements
329
330 m_type = std::numeric_limits<uint32_t>::max();
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700331 m_begin = m_end = m_value_begin = m_value_end = Buffer::const_iterator();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800332}
333
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800334inline void
335Block::resetWire()
336{
337 m_buffer.reset(); // reset of the shared_ptr
338 // keep subblocks
339
340 // keep type
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700341 m_begin = m_end = m_value_begin = m_value_end = Buffer::const_iterator();
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800342}
343
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800344inline uint32_t
345Block::type() const
346{
347 return m_type;
348}
349
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800350inline Block::element_const_iterator
351Block::find(uint32_t type) const
352{
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700353 for (element_const_iterator i = m_subBlocks.begin();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800354 i != m_subBlocks.end();
355 i++)
356 {
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700357 if (i->type() == type)
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800358 {
359 return i;
360 }
361 }
362 return m_subBlocks.end();
363}
364
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800365inline void
366Block::remove(uint32_t type)
367{
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800368 resetWire();
369
Alexander Afanasyev8ea763d2014-02-06 20:32:52 -0800370 element_container newContainer;
371 newContainer.reserve(m_subBlocks.size());
372 for (element_iterator i = m_subBlocks.begin();
373 i != m_subBlocks.end();
374 ++i)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800375 {
Alexander Afanasyev8ea763d2014-02-06 20:32:52 -0800376 if (i->type() != type)
377 newContainer.push_back(*i);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800378 }
Alexander Afanasyev8ea763d2014-02-06 20:32:52 -0800379 m_subBlocks.swap(newContainer);
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800380}
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800381
382inline Block::element_iterator
383Block::erase(Block::element_iterator position)
384{
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800385 resetWire();
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800386 return m_subBlocks.erase(position);
387}
388
389inline Block::element_iterator
390Block::erase(Block::element_iterator first, Block::element_iterator last)
391{
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800392 resetWire();
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800393 return m_subBlocks.erase(first, last);
394}
395
396
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800397inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700398Block::push_back(const Block& element)
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800399{
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800400 resetWire();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800401 m_subBlocks.push_back(element);
402}
403
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800404inline Buffer::const_iterator
405Block::begin() const
406{
407 if (!hasWire())
408 throw Error("Underlying wire buffer is empty");
409
410 return m_begin;
411}
412
413inline Buffer::const_iterator
414Block::end() const
415{
416 if (!hasWire())
417 throw Error("Underlying wire buffer is empty");
418
419 return m_end;
420}
421
422inline size_t
423Block::size() const
424{
425 if (hasWire() || hasValue()) {
426 return m_size;
427 }
428 else
429 throw Error("Block size cannot be determined (undefined block size)");
430}
431
432inline Buffer::const_iterator
433Block::value_begin() const
434{
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800435 return m_value_begin;
436}
437
438inline Buffer::const_iterator
439Block::value_end() const
440{
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800441 return m_value_end;
442}
443
444inline const uint8_t*
445Block::wire() const
446{
447 if (!hasWire())
448 throw Error("(Block::wire) Underlying wire buffer is empty");
449
450 return &*m_begin;
451}
452
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800453inline const uint8_t*
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800454Block::value() const
455{
456 if (!hasValue())
Alexander Afanasyev380420b2014-02-09 20:52:29 -0800457 return 0;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700458
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800459 return &*m_value_begin;
460}
461
462inline size_t
463Block::value_size() const
464{
465 if (!hasValue())
Alexander Afanasyev8ea763d2014-02-06 20:32:52 -0800466 return 0;
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800467
468 return m_value_end - m_value_begin;
469}
470
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800471inline const Block::element_container&
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700472Block::elements() const
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800473{
474 return m_subBlocks;
475}
476
477inline Block::element_const_iterator
478Block::elements_begin() const
479{
480 return m_subBlocks.begin();
481}
482
483inline Block::element_const_iterator
484Block::elements_end() const
485{
486 return m_subBlocks.end();
487}
488
489inline size_t
490Block::elements_size() const
491{
492 return m_subBlocks.size();
493}
494
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700495inline bool
496Block::operator==(const Block& other) const
497{
498 return (this->size() == other.size()) &&
499 std::equal(this->begin(), this->end(), other.begin());
500}
501
502inline bool
503Block::operator!=(const Block& other) const
504{
505 return !this->operator==(other);
506}
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800507
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800508} // ndn
509
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700510#endif // NDN_ENCODING_BLOCK_HPP