name.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2024 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 
22 #ifndef NDN_CXX_NAME_HPP
23 #define NDN_CXX_NAME_HPP
24 
26 
27 #include <iterator>
28 #include <limits>
29 #include <optional>
30 
31 namespace ndn {
32 
33 class Name;
34 
38 using PartialName = Name;
39 
44 class Name : private boost::totally_ordered<Name>
45 {
46 public: // nested types
49 
50  // Name appears as an ordered sequence of name components
52  using allocator_type = void;
53  using reference = Component&;
54  using const_reference = const Component&;
55  using pointer = Component*;
56  using const_pointer = const Component*;
57  using iterator = const Component*; // disallow modifying via iterator
58  using const_iterator = const Component*;
59  using reverse_iterator = std::reverse_iterator<iterator>;
60  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
61  using difference_type = std::vector<Component>::difference_type;
62  using size_type = std::vector<Component>::size_type;
63 
64 public: // constructors, encoding, decoding
69  Name();
70 
83  explicit
84  Name(const Block& wire);
85 
90  explicit
91  Name(std::string_view uri);
92 
98  Name(const char* uri)
99  : Name(std::string_view(uri))
100  {
101  }
102 
108  Name(const std::string& uri)
109  : Name(std::string_view(uri))
110  {
111  }
112 
117  void
118  toUri(std::ostream& os, name::UriFormat format = name::UriFormat::DEFAULT) const;
119 
126  std::string
128 
132  bool
133  hasWire() const noexcept
134  {
135  return m_wire.hasWire();
136  }
137 
141  template<encoding::Tag TAG>
142  size_t
143  wireEncode(EncodingImpl<TAG>& encoder) const;
144 
149  const Block&
150  wireEncode() const;
151 
157  void
158  wireDecode(const Block& wire);
159 
163  Name
164  deepCopy() const;
165 
166 public: // access
170  [[nodiscard]] bool
171  empty() const noexcept
172  {
173  return m_wire.elements().empty();
174  }
175 
179  size_t
180  size() const noexcept
181  {
182  return m_wire.elements_size();
183  }
184 
191  const Component&
192  get(ssize_t i) const noexcept
193  {
194  if (i < 0) {
195  i += static_cast<ssize_t>(size());
196  }
197  return static_cast<const Component&>(m_wire.elements()[static_cast<size_t>(i)]);
198  }
199 
203  const Component&
204  operator[](ssize_t i) const noexcept
205  {
206  return get(i);
207  }
208 
216  const Component&
217  at(ssize_t i) const;
218 
232  getSubName(ssize_t iStartComponent, size_t nComponents = npos) const;
233 
241  getPrefix(ssize_t nComponents) const
242  {
243  if (nComponents < 0)
244  return getSubName(0, size() + nComponents);
245  else
246  return getSubName(0, nComponents);
247  }
248 
249 public: // iterators
253  begin() const noexcept
254  {
255  return reinterpret_cast<const_iterator>(m_wire.elements().data());
256  }
257 
261  end() const noexcept
262  {
263  return reinterpret_cast<const_iterator>(m_wire.elements().data() + m_wire.elements().size());
264  }
265 
269  rbegin() const noexcept
270  {
271  return const_reverse_iterator(end());
272  }
273 
277  rend() const noexcept
278  {
279  return const_reverse_iterator(begin());
280  }
281 
282 public: // modifiers
290  Name&
291  set(ssize_t i, const Component& component);
292 
300  Name&
301  set(ssize_t i, Component&& component);
302 
307  Name&
308  append(const Component& component)
309  {
310  m_wire.push_back(component);
311  return *this;
312  }
313 
318  Name&
319  append(Component&& component)
320  {
321  m_wire.push_back(std::move(component));
322  return *this;
323  }
324 
329  Name&
330  append(uint32_t type, span<const uint8_t> value)
331  {
332  return append(Component(type, value));
333  }
334 
339  Name&
340  append(span<const uint8_t> value)
341  {
343  }
344 
354  template<class Iterator>
355  Name&
356  append(uint32_t type, Iterator first, Iterator last)
357  {
358  return append(Component(type, first, last));
359  }
360 
369  template<class Iterator>
370  Name&
371  append(Iterator first, Iterator last)
372  {
373  return append(Component(tlv::GenericNameComponent, first, last));
374  }
375 
382  Name&
383  append(const char* str)
384  {
385  return append(Component(str));
386  }
387 
393  Name&
394  append(const PartialName& name);
395 
401  Name&
402  appendNumber(uint64_t number)
403  {
404  return append(Component::fromNumber(number));
405  }
406 
418  Name&
419  appendNumberWithMarker(uint8_t marker, uint64_t number)
420  {
421  return append(Component::fromNumberWithMarker(marker, number));
422  }
423 
430  Name&
431  appendSegment(uint64_t segmentNo)
432  {
433  return append(Component::fromSegment(segmentNo));
434  }
435 
442  Name&
443  appendByteOffset(uint64_t offset)
444  {
445  return append(Component::fromByteOffset(offset));
446  }
447 
456  Name&
457  appendVersion(const std::optional<uint64_t>& version = std::nullopt);
458 
466  Name&
467  appendTimestamp(const std::optional<time::system_clock::time_point>& timestamp = std::nullopt);
468 
475  Name&
476  appendSequenceNumber(uint64_t seqNo)
477  {
478  return append(Component::fromSequenceNumber(seqNo));
479  }
480 
485  Name&
487  {
488  return append(Component(tlv::ImplicitSha256DigestComponent, std::move(digest)));
489  }
490 
495  Name&
496  appendImplicitSha256Digest(span<const uint8_t> digestBytes)
497  {
499  }
500 
505  Name&
507  {
508  return append(Component(tlv::ParametersSha256DigestComponent, std::move(digest)));
509  }
510 
515  Name&
516  appendParametersSha256Digest(span<const uint8_t> digestBytes)
517  {
519  }
520 
525  Name&
527 
532  Name&
533  appendKeyword(span<const uint8_t> keyword)
534  {
535  return append(Component(tlv::KeywordNameComponent, keyword));
536  }
537 
542  Name&
543  appendKeyword(std::string_view keyword)
544  {
546  {reinterpret_cast<const uint8_t*>(keyword.data()), keyword.size()}));
547  }
548 
555  void
556  erase(ssize_t i);
557 
562  void
563  clear();
564 
565 public: // algorithms
590  Name
591  getSuccessor() const;
592 
601  bool
602  isPrefixOf(const Name& other) const noexcept;
603 
609  bool
610  equals(const Name& other) const noexcept;
611 
633  int
634  compare(const Name& other) const
635  {
636  return this->compare(0, npos, other);
637  }
638 
644  int
645  compare(size_t pos1, size_t count1,
646  const Name& other, size_t pos2 = 0, size_t count2 = npos) const;
647 
648 private: // non-member operators
649  // NOTE: the following "hidden friend" operators are available via
650  // argument-dependent lookup only and must be defined inline.
651  // boost::totally_ordered provides !=, <=, >=, and > operators.
652 
653  friend bool
654  operator==(const Name& lhs, const Name& rhs) noexcept
655  {
656  return lhs.equals(rhs);
657  }
658 
659  friend bool
660  operator<(const Name& lhs, const Name& rhs)
661  {
662  return lhs.compare(rhs) < 0;
663  }
664 
669  friend std::ostream&
670  operator<<(std::ostream& os, const Name& name)
671  {
672  name.toUri(os);
673  return os;
674  }
675 
676 public:
680  static constexpr size_t npos = std::numeric_limits<size_t>::max();
681 
682 private:
683  mutable Block m_wire{tlv::Name};
684 };
685 
687 
692 std::istream&
693 operator>>(std::istream& is, Name& name);
694 
695 } // namespace ndn
696 
697 namespace std {
698 
699 template<>
700 struct hash<ndn::Name>
701 {
702  size_t
703  operator()(const ndn::Name& name) const;
704 };
705 
706 } // namespace std
707 
708 #endif // NDN_CXX_NAME_HPP
Represents a TLV element of the NDN packet format.
Definition: block.hpp:45
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
bool hasWire() const noexcept
Check if the Block contains a fully encoded wire representation.
Definition: block.hpp:205
void push_back(const Block &element)
Append a sub-element.
Definition: block.cpp:456
Represents an absolute name.
Definition: name.hpp:45
bool equals(const Name &other) const noexcept
Check if this name equals another name.
Definition: name.cpp:291
friend bool operator<(const Name &lhs, const Name &rhs)
Definition: name.hpp:660
Name & appendKeyword(span< const uint8_t > keyword)
Append a keyword component.
Definition: name.hpp:533
Name(const std::string &uri)
Create name from NDN URI.
Definition: name.hpp:108
const_reverse_iterator rend() const noexcept
Reverse end iterator.
Definition: name.hpp:277
Name & appendByteOffset(uint64_t offset)
Append a byte offset component.
Definition: name.hpp:443
Name & append(span< const uint8_t > value)
Append a GenericNameComponent, copying the TLV-VALUE from value.
Definition: name.hpp:340
Name & appendParametersSha256Digest(span< const uint8_t > digestBytes)
Append a ParametersSha256Digest component.
Definition: name.hpp:516
name::Component Component
Definition: name.hpp:47
Name & set(ssize_t i, const Component &component)
Replace the component at the specified index.
Definition: name.cpp:181
Name & appendSequenceNumber(uint64_t seqNo)
Append a sequence number component.
Definition: name.hpp:476
Name & appendTimestamp(const std::optional< time::system_clock::time_point > &timestamp=std::nullopt)
Append a timestamp component.
Definition: name.cpp:211
void allocator_type
Definition: name.hpp:52
Name getSuccessor() const
Get the successor of a name.
Definition: name.cpp:264
Name & appendNumber(uint64_t number)
Append a component with a NonNegativeInteger.
Definition: name.hpp:402
Name & append(uint32_t type, Iterator first, Iterator last)
Append a NameComponent of TLV-TYPE type, copying the TLV-VALUE from a range.
Definition: name.hpp:356
PartialName getPrefix(ssize_t nComponents) const
Returns a prefix of the name.
Definition: name.hpp:241
std::reverse_iterator< iterator > reverse_iterator
Definition: name.hpp:59
Name & append(Iterator first, Iterator last)
Append a GenericNameComponent, copying the TLV-VALUE from a range.
Definition: name.hpp:371
int compare(const Name &other) const
Compare this to the other Name using NDN canonical ordering.
Definition: name.hpp:634
Name & appendSegment(uint64_t segmentNo)
Append a segment number (sequential) component.
Definition: name.hpp:431
const Component & operator[](ssize_t i) const noexcept
Equivalent to get().
Definition: name.hpp:204
Name & appendNumberWithMarker(uint8_t marker, uint64_t number)
Append a component with a marked number.
Definition: name.hpp:419
const_reverse_iterator rbegin() const noexcept
Reverse begin iterator.
Definition: name.hpp:269
Name & appendParametersSha256DigestPlaceholder()
Append a placeholder for a ParametersSha256Digest component.
Definition: name.cpp:238
Name & appendVersion(const std::optional< uint64_t > &version=std::nullopt)
Append a version component.
Definition: name.cpp:205
size_t size() const noexcept
Returns the number of components.
Definition: name.hpp:180
static constexpr size_t npos
Indicates "until the end" in getSubName() and compare().
Definition: name.hpp:680
const_iterator begin() const noexcept
Begin iterator.
Definition: name.hpp:253
friend std::ostream & operator<<(std::ostream &os, const Name &name)
Print the URI representation of a name.
Definition: name.hpp:670
Name & appendImplicitSha256Digest(ConstBufferPtr digest)
Append an ImplicitSha256Digest component.
Definition: name.hpp:486
bool hasWire() const noexcept
Check if this instance already has wire encoding.
Definition: name.hpp:133
bool empty() const noexcept
Checks if the name is empty, i.e., has no components.
Definition: name.hpp:171
std::vector< Component >::difference_type difference_type
Definition: name.hpp:61
Name & append(uint32_t type, span< const uint8_t > value)
Append a NameComponent of TLV-TYPE type, copying the TLV-VALUE from value.
Definition: name.hpp:330
void clear()
Remove all components.
Definition: name.cpp:256
Name(const char *uri)
Create name from NDN URI.
Definition: name.hpp:98
Name & appendImplicitSha256Digest(span< const uint8_t > digestBytes)
Append an ImplicitSha256Digest component.
Definition: name.hpp:496
Name & append(const Component &component)
Append a name component.
Definition: name.hpp:308
Name()
Create an empty name.
friend bool operator==(const Name &lhs, const Name &rhs) noexcept
Definition: name.hpp:654
const_iterator end() const noexcept
End iterator.
Definition: name.hpp:261
std::vector< Component >::size_type size_type
Definition: name.hpp:62
Name & appendParametersSha256Digest(ConstBufferPtr digest)
Append a ParametersSha256Digest component.
Definition: name.hpp:506
const Component & at(ssize_t i) const
Returns an immutable reference to the component at the specified index, with bounds checking.
Definition: name.cpp:146
Name deepCopy() const
Make a deep copy of the name, reallocating the underlying memory buffer.
Definition: name.cpp:135
const Block & wireEncode() const
Perform wire encoding, or return existing (cached) wire encoding.
Definition: name.cpp:107
Name & append(Component &&component)
Append a name component.
Definition: name.hpp:319
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: name.hpp:60
Name & append(const char *str)
Append a GenericNameComponent, copying the TLV-VALUE from a null-terminated string.
Definition: name.hpp:383
PartialName getSubName(ssize_t iStartComponent, size_t nComponents=npos) const
Extracts some components as a sub-name (PartialName).
Definition: name.cpp:160
Name & appendKeyword(std::string_view keyword)
Append a keyword component.
Definition: name.hpp:543
void erase(ssize_t i)
Erase the component at the specified index.
Definition: name.cpp:245
const Component * const_iterator
Definition: name.hpp:58
void toUri(std::ostream &os, name::UriFormat format=name::UriFormat::DEFAULT) const
Write URI representation of the name to the output stream.
Definition: name.cpp:324
bool isPrefixOf(const Name &other) const noexcept
Check if this name is a prefix of another name.
Definition: name.cpp:275
void wireDecode(const Block &wire)
Decode name from wire encoding.
Definition: name.cpp:125
const Component & get(ssize_t i) const noexcept
Returns an immutable reference to the component at the specified index.
Definition: name.hpp:192
Represents a name component.
static Component fromSegment(uint64_t segmentNo)
Create a segment number component using NDN naming conventions.
static Component fromNumber(uint64_t number, uint32_t type=tlv::GenericNameComponent)
Create a component encoded as NonNegativeInteger.
static Component fromSequenceNumber(uint64_t seqNo)
Create a sequence number component using NDN naming conventions.
static Component fromByteOffset(uint64_t offset)
Create a byte offset component using NDN naming conventions.
static Component fromNumberWithMarker(uint8_t marker, uint64_t number)
Create a component encoded as NameComponentWithMarker.
#define NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(ClassName)
UriFormat
Format used for the URI representation of a name.
@ DEFAULT
Use the library's default format; currently equivalent to UriFormat::ENV_OR_ALTERNATE.
@ Name
Definition: tlv.hpp:71
@ GenericNameComponent
Definition: tlv.hpp:72
@ KeywordNameComponent
Definition: tlv.hpp:75
@ ParametersSha256DigestComponent
Definition: tlv.hpp:74
@ ImplicitSha256DigestComponent
Definition: tlv.hpp:73
Definition: data.cpp:25
std::shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:140
std::istream & operator>>(std::istream &is, Name &name)
Parse URI from stream as Name.
Definition: name.cpp:346