blob: 9c2db13e6d7cb685080d2b7fc8f9a1214d65faba [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 Afanasyev6a05b4b2014-07-18 17:23:00 -070032namespace boost {
33namespace asio {
34class const_buffer;
35} // namespace asio
36} // namespace boost
37
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080038namespace ndn {
39
Alexander Afanasyev233750e2014-02-16 00:50:07 -080040template<bool> class EncodingImpl;
41typedef EncodingImpl<true> EncodingBuffer;
42
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080043/**
44 * @brief Class representing wire element of the NDN packet
45 */
46class Block
47{
48public:
Alexander Afanasyev8ea763d2014-02-06 20:32:52 -080049 typedef std::vector<Block> element_container;
50 typedef element_container::iterator element_iterator;
51 typedef element_container::const_iterator element_const_iterator;
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080052
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070053 /// @brief Error that can be thrown from Block
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060054 class Error : public tlv::Error
Alexander Afanasyev937aa782014-03-21 13:17:57 -070055 {
Alexander Afanasyeva465e972014-03-22 17:21:49 -070056 public:
57 explicit
58 Error(const std::string& what)
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060059 : tlv::Error(what)
Alexander Afanasyeva465e972014-03-22 17:21:49 -070060 {
61 }
Alexander Afanasyev937aa782014-03-21 13:17:57 -070062 };
63
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080064 /**
65 * @brief Default constructor to create an empty Block
66 */
67 Block();
68
69 /**
Alexander Afanasyev15151312014-02-16 00:53:51 -080070 * @brief Create block based on EncodingBuffer object
71 */
72 explicit
73 Block(const EncodingBuffer& buffer);
Alexander Afanasyev937aa782014-03-21 13:17:57 -070074
Alexander Afanasyev15151312014-02-16 00:53:51 -080075 /**
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070076 * @brief A helper version of a constructor to create Block from the raw buffer (type
77 * and value-length parsing)
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080078 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -070079 explicit
Alexander Afanasyev937aa782014-03-21 13:17:57 -070080 Block(const ConstBufferPtr& buffer);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080081
82 /**
Alexander Afanasyev187bc482014-02-06 15:04:04 -080083 * @brief Another helper to create block from a buffer, directly specifying boundaries
84 * of the block within the buffer
85 *
86 * This version will automatically detect type and position of the value within the block
87 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -070088 Block(const ConstBufferPtr& buffer,
89 const Buffer::const_iterator& begin, const Buffer::const_iterator& end,
Alexander Afanasyev5964fb72014-02-18 12:42:45 -080090 bool verifyLength = true);
Alexander Afanasyev937aa782014-03-21 13:17:57 -070091
Alexander Afanasyev187bc482014-02-06 15:04:04 -080092 /**
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070093 * @brief A helper version of a constructor to create Block from the raw buffer (type
94 * and value-length parsing)
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080095 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -070096 Block(const uint8_t* buffer, size_t maxlength);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080097
Alexander Afanasyev937aa782014-03-21 13:17:57 -070098 Block(const void* buffer, size_t maxlength);
Yingdi Yu27158392014-01-20 13:04:20 -080099
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800100 /**
101 * @brief Create Block from the wire buffer (no parsing)
102 *
103 * This version of the constructor does not do any parsing
104 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700105 Block(const ConstBufferPtr& wire,
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800106 uint32_t type,
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700107 const Buffer::const_iterator& begin, const Buffer::const_iterator& end,
108 const Buffer::const_iterator& valueBegin, const Buffer::const_iterator& valueEnd);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800109
110 /**
111 * @brief Create Block of a specific type with empty wire buffer
112 */
Alexander Afanasyevf42ce132014-01-07 13:32:30 -0800113 explicit
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800114 Block(uint32_t type);
115
116 /**
117 * @brief Create Block of a specific type with the specified value
118 *
119 * The underlying buffer hold only value, additional operations are needed
120 * to construct wire encoding, one need to prepend the wire buffer with type
121 * and value-length VAR-NUMBERs
122 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700123 Block(uint32_t type, const ConstBufferPtr& value);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800124
125 /**
126 * @brief Create nested Block of a specific type with the specified value
127 *
128 * The underlying buffer hold only value, additional operations are needed
129 * to construct wire encoding, one need to prepend the wire buffer with type
130 * and value-length VAR-NUMBERs
131 */
Alexander Afanasyevf42ce132014-01-07 13:32:30 -0800132 explicit
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700133 Block(uint32_t type, const Block& value);
134
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700135 /*
136 * @brief A helper version of a constructor to create Block from the stream
137 *
138 * @deprecated Use Block::fromStream instead
139 */
140 explicit
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700141 DEPRECATED(Block(std::istream& is))
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700142 {
143 *this = Block::fromStream(is);
144 }
145
146 /*
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700147 * @brief Constructor Block from the stream
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700148 */
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700149 static Block
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700150 fromStream(std::istream& is);
151
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700152 /**
153 * @brief Try to construct block from Buffer, referencing data block pointed by wire
154 *
155 * @throws This method never throws an exception
156 *
157 * @returns true if Block successfully created, false if block cannot be created
158 */
159 static bool
160 fromBuffer(const ConstBufferPtr& wire, size_t offset, Block& block);
161
162 /**
163 * @brief Try to construct block from Buffer, referencing data block pointed by wire
164 *
165 * @throws This method never throws an exception
166 *
167 * @returns true if Block successfully created, false if block cannot be created
168 */
169 static bool
170 fromBuffer(const uint8_t* buffer, size_t maxSize, Block& block);
Alexander Afanasyev196b9aa2014-01-31 17:19:16 -0800171
172 /**
173 * @brief Check if the Block is empty
174 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700175 bool
Alexander Afanasyev196b9aa2014-01-31 17:19:16 -0800176 empty() const;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700177
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800178 /**
179 * @brief Check if the Block has fully encoded wire
180 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700181 bool
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800182 hasWire() const;
183
184 /**
185 * @brief Check if the Block has value block (no type and length are encoded)
186 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700187 bool
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800188 hasValue() const;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700189
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800190 /**
191 * @brief Reset wire buffer of the element
192 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700193 void
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800194 reset();
195
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800196 /**
197 * @brief Reset wire buffer but keep sub elements (if any)
198 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700199 void
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800200 resetWire();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800201
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800202 /**
203 * @brief Parse wire buffer into subblocks
204 *
205 * This method is not really const, but it does not modify any data. It simply
206 * parses contents of the buffer into subblocks
207 */
208 void
209 parse() const;
210
211 /**
212 * @brief Encode subblocks into wire buffer
213 */
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800214 void
215 encode();
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700216
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700217 uint32_t
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800218 type() const;
219
220 /**
221 * @brief Get the first subelement of the requested type
222 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700223 const Block&
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800224 get(uint32_t type) const;
225
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700226 element_const_iterator
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800227 find(uint32_t type) const;
228
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700229 void
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800230 remove(uint32_t type);
231
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700232 element_iterator
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800233 erase(element_iterator position);
234
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700235 element_iterator
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800236 erase(element_iterator first, element_iterator last);
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700237
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700238 void
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700239 push_back(const Block& element);
240
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700241 Buffer::const_iterator
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800242 begin() const;
243
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700244 Buffer::const_iterator
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800245 end() const;
246
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700247 const uint8_t*
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800248 wire() const;
249
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700250 size_t
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800251 size() const;
252
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700253 Buffer::const_iterator
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800254 value_begin() const;
255
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700256 Buffer::const_iterator
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800257 value_end() const;
258
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700259 const uint8_t*
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800260 value() const;
261
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700262 size_t
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800263 value_size() const;
264
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800265 /**
266 * @brief Get all subelements
267 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700268 const element_container&
269 elements() const;
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800270
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700271 element_const_iterator
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800272 elements_begin() const;
273
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700274 element_const_iterator
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800275 elements_end() const;
276
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700277 size_t
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800278 elements_size() const;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700279
Yingdi Yu4270f202014-01-28 14:19:16 -0800280 Block
281 blockFromValue() const;
282
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700283public: // EqualityComparable concept
284 bool
285 operator==(const Block& other) const;
286
287 bool
288 operator!=(const Block& other) const;
289
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700290public: // ConvertibleToConstBuffer
291 operator boost::asio::const_buffer() const;
292
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800293protected:
294 ConstBufferPtr m_buffer;
295
296 uint32_t m_type;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700297
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800298 Buffer::const_iterator m_begin;
299 Buffer::const_iterator m_end;
300 uint32_t m_size;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700301
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800302 Buffer::const_iterator m_value_begin;
303 Buffer::const_iterator m_value_end;
304
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800305 mutable element_container m_subBlocks;
Alexander Afanasyev233750e2014-02-16 00:50:07 -0800306 friend class EncodingImpl<true>;
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800307};
308
309////////////////////////////////////////////////////////////////////////////////
310////////////////////////////////////////////////////////////////////////////////
311////////////////////////////////////////////////////////////////////////////////
312
313inline bool
Alexander Afanasyev196b9aa2014-01-31 17:19:16 -0800314Block::empty() const
315{
316 return m_type == std::numeric_limits<uint32_t>::max();
317}
318
319
320inline bool
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800321Block::hasWire() const
322{
323 return m_buffer && (m_begin != m_end);
324}
325
326inline bool
327Block::hasValue() const
328{
329 return static_cast<bool>(m_buffer);
330}
331
332inline void
333Block::reset()
334{
335 m_buffer.reset(); // reset of the shared_ptr
336 m_subBlocks.clear(); // remove all parsed subelements
337
338 m_type = std::numeric_limits<uint32_t>::max();
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700339 m_begin = m_end = m_value_begin = m_value_end = Buffer::const_iterator();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800340}
341
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800342inline void
343Block::resetWire()
344{
345 m_buffer.reset(); // reset of the shared_ptr
346 // keep subblocks
347
348 // keep type
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700349 m_begin = m_end = m_value_begin = m_value_end = Buffer::const_iterator();
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800350}
351
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800352inline uint32_t
353Block::type() const
354{
355 return m_type;
356}
357
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800358inline Block::element_const_iterator
359Block::find(uint32_t type) const
360{
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700361 for (element_const_iterator i = m_subBlocks.begin();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800362 i != m_subBlocks.end();
363 i++)
364 {
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700365 if (i->type() == type)
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800366 {
367 return i;
368 }
369 }
370 return m_subBlocks.end();
371}
372
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800373inline void
374Block::remove(uint32_t type)
375{
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800376 resetWire();
377
Alexander Afanasyev8ea763d2014-02-06 20:32:52 -0800378 element_container newContainer;
379 newContainer.reserve(m_subBlocks.size());
380 for (element_iterator i = m_subBlocks.begin();
381 i != m_subBlocks.end();
382 ++i)
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800383 {
Alexander Afanasyev8ea763d2014-02-06 20:32:52 -0800384 if (i->type() != type)
385 newContainer.push_back(*i);
Alexander Afanasyev95e8c2f2014-02-06 17:29:30 -0800386 }
Alexander Afanasyev8ea763d2014-02-06 20:32:52 -0800387 m_subBlocks.swap(newContainer);
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800388}
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800389
390inline Block::element_iterator
391Block::erase(Block::element_iterator position)
392{
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800393 resetWire();
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800394 return m_subBlocks.erase(position);
395}
396
397inline Block::element_iterator
398Block::erase(Block::element_iterator first, Block::element_iterator last)
399{
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800400 resetWire();
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800401 return m_subBlocks.erase(first, last);
402}
403
404
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800405inline void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700406Block::push_back(const Block& element)
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800407{
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800408 resetWire();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800409 m_subBlocks.push_back(element);
410}
411
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800412inline Buffer::const_iterator
413Block::begin() const
414{
415 if (!hasWire())
416 throw Error("Underlying wire buffer is empty");
417
418 return m_begin;
419}
420
421inline Buffer::const_iterator
422Block::end() const
423{
424 if (!hasWire())
425 throw Error("Underlying wire buffer is empty");
426
427 return m_end;
428}
429
430inline size_t
431Block::size() const
432{
433 if (hasWire() || hasValue()) {
434 return m_size;
435 }
436 else
437 throw Error("Block size cannot be determined (undefined block size)");
438}
439
440inline Buffer::const_iterator
441Block::value_begin() const
442{
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800443 return m_value_begin;
444}
445
446inline Buffer::const_iterator
447Block::value_end() const
448{
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800449 return m_value_end;
450}
451
452inline const uint8_t*
453Block::wire() const
454{
455 if (!hasWire())
456 throw Error("(Block::wire) Underlying wire buffer is empty");
457
458 return &*m_begin;
459}
460
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800461inline const uint8_t*
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800462Block::value() const
463{
464 if (!hasValue())
Alexander Afanasyev380420b2014-02-09 20:52:29 -0800465 return 0;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700466
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800467 return &*m_value_begin;
468}
469
470inline size_t
471Block::value_size() const
472{
473 if (!hasValue())
Alexander Afanasyev8ea763d2014-02-06 20:32:52 -0800474 return 0;
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800475
476 return m_value_end - m_value_begin;
477}
478
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800479inline const Block::element_container&
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700480Block::elements() const
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800481{
482 return m_subBlocks;
483}
484
485inline Block::element_const_iterator
486Block::elements_begin() const
487{
488 return m_subBlocks.begin();
489}
490
491inline Block::element_const_iterator
492Block::elements_end() const
493{
494 return m_subBlocks.end();
495}
496
497inline size_t
498Block::elements_size() const
499{
500 return m_subBlocks.size();
501}
502
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700503inline bool
504Block::operator==(const Block& other) const
505{
506 return (this->size() == other.size()) &&
507 std::equal(this->begin(), this->end(), other.begin());
508}
509
510inline bool
511Block::operator!=(const Block& other) const
512{
513 return !this->operator==(other);
514}
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800515
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800516} // ndn
517
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700518#endif // NDN_ENCODING_BLOCK_HPP