blob: c91d12cfcb101bd06e0598806c94c6ef8cf3c155 [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 Afanasyev13bb51a2014-01-02 19:13:26 -080072 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -070073 explicit
Alexander Afanasyev937aa782014-03-21 13:17:57 -070074 Block(const ConstBufferPtr& buffer);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080075
76 /**
Alexander Afanasyev187bc482014-02-06 15:04:04 -080077 * @brief Another helper to create block from a buffer, directly specifying boundaries
78 * of the block within the buffer
79 *
80 * This version will automatically detect type and position of the value within the block
81 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -070082 Block(const ConstBufferPtr& buffer,
83 const Buffer::const_iterator& begin, const Buffer::const_iterator& end,
Alexander Afanasyev5964fb72014-02-18 12:42:45 -080084 bool verifyLength = true);
Alexander Afanasyev937aa782014-03-21 13:17:57 -070085
Alexander Afanasyev187bc482014-02-06 15:04:04 -080086 /**
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070087 * @brief A helper version of a constructor to create Block from the raw buffer (type
88 * and value-length parsing)
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080089 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -070090 Block(const uint8_t* buffer, size_t maxlength);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080091
Alexander Afanasyev937aa782014-03-21 13:17:57 -070092 Block(const void* buffer, size_t maxlength);
Yingdi Yu27158392014-01-20 13:04:20 -080093
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080094 /**
95 * @brief Create Block from the wire buffer (no parsing)
96 *
97 * This version of the constructor does not do any parsing
98 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -070099 Block(const ConstBufferPtr& wire,
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800100 uint32_t type,
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700101 const Buffer::const_iterator& begin, const Buffer::const_iterator& end,
102 const Buffer::const_iterator& valueBegin, const Buffer::const_iterator& valueEnd);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800103
104 /**
105 * @brief Create Block of a specific type with empty wire buffer
106 */
Alexander Afanasyevf42ce132014-01-07 13:32:30 -0800107 explicit
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800108 Block(uint32_t type);
109
110 /**
111 * @brief Create Block of a specific type with the specified value
112 *
113 * The underlying buffer hold only value, additional operations are needed
114 * to construct wire encoding, one need to prepend the wire buffer with type
115 * and value-length VAR-NUMBERs
116 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700117 Block(uint32_t type, const ConstBufferPtr& value);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800118
119 /**
120 * @brief Create nested Block of a specific type with the specified value
121 *
122 * The underlying buffer hold only value, additional operations are needed
123 * to construct wire encoding, one need to prepend the wire buffer with type
124 * and value-length VAR-NUMBERs
125 */
Alexander Afanasyevf42ce132014-01-07 13:32:30 -0800126 explicit
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700127 Block(uint32_t type, const Block& value);
128
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700129 /*
130 * @brief A helper version of a constructor to create Block from the stream
131 *
132 * @deprecated Use Block::fromStream instead
133 */
134 explicit
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700135 DEPRECATED(Block(std::istream& is))
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700136 {
137 *this = Block::fromStream(is);
138 }
139
140 /*
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700141 * @brief Constructor Block from the stream
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700142 */
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700143 static Block
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700144 fromStream(std::istream& is);
145
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700146 /**
147 * @brief Try to construct block from Buffer, referencing data block pointed by wire
148 *
149 * @throws This method never throws an exception
150 *
151 * @returns true if Block successfully created, false if block cannot be created
152 */
153 static bool
154 fromBuffer(const ConstBufferPtr& wire, size_t offset, Block& block);
155
156 /**
157 * @brief Try to construct block from Buffer, referencing data block pointed by wire
158 *
159 * @throws This method never throws an exception
160 *
161 * @returns true if Block successfully created, false if block cannot be created
162 */
163 static bool
164 fromBuffer(const uint8_t* buffer, size_t maxSize, Block& block);
Alexander Afanasyev196b9aa2014-01-31 17:19:16 -0800165
166 /**
167 * @brief Check if the Block is empty
168 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700169 bool
Alexander Afanasyev196b9aa2014-01-31 17:19:16 -0800170 empty() const;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700171
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800172 /**
173 * @brief Check if the Block has fully encoded wire
174 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700175 bool
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800176 hasWire() const;
177
178 /**
179 * @brief Check if the Block has value block (no type and length are encoded)
180 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700181 bool
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800182 hasValue() const;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700183
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800184 /**
185 * @brief Reset wire buffer of the element
186 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700187 void
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800188 reset();
189
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800190 /**
191 * @brief Reset wire buffer but keep sub elements (if any)
192 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700193 void
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800194 resetWire();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800195
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800196 /**
197 * @brief Parse wire buffer into subblocks
198 *
199 * This method is not really const, but it does not modify any data. It simply
200 * parses contents of the buffer into subblocks
201 */
202 void
203 parse() const;
204
205 /**
206 * @brief Encode subblocks into wire buffer
207 */
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800208 void
209 encode();
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700210
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700211 uint32_t
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800212 type() const;
213
214 /**
215 * @brief Get the first subelement of the requested type
216 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700217 const Block&
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800218 get(uint32_t type) const;
219
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700220 element_const_iterator
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800221 find(uint32_t type) const;
222
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700223 void
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800224 remove(uint32_t type);
225
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700226 element_iterator
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800227 erase(element_iterator position);
228
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700229 element_iterator
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800230 erase(element_iterator first, element_iterator last);
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700231
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700232 void
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700233 push_back(const Block& element);
234
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700235 Buffer::const_iterator
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800236 begin() const;
237
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700238 Buffer::const_iterator
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800239 end() const;
240
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700241 const uint8_t*
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800242 wire() const;
243
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700244 size_t
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800245 size() const;
246
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700247 Buffer::const_iterator
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800248 value_begin() const;
249
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700250 Buffer::const_iterator
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800251 value_end() const;
252
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700253 const uint8_t*
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800254 value() const;
255
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700256 size_t
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800257 value_size() const;
258
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800259 /**
260 * @brief Get all subelements
261 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700262 const element_container&
263 elements() const;
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800264
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700265 element_const_iterator
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800266 elements_begin() const;
267
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700268 element_const_iterator
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800269 elements_end() const;
270
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700271 size_t
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800272 elements_size() const;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700273
Yingdi Yu4270f202014-01-28 14:19:16 -0800274 Block
275 blockFromValue() const;
276
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700277public: // EqualityComparable concept
278 bool
279 operator==(const Block& other) const;
280
281 bool
282 operator!=(const Block& other) const;
283
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800284protected:
285 ConstBufferPtr m_buffer;
286
287 uint32_t m_type;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700288
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800289 Buffer::const_iterator m_begin;
290 Buffer::const_iterator m_end;
291 uint32_t m_size;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700292
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800293 Buffer::const_iterator m_value_begin;
294 Buffer::const_iterator m_value_end;
295
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800296 mutable element_container m_subBlocks;
Alexander Afanasyev233750e2014-02-16 00:50:07 -0800297 friend class EncodingImpl<true>;
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800298};
299
300////////////////////////////////////////////////////////////////////////////////
301////////////////////////////////////////////////////////////////////////////////
302////////////////////////////////////////////////////////////////////////////////
303
304inline bool
Alexander Afanasyev196b9aa2014-01-31 17:19:16 -0800305Block::empty() const
306{
307 return m_type == std::numeric_limits<uint32_t>::max();
308}
309
310
311inline bool
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800312Block::hasWire() const
313{
314 return m_buffer && (m_begin != m_end);
315}
316
317inline bool
318Block::hasValue() const
319{
320 return static_cast<bool>(m_buffer);
321}
322
323inline void
324Block::reset()
325{
326 m_buffer.reset(); // reset of the shared_ptr
327 m_subBlocks.clear(); // remove all parsed subelements
328
329 m_type = std::numeric_limits<uint32_t>::max();
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700330 m_begin = m_end = m_value_begin = m_value_end = Buffer::const_iterator();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800331}
332
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800333inline void
334Block::resetWire()
335{
336 m_buffer.reset(); // reset of the shared_ptr
337 // keep subblocks
338
339 // keep type
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700340 m_begin = m_end = m_value_begin = m_value_end = Buffer::const_iterator();
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800341}
342
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800343inline uint32_t
344Block::type() const
345{
346 return m_type;
347}
348
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800349inline Block::element_const_iterator
350Block::find(uint32_t type) const
351{
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700352 for (element_const_iterator i = m_subBlocks.begin();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800353 i != m_subBlocks.end();
354 i++)
355 {
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700356 if (i->type() == type)
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800357 {
358 return i;
359 }
360 }
361 return m_subBlocks.end();
362}
363
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800364inline void
365Block::remove(uint32_t type)
366{
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800367 resetWire();
368
Alexander Afanasyev8ea763d2014-02-06 20:32:52 -0800369 element_container newContainer;
370 newContainer.reserve(m_subBlocks.size());
371 for (element_iterator i = m_subBlocks.begin();
372 i != m_subBlocks.end();
373 ++i)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800374 {
Alexander Afanasyev8ea763d2014-02-06 20:32:52 -0800375 if (i->type() != type)
376 newContainer.push_back(*i);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800377 }
Alexander Afanasyev8ea763d2014-02-06 20:32:52 -0800378 m_subBlocks.swap(newContainer);
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800379}
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800380
381inline Block::element_iterator
382Block::erase(Block::element_iterator position)
383{
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800384 resetWire();
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800385 return m_subBlocks.erase(position);
386}
387
388inline Block::element_iterator
389Block::erase(Block::element_iterator first, Block::element_iterator last)
390{
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800391 resetWire();
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800392 return m_subBlocks.erase(first, last);
393}
394
395
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800396inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700397Block::push_back(const Block& element)
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800398{
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800399 resetWire();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800400 m_subBlocks.push_back(element);
401}
402
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800403inline Buffer::const_iterator
404Block::begin() const
405{
406 if (!hasWire())
407 throw Error("Underlying wire buffer is empty");
408
409 return m_begin;
410}
411
412inline Buffer::const_iterator
413Block::end() const
414{
415 if (!hasWire())
416 throw Error("Underlying wire buffer is empty");
417
418 return m_end;
419}
420
421inline size_t
422Block::size() const
423{
424 if (hasWire() || hasValue()) {
425 return m_size;
426 }
427 else
428 throw Error("Block size cannot be determined (undefined block size)");
429}
430
431inline Buffer::const_iterator
432Block::value_begin() const
433{
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800434 return m_value_begin;
435}
436
437inline Buffer::const_iterator
438Block::value_end() const
439{
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800440 return m_value_end;
441}
442
443inline const uint8_t*
444Block::wire() const
445{
446 if (!hasWire())
447 throw Error("(Block::wire) Underlying wire buffer is empty");
448
449 return &*m_begin;
450}
451
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800452inline const uint8_t*
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800453Block::value() const
454{
455 if (!hasValue())
Alexander Afanasyev380420b2014-02-09 20:52:29 -0800456 return 0;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700457
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800458 return &*m_value_begin;
459}
460
461inline size_t
462Block::value_size() const
463{
464 if (!hasValue())
Alexander Afanasyev8ea763d2014-02-06 20:32:52 -0800465 return 0;
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800466
467 return m_value_end - m_value_begin;
468}
469
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800470inline const Block::element_container&
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700471Block::elements() const
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800472{
473 return m_subBlocks;
474}
475
476inline Block::element_const_iterator
477Block::elements_begin() const
478{
479 return m_subBlocks.begin();
480}
481
482inline Block::element_const_iterator
483Block::elements_end() const
484{
485 return m_subBlocks.end();
486}
487
488inline size_t
489Block::elements_size() const
490{
491 return m_subBlocks.size();
492}
493
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700494inline bool
495Block::operator==(const Block& other) const
496{
497 return (this->size() == other.size()) &&
498 std::equal(this->begin(), this->end(), other.begin());
499}
500
501inline bool
502Block::operator!=(const Block& other) const
503{
504 return !this->operator==(other);
505}
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800506
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800507} // ndn
508
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700509#endif // NDN_ENCODING_BLOCK_HPP