All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
name.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
10 #ifndef NDN_NAME_HPP
11 #define NDN_NAME_HPP
12 
13 #include "common.hpp"
14 #include "name-component.hpp"
15 
16 #include "encoding/block.hpp"
18 
19 #include <boost/iterator/reverse_iterator.hpp>
20 
21 namespace ndn {
22 
26 class Name : public ptr_lib::enable_shared_from_this<Name>
27 {
28 public:
31  {
32  public:
33  explicit
34  Error(const std::string& what)
35  : name::Component::Error(what)
36  {
37  }
38  };
39 
41 
42  typedef std::vector<Component> component_container;
43 
45  typedef void allocator_type;
46  typedef Component& reference;
47  typedef const Component const_reference;
48  typedef Component* pointer;
49  typedef const Component* const_pointer;
50  typedef Component* iterator;
51  typedef const Component* const_iterator;
52 
53  typedef boost::reverse_iterator<iterator> reverse_iterator;
54  typedef boost::reverse_iterator<const_iterator> const_reverse_iterator;
55 
56  typedef component_container::difference_type difference_type;
57  typedef component_container::size_type size_type;
58 
62  Name()
63  : m_nameBlock(Tlv::Name)
64  {
65  }
66 
76  explicit
77  Name(const Block& wire)
78  {
79  m_nameBlock = wire;
80  m_nameBlock.parse();
81  }
82 
87  Name(const char* uri)
88  {
89  set(uri);
90  }
91 
96  Name(const std::string& uri)
97  {
98  set(uri.c_str());
99  }
100 
104  template<bool T>
105  size_t
106  wireEncode(EncodingImpl<T>& block) const;
107 
108  const Block&
109  wireEncode() const;
110 
111  void
112  wireDecode(const Block& wire);
113 
117  bool
118  hasWire() const;
119 
124  void
125  set(const char* uri);
126 
131  void
132  set(const std::string& uri)
133  {
134  set(uri.c_str());
135  }
136 
141  Name&
142  append(const uint8_t* value, size_t valueLength)
143  {
144  m_nameBlock.push_back(Component(value, valueLength));
145  return *this;
146  }
147 
152  template<class InputIterator>
153  Name&
154  append(InputIterator begin, InputIterator end)
155  {
156  m_nameBlock.push_back(Component(begin, end));
157  return *this;
158  }
159 
160  Name&
161  append(const ConstBufferPtr& value)
162  {
163  m_nameBlock.push_back(value);
164  return *this;
165  }
166 
167  Name&
168  append(const Component& value)
169  {
170  m_nameBlock.push_back(value);
171  return *this;
172  }
173 
181  Name&
182  append(const char* value)
183  {
184  m_nameBlock.push_back(Component(value));
185  return *this;
186  }
187 
188  Name&
189  append(const Block& value)
190  {
191  if (value.type() == Tlv::NameComponent)
192  m_nameBlock.push_back(value);
193  else
194  m_nameBlock.push_back(Block(Tlv::NameComponent, value));
195 
196  return *this;
197  }
198 
204  Name&
205  append(const Name& name);
206 
210  void
212  {
213  m_nameBlock = Block(Tlv::Name);
214  }
215 
222  Name
223  getSubName(size_t iStartComponent, size_t nComponents) const;
224 
230  Name
231  getSubName(size_t iStartComponent) const;
232 
239  Name
240  getPrefix(int nComponents) const
241  {
242  if (nComponents < 0)
243  return getSubName(0, m_nameBlock.elements_size() + nComponents);
244  else
245  return getSubName(0, nComponents);
246  }
247 
252  std::string
253  toUri() const;
254 
263  Name&
264  appendNumber(uint64_t number)
265  {
266  m_nameBlock.push_back(Component::fromNumber(number));
267  return *this;
268  }
269 
273  Name&
274  appendVersion(uint64_t number)
275  {
276  return appendNumber(number);
277  }
278 
283  Name&
284  appendVersion();
285 
289  Name&
290  appendSegment(uint64_t number)
291  {
292  return appendNumber(number);
293  }
294 
300  bool
301  equals(const Name& name) const;
302 
308  bool
309  isPrefixOf(const Name& name) const;
310 
311  //
312  // vector equivalent interface.
313  //
314 
318  bool
319  empty() const
320  {
321  return m_nameBlock.elements().empty();
322  }
323 
328  size_t
329  size() const
330  {
331  return m_nameBlock.elements_size();
332  }
333 
339  const Component&
340  get(ssize_t i) const
341  {
342  if (i >= 0)
343  return reinterpret_cast<const Component&>(m_nameBlock.elements()[i]);
344  else
345  return reinterpret_cast<const Component&>(m_nameBlock.elements()[size() + i]);
346  }
347 
348  const Component&
349  operator[](ssize_t i) const
350  {
351  return get(i);
352  }
353 
362  const Component&
363  at(ssize_t i) const
364  {
365  if ((i >= 0 && static_cast<size_t>(i) >= size()) ||
366  (i < 0 && static_cast<size_t>(-i) > size()))
367  throw Error("Requested component does not exist (out of bounds)");
368 
369  return get(i);
370  }
371 
389  int
390  compare(const Name& other) const;
391 
396  template<class T> void
397  push_back(const T& component)
398  {
399  append(component);
400  }
401 
407  bool
408  operator==(const Name& name) const
409  {
410  return equals(name);
411  }
412 
418  bool
419  operator!=(const Name& name) const
420  {
421  return !equals(name);
422  }
423 
430  bool
431  operator<=(const Name& other) const
432  {
433  return compare(other) <= 0;
434  }
435 
442  bool
443  operator<(const Name& other) const
444  {
445  return compare(other) < 0;
446  }
447 
454  bool
455  operator>=(const Name& other) const
456  {
457  return compare(other) >= 0;
458  }
459 
466  bool
467  operator>(const Name& other) const
468  {
469  return compare(other) > 0;
470  }
471 
472  //
473  // Iterator interface to name components.
474  //
475 
480  begin() const
481  {
482  return reinterpret_cast<const_iterator>(&*m_nameBlock.elements().begin());
483  }
484 
491  end() const
492  {
493  return reinterpret_cast<const_iterator>(&*m_nameBlock.elements().end());
494  }
495 
500  rbegin() const
501  {
502  return const_reverse_iterator(end());
503  }
504 
509  rend() const
510  {
511  return const_reverse_iterator(begin());
512  }
513 
514 private:
515  mutable Block m_nameBlock;
516 };
517 
518 inline std::ostream&
519 operator<<(std::ostream& os, const Name& name)
520 {
521  if (name.empty())
522  {
523  os << "/";
524  }
525  else
526  {
527  for (Name::const_iterator i = name.begin(); i != name.end(); i++) {
528  os << "/";
529  i->toEscapedString(os);
530  }
531  }
532  return os;
533 }
534 
535 inline std::string
536 Name::toUri() const
537 {
538  std::ostringstream os;
539  os << *this;
540  return os.str();
541 }
542 
543 inline std::istream&
544 operator>>(std::istream& is, Name& name)
545 {
546  std::string inputString;
547  is >> inputString;
548  name.set(inputString);
549 
550  return is;
551 }
552 
553 
554 inline void
555 Name::set(const char* uri_cstr)
556 {
557  clear();
558 
559  std::string uri = uri_cstr;
560  trim(uri);
561  if (uri.size() == 0)
562  return;
563 
564  size_t iColon = uri.find(':');
565  if (iColon != std::string::npos) {
566  // Make sure the colon came before a '/'.
567  size_t iFirstSlash = uri.find('/');
568  if (iFirstSlash == std::string::npos || iColon < iFirstSlash) {
569  // Omit the leading protocol such as ndn:
570  uri.erase(0, iColon + 1);
571  trim(uri);
572  }
573  }
574 
575  // Trim the leading slash and possibly the authority.
576  if (uri[0] == '/') {
577  if (uri.size() >= 2 && uri[1] == '/') {
578  // Strip the authority following "//".
579  size_t iAfterAuthority = uri.find('/', 2);
580  if (iAfterAuthority == std::string::npos)
581  // Unusual case: there was only an authority.
582  return;
583  else {
584  uri.erase(0, iAfterAuthority + 1);
585  trim(uri);
586  }
587  }
588  else {
589  uri.erase(0, 1);
590  trim(uri);
591  }
592  }
593 
594  size_t iComponentStart = 0;
595 
596  // Unescape the components.
597  while (iComponentStart < uri.size()) {
598  size_t iComponentEnd = uri.find("/", iComponentStart);
599  if (iComponentEnd == std::string::npos)
600  iComponentEnd = uri.size();
601 
602  Component component = Component::fromEscapedString(&uri[0], iComponentStart, iComponentEnd);
603  // Ignore illegal components. This also gets rid of a trailing '/'.
604  if (!component.empty())
605  append(Component(component));
606 
607  iComponentStart = iComponentEnd + 1;
608  }
609 }
610 
611 inline Name&
612 Name::append(const Name& name)
613 {
614  if (&name == this)
615  // Copying from this name, so need to make a copy first.
616  return append(Name(name));
617 
618  for (size_t i = 0; i < name.size(); ++i)
619  append(name.at(i));
620 
621  return *this;
622 }
623 
624 inline Name&
626 {
627  appendNumber(time::toUnixTimestamp(time::system_clock::now()).count());
628  return *this;
629 }
630 
631 inline Name
632 Name::getSubName(size_t iStartComponent, size_t nComponents) const
633 {
634  Name result;
635 
636  size_t iEnd = iStartComponent + nComponents;
637  for (size_t i = iStartComponent; i < iEnd && i < size(); ++i)
638  result.append(at(i));
639 
640  return result;
641 }
642 
643 inline Name
644 Name::getSubName(size_t iStartComponent) const
645 {
646  Name result;
647 
648  for (size_t i = iStartComponent; i < size(); ++i)
649  result.append(at(i));
650 
651  return result;
652 }
653 
654 inline bool
655 Name::equals(const Name& name) const
656 {
657  if (size() != name.size())
658  return false;
659 
660  for (size_t i = 0; i < size(); ++i) {
661  if (at(i) != name.at(i))
662  return false;
663  }
664 
665  return true;
666 }
667 
668 inline bool
669 Name::isPrefixOf(const Name& name) const
670 {
671  // This name is longer than the name we are checking it against.
672  if (size() > name.size())
673  return false;
674 
675  // Check if at least one of given components doesn't match.
676  for (size_t i = 0; i < size(); ++i) {
677  if (at(i) != name.at(i))
678  return false;
679  }
680 
681  return true;
682 }
683 
684 
685 inline int
686 Name::compare(const Name& other) const
687 {
688  for (size_t i = 0; i < size() && i < other.size(); ++i) {
689  int comparison = at(i).compare(other.at(i));
690  if (comparison == 0)
691  // The components at this index are equal, so check the next components.
692  continue;
693 
694  // Otherwise, the result is based on the components at this index.
695  return comparison;
696  }
697 
698  // The components up to min(this.size(), other.size()) are equal, so the shorter name is less.
699  if (size() < other.size())
700  return -1;
701  else if (size() > other.size())
702  return 1;
703  else
704  return 0;
705 }
706 
707 
708 
709 template<bool T>
710 inline size_t
712 {
713  size_t totalLength = 0;
714 
715  for (const_reverse_iterator i = rbegin();
716  i != rend();
717  ++i)
718  {
719  totalLength += i->wireEncode(blk);
720  }
721 
722  totalLength += blk.prependVarNumber(totalLength);
723  totalLength += blk.prependVarNumber(Tlv::Name);
724  return totalLength;
725 }
726 
727 inline const Block&
729 {
730  if (m_nameBlock.hasWire())
731  return m_nameBlock;
732 
733  EncodingEstimator estimator;
734  size_t estimatedSize = wireEncode(estimator);
735 
736  EncodingBuffer buffer(estimatedSize, 0);
737  wireEncode(buffer);
738 
739  m_nameBlock = buffer.block();
740  m_nameBlock.parse();
741 
742  return m_nameBlock;
743 }
744 
745 inline void
747 {
748  if (wire.type() != Tlv::Name)
749  throw Tlv::Error("Unexpected TLV type when decoding Name");
750 
751  m_nameBlock = wire;
752  m_nameBlock.parse();
753 }
754 
755 inline bool
757 {
758  return m_nameBlock.hasWire();
759 }
760 
761 } // namespace ndn
762 
763 #endif
static Component fromNumber(uint64_t number)
Create a component encoded as nonNegativeInteger.
void set(const std::string &uri)
Parse the uri according to the NDN URI Scheme and set the name with the components.
Definition: name.hpp:132
Name getSubName(size_t iStartComponent, size_t nComponents) const
Get a new name, constructed as a subset of components.
Definition: name.hpp:632
name::Component Component
Definition: name.hpp:40
bool operator!=(const Name &name) const
Check if this name has the same component count and components as the given name. ...
Definition: name.hpp:419
Component * pointer
Definition: name.hpp:48
const_iterator begin() const
Begin iterator (const).
Definition: name.hpp:480
Name getPrefix(int nComponents) const
Return a new Name with the first nComponents components of this Name.
Definition: name.hpp:240
int compare(const Component &other) const
Compare this to the other Component using NDN canonical ordering.
static Component fromEscapedString(const char *escapedString, size_t beginOffset, size_t endOffset)
Make a Blob value by decoding the escapedString between beginOffset and endOffset according to the ND...
Name & append(const char *value)
Append name component that represented as a string.
Definition: name.hpp:182
bool operator==(const Name &name) const
Check if this name has the same component count and components as the given name. ...
Definition: name.hpp:408
component_container::size_type size_type
Definition: name.hpp:57
const Component const_reference
Definition: name.hpp:47
Name & append(const Component &value)
Definition: name.hpp:168
Name & append(InputIterator begin, InputIterator end)
Append a new component, copying from value of length valueLength.
Definition: name.hpp:154
std::vector< Component > component_container
Definition: name.hpp:42
const element_container & elements() const
Get all subelements.
Definition: block.hpp:464
Class representing wire element of the NDN packet.
Definition: block.hpp:26
Name & appendSegment(uint64_t number)
An alias for appendNumber(uint64_t)
Definition: name.hpp:290
Name & appendNumber(uint64_t number)
Append a component with the number encoded as nonNegativeInteger.
Definition: name.hpp:264
const Component & operator[](ssize_t i) const
Definition: name.hpp:349
void set(const char *uri)
Parse the uri according to the NDN URI Scheme and set the name with the components.
Definition: name.hpp:555
Error that can be thrown from Name.
Definition: name.hpp:30
Component value_type
Definition: name.hpp:44
std::string toUri() const
Encode this name as a URI.
Definition: name.hpp:536
bool operator>=(const Name &other) const
Return true if this is less than or equal to the other Name in the NDN canonical ordering.
Definition: name.hpp:455
ptr_lib::shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:17
const Block & wireEncode() const
Definition: name.hpp:728
boost::reverse_iterator< iterator > reverse_iterator
Definition: name.hpp:53
const_iterator end() const
End iterator (const).
Definition: name.hpp:491
const Component * const_iterator
Definition: name.hpp:51
const_reverse_iterator rend() const
Reverse end iterator (const).
Definition: name.hpp:509
bool hasWire() const
Check if already has wire.
Definition: name.hpp:756
Name & append(const Block &value)
Definition: name.hpp:189
const Component * const_pointer
Definition: name.hpp:49
bool operator<=(const Name &other) const
Return true if this is less than or equal to the other Name in the NDN canonical ordering.
Definition: name.hpp:431
Component * iterator
Definition: name.hpp:50
size_t size() const
Get the number of components.
Definition: name.hpp:329
size_t elements_size() const
Definition: block.hpp:482
A Name holds an array of Name::Component and represents an NDN name.
Definition: name.hpp:26
void push_back(const Block &element)
Definition: block.hpp:390
std::istream & operator>>(std::istream &is, Name &name)
Definition: name.hpp:544
Error(const std::string &what)
Definition: name.hpp:34
void push_back(const T &component)
Append the component.
Definition: name.hpp:397
const_reverse_iterator rbegin() const
Reverse begin iterator (const).
Definition: name.hpp:500
void parse() const
Parse wire buffer into subblocks.
Definition: block.cpp:265
uint32_t type() const
Definition: block.hpp:320
Component holds a read-only name component value.
bool operator>(const Name &other) const
Return true if this is greater than the other Name in the NDN canonical ordering. ...
Definition: name.hpp:467
int compare(const Name &other) const
Compare this to the other Name using NDN canonical ordering.
Definition: name.hpp:686
milliseconds toUnixTimestamp(const system_clock::TimePoint &point)
Convert system_clock::TimePoint to UNIX timestamp.
Definition: time.hpp:107
bool operator<(const Name &other) const
Return true if this is less than the other Name in the NDN canonical ordering.
Definition: name.hpp:443
Component & reference
Definition: name.hpp:46
Name & append(const uint8_t *value, size_t valueLength)
Append a new component, copying from value of length valueLength.
Definition: name.hpp:142
bool empty() const
Check if name is emtpy.
Definition: name.hpp:319
bool hasWire() const
Check if the Block has fully encoded wire.
Definition: block.hpp:288
bool isPrefixOf(const Name &name) const
Check if the N components of this name are the same as the first N components of the given name...
Definition: name.hpp:669
void trim(std::string &str)
Modify str in place to erase whitespace on the left and right.
Name(const char *uri)
Parse the uri according to the NDN URI Scheme and create the name with the components.
Definition: name.hpp:87
component_container::difference_type difference_type
Definition: name.hpp:56
Name & appendVersion(uint64_t number)
An alias for appendNumber(uint64_t)
Definition: name.hpp:274
bool equals(const Name &name) const
Check if this name has the same component count and components as the given name. ...
Definition: name.hpp:655
std::ostream & operator<<(std::ostream &os, const Data &data)
Definition: data.hpp:523
void wireDecode(const Block &wire)
Definition: name.hpp:746
void allocator_type
Definition: name.hpp:45
boost::reverse_iterator< const_iterator > const_reverse_iterator
Definition: name.hpp:54
void clear()
Clear all the components.
Definition: name.hpp:211
const Component & at(ssize_t i) const
Get component at the specified index.
Definition: name.hpp:363
Name & appendVersion()
Append a component with the encoded version number (current UNIX timestamp in milliseconds) ...
Definition: name.hpp:625
Name()
Create a new Name with no components.
Definition: name.hpp:62
Class representing wire element of the NDN packet.
Error that can be thrown from name::Component.
Name & append(const ConstBufferPtr &value)
Definition: name.hpp:161
Name(const Block &wire)
Create Name object from wire block.
Definition: name.hpp:77
Name(const std::string &uri)
Parse the uri according to the NDN URI Scheme and create the name with the components.
Definition: name.hpp:96