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