blob: 4bbb1620cb59bc7c9b5da6d9917ebfa46a9fe9ab [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:
Junxiao Shi68b53852018-07-25 13:56:38 -060052 using tlv::Error::Error;
Alexander Afanasyev937aa782014-03-21 13:17:57 -070053 };
54
Junxiao Shi81a6c5d2014-11-30 00:14:42 -070055public: // constructor, creation, assignment
56 /** @brief Create an empty Block
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080057 */
58 Block();
59
Davide Pesavento3a3e1882018-07-17 14:49:15 -040060 /** @brief Copy constructor
61 */
62 Block(const Block&);
63
64 /** @brief Copy assignment operator
65 */
66 Block&
67 operator=(const Block&);
68
69 /** @brief Move constructor
70 */
71 Block(Block&&) noexcept;
72
73 /** @brief Move assignment operator
74 */
75 Block&
76 operator=(Block&&) noexcept;
77
Junxiao Shidb7464d2017-07-13 03:11:17 +000078 /** @brief Parse Block from an EncodingBuffer
79 * @param buffer an EncodingBuffer containing one TLV element
80 * @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
Alexander Afanasyev15151312014-02-16 00:53:51 -080081 */
82 explicit
83 Block(const EncodingBuffer& buffer);
Alexander Afanasyev937aa782014-03-21 13:17:57 -070084
Junxiao Shidb7464d2017-07-13 03:11:17 +000085 /** @brief Parse Block from a wire Buffer
86 * @param buffer a Buffer containing one TLV element
87 * @note This constructor takes shared ownership of @p buffer.
88 * @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080089 */
Alexander Afanasyev197e5652014-06-13 16:56:31 -070090 explicit
Alexander Afanasyev937aa782014-03-21 13:17:57 -070091 Block(const ConstBufferPtr& buffer);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080092
Junxiao Shidb7464d2017-07-13 03:11:17 +000093 /** @brief Parse Block within boundaries of a wire Buffer
94 * @param buffer a Buffer containing an TLV element at [@p begin,@p end)
95 * @param begin begin position of the TLV element within @p buffer
96 * @param end end position of the TLV element within @p buffer
97 * @param verifyLength if true, check TLV-LENGTH equals size of TLV-VALUE
98 * @throw std::invalid_argument @p buffer is empty, or [@p begin,@p end) range are not within @p buffer
99 * @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
100 * @note This overload automatically detects TLV-TYPE and position of TLV-VALUE.
Alexander Afanasyev187bc482014-02-06 15:04:04 -0800101 */
Junxiao Shidb7464d2017-07-13 03:11:17 +0000102 Block(ConstBufferPtr buffer, Buffer::const_iterator begin, Buffer::const_iterator end,
Alexander Afanasyev5964fb72014-02-18 12:42:45 -0800103 bool verifyLength = true);
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700104
Junxiao Shidb7464d2017-07-13 03:11:17 +0000105 /** @brief Parse Block within boundaries of an existing Block, reusing underlying wire Buffer
106 * @param block a Block whose buffer contains an TLV element at [@p begin,@p end)
107 * @param begin begin position of the TLV element within @p block
108 * @param end end position of the TLV element within @p block
109 * @param verifyLength if true, check TLV-LENGTH equals size of TLV-VALUE
110 * @throw std::invalid_argument [@p begin,@p end) range are not within @p block
111 * @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
Alexander Afanasyev4448d292015-08-09 20:11:37 -0700112 */
Junxiao Shidb7464d2017-07-13 03:11:17 +0000113 Block(const Block& block, Buffer::const_iterator begin, Buffer::const_iterator end,
Alexander Afanasyev4448d292015-08-09 20:11:37 -0700114 bool verifyLength = true);
115
Junxiao Shidb7464d2017-07-13 03:11:17 +0000116 /** @brief Create a Block from a wire Buffer without parsing
117 * @param buffer a Buffer containing an TLV element at [@p begin,@p end)
118 * @param type TLV-TYPE
119 * @param begin begin position of the TLV element within @p buffer
120 * @param end end position of the TLV element within @p buffer
121 * @param valueBegin begin position of TLV-VALUE within @p buffer
122 * @param valueEnd end position of TLV-VALUE within @p buffer
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800123 */
Junxiao Shidb7464d2017-07-13 03:11:17 +0000124 Block(ConstBufferPtr buffer, uint32_t type,
125 Buffer::const_iterator begin, Buffer::const_iterator end,
126 Buffer::const_iterator valueBegin, Buffer::const_iterator valueEnd);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800127
Junxiao Shidb7464d2017-07-13 03:11:17 +0000128 /** @brief Parse Block from a raw buffer
129 * @param buf pointer to the first octet of an TLV element
130 * @param bufSize size of the raw buffer; may be more than size of the TLV element
131 * @throw tlv::Error Type-Length parsing fails, or size of TLV-VALUE exceeds @p bufSize
132 * @note This overload copies the TLV element into an internal wire buffer.
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700133 */
Junxiao Shidb7464d2017-07-13 03:11:17 +0000134 Block(const uint8_t* buf, size_t bufSize);
Yingdi Yu27158392014-01-20 13:04:20 -0800135
Junxiao Shidb7464d2017-07-13 03:11:17 +0000136 /** @brief Create an empty Block with specified TLV-TYPE
137 * @param type TLV-TYPE
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800138 */
Alexander Afanasyevf42ce132014-01-07 13:32:30 -0800139 explicit
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800140 Block(uint32_t type);
141
Junxiao Shidb7464d2017-07-13 03:11:17 +0000142 /** @brief Create a Block with specified TLV-TYPE and TLV-VALUE
143 * @param type TLV-TYPE
144 * @param value a Buffer containing the TLV-VALUE
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800145 */
Junxiao Shidb7464d2017-07-13 03:11:17 +0000146 Block(uint32_t type, ConstBufferPtr value);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800147
Junxiao Shidb7464d2017-07-13 03:11:17 +0000148 /** @brief Create a Block with specified TLV-TYPE and TLV-VALUE
149 * @param type TLV-TYPE
150 * @param value a Block to be nested as TLV-VALUE
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800151 */
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700152 Block(uint32_t type, const Block& value);
153
Junxiao Shidb7464d2017-07-13 03:11:17 +0000154 /** @brief Parse Block from an input stream
Junxiao Shi760cc7b2017-07-22 19:17:49 +0000155 * @throw tlv::Error TLV-LENGTH is zero or exceeds upper bound
156 * @warning If decoding fails, bytes are still consumed from the input stream.
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700157 */
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700158 static Block
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700159 fromStream(std::istream& is);
160
Junxiao Shidb7464d2017-07-13 03:11:17 +0000161 /** @brief Try to parse Block from a wire buffer
162 * @param buffer a Buffer containing an TLV element at offset @p offset
163 * @param offset begin position of the TLV element within @p buffer
164 * @note This function does not throw exceptions upon decoding failure.
165 * @return true and the Block if parsing succeeds; otherwise false
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700166 */
Junxiao Shi02a4bf32015-02-21 21:07:46 -0700167 static std::tuple<bool, Block>
168 fromBuffer(ConstBufferPtr buffer, size_t offset);
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700169
Junxiao Shidb7464d2017-07-13 03:11:17 +0000170 /** @brief Try to parse Block from a raw buffer
171 * @param buf pointer to the first octet of an TLV element
172 * @param bufSize size of the raw buffer; may be more than size of the TLV element
173 * @note This function does not throw exceptions upon decoding failure.
174 * @note This overload copies the TLV element into an internal wire buffer.
175 * @return true and the Block if parsing succeeds; otherwise false
Junxiao Shi02a4bf32015-02-21 21:07:46 -0700176 */
177 static std::tuple<bool, Block>
Junxiao Shidb7464d2017-07-13 03:11:17 +0000178 fromBuffer(const uint8_t* buf, size_t bufSize);
Junxiao Shi02a4bf32015-02-21 21:07:46 -0700179
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700180public: // wire format
181 /** @brief Check if the Block is empty
Junxiao Shidb7464d2017-07-13 03:11:17 +0000182 *
183 * A Block is "empty" only if it is default-constructed. A Block with zero-length TLV-VALUE is
184 * not considered empty.
Alexander Afanasyev196b9aa2014-01-31 17:19:16 -0800185 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700186 bool
Junxiao Shidb7464d2017-07-13 03:11:17 +0000187 empty() const
188 {
189 return m_type == std::numeric_limits<uint32_t>::max();
190 }
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700191
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700192 /** @brief Check if the Block has fully encoded wire
Junxiao Shidb7464d2017-07-13 03:11:17 +0000193 *
194 * A Block has fully encoded wire if the underlying buffer exists and contains full
195 * Type-Length-Value instead of just TLV-VALUE field.
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800196 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700197 bool
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800198 hasWire() const;
199
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700200 /** @brief Reset wire buffer of the element
Junxiao Shidb7464d2017-07-13 03:11:17 +0000201 * @post empty() == true
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800202 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700203 void
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800204 reset();
205
Junxiao Shidb7464d2017-07-13 03:11:17 +0000206 /** @brief Reset wire buffer but keep TLV-TYPE and sub elements (if any)
207 * @post hasWire() == false
208 * @post hasValue() == false
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800209 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700210 void
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800211 resetWire();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800212
Junxiao Shidb7464d2017-07-13 03:11:17 +0000213 /** @brief Get begin iterator of encoded wire
214 * @pre hasWire() == true
215 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700216 Buffer::const_iterator
217 begin() const;
218
Junxiao Shidb7464d2017-07-13 03:11:17 +0000219 /** @brief Get end iterator of encoded wire
220 * @pre hasWire() == true
221 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700222 Buffer::const_iterator
223 end() const;
224
Junxiao Shidb7464d2017-07-13 03:11:17 +0000225 /** @brief Get pointer to encoded wire
226 * @pre hasWire() == true
227 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700228 const uint8_t*
229 wire() const;
230
Junxiao Shidb7464d2017-07-13 03:11:17 +0000231 /** @brief Get size of encoded wire, including Type-Length-Value
232 * @pre empty() == false
233 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700234 size_t
235 size() const;
236
Junxiao Shidb7464d2017-07-13 03:11:17 +0000237 /** @brief Get underlying buffer
238 */
239 shared_ptr<const Buffer>
240 getBuffer() const
241 {
242 return m_buffer;
243 }
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700244
Junxiao Shidb7464d2017-07-13 03:11:17 +0000245public: // type and value
246 /** @brief Get TLV-TYPE
247 */
248 uint32_t
249 type() const
250 {
251 return m_type;
252 }
253
254 /** @brief Get begin iterator of TLV-VALUE
255 *
256 * This property reflects whether the underlying buffer contains TLV-VALUE. If this is false,
257 * TLV-VALUE has zero-length. If this is true, TLV-VALUE may be zero-length.
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700258 */
259 bool
Junxiao Shidb7464d2017-07-13 03:11:17 +0000260 hasValue() const
261 {
262 return m_buffer != nullptr;
263 }
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700264
Junxiao Shidb7464d2017-07-13 03:11:17 +0000265 /** @brief Get begin iterator of TLV-VALUE
266 * @pre hasValue() == true
267 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700268 Buffer::const_iterator
Junxiao Shidb7464d2017-07-13 03:11:17 +0000269 value_begin() const
270 {
271 return m_valueBegin;
272 }
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700273
Junxiao Shidb7464d2017-07-13 03:11:17 +0000274 /** @brief Get end iterator of TLV-VALUE
275 * @pre hasValue() == true
276 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700277 Buffer::const_iterator
Junxiao Shidb7464d2017-07-13 03:11:17 +0000278 value_end() const
279 {
280 return m_valueEnd;
281 }
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700282
Junxiao Shidb7464d2017-07-13 03:11:17 +0000283 /** @brief Get pointer to TLV-VALUE
284 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700285 const uint8_t*
286 value() const;
287
Junxiao Shidb7464d2017-07-13 03:11:17 +0000288 /** @brief Get size of TLV-VALUE aka TLV-LENGTH
289 */
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700290 size_t
291 value_size() const;
292
Yingdi Yu4270f202014-01-28 14:19:16 -0800293 Block
294 blockFromValue() const;
295
Junxiao Shidb7464d2017-07-13 03:11:17 +0000296public: // sub elements
297 /** @brief Parse TLV-VALUE into sub elements
298 * @post elements() reflects sub elements found in TLV-VALUE
299 * @throw tlv::Error TLV-VALUE is not a sequence of TLV elements
300 * @note This method does not perform recursive parsing.
301 * @note This method has no effect if elements() is already populated.
302 * @note This method is not really const, but it does not modify any data.
Alexander Afanasyev74633892015-02-08 18:08:46 -0800303 */
Junxiao Shidb7464d2017-07-13 03:11:17 +0000304 void
305 parse() const;
Alexander Afanasyev74633892015-02-08 18:08:46 -0800306
Junxiao Shidb7464d2017-07-13 03:11:17 +0000307 /** @brief Encode sub elements into TLV-VALUE
308 * @post TLV-VALUE contains sub elements from elements()
309 */
310 void
311 encode();
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700312
Junxiao Shidb7464d2017-07-13 03:11:17 +0000313 /** @brief Get the first sub element of specified TLV-TYPE
314 * @pre parse() has been executed
315 * @throw Error sub element of @p type does not exist
316 */
317 const Block&
318 get(uint32_t type) const;
Junxiao Shiaf8eeea2014-03-31 20:10:56 -0700319
Junxiao Shidb7464d2017-07-13 03:11:17 +0000320 /** @brief Find the first sub element of specified TLV-TYPE
321 * @pre parse() has been executed
322 * @return iterator in elements() to the found sub element, otherwise elements_end()
323 */
324 element_const_iterator
325 find(uint32_t type) const;
326
327 /** @brief Remove all sub elements of specified TLV-TYPE
328 * @pre parse() has been executed
329 * @post find(type) == elements_end()
330 */
331 void
332 remove(uint32_t type);
333
334 /** @brief Erase a sub element
335 */
336 element_iterator
337 erase(element_const_iterator position);
338
339 /** @brief Erase a range of sub elements
340 */
341 element_iterator
342 erase(element_const_iterator first, element_const_iterator last);
343
344 /** @brief Append a sub element
345 */
346 void
347 push_back(const Block& element);
348
349 /** @brief Insert a sub element
350 * @param pos position of new sub element
351 * @param element new sub element
352 * @return iterator in elements() to the new sub element
353 */
354 element_iterator
355 insert(element_const_iterator pos, const Block& element);
356
357 /** @brief Get container of sub elements
358 * @pre parse() has been executed
359 */
360 const element_container&
361 elements() const
362 {
363 return m_elements;
364 }
365
366 /** @brief Equivalent to elements().begin()
367 */
368 element_const_iterator
369 elements_begin() const
370 {
371 return m_elements.begin();
372 }
373
374 /** @brief Equivalent to elements().end()
375 */
376 element_const_iterator
377 elements_end() const
378 {
379 return m_elements.end();
380 }
381
382 /** @brief Equivalent to elements().size()
383 */
384 size_t
385 elements_size() const
386 {
387 return m_elements.size();
388 }
389
390public: // misc
391 /** @brief Implicit conversion to const_buffer
392 */
Alexander Afanasyev6a05b4b2014-07-18 17:23:00 -0700393 operator boost::asio::const_buffer() const;
394
Junxiao Shid2777fa2017-07-27 18:35:34 +0000395private:
396 /** @brief Estimate Block size as if sub elements are encoded into TLV-VALUE
397 */
398 size_t
399 encode(EncodingEstimator& estimator) const;
400
Junxiao Shi72c0c642018-04-20 15:41:09 +0000401 /** @brief Estimate TLV-LENGTH as if sub elements are encoded into TLV-VALUE
402 */
403 size_t
404 encodeValue(EncodingEstimator& estimator) const;
405
Junxiao Shid2777fa2017-07-27 18:35:34 +0000406 /** @brief Encode sub elements into TLV-VALUE and prepend Block to encoder
407 * @post TLV-VALUE contains sub elements from elements()
408 * @post internal buffer and iterators point to Encoder's buffer
409 */
410 size_t
411 encode(EncodingBuffer& encoder);
412
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800413protected:
Junxiao Shidb7464d2017-07-13 03:11:17 +0000414 /** @brief underlying buffer storing TLV-VALUE and possibly TLV-TYPE and TLV-LENGTH fields
415 *
416 * If m_buffer is nullptr, this is an empty Block with TLV-TYPE given in m_type.
417 * Otherwise,
418 * - [m_valueBegin, m_valueEnd) point to TLV-VALUE within m_buffer.
419 * - If m_begin != m_end, [m_begin,m_end) point to Type-Length-Value of this Block within m_buffer.
420 * Otherwise, m_buffer does not contain TLV-TYPE and TLV-LENGTH fields.
421 */
Alexander Afanasyev74633892015-02-08 18:08:46 -0800422 shared_ptr<const Buffer> m_buffer;
Junxiao Shidb7464d2017-07-13 03:11:17 +0000423 Buffer::const_iterator m_begin; ///< @sa m_buffer
424 Buffer::const_iterator m_end; ///< @sa m_buffer
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800425
Junxiao Shidb7464d2017-07-13 03:11:17 +0000426 Buffer::const_iterator m_valueBegin; ///< @sa m_buffer
427 Buffer::const_iterator m_valueEnd; ///< @sa m_buffer
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700428
Davide Pesavento3a3e1882018-07-17 14:49:15 -0400429 uint32_t m_type = std::numeric_limits<uint32_t>::max(); ///< TLV-TYPE
Junxiao Shidb7464d2017-07-13 03:11:17 +0000430
431 /** @brief total size including Type-Length-Value
432 *
433 * This field is valid only if empty() is false.
434 */
Davide Pesavento3a3e1882018-07-17 14:49:15 -0400435 size_t m_size = 0;
Alexander Afanasyev937aa782014-03-21 13:17:57 -0700436
Junxiao Shidb7464d2017-07-13 03:11:17 +0000437 /** @brief sub elements
438 *
439 * This field is valid only if parse() has been executed.
440 */
441 mutable element_container m_elements;
Junxiao Shi72c0c642018-04-20 15:41:09 +0000442
443 /** @brief Print @p block to @p os.
444 *
445 * Default-constructed block is printed as: `[invalid]`.
446 * Zero-length block is printed as: `TT[empty]`, where TT is TLV-TYPE in decimal.
447 * Non-zero-length block on which @c Block::parse is not called is printed as: `TT[LL]=VVVV`,
448 * where LL is TLV-LENGTH in decimal, and VVVV is TLV-VALUE is hexadecimal.
449 * Block on which @c Block::parse has been called in printed as: `TT[LL]={SUB,SUB}`,
450 * where SUB is a sub-element printed using this format.
451 */
452 friend std::ostream&
453 operator<<(std::ostream& os, const Block& block);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800454};
455
Davide Pesavento3a3e1882018-07-17 14:49:15 -0400456inline
457Block::Block(Block&&) noexcept = default;
458
459inline Block&
460Block::operator=(Block&&) noexcept = default;
461
Junxiao Shidb7464d2017-07-13 03:11:17 +0000462/** @brief Compare whether two Blocks have same TLV-TYPE, TLV-LENGTH, and TLV-VALUE
463 */
464bool
465operator==(const Block& lhs, const Block& rhs);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800466
Junxiao Shidb7464d2017-07-13 03:11:17 +0000467inline bool
468operator!=(const Block& lhs, const Block& rhs)
Alexander Afanasyev74633892015-02-08 18:08:46 -0800469{
Junxiao Shidb7464d2017-07-13 03:11:17 +0000470 return !(lhs == rhs);
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800471}
472
Junxiao Shi2b322eb2018-08-24 10:43:27 -0600473/** \brief Construct a \c Block from hexadecimal \p input.
474 * \param input a string containing hexadecimal bytes and comments.
475 * 0-9 and upper-case A-F are input; all other characters are comments.
476 * \param len length of \p input.
477 * \throw std::invalid_argument input is empty or has odd number of hexadecimal digits.
478 * \throw tlv::Error input cannot be parsed into valid \c Block.
479 *
480 * Example
481 * \code
482 * Block nameBlock = "0706 080141 080142"_block;
483 * Block nackBlock = "FD032005 reason(no-route)=FD03210196"_block;
484 * \endcode
485 */
486Block
487operator "" _block(const char* input, std::size_t len);
488
Junxiao Shi81a6c5d2014-11-30 00:14:42 -0700489} // namespace ndn
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800490
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -0700491#endif // NDN_ENCODING_BLOCK_HPP