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-2018 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& input) const
95  {
96  BOOST_ASSERT(false);
97  return Component();
98  }
99 
105  virtual void
106  writeUri(std::ostream& os, const Component& comp) const
107  {
108  os << comp.type() << '=';
109  writeUriEscapedValue(os, comp);
110  }
111 
112 protected:
116  std::pair<bool, Block>
117  getSuccessorImpl(const Component& comp) const
118  {
119  EncodingBuffer encoder(comp.size() + 9, 9);
120  // leave room for additional byte when TLV-VALUE overflows, and for TLV-LENGTH size increase
121 
122  bool isOverflow = true;
123  size_t i = comp.value_size();
124  for (; isOverflow && i > 0; i--) {
125  uint8_t newValue = static_cast<uint8_t>((comp.value()[i - 1] + 1) & 0xFF);
126  encoder.prependByte(newValue);
127  isOverflow = (newValue == 0);
128  }
129  encoder.prependByteArray(comp.value(), i);
130 
131  if (isOverflow) {
132  // new name component has to be extended
133  encoder.appendByte(0);
134  }
135 
136  encoder.prependVarNumber(encoder.size());
137  encoder.prependVarNumber(comp.type());
138  return {isOverflow, encoder.block()};
139  }
140 
143  void
144  writeUriEscapedValue(std::ostream& os, const Component& comp) const
145  {
146  bool isAllPeriods = std::all_of(comp.value_begin(), comp.value_end(),
147  [] (uint8_t x) { return x == '.'; });
148  if (isAllPeriods) {
149  os << "...";
150  }
151  escape(os, reinterpret_cast<const char*>(comp.value()), comp.value_size());
152  }
153 };
154 
161 {
162 public:
163  void
164  writeUri(std::ostream& os, const Component& comp) const final
165  {
166  writeUriEscapedValue(os, comp);
167  }
168 };
169 
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  if (!match(comp)) {
192  BOOST_THROW_EXCEPTION(Error(m_typeName + " TLV-LENGTH must be " +
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  BOOST_THROW_EXCEPTION(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  uint32_t m_type;
256  std::string m_typeName;
257  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 
278 class ComponentTypeTable : noncopyable
279 {
280 public:
282 
285  const ComponentType&
286  get(uint32_t type) const
287  {
288  if (type >= m_table.size() || m_table[type] == nullptr) {
289  return m_baseType;
290  }
291  return *m_table[type];
292  }
293 
296  const ComponentType*
297  findByUriPrefix(const std::string& prefix) const
298  {
299  auto it = m_uriPrefixes.find(prefix);
300  if (it == m_uriPrefixes.end()) {
301  return nullptr;
302  }
303  return it->second;
304  }
305 
306 private:
307  void
308  set(uint32_t type, const ComponentType& ct)
309  {
310  m_table.at(type) = &ct;
311  if (ct.getAltUriPrefix() != nullptr) {
312  m_uriPrefixes[ct.getAltUriPrefix()] = &ct;
313  }
314  }
315 
316 private:
317  ComponentType m_baseType;
318  std::array<const ComponentType*, 32> m_table;
319  std::unordered_map<std::string, const ComponentType*> m_uriPrefixes;
320 };
321 
322 inline
324 {
325  m_table.fill(nullptr);
326 
327  static GenericNameComponentType ct8;
328  set(tlv::GenericNameComponent, ct8);
329 
332 }
333 
336 inline const ComponentTypeTable&
338 {
339  static ComponentTypeTable ctt;
340  return ctt;
341 }
342 
343 } // namespace detail
344 } // namespace name
345 } // namespace ndn
346 
347 #endif // NDN_IMPL_NAME_COMPONENT_TYPES_HPP
Rules regarding GenericNameComponent.
Copyright (c) 2011-2015 Regents of the University of California.
const ComponentTypeTable & getComponentTypeTable()
Get the global ComponentTypeTable.
const ComponentType & get(uint32_t type) const
Retrieve ComponentType by TLV-TYPE.
static const size_t DIGEST_SIZE
Length in bytes of a SHA-256 digest.
Definition: sha256.hpp:56
Sha256ComponentType(uint32_t type, const std::string &typeName, const std::string &uriPrefix)
size_t value_size() const
Get size of TLV-VALUE aka TLV-LENGTH.
Definition: block.cpp:316
Rules regarding NameComponent types.
bool match(const Component &comp) const
Declare rules regarding a NameComponent type.
Represents a TLV element of NDN packet format.
Definition: block.hpp:42
const uint8_t * value() const
Get pointer to TLV-VALUE.
Definition: block.cpp:310
virtual void writeUri(std::ostream &os, const Component &comp) const
Write URI representation of comp to os.
const Sha256ComponentType & getComponentType1()
const Sha256ComponentType & getComponentType2()
void writeUri(std::ostream &os, const Component &comp) const final
Write URI representation of comp to os.
Rules regarding a component type holding a SHA256 digest value.
virtual Component parseAltUriValue(const std::string &input) const
Parse component from alternate URI representation.
Buffer::const_iterator value_begin() const
Get begin iterator of TLV-VALUE.
Definition: block.hpp:269
size_t size() const
Get size of encoded wire, including Type-Length-Value.
Definition: block.cpp:298
shared_ptr< Buffer > fromHex(const std::string &hexString)
Convert the hex string to buffer.
virtual std::pair< bool, Component > getSuccessor(const Component &comp) const
Calculate the successor of comp.
Component create(ConstBufferPtr value) const
Block makeBinaryBlock(uint32_t type, const uint8_t *value, size_t length)
Create a TLV block copying TLV-VALUE from raw buffer.
virtual ~ComponentType()=default
Buffer::const_iterator value_end() const
Get end iterator of TLV-VALUE.
Definition: block.hpp:278
virtual const char * getAltUriPrefix() const
Return the prefix of the alternate URI representation.
const std::vector< uint8_t > & getMinValue() const final
Return the minimum allowable TLV-VALUE of this component type.
virtual const std::vector< uint8_t > & getMinValue() const
Return the minimum allowable TLV-VALUE of this component type.
void writeUriEscapedValue(std::ostream &os, const Component &comp) const
Write TLV-VALUE as <escaped-value> of NDN URI syntax.
std::string escape(const std::string &str)
Percent-encode a string.
const ComponentType * findByUriPrefix(const std::string &prefix) const
Retrieve ComponentType by alternate URI prefix.
std::pair< bool, Component > getSuccessor(const Component &comp) const final
Calculate the successor of comp.
Represents a name component.
void check(const Component &comp) const final
Throw Component::Error if comp is invalid.
Component parseAltUriValue(const std::string &input) const final
Parse component from alternate URI representation.
void printHex(std::ostream &os, uint64_t num, bool wantUpperCase)
Output the hex representation of num to the output stream os.
void writeUri(std::ostream &os, const Component &comp) const final
Write URI representation of comp to os.
std::string to_string(const V &v)
Definition: backports.hpp:67
const char * getAltUriPrefix() const final
Return the prefix of the alternate URI representation.
virtual void check(const Component &comp) const
Throw Component::Error if comp is invalid.
Component create(const uint8_t *value, size_t valueSize) const
std::pair< bool, Block > getSuccessorImpl(const Component &comp) const
Calculate the successor of comp, extending TLV-LENGTH if value overflows.
EncodingImpl< EncoderTag > EncodingBuffer
uint32_t type() const
Get TLV-TYPE.
Definition: block.hpp:249
shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:126