NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.5: NDN, CCN, CCNx, content centric networks
API Documentation
name-component-types.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2019 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_IMPL_NAME_COMPONENT_TYPES_HPP
23 #define NDN_IMPL_NAME_COMPONENT_TYPES_HPP
24 
26 #include "ndn-cxx/util/sha256.hpp"
28 
29 #include <array>
30 #include <unordered_map>
31 
32 namespace ndn {
33 namespace name {
34 namespace detail {
35 
38 class ComponentType : noncopyable
39 {
40 public:
42 
43  virtual
44  ~ComponentType() = default;
45 
48  virtual void
49  check(const Component& comp) const
50  {
51  }
52 
58  virtual std::pair<bool, Component>
59  getSuccessor(const Component& comp) const
60  {
61  return {false, getSuccessorImpl(comp).second};
62  }
63 
66  virtual const std::vector<uint8_t>&
67  getMinValue() const
68  {
69  static std::vector<uint8_t> value;
70  return value;
71  }
72 
82  virtual const char*
84  {
85  return nullptr;
86  }
87 
93  virtual Component
94  parseAltUriValue(const std::string&) const
95  {
97  }
98 
104  virtual void
105  writeUri(std::ostream& os, const Component& comp) const
106  {
107  os << comp.type() << '=';
108  writeUriEscapedValue(os, comp);
109  }
110 
111 protected:
115  std::pair<bool, Block>
116  getSuccessorImpl(const Component& comp) const
117  {
118  EncodingBuffer encoder(comp.size() + 9, 9);
119  // leave room for additional byte when TLV-VALUE overflows, and for TLV-LENGTH size increase
120 
121  bool isOverflow = true;
122  size_t i = comp.value_size();
123  for (; isOverflow && i > 0; i--) {
124  uint8_t newValue = static_cast<uint8_t>((comp.value()[i - 1] + 1) & 0xFF);
125  encoder.prependByte(newValue);
126  isOverflow = (newValue == 0);
127  }
128  encoder.prependByteArray(comp.value(), i);
129 
130  if (isOverflow) {
131  // new name component has to be extended
132  encoder.appendByte(0);
133  }
134 
135  encoder.prependVarNumber(encoder.size());
136  encoder.prependVarNumber(comp.type());
137  return {isOverflow, encoder.block()};
138  }
139 
142  void
143  writeUriEscapedValue(std::ostream& os, const Component& comp) const
144  {
145  bool isAllPeriods = std::all_of(comp.value_begin(), comp.value_end(),
146  [] (uint8_t x) { return x == '.'; });
147  if (isAllPeriods) {
148  os << "...";
149  }
150  escape(os, reinterpret_cast<const char*>(comp.value()), comp.value_size());
151  }
152 };
153 
160 {
161 public:
162  void
163  writeUri(std::ostream& os, const Component& comp) const final
164  {
165  writeUriEscapedValue(os, comp);
166  }
167 };
168 
172 class Sha256ComponentType final : public ComponentType
173 {
174 public:
175  Sha256ComponentType(uint32_t type, const std::string& typeName, const std::string& uriPrefix)
176  : m_type(type)
177  , m_typeName(typeName)
178  , m_uriPrefix(uriPrefix)
179  {
180  }
181 
182  bool
183  match(const Component& comp) const
184  {
185  return comp.type() == m_type && comp.value_size() == util::Sha256::DIGEST_SIZE;
186  }
187 
188  void
189  check(const Component& comp) const final
190  {
191  BOOST_ASSERT(comp.type() == m_type);
192  if (comp.value_size() != util::Sha256::DIGEST_SIZE) {
193  NDN_THROW(Error(m_typeName + " TLV-LENGTH must be " + to_string(util::Sha256::DIGEST_SIZE)));
194  }
195  }
196 
197  Component
198  create(ConstBufferPtr value) const
199  {
200  return Component(Block(m_type, std::move(value)));
201  }
202 
203  Component
204  create(const uint8_t* value, size_t valueSize) const
205  {
206  return Component(makeBinaryBlock(m_type, value, valueSize));
207  }
208 
209  std::pair<bool, Component>
210  getSuccessor(const Component& comp) const final
211  {
212  bool isExtended = false;
213  Block successor;
214  std::tie(isExtended, successor) = getSuccessorImpl(comp);
215  if (isExtended) {
216  return {true, comp};
217  }
218  return {false, Component(successor)};
219  }
220 
221  const std::vector<uint8_t>&
222  getMinValue() const final
223  {
224  static std::vector<uint8_t> value(util::Sha256::DIGEST_SIZE);
225  return value;
226  }
227 
228  const char*
229  getAltUriPrefix() const final
230  {
231  return m_uriPrefix.data();
232  }
233 
234  Component
235  parseAltUriValue(const std::string& input) const final
236  {
237  shared_ptr<Buffer> value;
238  try {
239  value = fromHex(input);
240  }
241  catch (const StringHelperError&) {
242  NDN_THROW(Error("Cannot convert to " + m_typeName + " (invalid hex encoding)"));
243  }
244  return Component(m_type, std::move(value));
245  }
246 
247  void
248  writeUri(std::ostream& os, const Component& comp) const final
249  {
250  os << m_uriPrefix << '=';
251  printHex(os, comp.value(), comp.value_size(), false);
252  }
253 
254 private:
255  const uint32_t m_type;
256  const std::string m_typeName;
257  const std::string m_uriPrefix;
258 };
259 
260 inline const Sha256ComponentType&
262 {
264  "ImplicitSha256DigestComponent", "sha256digest");
265  return ct1;
266 }
267 
268 inline const Sha256ComponentType&
270 {
272  "ParametersSha256DigestComponent", "params-sha256");
273  return ct2;
274 }
275 
280 {
281 public:
282  DecimalComponentType(uint32_t type, const std::string& typeName, const std::string& uriPrefix)
283  : m_type(type)
284  , m_typeName(typeName)
285  , m_uriPrefix(uriPrefix)
286  {
287  }
288 
289  // NOTE:
290  // We do not override check() and ensure that the component value is a well-formed
291  // nonNegativeInteger, because the application may be using the same typed component
292  // with different syntax and semantics.
293 
294  const char*
295  getAltUriPrefix() const final
296  {
297  return m_uriPrefix.data();
298  }
299 
300  Component
301  parseAltUriValue(const std::string& input) const final
302  {
303  uint64_t n = 0;
304  try {
305  n = std::stoull(input);
306  }
307  catch (const std::invalid_argument&) {
308  NDN_THROW(Error("Cannot convert to " + m_typeName + " (invalid format)"));
309  }
310  catch (const std::out_of_range&) {
311  NDN_THROW(Error("Cannot convert to " + m_typeName + " (out of range)"));
312  }
313  if (to_string(n) != input) {
314  NDN_THROW(Error("Cannot convert to " + m_typeName + " (invalid format)"));
315  }
316  return Component::fromNumber(n, m_type);
317  }
318 
319  void
320  writeUri(std::ostream& os, const Component& comp) const final
321  {
322  if (comp.isNumber()) {
323  os << m_uriPrefix << '=' << comp.toNumber();
324  }
325  else {
326  ComponentType::writeUri(os, comp);
327  }
328  }
329 
330 private:
331  const uint32_t m_type;
332  const std::string m_typeName;
333  const std::string m_uriPrefix;
334 };
335 
338 class ComponentTypeTable : noncopyable
339 {
340 public:
342 
345  const ComponentType&
346  get(uint32_t type) const
347  {
348  if (type >= m_table.size() || m_table[type] == nullptr) {
349  return m_baseType;
350  }
351  return *m_table[type];
352  }
353 
356  const ComponentType*
357  findByUriPrefix(const std::string& prefix) const
358  {
359  auto it = m_uriPrefixes.find(prefix);
360  if (it == m_uriPrefixes.end()) {
361  return nullptr;
362  }
363  return it->second;
364  }
365 
366 private:
367  void
368  set(uint32_t type, const ComponentType& ct)
369  {
370  m_table.at(type) = &ct;
371  if (ct.getAltUriPrefix() != nullptr) {
372  m_uriPrefixes[ct.getAltUriPrefix()] = &ct;
373  }
374  }
375 
376 private:
377  const ComponentType m_baseType;
378  std::array<const ComponentType*, 38> m_table;
379  std::unordered_map<std::string, const ComponentType*> m_uriPrefixes;
380 };
381 
382 inline
384 {
385  m_table.fill(nullptr);
386 
389 
390  static const GenericNameComponentType ct8;
391  set(tlv::GenericNameComponent, ct8);
392 
393  static const DecimalComponentType ct33(tlv::SegmentNameComponent, "SegmentNameComponent", "seg");
394  set(tlv::SegmentNameComponent, ct33);
395  static const DecimalComponentType ct34(tlv::ByteOffsetNameComponent, "ByteOffsetNameComponent", "off");
396  set(tlv::ByteOffsetNameComponent, ct34);
397  static const DecimalComponentType ct35(tlv::VersionNameComponent, "VersionNameComponent", "v");
398  set(tlv::VersionNameComponent, ct35);
399  static const DecimalComponentType ct36(tlv::TimestampNameComponent, "TimestampNameComponent", "t");
400  set(tlv::TimestampNameComponent, ct36);
401  static const DecimalComponentType ct37(tlv::SequenceNumNameComponent, "SequenceNumNameComponent", "seq");
403 }
404 
407 inline const ComponentTypeTable&
409 {
410  static ComponentTypeTable ctt;
411  return ctt;
412 }
413 
414 } // namespace detail
415 } // namespace name
416 } // namespace ndn
417 
418 #endif // NDN_IMPL_NAME_COMPONENT_TYPES_HPP
ndn::tlv::SegmentNameComponent
@ SegmentNameComponent
Definition: tlv.hpp:119
ndn::name::Component::fromNumber
static Component fromNumber(uint64_t number, uint32_t type=tlv::GenericNameComponent)
Create a component encoded as nonNegativeInteger.
Definition: name-component.cpp:341
ndn::name::detail::Sha256ComponentType::Sha256ComponentType
Sha256ComponentType(uint32_t type, const std::string &typeName, const std::string &uriPrefix)
Definition: name-component-types.hpp:175
ndn::fromHex
shared_ptr< Buffer > fromHex(const std::string &hexString)
Convert the hex string to buffer.
Definition: string-helper.cpp:81
string-helper.hpp
nonstd::optional_lite::std11::move
T & move(T &t)
Definition: optional.hpp:421
ndn::tlv::VersionNameComponent
@ VersionNameComponent
Definition: tlv.hpp:121
ndn::Block::value_size
size_t value_size() const noexcept
Return the size of TLV-VALUE, aka TLV-LENGTH.
Definition: block.cpp:308
ndn::name::detail::GenericNameComponentType::writeUri
void writeUri(std::ostream &os, const Component &comp) const final
Write URI representation of comp to os.
Definition: name-component-types.hpp:163
ndn::tlv::TimestampNameComponent
@ TimestampNameComponent
Definition: tlv.hpp:122
ndn::tlv::ParametersSha256DigestComponent
@ ParametersSha256DigestComponent
Definition: tlv.hpp:70
ndn::name::detail::GenericNameComponentType
Rules for GenericNameComponent.
Definition: name-component-types.hpp:160
ndn::name::detail::Sha256ComponentType::getMinValue
const std::vector< uint8_t > & getMinValue() const final
Return the minimum allowable TLV-VALUE of this component type.
Definition: name-component-types.hpp:222
ndn::name::detail::ComponentType::writeUriEscapedValue
void writeUriEscapedValue(std::ostream &os, const Component &comp) const
Write TLV-VALUE as <escaped-value> of NDN URI syntax.
Definition: name-component-types.hpp:143
NDN_CXX_UNREACHABLE
#define NDN_CXX_UNREACHABLE
Definition: backports.hpp:72
ndn::name::detail::DecimalComponentType::parseAltUriValue
Component parseAltUriValue(const std::string &input) const final
Parse component from alternate URI representation.
Definition: name-component-types.hpp:301
ndn::util::Sha256::DIGEST_SIZE
static const size_t DIGEST_SIZE
Length in bytes of a SHA-256 digest.
Definition: sha256.hpp:56
ndn::name::detail::ComponentType::~ComponentType
virtual ~ComponentType()=default
ndn::name::detail::Sha256ComponentType::writeUri
void writeUri(std::ostream &os, const Component &comp) const final
Write URI representation of comp to os.
Definition: name-component-types.hpp:248
ndn::Block::value_end
Buffer::const_iterator value_end() const
Get end iterator of TLV-VALUE.
Definition: block.hpp:305
ndn::name::detail::getComponentType2
const Sha256ComponentType & getComponentType2()
Definition: name-component-types.hpp:269
ndn::name::detail::Sha256ComponentType::getSuccessor
std::pair< bool, Component > getSuccessor(const Component &comp) const final
Calculate the successor of comp.
Definition: name-component-types.hpp:210
ndn::name::detail::DecimalComponentType::DecimalComponentType
DecimalComponentType(uint32_t type, const std::string &typeName, const std::string &uriPrefix)
Definition: name-component-types.hpp:282
ndn::name::detail::ComponentType::writeUri
virtual void writeUri(std::ostream &os, const Component &comp) const
Write URI representation of comp to os.
Definition: name-component-types.hpp:105
ndn::name::detail::DecimalComponentType::getAltUriPrefix
const char * getAltUriPrefix() const final
Return the prefix of the alternate URI representation.
Definition: name-component-types.hpp:295
ndn::Block::type
uint32_t type() const
Return the TLV-TYPE of the Block.
Definition: block.hpp:274
ndn::tlv::SequenceNumNameComponent
@ SequenceNumNameComponent
Definition: tlv.hpp:123
ndn::Block::value_begin
Buffer::const_iterator value_begin() const
Get begin iterator of TLV-VALUE.
Definition: block.hpp:296
ndn::name::detail::Sha256ComponentType::create
Component create(const uint8_t *value, size_t valueSize) const
Definition: name-component-types.hpp:204
ndn::printHex
void printHex(std::ostream &os, uint64_t num, bool wantUpperCase)
Output the hex representation of num to the output stream os.
Definition: string-helper.cpp:42
NDN_THROW
#define NDN_THROW(e)
Definition: exception.hpp:61
ndn::name::detail::Sha256ComponentType::create
Component create(ConstBufferPtr value) const
Definition: name-component-types.hpp:198
ndn::name::detail::getComponentType1
const Sha256ComponentType & getComponentType1()
Definition: name-component-types.hpp:261
ndn::name::detail::ComponentType::Error
Component::Error Error
Definition: name-component-types.hpp:41
ndn::name::Component::Error
Definition: name-component.hpp:97
ndn::tlv::GenericNameComponent
@ GenericNameComponent
Definition: tlv.hpp:68
ndn::name::detail::getComponentTypeTable
const ComponentTypeTable & getComponentTypeTable()
Get the global ComponentTypeTable.
Definition: name-component-types.hpp:408
ndn::name::detail::ComponentType::getMinValue
virtual const std::vector< uint8_t > & getMinValue() const
Return the minimum allowable TLV-VALUE of this component type.
Definition: name-component-types.hpp:67
ndn::name::detail::ComponentTypeTable::findByUriPrefix
const ComponentType * findByUriPrefix(const std::string &prefix) const
Retrieve ComponentType by alternate URI prefix.
Definition: name-component-types.hpp:357
ndn::name::detail::ComponentTypeTable
Rules regarding NameComponent types.
Definition: name-component-types.hpp:339
ndn::name::detail::ComponentTypeTable::ComponentTypeTable
ComponentTypeTable()
Definition: name-component-types.hpp:383
ndn::name::detail::ComponentType::parseAltUriValue
virtual Component parseAltUriValue(const std::string &) const
Parse component from alternate URI representation.
Definition: name-component-types.hpp:94
ndn::name::detail::Sha256ComponentType::check
void check(const Component &comp) const final
Throw Component::Error if comp is invalid.
Definition: name-component-types.hpp:189
ndn::StringHelperError
Definition: string-helper.hpp:32
ndn::name::detail::ComponentType
Declare rules for a NameComponent type.
Definition: name-component-types.hpp:39
ndn::name::detail::ComponentType::getAltUriPrefix
virtual const char * getAltUriPrefix() const
Return the prefix of the alternate URI representation.
Definition: name-component-types.hpp:83
ndn::name::detail::DecimalComponentType::writeUri
void writeUri(std::ostream &os, const Component &comp) const final
Write URI representation of comp to os.
Definition: name-component-types.hpp:320
ndn::name::detail::Sha256ComponentType::getAltUriPrefix
const char * getAltUriPrefix() const final
Return the prefix of the alternate URI representation.
Definition: name-component-types.hpp:229
ndn::name::detail::Sha256ComponentType
Rules for a component type holding a SHA256 digest value, written as a hex string in URI representati...
Definition: name-component-types.hpp:173
ndn::Block::value
const uint8_t * value() const noexcept
Return a raw pointer to the beginning of TLV-VALUE.
Definition: block.cpp:302
ndn::name::Component
Represents a name component.
Definition: name-component.hpp:94
ndn::Block
Represents a TLV element of NDN packet format.
Definition: block.hpp:43
ndn::Block::size
size_t size() const
Return the size of the encoded wire, i.e.
Definition: block.cpp:290
ndn::to_string
std::string to_string(const T &val)
Definition: backports.hpp:102
ndn::name::detail::ComponentTypeTable::get
const ComponentType & get(uint32_t type) const
Retrieve ComponentType by TLV-TYPE.
Definition: name-component-types.hpp:346
ndn::name
Definition: name-component-types.hpp:33
ndn::escape
std::string escape(const std::string &str)
Percent-encode a string.
Definition: string-helper.cpp:97
ndn::name::detail::ComponentType::getSuccessor
virtual std::pair< bool, Component > getSuccessor(const Component &comp) const
Calculate the successor of comp.
Definition: name-component-types.hpp:59
ndn::name::detail::ComponentType::getSuccessorImpl
std::pair< bool, Block > getSuccessorImpl(const Component &comp) const
Calculate the successor of comp, extending TLV-LENGTH if value overflows.
Definition: name-component-types.hpp:116
ndn::tlv::ByteOffsetNameComponent
@ ByteOffsetNameComponent
Definition: tlv.hpp:120
name-component.hpp
ndn::encoding::makeBinaryBlock
Block makeBinaryBlock(uint32_t type, const uint8_t *value, size_t length)
Create a TLV block copying TLV-VALUE from raw buffer.
Definition: block-helpers.cpp:181
ndn::ConstBufferPtr
shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:126
ndn::name::detail::DecimalComponentType
Rules for a component type holding a nonNegativeInteger value, written as a decimal number in URI rep...
Definition: name-component-types.hpp:280
ndn
Copyright (c) 2011-2015 Regents of the University of California.
Definition: ndn-strategy-choice-helper.hpp:34
ndn::tlv::ImplicitSha256DigestComponent
@ ImplicitSha256DigestComponent
Definition: tlv.hpp:69
ndn::encoding::EncodingBuffer
EncodingImpl< EncoderTag > EncodingBuffer
Definition: encoding-buffer-fwd.hpp:38
ndn::name::detail::Sha256ComponentType::match
bool match(const Component &comp) const
Definition: name-component-types.hpp:183
ndn::name::detail::ComponentType::check
virtual void check(const Component &comp) const
Throw Component::Error if comp is invalid.
Definition: name-component-types.hpp:49
ndn::name::detail::Sha256ComponentType::parseAltUriValue
Component parseAltUriValue(const std::string &input) const final
Parse component from alternate URI representation.
Definition: name-component-types.hpp:235
sha256.hpp