NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.0: NDN, CCN, CCNx, content centric networks
API Documentation
name.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
26 #include "name.hpp"
27 
28 #include "util/time.hpp"
29 #include "util/string-helper.hpp"
30 #include "encoding/block.hpp"
32 
33 #include <boost/functional/hash.hpp>
34 
35 namespace ndn {
36 
37 BOOST_CONCEPT_ASSERT((boost::EqualityComparable<Name>));
38 BOOST_CONCEPT_ASSERT((WireEncodable<Name>));
39 BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<Name>));
40 BOOST_CONCEPT_ASSERT((WireDecodable<Name>));
41 static_assert(std::is_base_of<tlv::Error, Name::Error>::value,
42  "Name::Error must inherit from tlv::Error");
43 
44 const size_t Name::npos = std::numeric_limits<size_t>::max();
45 
47  : m_nameBlock(tlv::Name)
48 {
49 }
50 
51 Name::Name(const Block& wire)
52 {
53  m_nameBlock = wire;
54  m_nameBlock.parse();
55 }
56 
57 Name::Name(const char* uri)
58 {
59  construct(uri);
60 }
61 
62 Name::Name(const std::string& uri)
63 {
64  construct(uri.c_str());
65 }
66 
67 template<encoding::Tag TAG>
68 size_t
69 Name::wireEncode(EncodingImpl<TAG>& encoder) const
70 {
71  size_t totalLength = 0;
72 
73  for (const_reverse_iterator i = rbegin(); i != rend(); ++i)
74  {
75  totalLength += i->wireEncode(encoder);
76  }
77 
78  totalLength += encoder.prependVarNumber(totalLength);
79  totalLength += encoder.prependVarNumber(tlv::Name);
80  return totalLength;
81 }
82 
83 template size_t
84 Name::wireEncode<encoding::EncoderTag>(EncodingImpl<encoding::EncoderTag>& encoder) const;
85 
86 template size_t
87 Name::wireEncode<encoding::EstimatorTag>(EncodingImpl<encoding::EstimatorTag>& encoder) const;
88 
89 const Block&
91 {
92  if (m_nameBlock.hasWire())
93  return m_nameBlock;
94 
95  EncodingEstimator estimator;
96  size_t estimatedSize = wireEncode(estimator);
97 
98  EncodingBuffer buffer(estimatedSize, 0);
99  wireEncode(buffer);
100 
101  m_nameBlock = buffer.block();
102  m_nameBlock.parse();
103 
104  return m_nameBlock;
105 }
106 
107 void
109 {
110  if (wire.type() != tlv::Name)
111  BOOST_THROW_EXCEPTION(tlv::Error("Unexpected TLV type when decoding Name"));
112 
113  m_nameBlock = wire;
114  m_nameBlock.parse();
115 }
116 
117 void
118 Name::construct(const char* uriOrig)
119 {
120  clear();
121 
122  std::string uri = uriOrig;
123  trim(uri);
124  if (uri.size() == 0)
125  return;
126 
127  size_t iColon = uri.find(':');
128  if (iColon != std::string::npos) {
129  // Make sure the colon came before a '/'.
130  size_t iFirstSlash = uri.find('/');
131  if (iFirstSlash == std::string::npos || iColon < iFirstSlash) {
132  // Omit the leading protocol such as ndn:
133  uri.erase(0, iColon + 1);
134  trim(uri);
135  }
136  }
137 
138  // Trim the leading slash and possibly the authority.
139  if (uri[0] == '/') {
140  if (uri.size() >= 2 && uri[1] == '/') {
141  // Strip the authority following "//".
142  size_t iAfterAuthority = uri.find('/', 2);
143  if (iAfterAuthority == std::string::npos)
144  // Unusual case: there was only an authority.
145  return;
146  else {
147  uri.erase(0, iAfterAuthority + 1);
148  trim(uri);
149  }
150  }
151  else {
152  uri.erase(0, 1);
153  trim(uri);
154  }
155  }
156 
157  size_t iComponentStart = 0;
158 
159  // Unescape the components.
160  while (iComponentStart < uri.size()) {
161  size_t iComponentEnd = uri.find("/", iComponentStart);
162  if (iComponentEnd == std::string::npos)
163  iComponentEnd = uri.size();
164 
165  append(Component::fromEscapedString(&uri[0], iComponentStart, iComponentEnd));
166  iComponentStart = iComponentEnd + 1;
167  }
168 }
169 
170 void
171 Name::set(const char* uri)
172 {
173  *this = std::move(Name(uri));
174 }
175 
176 void
177 Name::set(const std::string& uri)
178 {
179  *this = std::move(Name(uri));
180 }
181 
182 std::string
183 Name::toUri() const
184 {
185  std::ostringstream os;
186  os << *this;
187  return os.str();
188 }
189 
190 Name&
192 {
193  if (&name == this)
194  // Copying from this name, so need to make a copy first.
195  return append(PartialName(name));
196 
197  for (size_t i = 0; i < name.size(); ++i)
198  append(name.at(i));
199 
200  return *this;
201 }
202 
203 Name&
204 Name::appendNumber(uint64_t number)
205 {
206  m_nameBlock.push_back(Component::fromNumber(number));
207  return *this;
208 }
209 
210 Name&
211 Name::appendNumberWithMarker(uint8_t marker, uint64_t number)
212 {
213  m_nameBlock.push_back(Component::fromNumberWithMarker(marker, number));
214  return *this;
215 }
216 
217 Name&
218 Name::appendVersion(uint64_t version)
219 {
220  m_nameBlock.push_back(Component::fromVersion(version));
221  return *this;
222 }
223 
224 Name&
226 {
228  return *this;
229 }
230 
231 Name&
232 Name::appendSegment(uint64_t segmentNo)
233 {
234  m_nameBlock.push_back(Component::fromSegment(segmentNo));
235  return *this;
236 }
237 
238 Name&
240 {
241  m_nameBlock.push_back(Component::fromSegmentOffset(offset));
242  return *this;
243 }
244 
245 Name&
247 {
248  m_nameBlock.push_back(Component::fromTimestamp(timePoint));
249  return *this;
250 }
251 
252 Name&
254 {
255  m_nameBlock.push_back(Component::fromSequenceNumber(seqNo));
256  return *this;
257 }
258 
259 Name&
261 {
262  m_nameBlock.push_back(Component::fromImplicitSha256Digest(digest));
263  return *this;
264 }
265 
266 Name&
267 Name::appendImplicitSha256Digest(const uint8_t* digest, size_t digestSize)
268 {
269  m_nameBlock.push_back(Component::fromImplicitSha256Digest(digest, digestSize));
270  return *this;
271 }
272 
274 Name::getSubName(ssize_t iStartComponent, size_t nComponents) const
275 {
276  PartialName result;
277 
278  ssize_t iStart = iStartComponent < 0 ? this->size() + iStartComponent : iStartComponent;
279  size_t iEnd = this->size();
280 
281  iStart = std::max(iStart, static_cast<ssize_t>(0));
282 
283  if (nComponents != npos)
284  iEnd = std::min(this->size(), iStart + nComponents);
285 
286  for (size_t i = iStart; i < iEnd; ++i)
287  result.append(at(i));
288 
289  return result;
290 }
291 
292 Name
294 {
295  if (empty()) {
296  static uint8_t firstValue[] = { 0 };
297  Name firstName;
298  firstName.append(firstValue, 1);
299  return firstName;
300  }
301 
302  return getPrefix(-1).append(get(-1).getSuccessor());
303 }
304 
305 bool
306 Name::equals(const Name& name) const
307 {
308  if (size() != name.size())
309  return false;
310 
311  for (size_t i = 0; i < size(); ++i) {
312  if (at(i) != name.at(i))
313  return false;
314  }
315 
316  return true;
317 }
318 
319 bool
321 {
322  // This name is longer than the name we are checking against.
323  if (size() > name.size())
324  return false;
325 
326  // Check if at least one of given components doesn't match.
327  for (size_t i = 0; i < size(); ++i) {
328  if (at(i) != name.at(i))
329  return false;
330  }
331 
332  return true;
333 }
334 
335 int
336 Name::compare(size_t pos1, size_t count1, const Name& other, size_t pos2, size_t count2) const
337 {
338  count1 = std::min(count1, this->size() - pos1);
339  count2 = std::min(count2, other.size() - pos2);
340  size_t count = std::min(count1, count2);
341 
342  for (size_t i = 0; i < count; ++i) {
343  int comp = this->at(pos1 + i).compare(other.at(pos2 + i));
344  if (comp != 0) { // i-th component differs
345  return comp;
346  }
347  }
348  // [pos1, pos1+count) of this Name equals [pos2, pos2+count) of other Name
349  return count1 - count2;
350 }
351 
352 std::ostream&
353 operator<<(std::ostream& os, const Name& name)
354 {
355  if (name.empty())
356  {
357  os << "/";
358  }
359  else
360  {
361  for (Name::const_iterator i = name.begin(); i != name.end(); i++) {
362  os << "/";
363  i->toUri(os);
364  }
365  }
366  return os;
367 }
368 
369 std::istream&
370 operator>>(std::istream& is, Name& name)
371 {
372  std::string inputString;
373  is >> inputString;
374  name = std::move(Name(inputString));
375 
376  return is;
377 }
378 
379 } // namespace ndn
380 
381 namespace std {
382 size_t
383 hash<ndn::Name>::operator()(const ndn::Name& name) const
384 {
385  return boost::hash_range(name.wireEncode().wire(),
386  name.wireEncode().wire() + name.wireEncode().size());
387 }
388 
389 } // namespace std
static Component fromNumber(uint64_t number)
Create a component encoded as nonNegativeInteger.
static Component fromSequenceNumber(uint64_t seqNo)
Create sequence number component using NDN naming conventions.
Copyright (c) 2011-2015 Regents of the University of California.
const_iterator begin() const
Begin iterator (const).
Definition: name.hpp:576
static Component fromNumberWithMarker(uint8_t marker, uint64_t number)
Create a component encoded as NameComponentWithMarker.
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)
Create name::Component by decoding the escapedString between beginOffset and endOffset according to t...
Name & appendNumber(uint64_t number)
Append a component with the number encoded as nonNegativeInteger.
Definition: name.cpp:204
Name getSuccessor() const
Get the successor of a name.
Definition: name.cpp:293
EncodingImpl< EstimatorTag > EncodingEstimator
std::ostream & operator<<(std::ostream &os, const Data &data)
Definition: data.cpp:340
static Component fromTimestamp(const time::system_clock::TimePoint &timePoint)
Create sequence number component using NDN naming conventions.
static const size_t npos
indicates "until the end" in getSubName and compare
Definition: name.hpp:617
STL namespace.
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
Definition: name.cpp:69
Class representing a wire element of NDN-TLV packet format.
Definition: block.hpp:43
static time_point now() noexcept
Definition: time.cpp:45
static Component fromSegmentOffset(uint64_t offset)
Create segment offset component using NDN naming conventions.
Name & appendSequenceNumber(uint64_t seqNo)
Append sequence number using NDN naming conventions.
Definition: name.cpp:253
static Component fromSegment(uint64_t segmentNo)
Create segment number component using NDN naming conventions.
std::string toUri() const
Encode this name as a URI.
Definition: name.cpp:183
a concept check for TLV abstraction with .wireEncode method
Definition: concepts.hpp:50
const Block & wireEncode() const
Definition: name.cpp:90
Name & appendSegmentOffset(uint64_t offset)
Append segment byte offset using NDN naming conventions.
Definition: name.cpp:239
EncodingImpl< EncoderTag > EncodingBuffer
const_iterator end() const
End iterator (const).
Definition: name.hpp:587
const_reverse_iterator rend() const
Reverse end iterator (const).
Definition: name.hpp:605
Name & appendSegment(uint64_t segmentNo)
Append segment number (sequential) using NDN naming conventions.
Definition: name.cpp:232
size_t size() const
Get the number of components.
Definition: name.hpp:408
Name & appendTimestamp(const time::system_clock::TimePoint &timePoint=time::system_clock::now())
Append timestamp using NDN naming conventions.
Definition: name.cpp:246
std::istream & operator>>(std::istream &is, Name &name)
Definition: name.cpp:370
Name abstraction to represent an absolute name.
Definition: name.hpp:46
void push_back(const Block &element)
Definition: block.cpp:568
const_reverse_iterator rbegin() const
Reverse begin iterator (const).
Definition: name.hpp:596
void parse() const
Parse wire buffer into subblocks.
Definition: block.cpp:322
uint32_t type() const
Definition: block.hpp:346
time_point TimePoint
Definition: time.hpp:78
Component holds a read-only name component value.
static Component fromImplicitSha256Digest(const ConstBufferPtr &digest)
Create ImplicitSha256DigestComponent component.
int compare(const Name &other) const
Compare this to the other Name using NDN canonical ordering.
Definition: name.hpp:474
milliseconds toUnixTimestamp(const system_clock::TimePoint &point)
Convert system_clock::TimePoint to UNIX timestamp.
Definition: time.cpp:118
Name & appendNumberWithMarker(uint8_t marker, uint64_t number)
Create a component encoded as NameComponentWithMarker.
Definition: name.cpp:211
Name & append(const uint8_t *value, size_t valueLength)
Append a new component, copying from value of length valueLength.
Definition: name.hpp:148
bool empty() const
Check if name is emtpy.
Definition: name.hpp:398
bool hasWire() const
Check if the Block has fully encoded wire.
Definition: block.cpp:471
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.cpp:320
void trim(std::string &str)
Modify str in place to erase whitespace on the left and right.
PartialName getSubName(ssize_t iStartComponent, size_t nComponents=npos) const
Extract a sub-name (PartialName) of nComponents components starting from iStartComponent.
Definition: name.cpp:274
PartialName getPrefix(ssize_t nComponents) const
Extract a prefix (PartialName) of the name, containing first nComponents components.
Definition: name.hpp:249
Name PartialName
Partial name abstraction to represent an arbitrary sequence of name components.
Definition: name.hpp:36
static Component fromVersion(uint64_t version)
Create version component using NDN naming conventions.
bool equals(const Name &name) const
Check if this name has the same component count and components as the given name. ...
Definition: name.cpp:306
shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:33
void wireDecode(const Block &wire)
Definition: name.cpp:108
a concept check for TLV abstraction with .wireEncode method
Definition: concepts.hpp:34
a concept check for TLV abstraction with .wireDecode method and constructible from Block ...
Definition: concepts.hpp:70
boost::reverse_iterator< const_iterator > const_reverse_iterator
Definition: name.hpp:76
void clear()
Clear all the components.
Definition: name.hpp:218
const Component & at(ssize_t i) const
Get component at the specified index.
Definition: name.hpp:442
Name & appendVersion()
Append version using NDN naming conventions based on current UNIX timestamp in milliseconds.
Definition: name.cpp:225
Name()
Create a new Name with no components.
Definition: name.cpp:46
represents an error in TLV encoding or decoding
Definition: tlv.hpp:50
Name & appendImplicitSha256Digest(const ConstBufferPtr &digest)
Append ImplicitSha256Digest.
Definition: name.cpp:260