blob: 91ab51cf6623e7d862334869e237136d54bbfe6e [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shidb7464d2017-07-13 03:11:17 +00002/*
3 * Copyright (c) 2013-2017 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 Shi760cc7b2017-07-22 19:17:49 +000041/** @brief Represents a TLV element of NDN packet format
42 * @sa https://named-data.net/doc/ndn-tlv/tlv.html
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080043 */
44class Block
45{
46public:
Junxiao Shidb7464d2017-07-13 03:11:17 +000047 using element_container = std::vector<Block>;
48 using element_iterator = element_container::iterator;
49 using element_const_iterator = element_container::const_iterator;
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080050
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060051 class Error : public tlv::Error
Alexander Afanasyev937aa782014-03-21 13:17:57 -070052 {
Alexander Afanasyeva465e972014-03-22 17:21:49 -070053 public:
54 explicit
55 Error(const std::string& what)
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060056 : tlv::Error(what)
Alexander Afanasyeva465e972014-03-22 17:21:49 -070057 {
58 }
Alexander Afanasyev937aa782014-03-21 13:17:57 -070059 };
60
Junxiao Shi81a6c5d2014-11-30 00:14:42 -070061public: // constructor, creation, assignment
62 /** @brief Create an empty Block
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080063 */
64 Block();
65
Junxiao Shidb7464d2017-07-13 03:11:17 +000066 /** @brief Parse Block from an EncodingBuffer
67 * @param buffer an EncodingBuffer containing one TLV element
68 * @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
Alexander Afanasyev15151312014-02-16 00:53:51 -080069 */
70 explicit
71 Block(const EncodingBuffer& buffer);
Alexander Afanasyev937aa782014-03-21 13:17:57 -070072
Junxiao Shidb7464d2017-07-13 03:11:17 +000073 /** @brief Parse Block from a wire Buffer
74 * @param buffer a Buffer containing one TLV element
75 * @note This constructor takes shared ownership of @p buffer.
76 * @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080077 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -070078 explicit
Alexander Afanasyev937aa782014-03-21 13:17:57 -070079 Block(const ConstBufferPtr& buffer);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080080
Junxiao Shidb7464d2017-07-13 03:11:17 +000081 /** @brief Parse Block within boundaries of a wire Buffer
82 * @param buffer a Buffer containing an TLV element at [@p begin,@p end)
83 * @param begin begin position of the TLV element within @p buffer
84 * @param end end position of the TLV element within @p buffer
85 * @param verifyLength if true, check TLV-LENGTH equals size of TLV-VALUE
86 * @throw std::invalid_argument @p buffer is empty, or [@p begin,@p end) range are not within @p buffer
87 * @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
88 * @note This overload automatically detects TLV-TYPE and position of TLV-VALUE.
Alexander Afanasyev187bc482014-02-06 15:04:04 -080089 */
Junxiao Shidb7464d2017-07-13 03:11:17 +000090 Block(ConstBufferPtr buffer, Buffer::const_iterator begin, Buffer::const_iterator end,
Alexander Afanasyev5964fb72014-02-18 12:42:45 -080091 bool verifyLength = true);
Alexander Afanasyev937aa782014-03-21 13:17:57 -070092
Junxiao Shidb7464d2017-07-13 03:11:17 +000093 /** @brief Parse Block within boundaries of an existing Block, reusing underlying wire Buffer
94 * @param block a Block whose buffer contains an TLV element at [@p begin,@p end)
95 * @param begin begin position of the TLV element within @p block
96 * @param end end position of the TLV element within @p block
97 * @param verifyLength if true, check TLV-LENGTH equals size of TLV-VALUE
98 * @throw std::invalid_argument [@p begin,@p end) range are not within @p block
99 * @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
Alexander Afanasyev4448d292015-08-09 20:11:37 -0700100 */
Junxiao Shidb7464d2017-07-13 03:11:17 +0000101 Block(const Block& block, Buffer::const_iterator begin, Buffer::const_iterator end,
Alexander Afanasyev4448d292015-08-09 20:11:37 -0700102 bool verifyLength = true);
103
Junxiao Shidb7464d2017-07-13 03:11:17 +0000104 /** @brief Create a Block from a wire Buffer without parsing
105 * @param buffer a Buffer containing an TLV element at [@p begin,@p end)
106 * @param type TLV-TYPE
107 * @param begin begin position of the TLV element within @p buffer
108 * @param end end position of the TLV element within @p buffer
109 * @param valueBegin begin position of TLV-VALUE within @p buffer
110 * @param valueEnd end position of TLV-VALUE within @p buffer
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800111 */
Junxiao Shidb7464d2017-07-13 03:11:17 +0000112 Block(ConstBufferPtr buffer, uint32_t type,
113 Buffer::const_iterator begin, Buffer::const_iterator end,
114 Buffer::const_iterator valueBegin, Buffer::const_iterator valueEnd);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800115
Junxiao Shidb7464d2017-07-13 03:11:17 +0000116 /** @brief Parse Block from a raw buffer
117 * @param buf pointer to the first octet of an TLV element
118 * @param bufSize size of the raw buffer; may be more than size of the TLV element
119 * @throw tlv::Error Type-Length parsing fails, or size of TLV-VALUE exceeds @p bufSize
120 * @note This overload copies the TLV element into an internal wire buffer.
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700121 */
Junxiao Shidb7464d2017-07-13 03:11:17 +0000122 Block(const uint8_t* buf, size_t bufSize);
Yingdi Yu27158392014-01-20 13:04:20 -0800123
Junxiao Shidb7464d2017-07-13 03:11:17 +0000124 /** @brief Parse Block from a raw buffer
125 * @deprecated use Block(const uint8_t*, size_t)
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800126 */
Junxiao Shidb7464d2017-07-13 03:11:17 +0000127 Block(const void* buf, size_t bufSize);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800128
Junxiao Shidb7464d2017-07-13 03:11:17 +0000129 /** @brief Create an empty Block with specified TLV-TYPE
130 * @param type TLV-TYPE
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800131 */
Alexander Afanasyevf42ce132014-01-07 13:32:30 -0800132 explicit
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800133 Block(uint32_t type);
134
Junxiao Shidb7464d2017-07-13 03:11:17 +0000135 /** @brief Create a Block with specified TLV-TYPE and TLV-VALUE
136 * @param type TLV-TYPE
137 * @param value a Buffer containing the TLV-VALUE
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800138 */
Junxiao Shidb7464d2017-07-13 03:11:17 +0000139 Block(uint32_t type, ConstBufferPtr value);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800140
Junxiao Shidb7464d2017-07-13 03:11:17 +0000141 /** @brief Create a Block with specified TLV-TYPE and TLV-VALUE
142 * @param type TLV-TYPE
143 * @param value a Block to be nested as TLV-VALUE
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800144 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700145 Block(uint32_t type, const Block& value);
146
Junxiao Shidb7464d2017-07-13 03:11:17 +0000147 /** @brief Parse Block from an input stream
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000148 * @throw tlv::Error TLV-LENGTH is zero or exceeds upper bound
149 * @warning If decoding fails, bytes are still consumed from the input stream.
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700150 */
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700151 static Block
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700152 fromStream(std::istream& is);
153
Junxiao Shidb7464d2017-07-13 03:11:17 +0000154 /** @brief Try to parse Block from a wire buffer
155 * @param buffer a Buffer containing an TLV element at offset @p offset
156 * @param offset begin position of the TLV element within @p buffer
157 * @note This function does not throw exceptions upon decoding failure.
158 * @return true and the Block if parsing succeeds; otherwise false
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700159 */
Junxiao Shi02a4bf32015-02-21 21:07:46 -0700160 static std::tuple<bool, Block>
161 fromBuffer(ConstBufferPtr buffer, size_t offset);
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700162
Junxiao Shidb7464d2017-07-13 03:11:17 +0000163 /** @brief Try to parse Block from a raw buffer
164 * @param buf pointer to the first octet of an TLV element
165 * @param bufSize size of the raw buffer; may be more than size of the TLV element
166 * @note This function does not throw exceptions upon decoding failure.
167 * @note This overload copies the TLV element into an internal wire buffer.
168 * @return true and the Block if parsing succeeds; otherwise false
Junxiao Shi02a4bf32015-02-21 21:07:46 -0700169 */
170 static std::tuple<bool, Block>
Junxiao Shidb7464d2017-07-13 03:11:17 +0000171 fromBuffer(const uint8_t* buf, size_t bufSize);
Junxiao Shi02a4bf32015-02-21 21:07:46 -0700172
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700173public: // wire format
174 /** @brief Check if the Block is empty
Junxiao Shidb7464d2017-07-13 03:11:17 +0000175 *
176 * A Block is "empty" only if it is default-constructed. A Block with zero-length TLV-VALUE is
177 * not considered empty.
Alexander Afanasyev196b9aa2014-01-31 17:19:16 -0800178 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700179 bool
Junxiao Shidb7464d2017-07-13 03:11:17 +0000180 empty() const
181 {
182 return m_type == std::numeric_limits<uint32_t>::max();
183 }
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700184
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700185 /** @brief Check if the Block has fully encoded wire
Junxiao Shidb7464d2017-07-13 03:11:17 +0000186 *
187 * A Block has fully encoded wire if the underlying buffer exists and contains full
188 * Type-Length-Value instead of just TLV-VALUE field.
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800189 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700190 bool
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800191 hasWire() const;
192
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700193 /** @brief Reset wire buffer of the element
Junxiao Shidb7464d2017-07-13 03:11:17 +0000194 * @post empty() == true
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800195 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700196 void
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800197 reset();
198
Junxiao Shidb7464d2017-07-13 03:11:17 +0000199 /** @brief Reset wire buffer but keep TLV-TYPE and sub elements (if any)
200 * @post hasWire() == false
201 * @post hasValue() == false
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800202 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700203 void
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800204 resetWire();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800205
Junxiao Shidb7464d2017-07-13 03:11:17 +0000206 /** @brief Get begin iterator of encoded wire
207 * @pre hasWire() == true
208 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700209 Buffer::const_iterator
210 begin() const;
211
Junxiao Shidb7464d2017-07-13 03:11:17 +0000212 /** @brief Get end iterator of encoded wire
213 * @pre hasWire() == true
214 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700215 Buffer::const_iterator
216 end() const;
217
Junxiao Shidb7464d2017-07-13 03:11:17 +0000218 /** @brief Get pointer to encoded wire
219 * @pre hasWire() == true
220 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700221 const uint8_t*
222 wire() const;
223
Junxiao Shidb7464d2017-07-13 03:11:17 +0000224 /** @brief Get size of encoded wire, including Type-Length-Value
225 * @pre empty() == false
226 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700227 size_t
228 size() const;
229
Junxiao Shidb7464d2017-07-13 03:11:17 +0000230 /** @brief Get underlying buffer
231 */
232 shared_ptr<const Buffer>
233 getBuffer() const
234 {
235 return m_buffer;
236 }
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700237
Junxiao Shidb7464d2017-07-13 03:11:17 +0000238public: // type and value
239 /** @brief Get TLV-TYPE
240 */
241 uint32_t
242 type() const
243 {
244 return m_type;
245 }
246
247 /** @brief Get begin iterator of TLV-VALUE
248 *
249 * This property reflects whether the underlying buffer contains TLV-VALUE. If this is false,
250 * TLV-VALUE has zero-length. If this is true, TLV-VALUE may be zero-length.
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700251 */
252 bool
Junxiao Shidb7464d2017-07-13 03:11:17 +0000253 hasValue() const
254 {
255 return m_buffer != nullptr;
256 }
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700257
Junxiao Shidb7464d2017-07-13 03:11:17 +0000258 /** @brief Get begin iterator of TLV-VALUE
259 * @pre hasValue() == true
260 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700261 Buffer::const_iterator
Junxiao Shidb7464d2017-07-13 03:11:17 +0000262 value_begin() const
263 {
264 return m_valueBegin;
265 }
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700266
Junxiao Shidb7464d2017-07-13 03:11:17 +0000267 /** @brief Get end iterator of TLV-VALUE
268 * @pre hasValue() == true
269 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700270 Buffer::const_iterator
Junxiao Shidb7464d2017-07-13 03:11:17 +0000271 value_end() const
272 {
273 return m_valueEnd;
274 }
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700275
Junxiao Shidb7464d2017-07-13 03:11:17 +0000276 /** @brief Get pointer to TLV-VALUE
277 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700278 const uint8_t*
279 value() const;
280
Junxiao Shidb7464d2017-07-13 03:11:17 +0000281 /** @brief Get size of TLV-VALUE aka TLV-LENGTH
282 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700283 size_t
284 value_size() const;
285
Yingdi Yu4270f202014-01-28 14:19:16 -0800286 Block
287 blockFromValue() const;
288
Junxiao Shidb7464d2017-07-13 03:11:17 +0000289public: // sub elements
290 /** @brief Parse TLV-VALUE into sub elements
291 * @post elements() reflects sub elements found in TLV-VALUE
292 * @throw tlv::Error TLV-VALUE is not a sequence of TLV elements
293 * @note This method does not perform recursive parsing.
294 * @note This method has no effect if elements() is already populated.
295 * @note This method is not really const, but it does not modify any data.
Alexander Afanasyev74633892015-02-08 18:08:46 -0800296 */
Junxiao Shidb7464d2017-07-13 03:11:17 +0000297 void
298 parse() const;
Alexander Afanasyev74633892015-02-08 18:08:46 -0800299
Junxiao Shidb7464d2017-07-13 03:11:17 +0000300 /** @brief Encode sub elements into TLV-VALUE
301 * @post TLV-VALUE contains sub elements from elements()
302 */
303 void
304 encode();
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700305
Junxiao Shidb7464d2017-07-13 03:11:17 +0000306 /** @brief Get the first sub element of specified TLV-TYPE
307 * @pre parse() has been executed
308 * @throw Error sub element of @p type does not exist
309 */
310 const Block&
311 get(uint32_t type) const;
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700312
Junxiao Shidb7464d2017-07-13 03:11:17 +0000313 /** @brief Find the first sub element of specified TLV-TYPE
314 * @pre parse() has been executed
315 * @return iterator in elements() to the found sub element, otherwise elements_end()
316 */
317 element_const_iterator
318 find(uint32_t type) const;
319
320 /** @brief Remove all sub elements of specified TLV-TYPE
321 * @pre parse() has been executed
322 * @post find(type) == elements_end()
323 */
324 void
325 remove(uint32_t type);
326
327 /** @brief Erase a sub element
328 */
329 element_iterator
330 erase(element_const_iterator position);
331
332 /** @brief Erase a range of sub elements
333 */
334 element_iterator
335 erase(element_const_iterator first, element_const_iterator last);
336
337 /** @brief Append a sub element
338 */
339 void
340 push_back(const Block& element);
341
342 /** @brief Insert a sub element
343 * @param pos position of new sub element
344 * @param element new sub element
345 * @return iterator in elements() to the new sub element
346 */
347 element_iterator
348 insert(element_const_iterator pos, const Block& element);
349
350 /** @brief Get container of sub elements
351 * @pre parse() has been executed
352 */
353 const element_container&
354 elements() const
355 {
356 return m_elements;
357 }
358
359 /** @brief Equivalent to elements().begin()
360 */
361 element_const_iterator
362 elements_begin() const
363 {
364 return m_elements.begin();
365 }
366
367 /** @brief Equivalent to elements().end()
368 */
369 element_const_iterator
370 elements_end() const
371 {
372 return m_elements.end();
373 }
374
375 /** @brief Equivalent to elements().size()
376 */
377 size_t
378 elements_size() const
379 {
380 return m_elements.size();
381 }
382
383public: // misc
384 /** @brief Implicit conversion to const_buffer
385 */
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700386 operator boost::asio::const_buffer() const;
387
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800388protected:
Junxiao Shidb7464d2017-07-13 03:11:17 +0000389 /** @brief underlying buffer storing TLV-VALUE and possibly TLV-TYPE and TLV-LENGTH fields
390 *
391 * If m_buffer is nullptr, this is an empty Block with TLV-TYPE given in m_type.
392 * Otherwise,
393 * - [m_valueBegin, m_valueEnd) point to TLV-VALUE within m_buffer.
394 * - If m_begin != m_end, [m_begin,m_end) point to Type-Length-Value of this Block within m_buffer.
395 * Otherwise, m_buffer does not contain TLV-TYPE and TLV-LENGTH fields.
396 */
Alexander Afanasyev74633892015-02-08 18:08:46 -0800397 shared_ptr<const Buffer> m_buffer;
Junxiao Shidb7464d2017-07-13 03:11:17 +0000398 Buffer::const_iterator m_begin; ///< @sa m_buffer
399 Buffer::const_iterator m_end; ///< @sa m_buffer
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800400
Junxiao Shidb7464d2017-07-13 03:11:17 +0000401 Buffer::const_iterator m_valueBegin; ///< @sa m_buffer
402 Buffer::const_iterator m_valueEnd; ///< @sa m_buffer
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700403
Junxiao Shidb7464d2017-07-13 03:11:17 +0000404 uint32_t m_type; ///< TLV-TYPE
405
406 /** @brief total size including Type-Length-Value
407 *
408 * This field is valid only if empty() is false.
409 */
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800410 uint32_t m_size;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700411
Junxiao Shidb7464d2017-07-13 03:11:17 +0000412 /** @brief sub elements
413 *
414 * This field is valid only if parse() has been executed.
415 */
416 mutable element_container m_elements;
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800417};
418
Junxiao Shidb7464d2017-07-13 03:11:17 +0000419/** @brief Compare whether two Blocks have same TLV-TYPE, TLV-LENGTH, and TLV-VALUE
420 */
421bool
422operator==(const Block& lhs, const Block& rhs);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800423
Junxiao Shidb7464d2017-07-13 03:11:17 +0000424inline bool
425operator!=(const Block& lhs, const Block& rhs)
Alexander Afanasyev74633892015-02-08 18:08:46 -0800426{
Junxiao Shidb7464d2017-07-13 03:11:17 +0000427 return !(lhs == rhs);
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800428}
429
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700430} // namespace ndn
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800431
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700432#endif // NDN_ENCODING_BLOCK_HPP