blob: 6ba60ee2f1a2f00d9c582d19780ce96592e936d9 [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 Afanasyevaf99f462015-01-19 21:43:09 -08003 * Copyright (c) 2013-2015 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"
Alexander Afanasyev74633892015-02-08 18:08:46 -080031#include "encoding-buffer-fwd.hpp"
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080032
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -070033namespace boost {
34namespace asio {
35class const_buffer;
36} // namespace asio
37} // namespace boost
38
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080039namespace ndn {
40
Junxiao Shi81a6c5d2014-11-30 00:14:42 -070041/** @brief Class representing a wire element of NDN-TLV packet format
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080042 */
43class Block
44{
45public:
Alexander Afanasyev8ea763d2014-02-06 20:32:52 -080046 typedef std::vector<Block> element_container;
47 typedef element_container::iterator element_iterator;
48 typedef element_container::const_iterator element_const_iterator;
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080049
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060050 class Error : public tlv::Error
Alexander Afanasyev937aa782014-03-21 13:17:57 -070051 {
Alexander Afanasyeva465e972014-03-22 17:21:49 -070052 public:
53 explicit
54 Error(const std::string& what)
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060055 : tlv::Error(what)
Alexander Afanasyeva465e972014-03-22 17:21:49 -070056 {
57 }
Alexander Afanasyev937aa782014-03-21 13:17:57 -070058 };
59
Junxiao Shi81a6c5d2014-11-30 00:14:42 -070060public: // constructor, creation, assignment
61 /** @brief Create an empty Block
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080062 */
63 Block();
64
Junxiao Shi81a6c5d2014-11-30 00:14:42 -070065 /** @brief Create a Block based on EncodingBuffer object
Alexander Afanasyev15151312014-02-16 00:53:51 -080066 */
67 explicit
68 Block(const EncodingBuffer& buffer);
Alexander Afanasyev937aa782014-03-21 13:17:57 -070069
Junxiao Shi81a6c5d2014-11-30 00:14:42 -070070 /** @brief Create a Block from the raw buffer with Type-Length parsing
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080071 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -070072 explicit
Alexander Afanasyev937aa782014-03-21 13:17:57 -070073 Block(const ConstBufferPtr& buffer);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080074
Junxiao Shi81a6c5d2014-11-30 00:14:42 -070075 /** @brief Create a Block from a buffer, directly specifying boundaries
76 * of the block within the buffer
Alexander Afanasyev187bc482014-02-06 15:04:04 -080077 *
Junxiao Shi81a6c5d2014-11-30 00:14:42 -070078 * This overload will automatically detect type and position of the value within the block
Alexander Afanasyev187bc482014-02-06 15:04:04 -080079 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -070080 Block(const ConstBufferPtr& buffer,
81 const Buffer::const_iterator& begin, const Buffer::const_iterator& end,
Alexander Afanasyev5964fb72014-02-18 12:42:45 -080082 bool verifyLength = true);
Alexander Afanasyev937aa782014-03-21 13:17:57 -070083
Junxiao Shi81a6c5d2014-11-30 00:14:42 -070084 /** @brief Create a Block from the raw buffer with Type-Length parsing
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080085 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -070086 Block(const uint8_t* buffer, size_t maxlength);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080087
Junxiao Shi81a6c5d2014-11-30 00:14:42 -070088 /** @brief Create a Block from the raw buffer with Type-Length parsing
89 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -070090 Block(const void* buffer, size_t maxlength);
Yingdi Yu27158392014-01-20 13:04:20 -080091
Junxiao Shi81a6c5d2014-11-30 00:14:42 -070092 /** @brief Create a Block from the wire buffer (no parsing)
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080093 *
Junxiao Shi81a6c5d2014-11-30 00:14:42 -070094 * This overload does not do any parsing
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080095 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -070096 Block(const ConstBufferPtr& wire,
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080097 uint32_t type,
Alexander Afanasyev937aa782014-03-21 13:17:57 -070098 const Buffer::const_iterator& begin, const Buffer::const_iterator& end,
99 const Buffer::const_iterator& valueBegin, const Buffer::const_iterator& valueEnd);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800100
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700101 /** @brief Create Block of a specific type with empty wire buffer
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800102 */
Alexander Afanasyevf42ce132014-01-07 13:32:30 -0800103 explicit
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800104 Block(uint32_t type);
105
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700106 /** @brief Create a Block of a specific type with the specified value
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800107 *
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700108 * The underlying buffer holds only value Additional operations are needed
109 * to construct wire encoding, one need to prepend the wire buffer with type
110 * and value-length VAR-NUMBERs
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800111 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700112 Block(uint32_t type, const ConstBufferPtr& value);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800113
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700114 /** @brief Create a nested Block of a specific type with the specified value
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800115 *
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700116 * The underlying buffer holds only value. Additional operations are needed
117 * to construct wire encoding, one need to prepend the wire buffer with type
118 * and value-length VAR-NUMBERs
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800119 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700120 Block(uint32_t type, const Block& value);
121
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700122 /** @brief Create a Block from an input stream
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700123 */
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700124 static Block
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700125 fromStream(std::istream& is);
126
Junxiao Shi02a4bf32015-02-21 21:07:46 -0700127 /** @brief Try to construct block from Buffer
128 * @param buffer the buffer to construct block from
129 * @note buffer is passed by value because the constructed block
130 * takes shared ownership of the buffer
131 * @param offset offset from beginning of \p buffer to construct Block from
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700132 *
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700133 * This method does not throw upon decoding error.
Junxiao Shi02a4bf32015-02-21 21:07:46 -0700134 * This method does not copy the bytes.
135 *
136 * @return true and the Block, if Block is successfully created; otherwise false
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700137 */
Junxiao Shi02a4bf32015-02-21 21:07:46 -0700138 static std::tuple<bool, Block>
139 fromBuffer(ConstBufferPtr buffer, size_t offset);
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700140
Junxiao Shi02a4bf32015-02-21 21:07:46 -0700141 /** @deprecated use fromBuffer(ConstBufferPtr, size_t)
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700142 */
Junxiao Shi1a750b42015-02-28 22:20:45 -0700143 DEPRECATED(
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700144 static bool
Junxiao Shi1a750b42015-02-28 22:20:45 -0700145 fromBuffer(const ConstBufferPtr& buffer, size_t offset, Block& block))
Junxiao Shi02a4bf32015-02-21 21:07:46 -0700146 {
147 bool isOk = false;
148 std::tie(isOk, block) = Block::fromBuffer(buffer, offset);
149 return isOk;
150 }
151
152 /** @brief Try to construct block from raw buffer
153 * @param buffer the raw buffer to copy bytes from
154 * @param maxSize the maximum size of constructed block;
155 * @p buffer must have a size of at least @p maxSize
156 *
157 * This method does not throw upon decoding error.
158 * This method copies the bytes into a new Buffer.
159 *
160 * @return true and the Block, if Block is successfully created; otherwise false
161 */
162 static std::tuple<bool, Block>
163 fromBuffer(const uint8_t* buffer, size_t maxSize);
164
165 /** @deprecated use fromBuffer(const uint8_t*, size_t)
166 */
Junxiao Shi1a750b42015-02-28 22:20:45 -0700167 DEPRECATED(
Junxiao Shi02a4bf32015-02-21 21:07:46 -0700168 static bool
Junxiao Shi1a750b42015-02-28 22:20:45 -0700169 fromBuffer(const uint8_t* buffer, size_t maxSize, Block& block))
Junxiao Shi02a4bf32015-02-21 21:07:46 -0700170 {
171 bool isOk = false;
172 std::tie(isOk, block) = Block::fromBuffer(buffer, maxSize);
173 return isOk;
174 }
Alexander Afanasyev196b9aa2014-01-31 17:19:16 -0800175
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700176public: // wire format
177 /** @brief Check if the Block is empty
Alexander Afanasyev196b9aa2014-01-31 17:19:16 -0800178 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700179 bool
Alexander Afanasyev196b9aa2014-01-31 17:19:16 -0800180 empty() const;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700181
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700182 /** @brief Check if the Block has fully encoded wire
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800183 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700184 bool
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800185 hasWire() const;
186
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700187 /** @brief Reset wire buffer of the element
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800188 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700189 void
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800190 reset();
191
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700192 /** @brief Reset wire buffer but keep sub elements (if any)
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800193 */
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
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700197 Buffer::const_iterator
198 begin() const;
199
200 Buffer::const_iterator
201 end() const;
202
203 const uint8_t*
204 wire() const;
205
206 size_t
207 size() const;
208
209public: // type and value
210 uint32_t
211 type() const;
212
213 /** @brief Check if the Block has value block (no type and length are encoded)
214 */
215 bool
216 hasValue() const;
217
218 Buffer::const_iterator
219 value_begin() const;
220
221 Buffer::const_iterator
222 value_end() const;
223
224 const uint8_t*
225 value() const;
226
227 size_t
228 value_size() const;
229
230public: // sub elements
231 /** @brief Parse wire buffer into subblocks
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800232 *
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700233 * This method is not really const, but it does not modify any data. It simply
234 * parses contents of the buffer into subblocks
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800235 */
236 void
237 parse() const;
238
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700239 /** @brief Encode subblocks into wire buffer
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800240 */
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800241 void
242 encode();
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700243
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700244 /** @brief Get the first subelement of the requested type
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800245 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700246 const Block&
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800247 get(uint32_t type) const;
248
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700249 element_const_iterator
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800250 find(uint32_t type) const;
251
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700252 void
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800253 remove(uint32_t type);
254
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700255 element_iterator
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800256 erase(element_iterator position);
257
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700258 element_iterator
Alexander Afanasyevf5c35ae2014-01-17 16:06:31 -0800259 erase(element_iterator first, element_iterator last);
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700260
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700261 void
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700262 push_back(const Block& element);
263
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700264 /** @brief Get all subelements
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800265 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700266 const element_container&
267 elements() const;
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800268
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700269 element_const_iterator
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800270 elements_begin() const;
271
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700272 element_const_iterator
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800273 elements_end() const;
274
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700275 size_t
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800276 elements_size() const;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700277
Yingdi Yu4270f202014-01-28 14:19:16 -0800278 Block
279 blockFromValue() const;
280
Alexander Afanasyev74633892015-02-08 18:08:46 -0800281 /**
282 * @brief Get underlying buffer
283 */
284 shared_ptr<const Buffer>
285 getBuffer() const;
286
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700287public: // EqualityComparable concept
288 bool
289 operator==(const Block& other) const;
290
291 bool
292 operator!=(const Block& other) const;
293
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700294public: // ConvertibleToConstBuffer
295 operator boost::asio::const_buffer() const;
296
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800297protected:
Alexander Afanasyev74633892015-02-08 18:08:46 -0800298 shared_ptr<const Buffer> m_buffer;
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800299
300 uint32_t m_type;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700301
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800302 Buffer::const_iterator m_begin;
303 Buffer::const_iterator m_end;
304 uint32_t m_size;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700305
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800306 Buffer::const_iterator m_value_begin;
307 Buffer::const_iterator m_value_end;
308
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800309 mutable element_container m_subBlocks;
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800310};
311
312////////////////////////////////////////////////////////////////////////////////
313////////////////////////////////////////////////////////////////////////////////
314////////////////////////////////////////////////////////////////////////////////
315
Alexander Afanasyev74633892015-02-08 18:08:46 -0800316inline shared_ptr<const Buffer>
317Block::getBuffer() const
318{
319 return m_buffer;
320}
321
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800322inline bool
Alexander Afanasyev196b9aa2014-01-31 17:19:16 -0800323Block::empty() const
324{
325 return m_type == std::numeric_limits<uint32_t>::max();
326}
327
Alexander Afanasyev196b9aa2014-01-31 17:19:16 -0800328inline bool
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800329Block::hasWire() const
330{
331 return m_buffer && (m_begin != m_end);
332}
333
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800334inline Buffer::const_iterator
335Block::begin() const
336{
337 if (!hasWire())
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700338 throw Error("Underlying wire buffer is empty");
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800339
340 return m_begin;
341}
342
343inline Buffer::const_iterator
344Block::end() const
345{
346 if (!hasWire())
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700347 throw Error("Underlying wire buffer is empty");
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800348
349 return m_end;
350}
351
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700352inline const uint8_t*
353Block::wire() const
354{
355 if (!hasWire())
356 throw Error("(Block::wire) Underlying wire buffer is empty");
357
358 return &*m_begin;
359}
360
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800361inline size_t
362Block::size() const
363{
364 if (hasWire() || hasValue()) {
365 return m_size;
366 }
367 else
368 throw Error("Block size cannot be determined (undefined block size)");
369}
370
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700371inline uint32_t
372Block::type() const
373{
374 return m_type;
375}
376
377inline bool
378Block::hasValue() const
379{
380 return static_cast<bool>(m_buffer);
381}
382
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800383inline Buffer::const_iterator
384Block::value_begin() const
385{
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800386 return m_value_begin;
387}
388
389inline Buffer::const_iterator
390Block::value_end() const
391{
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800392 return m_value_end;
393}
394
395inline const uint8_t*
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800396Block::value() const
397{
398 if (!hasValue())
Alexander Afanasyev380420b2014-02-09 20:52:29 -0800399 return 0;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700400
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800401 return &*m_value_begin;
402}
403
404inline size_t
405Block::value_size() const
406{
407 if (!hasValue())
Alexander Afanasyev8ea763d2014-02-06 20:32:52 -0800408 return 0;
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800409
410 return m_value_end - m_value_begin;
411}
412
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700413inline Block::element_iterator
414Block::erase(Block::element_iterator position)
415{
416 resetWire();
417 return m_subBlocks.erase(position);
418}
419
420inline Block::element_iterator
421Block::erase(Block::element_iterator first, Block::element_iterator last)
422{
423 resetWire();
424 return m_subBlocks.erase(first, last);
425}
426
427inline void
428Block::push_back(const Block& element)
429{
430 resetWire();
431 m_subBlocks.push_back(element);
432}
433
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800434inline const Block::element_container&
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700435Block::elements() const
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800436{
437 return m_subBlocks;
438}
439
440inline Block::element_const_iterator
441Block::elements_begin() const
442{
443 return m_subBlocks.begin();
444}
445
446inline Block::element_const_iterator
447Block::elements_end() const
448{
449 return m_subBlocks.end();
450}
451
452inline size_t
453Block::elements_size() const
454{
455 return m_subBlocks.size();
456}
457
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700458inline bool
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700459Block::operator!=(const Block& other) const
460{
461 return !this->operator==(other);
462}
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800463
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700464} // namespace ndn
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800465
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700466#endif // NDN_ENCODING_BLOCK_HPP