block.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2023 Regents of the University of California.
4  *
5  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6  *
7  * 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.
20  *
21  * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
22  */
23 
24 #ifndef NDN_CXX_ENCODING_BLOCK_HPP
25 #define NDN_CXX_ENCODING_BLOCK_HPP
26 
29 #include "ndn-cxx/encoding/tlv.hpp"
30 #include "ndn-cxx/util/span.hpp"
31 
32 #include <boost/operators.hpp>
33 
34 namespace boost::asio {
35 class const_buffer;
36 } // namespace boost::asio
37 
38 namespace ndn {
39 
44 class Block : private boost::equality_comparable<Block>
45 {
46 public:
47  using value_type = Buffer::value_type;
48  using const_iterator = Buffer::const_iterator;
49  using element_container = std::vector<Block>;
50  using element_iterator = element_container::iterator;
51  using element_const_iterator = element_container::const_iterator;
52 
53  class Error : public tlv::Error
54  {
55  public:
56  using tlv::Error::Error;
57  };
58 
59 public: // construction, assignment
63  Block();
64 
67  Block(const Block&);
68 
71  Block&
72  operator=(const Block&);
73 
76  Block(Block&&) noexcept;
77 
80  Block&
81  operator=(Block&&) noexcept;
82 
89  explicit
90  Block(span<const uint8_t> buffer);
91 
96  explicit
97  Block(const EncodingBuffer& buffer);
98 
104  explicit
105  Block(const ConstBufferPtr& buffer);
106 
116  bool verifyLength = true);
117 
127  bool verifyLength = true);
128 
137  Block(ConstBufferPtr buffer, uint32_t type,
139  Buffer::const_iterator valueBegin, Buffer::const_iterator valueEnd);
140 
144  explicit
145  Block(uint32_t type);
146 
151  Block(uint32_t type, ConstBufferPtr value);
152 
157  Block(uint32_t type, const Block& value);
158 
165  [[nodiscard]] static std::tuple<bool, Block>
166  fromBuffer(ConstBufferPtr buffer, size_t offset = 0);
167 
175  [[nodiscard]] static std::tuple<bool, Block>
176  fromBuffer(span<const uint8_t> buffer);
177 
182  static Block
183  fromStream(std::istream& is);
184 
185 public: // wire format
192  bool
193  isValid() const noexcept
194  {
195  return m_type != tlv::Invalid;
196  }
197 
204  bool
205  hasWire() const noexcept
206  {
207  return m_buffer != nullptr && m_begin != m_end;
208  }
209 
215  const uint8_t*
216  data() const;
217 
223  size_t
224  size() const;
225 
231  begin() const;
232 
238  end() const;
239 
244  getBuffer() const
245  {
246  return m_buffer;
247  }
248 
257  void
258  reset() noexcept;
259 
266  void
267  resetWire() noexcept;
268 
269 public: // type and value
274  uint32_t
275  type() const noexcept
276  {
277  return m_type;
278  }
279 
288  bool
289  hasValue() const noexcept
290  {
291  return m_buffer != nullptr;
292  }
293 
298  size_t
299  value_size() const noexcept
300  {
301  return hasValue() ? static_cast<size_t>(m_valueEnd - m_valueBegin) : 0;
302  }
303 
307  span<const uint8_t>
308  value_bytes() const noexcept
309  {
310  if (hasValue())
311  return {m_valueBegin, m_valueEnd};
312  else
313  return {};
314  }
315 
320  const uint8_t*
321  value() const noexcept;
322 
328  value_begin() const noexcept
329  {
330  return m_valueBegin;
331  }
332 
338  value_end() const noexcept
339  {
340  return m_valueEnd;
341  }
342 
347  Block
348  blockFromValue() const;
349 
350 public: // sub-elements
358  void
359  parse() const;
360 
364  void
365  encode();
366 
371  const Block&
372  get(uint32_t type) const;
373 
380  find(uint32_t type) const;
381 
386  void
387  remove(uint32_t type);
388 
392  erase(element_const_iterator position);
393 
398 
402  void
403  push_back(const Block& element);
404 
408  void
409  push_back(Block&& element);
410 
417  insert(element_const_iterator pos, const Block& element);
418 
423  const element_container&
424  elements() const noexcept
425  {
426  return m_elements;
427  }
428 
433  elements_begin() const noexcept
434  {
435  return m_elements.begin();
436  }
437 
442  elements_end() const noexcept
443  {
444  return m_elements.end();
445  }
446 
450  size_t
451  elements_size() const noexcept
452  {
453  return m_elements.size();
454  }
455 
456 public: // misc
460  operator boost::asio::const_buffer() const;
461 
462 private:
466  size_t
467  encode(EncodingEstimator& estimator) const;
468 
472  size_t
473  encodeValue(EncodingEstimator& estimator) const;
474 
480  size_t
481  encode(EncodingBuffer& encoder);
482 
486  bool
487  equals(const Block& other) const noexcept;
488 
489  void
490  print(std::ostream& os) const;
491 
492 private: // non-member operators
493  // NOTE: the following "hidden friend" operators are available via
494  // argument-dependent lookup only and must be defined inline.
495  // boost::equality_comparable provides != operator.
496 
500  friend bool
501  operator==(const Block& lhs, const Block& rhs) noexcept
502  {
503  return lhs.equals(rhs);
504  }
505 
516  friend std::ostream&
517  operator<<(std::ostream& os, const Block& block)
518  {
519  block.print(os);
520  return os;
521  }
522 
523 protected:
532  shared_ptr<const Buffer> m_buffer;
533  Buffer::const_iterator m_begin;
534  Buffer::const_iterator m_end;
535 
536  Buffer::const_iterator m_valueBegin;
537  Buffer::const_iterator m_valueEnd;
538 
539  uint32_t m_type = tlv::Invalid;
540 
546  size_t m_size = 0;
547 
554 };
555 
556 inline
557 Block::Block(Block&&) noexcept = default;
558 
559 inline Block&
560 Block::operator=(Block&&) noexcept = default;
561 
562 inline namespace literals {
563 inline namespace block_literals {
564 
578 Block
579 operator ""_block(const char* input, std::size_t len);
580 
581 } // inline namespace block_literals
582 } // inline namespace literals
583 } // namespace ndn
584 
585 #endif // NDN_CXX_ENCODING_BLOCK_HPP
Represents a TLV element of the NDN packet format.
Definition: block.hpp:45
element_const_iterator elements_begin() const noexcept
Equivalent to elements().begin().
Definition: block.hpp:433
element_container::const_iterator element_const_iterator
Definition: block.hpp:51
const uint8_t * data() const
Returns a raw pointer to the beginning of the encoded wire, i.e., the whole TLV.
Definition: block.cpp:256
Buffer::const_iterator const_iterator
Definition: block.hpp:48
const_iterator value_end() const noexcept
Get end iterator of TLV-VALUE.
Definition: block.hpp:338
uint32_t m_type
TLV-TYPE.
Definition: block.hpp:539
element_const_iterator find(uint32_t type) const
Find the first sub-element of the specified TLV-TYPE.
Definition: block.cpp:425
Buffer::value_type value_type
Definition: block.hpp:47
const_iterator begin() const
Returns an iterator to the beginning of the encoded wire.
Definition: block.cpp:275
Block blockFromValue() const
Return a new Block constructed from the TLV-VALUE of this Block.
Definition: block.cpp:314
element_iterator erase(element_const_iterator position)
Erase a sub-element.
Definition: block.cpp:442
friend std::ostream & operator<<(std::ostream &os, const Block &block)
Print block to os.
Definition: block.hpp:517
size_t elements_size() const noexcept
Equivalent to elements().size().
Definition: block.hpp:451
const element_container & elements() const noexcept
Get container of sub-elements.
Definition: block.hpp:424
void remove(uint32_t type)
Remove all sub-elements of the specified TLV-TYPE.
Definition: block.cpp:432
size_t size() const
Returns the size of the encoded wire, i.e., of the whole TLV.
Definition: block.cpp:265
element_const_iterator elements_end() const noexcept
Equivalent to elements().end().
Definition: block.hpp:442
bool hasWire() const noexcept
Check if the Block contains a fully encoded wire representation.
Definition: block.hpp:205
size_t m_size
Total size including Type-Length-Value.
Definition: block.hpp:546
Buffer::const_iterator m_valueEnd
Definition: block.hpp:537
void resetWire() noexcept
Reset wire buffer but keep TLV-TYPE and sub-elements (if any).
Definition: block.cpp:299
element_container m_elements
Contains the sub-elements.
Definition: block.hpp:553
static std::tuple< bool, Block > fromBuffer(ConstBufferPtr buffer, size_t offset=0)
Try to parse Block from a wire buffer.
Definition: block.cpp:165
void push_back(const Block &element)
Append a sub-element.
Definition: block.cpp:456
Block(Block &&) noexcept
Move constructor.
Block & operator=(const Block &)
Copy assignment operator.
Buffer::const_iterator m_end
Definition: block.hpp:534
Buffer::const_iterator m_valueBegin
Definition: block.hpp:536
Block(const Block &)
Copy constructor.
ConstBufferPtr getBuffer() const
Returns the underlying buffer.
Definition: block.hpp:244
friend bool operator==(const Block &lhs, const Block &rhs) noexcept
Compare whether two Blocks have the same TLV-TYPE, TLV-LENGTH, and TLV-VALUE.
Definition: block.hpp:501
bool hasValue() const noexcept
Check if the Block has a non-empty TLV-VALUE.
Definition: block.hpp:289
bool isValid() const noexcept
Check if the Block is valid.
Definition: block.hpp:193
element_container::iterator element_iterator
Definition: block.hpp:50
void encode()
Encode sub-elements into TLV-VALUE.
Definition: block.cpp:353
span< const uint8_t > value_bytes() const noexcept
Return a read-only view of TLV-VALUE as a contiguous range of bytes.
Definition: block.hpp:308
const_iterator end() const
Returns an iterator past-the-end of the encoded wire.
Definition: block.cpp:284
uint32_t type() const noexcept
Return the TLV-TYPE of the Block.
Definition: block.hpp:275
static Block fromStream(std::istream &is)
Parse Block from an input stream.
Definition: block.cpp:222
void reset() noexcept
Reset the Block to a default-constructed state.
Definition: block.cpp:293
Buffer::const_iterator m_begin
Definition: block.hpp:533
shared_ptr< const Buffer > m_buffer
Underlying buffer storing TLV-VALUE and possibly TLV-TYPE and TLV-LENGTH fields.
Definition: block.hpp:532
std::vector< Block > element_container
Definition: block.hpp:49
void parse() const
Parse TLV-VALUE into sub-elements.
Definition: block.cpp:326
const_iterator value_begin() const noexcept
Get begin iterator of TLV-VALUE.
Definition: block.hpp:328
const Block & get(uint32_t type) const
Return the first sub-element of the specified TLV-TYPE.
Definition: block.cpp:414
size_t value_size() const noexcept
Return the size of TLV-VALUE, i.e., the TLV-LENGTH.
Definition: block.hpp:299
Block()
Create an invalid Block.
element_iterator insert(element_const_iterator pos, const Block &element)
Insert a sub-element.
Definition: block.cpp:470
const uint8_t * value() const noexcept
Return a raw pointer to the beginning of TLV-VALUE.
Definition: block.cpp:308
General-purpose automatically managed/resized buffer.
Definition: buffer.hpp:43
Represents an error in TLV encoding or decoding.
Definition: tlv.hpp:54
Error(const char *expectedType, uint32_t actualType)
Definition: tlv.cpp:28
EncodingImpl< EstimatorTag > EncodingEstimator
EncodingImpl< EncoderTag > EncodingBuffer
@ Invalid
Definition: tlv.hpp:67
Definition: data.cpp:25
std::shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:140