blob: 2aec91c01cd9f3dadd52c02df937a4e459dea13e [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/*
Junxiao Shi72c0c642018-04-20 15:41:09 +00003 * Copyright (c) 2013-2018 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 Afanasyev13bb51a2014-01-02 19:13:26 -080027#include "buffer.hpp"
Alexander Afanasyev74633892015-02-08 18:08:46 -080028#include "encoding-buffer-fwd.hpp"
Davide Pesavento88a0d812017-08-19 21:31:42 -040029#include "tlv.hpp"
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080030
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -070031namespace boost {
32namespace asio {
33class const_buffer;
34} // namespace asio
35} // namespace boost
36
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080037namespace ndn {
38
Junxiao Shi760cc7b2017-07-22 19:17:49 +000039/** @brief Represents a TLV element of NDN packet format
40 * @sa https://named-data.net/doc/ndn-tlv/tlv.html
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080041 */
42class Block
43{
44public:
Junxiao Shidb7464d2017-07-13 03:11:17 +000045 using element_container = std::vector<Block>;
46 using element_iterator = element_container::iterator;
47 using element_const_iterator = element_container::const_iterator;
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080048
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060049 class Error : public tlv::Error
Alexander Afanasyev937aa782014-03-21 13:17:57 -070050 {
Alexander Afanasyeva465e972014-03-22 17:21:49 -070051 public:
52 explicit
53 Error(const std::string& what)
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060054 : tlv::Error(what)
Alexander Afanasyeva465e972014-03-22 17:21:49 -070055 {
56 }
Alexander Afanasyev937aa782014-03-21 13:17:57 -070057 };
58
Junxiao Shi81a6c5d2014-11-30 00:14:42 -070059public: // constructor, creation, assignment
60 /** @brief Create an empty Block
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080061 */
62 Block();
63
Davide Pesavento3a3e1882018-07-17 14:49:15 -040064 /** @brief Copy constructor
65 */
66 Block(const Block&);
67
68 /** @brief Copy assignment operator
69 */
70 Block&
71 operator=(const Block&);
72
73 /** @brief Move constructor
74 */
75 Block(Block&&) noexcept;
76
77 /** @brief Move assignment operator
78 */
79 Block&
80 operator=(Block&&) noexcept;
81
Junxiao Shidb7464d2017-07-13 03:11:17 +000082 /** @brief Parse Block from an EncodingBuffer
83 * @param buffer an EncodingBuffer containing one TLV element
84 * @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
Alexander Afanasyev15151312014-02-16 00:53:51 -080085 */
86 explicit
87 Block(const EncodingBuffer& buffer);
Alexander Afanasyev937aa782014-03-21 13:17:57 -070088
Junxiao Shidb7464d2017-07-13 03:11:17 +000089 /** @brief Parse Block from a wire Buffer
90 * @param buffer a Buffer containing one TLV element
91 * @note This constructor takes shared ownership of @p buffer.
92 * @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080093 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -070094 explicit
Alexander Afanasyev937aa782014-03-21 13:17:57 -070095 Block(const ConstBufferPtr& buffer);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080096
Junxiao Shidb7464d2017-07-13 03:11:17 +000097 /** @brief Parse Block within boundaries of a wire Buffer
98 * @param buffer a Buffer containing an TLV element at [@p begin,@p end)
99 * @param begin begin position of the TLV element within @p buffer
100 * @param end end position of the TLV element within @p buffer
101 * @param verifyLength if true, check TLV-LENGTH equals size of TLV-VALUE
102 * @throw std::invalid_argument @p buffer is empty, or [@p begin,@p end) range are not within @p buffer
103 * @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
104 * @note This overload automatically detects TLV-TYPE and position of TLV-VALUE.
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800105 */
Junxiao Shidb7464d2017-07-13 03:11:17 +0000106 Block(ConstBufferPtr buffer, Buffer::const_iterator begin, Buffer::const_iterator end,
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800107 bool verifyLength = true);
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700108
Junxiao Shidb7464d2017-07-13 03:11:17 +0000109 /** @brief Parse Block within boundaries of an existing Block, reusing underlying wire Buffer
110 * @param block a Block whose buffer contains an TLV element at [@p begin,@p end)
111 * @param begin begin position of the TLV element within @p block
112 * @param end end position of the TLV element within @p block
113 * @param verifyLength if true, check TLV-LENGTH equals size of TLV-VALUE
114 * @throw std::invalid_argument [@p begin,@p end) range are not within @p block
115 * @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
Alexander Afanasyev4448d292015-08-09 20:11:37 -0700116 */
Junxiao Shidb7464d2017-07-13 03:11:17 +0000117 Block(const Block& block, Buffer::const_iterator begin, Buffer::const_iterator end,
Alexander Afanasyev4448d292015-08-09 20:11:37 -0700118 bool verifyLength = true);
119
Junxiao Shidb7464d2017-07-13 03:11:17 +0000120 /** @brief Create a Block from a wire Buffer without parsing
121 * @param buffer a Buffer containing an TLV element at [@p begin,@p end)
122 * @param type TLV-TYPE
123 * @param begin begin position of the TLV element within @p buffer
124 * @param end end position of the TLV element within @p buffer
125 * @param valueBegin begin position of TLV-VALUE within @p buffer
126 * @param valueEnd end position of TLV-VALUE within @p buffer
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800127 */
Junxiao Shidb7464d2017-07-13 03:11:17 +0000128 Block(ConstBufferPtr buffer, uint32_t type,
129 Buffer::const_iterator begin, Buffer::const_iterator end,
130 Buffer::const_iterator valueBegin, Buffer::const_iterator valueEnd);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800131
Junxiao Shidb7464d2017-07-13 03:11:17 +0000132 /** @brief Parse Block from a raw buffer
133 * @param buf pointer to the first octet of an TLV element
134 * @param bufSize size of the raw buffer; may be more than size of the TLV element
135 * @throw tlv::Error Type-Length parsing fails, or size of TLV-VALUE exceeds @p bufSize
136 * @note This overload copies the TLV element into an internal wire buffer.
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700137 */
Junxiao Shidb7464d2017-07-13 03:11:17 +0000138 Block(const uint8_t* buf, size_t bufSize);
Yingdi Yu27158392014-01-20 13:04:20 -0800139
Junxiao Shidb7464d2017-07-13 03:11:17 +0000140 /** @brief Create an empty Block with specified TLV-TYPE
141 * @param type TLV-TYPE
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800142 */
Alexander Afanasyevf42ce132014-01-07 13:32:30 -0800143 explicit
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800144 Block(uint32_t type);
145
Junxiao Shidb7464d2017-07-13 03:11:17 +0000146 /** @brief Create a Block with specified TLV-TYPE and TLV-VALUE
147 * @param type TLV-TYPE
148 * @param value a Buffer containing the TLV-VALUE
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800149 */
Junxiao Shidb7464d2017-07-13 03:11:17 +0000150 Block(uint32_t type, ConstBufferPtr value);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800151
Junxiao Shidb7464d2017-07-13 03:11:17 +0000152 /** @brief Create a Block with specified TLV-TYPE and TLV-VALUE
153 * @param type TLV-TYPE
154 * @param value a Block to be nested as TLV-VALUE
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800155 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700156 Block(uint32_t type, const Block& value);
157
Junxiao Shidb7464d2017-07-13 03:11:17 +0000158 /** @brief Parse Block from an input stream
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000159 * @throw tlv::Error TLV-LENGTH is zero or exceeds upper bound
160 * @warning If decoding fails, bytes are still consumed from the input stream.
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700161 */
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700162 static Block
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700163 fromStream(std::istream& is);
164
Junxiao Shidb7464d2017-07-13 03:11:17 +0000165 /** @brief Try to parse Block from a wire buffer
166 * @param buffer a Buffer containing an TLV element at offset @p offset
167 * @param offset begin position of the TLV element within @p buffer
168 * @note This function does not throw exceptions upon decoding failure.
169 * @return true and the Block if parsing succeeds; otherwise false
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700170 */
Junxiao Shi02a4bf32015-02-21 21:07:46 -0700171 static std::tuple<bool, Block>
172 fromBuffer(ConstBufferPtr buffer, size_t offset);
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700173
Junxiao Shidb7464d2017-07-13 03:11:17 +0000174 /** @brief Try to parse Block from a raw buffer
175 * @param buf pointer to the first octet of an TLV element
176 * @param bufSize size of the raw buffer; may be more than size of the TLV element
177 * @note This function does not throw exceptions upon decoding failure.
178 * @note This overload copies the TLV element into an internal wire buffer.
179 * @return true and the Block if parsing succeeds; otherwise false
Junxiao Shi02a4bf32015-02-21 21:07:46 -0700180 */
181 static std::tuple<bool, Block>
Junxiao Shidb7464d2017-07-13 03:11:17 +0000182 fromBuffer(const uint8_t* buf, size_t bufSize);
Junxiao Shi02a4bf32015-02-21 21:07:46 -0700183
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700184public: // wire format
185 /** @brief Check if the Block is empty
Junxiao Shidb7464d2017-07-13 03:11:17 +0000186 *
187 * A Block is "empty" only if it is default-constructed. A Block with zero-length TLV-VALUE is
188 * not considered empty.
Alexander Afanasyev196b9aa2014-01-31 17:19:16 -0800189 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700190 bool
Junxiao Shidb7464d2017-07-13 03:11:17 +0000191 empty() const
192 {
193 return m_type == std::numeric_limits<uint32_t>::max();
194 }
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700195
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700196 /** @brief Check if the Block has fully encoded wire
Junxiao Shidb7464d2017-07-13 03:11:17 +0000197 *
198 * A Block has fully encoded wire if the underlying buffer exists and contains full
199 * Type-Length-Value instead of just TLV-VALUE field.
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800200 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700201 bool
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800202 hasWire() const;
203
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700204 /** @brief Reset wire buffer of the element
Junxiao Shidb7464d2017-07-13 03:11:17 +0000205 * @post empty() == true
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800206 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700207 void
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800208 reset();
209
Junxiao Shidb7464d2017-07-13 03:11:17 +0000210 /** @brief Reset wire buffer but keep TLV-TYPE and sub elements (if any)
211 * @post hasWire() == false
212 * @post hasValue() == false
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800213 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700214 void
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800215 resetWire();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800216
Junxiao Shidb7464d2017-07-13 03:11:17 +0000217 /** @brief Get begin iterator of encoded wire
218 * @pre hasWire() == true
219 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700220 Buffer::const_iterator
221 begin() const;
222
Junxiao Shidb7464d2017-07-13 03:11:17 +0000223 /** @brief Get end iterator of encoded wire
224 * @pre hasWire() == true
225 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700226 Buffer::const_iterator
227 end() const;
228
Junxiao Shidb7464d2017-07-13 03:11:17 +0000229 /** @brief Get pointer to encoded wire
230 * @pre hasWire() == true
231 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700232 const uint8_t*
233 wire() const;
234
Junxiao Shidb7464d2017-07-13 03:11:17 +0000235 /** @brief Get size of encoded wire, including Type-Length-Value
236 * @pre empty() == false
237 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700238 size_t
239 size() const;
240
Junxiao Shidb7464d2017-07-13 03:11:17 +0000241 /** @brief Get underlying buffer
242 */
243 shared_ptr<const Buffer>
244 getBuffer() const
245 {
246 return m_buffer;
247 }
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700248
Junxiao Shidb7464d2017-07-13 03:11:17 +0000249public: // type and value
250 /** @brief Get TLV-TYPE
251 */
252 uint32_t
253 type() const
254 {
255 return m_type;
256 }
257
258 /** @brief Get begin iterator of TLV-VALUE
259 *
260 * This property reflects whether the underlying buffer contains TLV-VALUE. If this is false,
261 * TLV-VALUE has zero-length. If this is true, TLV-VALUE may be zero-length.
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700262 */
263 bool
Junxiao Shidb7464d2017-07-13 03:11:17 +0000264 hasValue() const
265 {
266 return m_buffer != nullptr;
267 }
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700268
Junxiao Shidb7464d2017-07-13 03:11:17 +0000269 /** @brief Get begin iterator of TLV-VALUE
270 * @pre hasValue() == true
271 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700272 Buffer::const_iterator
Junxiao Shidb7464d2017-07-13 03:11:17 +0000273 value_begin() const
274 {
275 return m_valueBegin;
276 }
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700277
Junxiao Shidb7464d2017-07-13 03:11:17 +0000278 /** @brief Get end iterator of TLV-VALUE
279 * @pre hasValue() == true
280 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700281 Buffer::const_iterator
Junxiao Shidb7464d2017-07-13 03:11:17 +0000282 value_end() const
283 {
284 return m_valueEnd;
285 }
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700286
Junxiao Shidb7464d2017-07-13 03:11:17 +0000287 /** @brief Get pointer to TLV-VALUE
288 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700289 const uint8_t*
290 value() const;
291
Junxiao Shidb7464d2017-07-13 03:11:17 +0000292 /** @brief Get size of TLV-VALUE aka TLV-LENGTH
293 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700294 size_t
295 value_size() const;
296
Yingdi Yu4270f202014-01-28 14:19:16 -0800297 Block
298 blockFromValue() const;
299
Junxiao Shidb7464d2017-07-13 03:11:17 +0000300public: // sub elements
301 /** @brief Parse TLV-VALUE into sub elements
302 * @post elements() reflects sub elements found in TLV-VALUE
303 * @throw tlv::Error TLV-VALUE is not a sequence of TLV elements
304 * @note This method does not perform recursive parsing.
305 * @note This method has no effect if elements() is already populated.
306 * @note This method is not really const, but it does not modify any data.
Alexander Afanasyev74633892015-02-08 18:08:46 -0800307 */
Junxiao Shidb7464d2017-07-13 03:11:17 +0000308 void
309 parse() const;
Alexander Afanasyev74633892015-02-08 18:08:46 -0800310
Junxiao Shidb7464d2017-07-13 03:11:17 +0000311 /** @brief Encode sub elements into TLV-VALUE
312 * @post TLV-VALUE contains sub elements from elements()
313 */
314 void
315 encode();
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700316
Junxiao Shidb7464d2017-07-13 03:11:17 +0000317 /** @brief Get the first sub element of specified TLV-TYPE
318 * @pre parse() has been executed
319 * @throw Error sub element of @p type does not exist
320 */
321 const Block&
322 get(uint32_t type) const;
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700323
Junxiao Shidb7464d2017-07-13 03:11:17 +0000324 /** @brief Find the first sub element of specified TLV-TYPE
325 * @pre parse() has been executed
326 * @return iterator in elements() to the found sub element, otherwise elements_end()
327 */
328 element_const_iterator
329 find(uint32_t type) const;
330
331 /** @brief Remove all sub elements of specified TLV-TYPE
332 * @pre parse() has been executed
333 * @post find(type) == elements_end()
334 */
335 void
336 remove(uint32_t type);
337
338 /** @brief Erase a sub element
339 */
340 element_iterator
341 erase(element_const_iterator position);
342
343 /** @brief Erase a range of sub elements
344 */
345 element_iterator
346 erase(element_const_iterator first, element_const_iterator last);
347
348 /** @brief Append a sub element
349 */
350 void
351 push_back(const Block& element);
352
353 /** @brief Insert a sub element
354 * @param pos position of new sub element
355 * @param element new sub element
356 * @return iterator in elements() to the new sub element
357 */
358 element_iterator
359 insert(element_const_iterator pos, const Block& element);
360
361 /** @brief Get container of sub elements
362 * @pre parse() has been executed
363 */
364 const element_container&
365 elements() const
366 {
367 return m_elements;
368 }
369
370 /** @brief Equivalent to elements().begin()
371 */
372 element_const_iterator
373 elements_begin() const
374 {
375 return m_elements.begin();
376 }
377
378 /** @brief Equivalent to elements().end()
379 */
380 element_const_iterator
381 elements_end() const
382 {
383 return m_elements.end();
384 }
385
386 /** @brief Equivalent to elements().size()
387 */
388 size_t
389 elements_size() const
390 {
391 return m_elements.size();
392 }
393
394public: // misc
395 /** @brief Implicit conversion to const_buffer
396 */
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700397 operator boost::asio::const_buffer() const;
398
Junxiao Shid2777fa2017-07-27 18:35:34 +0000399private:
400 /** @brief Estimate Block size as if sub elements are encoded into TLV-VALUE
401 */
402 size_t
403 encode(EncodingEstimator& estimator) const;
404
Junxiao Shi72c0c642018-04-20 15:41:09 +0000405 /** @brief Estimate TLV-LENGTH as if sub elements are encoded into TLV-VALUE
406 */
407 size_t
408 encodeValue(EncodingEstimator& estimator) const;
409
Junxiao Shid2777fa2017-07-27 18:35:34 +0000410 /** @brief Encode sub elements into TLV-VALUE and prepend Block to encoder
411 * @post TLV-VALUE contains sub elements from elements()
412 * @post internal buffer and iterators point to Encoder's buffer
413 */
414 size_t
415 encode(EncodingBuffer& encoder);
416
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800417protected:
Junxiao Shidb7464d2017-07-13 03:11:17 +0000418 /** @brief underlying buffer storing TLV-VALUE and possibly TLV-TYPE and TLV-LENGTH fields
419 *
420 * If m_buffer is nullptr, this is an empty Block with TLV-TYPE given in m_type.
421 * Otherwise,
422 * - [m_valueBegin, m_valueEnd) point to TLV-VALUE within m_buffer.
423 * - If m_begin != m_end, [m_begin,m_end) point to Type-Length-Value of this Block within m_buffer.
424 * Otherwise, m_buffer does not contain TLV-TYPE and TLV-LENGTH fields.
425 */
Alexander Afanasyev74633892015-02-08 18:08:46 -0800426 shared_ptr<const Buffer> m_buffer;
Junxiao Shidb7464d2017-07-13 03:11:17 +0000427 Buffer::const_iterator m_begin; ///< @sa m_buffer
428 Buffer::const_iterator m_end; ///< @sa m_buffer
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800429
Junxiao Shidb7464d2017-07-13 03:11:17 +0000430 Buffer::const_iterator m_valueBegin; ///< @sa m_buffer
431 Buffer::const_iterator m_valueEnd; ///< @sa m_buffer
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700432
Davide Pesavento3a3e1882018-07-17 14:49:15 -0400433 uint32_t m_type = std::numeric_limits<uint32_t>::max(); ///< TLV-TYPE
Junxiao Shidb7464d2017-07-13 03:11:17 +0000434
435 /** @brief total size including Type-Length-Value
436 *
437 * This field is valid only if empty() is false.
438 */
Davide Pesavento3a3e1882018-07-17 14:49:15 -0400439 size_t m_size = 0;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700440
Junxiao Shidb7464d2017-07-13 03:11:17 +0000441 /** @brief sub elements
442 *
443 * This field is valid only if parse() has been executed.
444 */
445 mutable element_container m_elements;
Junxiao Shi72c0c642018-04-20 15:41:09 +0000446
447 /** @brief Print @p block to @p os.
448 *
449 * Default-constructed block is printed as: `[invalid]`.
450 * Zero-length block is printed as: `TT[empty]`, where TT is TLV-TYPE in decimal.
451 * Non-zero-length block on which @c Block::parse is not called is printed as: `TT[LL]=VVVV`,
452 * where LL is TLV-LENGTH in decimal, and VVVV is TLV-VALUE is hexadecimal.
453 * Block on which @c Block::parse has been called in printed as: `TT[LL]={SUB,SUB}`,
454 * where SUB is a sub-element printed using this format.
455 */
456 friend std::ostream&
457 operator<<(std::ostream& os, const Block& block);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800458};
459
Davide Pesavento3a3e1882018-07-17 14:49:15 -0400460inline
461Block::Block(Block&&) noexcept = default;
462
463inline Block&
464Block::operator=(Block&&) noexcept = default;
465
Junxiao Shidb7464d2017-07-13 03:11:17 +0000466/** @brief Compare whether two Blocks have same TLV-TYPE, TLV-LENGTH, and TLV-VALUE
467 */
468bool
469operator==(const Block& lhs, const Block& rhs);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800470
Junxiao Shidb7464d2017-07-13 03:11:17 +0000471inline bool
472operator!=(const Block& lhs, const Block& rhs)
Alexander Afanasyev74633892015-02-08 18:08:46 -0800473{
Junxiao Shidb7464d2017-07-13 03:11:17 +0000474 return !(lhs == rhs);
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800475}
476
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700477} // namespace ndn
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800478
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700479#endif // NDN_ENCODING_BLOCK_HPP