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-2022 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 BOOST_CONCEPT_ASSERT((boost::EqualityComparable<KeyLocator>));
31 BOOST_CONCEPT_ASSERT((WireEncodable<KeyLocator>));
32 BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<KeyLocator>));
33 BOOST_CONCEPT_ASSERT((WireDecodable<KeyLocator>));
34 static_assert(std::is_base_of<tlv::Error, KeyLocator::Error>::value,
35  "KeyLocator::Error must inherit from tlv::Error");
36 
38 
39 KeyLocator::KeyLocator() = default;
40 
42 {
43  wireDecode(wire);
44 }
45 
47  : m_locator(name)
48 {
49 }
50 
51 template<encoding::Tag TAG>
52 size_t
54 {
55  // KeyLocator = KEY-LOCATOR-TYPE TLV-LENGTH (Name / KeyDigest)
56  // KeyDigest = KEY-DIGEST-TYPE TLV-LENGTH *OCTET
57 
58  size_t totalLength = 0;
59 
60  auto visitor = boost::hana::overload(
61  [] (monostate) {}, // nothing to encode, TLV-VALUE is empty
62  [&] (const Name& name) { totalLength += name.wireEncode(encoder); },
63  [&] (const Block& digest) { totalLength += prependBlock(encoder, digest); },
64  [] (uint32_t type) { NDN_THROW(Error("Unsupported KeyLocator type " + to_string(type))); });
65  visit(visitor, m_locator);
66 
67  totalLength += encoder.prependVarNumber(totalLength);
68  totalLength += encoder.prependVarNumber(tlv::KeyLocator);
69  return totalLength;
70 }
71 
73 
74 const Block&
76 {
77  if (m_wire.hasWire())
78  return m_wire;
79 
80  EncodingEstimator estimator;
81  size_t estimatedSize = wireEncode(estimator);
82 
83  EncodingBuffer buffer(estimatedSize, 0);
84  wireEncode(buffer);
85 
86  m_wire = buffer.block();
87  return m_wire;
88 }
89 
90 void
92 {
93  if (wire.type() != tlv::KeyLocator)
94  NDN_THROW(Error("KeyLocator", wire.type()));
95 
96  clear();
97  m_wire = wire;
98  m_wire.parse();
99 
100  auto element = m_wire.elements_begin();
101  if (element == m_wire.elements().end()) {
102  return;
103  }
104 
105  switch (element->type()) {
106  case tlv::Name:
107  m_locator.emplace<Name>(*element);
108  break;
109  case tlv::KeyDigest:
110  m_locator.emplace<Block>(*element);
111  break;
112  default:
113  m_locator = element->type();
114  break;
115  }
116 }
117 
118 uint32_t
120 {
121  switch (m_locator.index()) {
122  case 0:
123  return tlv::Invalid;
124  case 1:
125  return tlv::Name;
126  case 2:
127  return tlv::KeyDigest;
128  case 3:
129  return get<uint32_t>(m_locator);
130  default:
132  }
133 }
134 
135 KeyLocator&
137 {
138  m_locator = monostate{};
139  m_wire.reset();
140  return *this;
141 }
142 
143 const Name&
145 {
146  try {
147  return get<Name>(m_locator);
148  }
149  catch (const bad_variant_access&) {
150  NDN_THROW(Error("KeyLocator does not contain a Name"));
151  }
152 }
153 
154 KeyLocator&
156 {
157  m_locator = name;
158  m_wire.reset();
159  return *this;
160 }
161 
162 const Block&
164 {
165  try {
166  return get<Block>(m_locator);
167  }
168  catch (const bad_variant_access&) {
169  NDN_THROW(Error("KeyLocator does not contain a KeyDigest"));
170  }
171 }
172 
173 KeyLocator&
175 {
176  if (keyDigest.type() != tlv::KeyDigest) {
177  NDN_THROW(std::invalid_argument("Invalid KeyDigest block of type " + to_string(keyDigest.type())));
178  }
179  m_locator = keyDigest;
180  m_wire.reset();
181  return *this;
182 }
183 
184 KeyLocator&
186 {
187  BOOST_ASSERT(keyDigest != nullptr);
188  m_locator = makeBinaryBlock(tlv::KeyDigest, *keyDigest);
189  m_wire.reset();
190  return *this;
191 }
192 
193 std::ostream&
194 operator<<(std::ostream& os, const KeyLocator& keyLocator)
195 {
196  auto visitor = boost::hana::overload(
197  [&] (monostate) {
198  os << "None";
199  },
200  [&] (const Name& name) {
201  os << "Name=" << name;
202  },
203  [&] (const Block& digest) {
204  os << "KeyDigest=";
205  printHex(os, {digest.value(), std::min(digest.value_size(), MAX_KEY_DIGEST_OCTETS_TO_SHOW)});
206  if (digest.value_size() > MAX_KEY_DIGEST_OCTETS_TO_SHOW) {
207  os << "...";
208  }
209  },
210  [&] (uint32_t type) {
211  os << "Unknown(" << type << ")";
212  });
213  visit(visitor, keyLocator.m_locator);
214  return os;
215 }
216 
217 } // namespace ndn
#define NDN_CXX_UNREACHABLE
Definition: backports.hpp:138
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:435
const element_container & elements() const noexcept
Get container of sub-elements.
Definition: block.hpp:426
bool hasWire() const noexcept
Check if the Block contains a fully encoded wire representation.
Definition: block.hpp:221
uint32_t type() const noexcept
Return the TLV-TYPE of the Block.
Definition: block.hpp:277
void reset() noexcept
Reset the Block to a default-constructed state.
Definition: block.cpp:254
void parse() const
Parse TLV-VALUE into sub-elements.
Definition: block.cpp:324
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:75
uint32_t getType() const
void wireDecode(const Block &wire)
Decode from wire encoding.
Definition: key-locator.cpp:91
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:44
#define NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(ClassName)
#define NDN_THROW(e)
Definition: exception.hpp:61
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:31
@ 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.
shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:139
const size_t MAX_KEY_DIGEST_OCTETS_TO_SHOW
Definition: key-locator.cpp:37
std::ostream & operator<<(std::ostream &os, const Data &data)
Definition: data.cpp:374