key-locator.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2023 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 #include "ndn-cxx/key-locator.hpp"
25 
26 #include <boost/hana/functional/overload.hpp>
27 
28 namespace ndn {
29 
30 constexpr size_t MAX_KEY_DIGEST_OCTETS_TO_SHOW = 8;
31 
32 KeyLocator::KeyLocator() = default;
33 
35 {
36  wireDecode(wire);
37 }
38 
40  : m_locator(name)
41 {
42 }
43 
44 template<encoding::Tag TAG>
45 size_t
47 {
48  // KeyLocator = KEY-LOCATOR-TYPE TLV-LENGTH (Name / KeyDigest)
49  // KeyDigest = KEY-DIGEST-TYPE TLV-LENGTH *OCTET
50 
51  size_t totalLength = 0;
52 
53  std::visit(boost::hana::overload(
54  [] (std::monostate) {}, // nothing to encode, TLV-VALUE is empty
55  [&] (const Name& name) { totalLength += name.wireEncode(encoder); },
56  [&] (const Block& digest) { totalLength += prependBlock(encoder, digest); },
57  [] (uint32_t type) { NDN_THROW(Error("Unsupported KeyLocator type " + to_string(type))); }),
58  m_locator);
59 
60  totalLength += encoder.prependVarNumber(totalLength);
61  totalLength += encoder.prependVarNumber(tlv::KeyLocator);
62  return totalLength;
63 }
64 
66 
67 const Block&
69 {
70  if (m_wire.hasWire())
71  return m_wire;
72 
73  EncodingEstimator estimator;
74  size_t estimatedSize = wireEncode(estimator);
75 
76  EncodingBuffer buffer(estimatedSize, 0);
77  wireEncode(buffer);
78 
79  m_wire = buffer.block();
80  return m_wire;
81 }
82 
83 void
85 {
86  if (wire.type() != tlv::KeyLocator)
87  NDN_THROW(Error("KeyLocator", wire.type()));
88 
89  clear();
90  m_wire = wire;
91  m_wire.parse();
92 
93  auto element = m_wire.elements_begin();
94  if (element == m_wire.elements().end()) {
95  return;
96  }
97 
98  switch (element->type()) {
99  case tlv::Name:
100  m_locator.emplace<Name>(*element);
101  break;
102  case tlv::KeyDigest:
103  m_locator.emplace<Block>(*element);
104  break;
105  default:
106  m_locator = element->type();
107  break;
108  }
109 }
110 
111 uint32_t
113 {
114  switch (m_locator.index()) {
115  case 0:
116  return tlv::Invalid;
117  case 1:
118  return tlv::Name;
119  case 2:
120  return tlv::KeyDigest;
121  case 3:
122  return std::get<uint32_t>(m_locator);
123  default:
125  }
126 }
127 
128 KeyLocator&
130 {
131  m_locator = std::monostate{};
132  m_wire.reset();
133  return *this;
134 }
135 
136 const Name&
138 {
139  try {
140  return std::get<Name>(m_locator);
141  }
142  catch (const std::bad_variant_access&) {
143  NDN_THROW(Error("KeyLocator does not contain a Name"));
144  }
145 }
146 
147 KeyLocator&
149 {
150  m_locator = name;
151  m_wire.reset();
152  return *this;
153 }
154 
155 const Block&
157 {
158  try {
159  return std::get<Block>(m_locator);
160  }
161  catch (const std::bad_variant_access&) {
162  NDN_THROW(Error("KeyLocator does not contain a KeyDigest"));
163  }
164 }
165 
166 KeyLocator&
168 {
169  if (keyDigest.type() != tlv::KeyDigest) {
170  NDN_THROW(std::invalid_argument("Invalid KeyDigest block of type " + to_string(keyDigest.type())));
171  }
172  m_locator = keyDigest;
173  m_wire.reset();
174  return *this;
175 }
176 
177 KeyLocator&
179 {
180  BOOST_ASSERT(keyDigest != nullptr);
181  m_locator = makeBinaryBlock(tlv::KeyDigest, *keyDigest);
182  m_wire.reset();
183  return *this;
184 }
185 
186 void
187 KeyLocator::print(std::ostream& os) const
188 {
189  std::visit(boost::hana::overload(
190  [&] (std::monostate) {
191  os << "None";
192  },
193  [&] (const Name& name) {
194  os << "Name=" << name;
195  },
196  [&] (const Block& digest) {
197  os << "KeyDigest=";
198  printHex(os, {digest.value(), std::min(digest.value_size(), MAX_KEY_DIGEST_OCTETS_TO_SHOW)});
199  if (digest.value_size() > MAX_KEY_DIGEST_OCTETS_TO_SHOW) {
200  os << "...";
201  }
202  },
203  [&] (uint32_t type) {
204  os << "Unknown(" << type << ")";
205  }),
206  m_locator);
207 }
208 
209 } // namespace ndn
#define NDN_CXX_UNREACHABLE
Definition: backports.hpp:57
Represents a TLV element of the NDN packet format.
Definition: block.hpp:45
element_const_iterator elements_begin() const noexcept
Equivalent to elements().begin().
Definition: block.hpp:433
const element_container & elements() const noexcept
Get container of sub-elements.
Definition: block.hpp:424
bool hasWire() const noexcept
Check if the Block contains a fully encoded wire representation.
Definition: block.hpp:205
uint32_t type() const noexcept
Return the TLV-TYPE of the Block.
Definition: block.hpp:275
void reset() noexcept
Reset the Block to a default-constructed state.
Definition: block.cpp:293
void parse() const
Parse TLV-VALUE into sub-elements.
Definition: block.cpp:326
const Block & getKeyDigest() const
Get nested KeyDigest element.
const Name & getName() const
Get nested Name element.
KeyLocator()
Construct an empty KeyLocator.
const Block & wireEncode() const
Definition: key-locator.cpp:68
uint32_t getType() const
void wireDecode(const Block &wire)
Decode from wire encoding.
Definition: key-locator.cpp:84
KeyLocator & setKeyDigest(const Block &keyDigest)
Set nested KeyDigest element (whole TLV).
KeyLocator & clear()
Reset KeyLocator to its default-constructed state.
KeyLocator & setName(const Name &name)
Set nested Name element.
Represents an absolute name.
Definition: name.hpp:45
#define NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(ClassName)
#define NDN_THROW(e)
Definition: exception.hpp:56
EncodingImpl< EstimatorTag > EncodingEstimator
Block makeBinaryBlock(uint32_t type, span< const uint8_t > value)
Create a TLV block copying the TLV-VALUE from a byte range.
EncodingImpl< EncoderTag > EncodingBuffer
size_t prependBlock(EncodingImpl< TAG > &encoder, const Block &block)
Prepend a TLV element.
std::string to_string(const errinfo_stacktrace &x)
Definition: exception.cpp:30
@ Name
Definition: tlv.hpp:71
@ KeyDigest
Definition: tlv.hpp:102
@ Invalid
Definition: tlv.hpp:67
@ KeyLocator
Definition: tlv.hpp:101
Definition: data.cpp:25
void printHex(std::ostream &os, uint64_t num, bool wantUpperCase)
Output the hex representation of num to the output stream os.
constexpr size_t MAX_KEY_DIGEST_OCTETS_TO_SHOW
Definition: key-locator.cpp:30
std::shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:140