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-2017 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 "key-locator.hpp"
24 #include "util/string-helper.hpp"
25 
26 namespace ndn {
27 
28 BOOST_CONCEPT_ASSERT((boost::EqualityComparable<KeyLocator>));
29 BOOST_CONCEPT_ASSERT((WireEncodable<KeyLocator>));
30 BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<KeyLocator>));
31 BOOST_CONCEPT_ASSERT((WireDecodable<KeyLocator>));
32 static_assert(std::is_base_of<tlv::Error, KeyLocator::Error>::value,
33  "KeyLocator::Error must inherit from tlv::Error");
34 
36  : m_type(KeyLocator_None)
37 {
38 }
39 
41 {
42  wireDecode(wire);
43 }
44 
46 {
47  setName(name);
48 }
49 
50 template<encoding::Tag TAG>
51 size_t
52 KeyLocator::wireEncode(EncodingImpl<TAG>& encoder) const
53 {
54  // KeyLocator ::= KEY-LOCATOR-TYPE TLV-LENGTH (Name | KeyDigest)
55  // KeyDigest ::= KEY-DIGEST-TYPE TLV-LENGTH BYTE+
56 
57  size_t totalLength = 0;
58 
59  switch (m_type) {
60  case KeyLocator_None:
61  break;
62  case KeyLocator_Name:
63  totalLength += m_name.wireEncode(encoder);
64  break;
66  totalLength += encoder.prependBlock(m_keyDigest);
67  break;
68  default:
69  BOOST_THROW_EXCEPTION(Error("Unsupported KeyLocator type"));
70  }
71 
72  totalLength += encoder.prependVarNumber(totalLength);
73  totalLength += encoder.prependVarNumber(tlv::KeyLocator);
74  return totalLength;
75 }
76 
78 
79 const Block&
81 {
82  if (m_wire.hasWire())
83  return m_wire;
84 
85  EncodingEstimator estimator;
86  size_t estimatedSize = wireEncode(estimator);
87 
88  EncodingBuffer buffer(estimatedSize, 0);
89  wireEncode(buffer);
90 
91  m_wire = buffer.block();
92  return m_wire;
93 }
94 
95 void
97 {
98  if (wire.type() != tlv::KeyLocator)
99  BOOST_THROW_EXCEPTION(Error("Unexpected TLV type during KeyLocator decoding"));
100 
101  m_wire = wire;
102  m_wire.parse();
103 
104  if (m_wire.elements().empty()) {
105  m_type = KeyLocator_None;
106  return;
107  }
108 
109  switch (m_wire.elements_begin()->type()) {
110  case tlv::Name:
111  m_type = KeyLocator_Name;
112  m_name.wireDecode(*m_wire.elements_begin());
113  break;
114  case tlv::KeyDigest:
115  m_type = KeyLocator_KeyDigest;
116  m_keyDigest = *m_wire.elements_begin();
117  break;
118  default:
119  m_type = KeyLocator_Unknown;
120  break;
121  }
122 }
123 
124 KeyLocator&
126 {
127  m_wire.reset();
128  m_type = KeyLocator_None;
129  m_name.clear();
130  m_keyDigest.reset();
131  return *this;
132 }
133 
134 const Name&
136 {
137  if (m_type != KeyLocator_Name)
138  BOOST_THROW_EXCEPTION(Error("KeyLocator type is not Name"));
139 
140  return m_name;
141 }
142 
143 KeyLocator&
145 {
146  this->clear();
147  m_type = KeyLocator_Name;
148  m_name = name;
149  return *this;
150 }
151 
152 const Block&
154 {
155  if (m_type != KeyLocator_KeyDigest)
156  BOOST_THROW_EXCEPTION(Error("KeyLocator type is not KeyDigest"));
157 
158  return m_keyDigest;
159 }
160 
161 KeyLocator&
163 {
164  if (keyDigest.type() != tlv::KeyDigest)
165  BOOST_THROW_EXCEPTION(Error("expecting KeyDigest block"));
166 
167  this->clear();
168  m_type = KeyLocator_KeyDigest;
169  m_keyDigest = keyDigest;
170  return *this;
171 }
172 
173 KeyLocator&
175 {
176  // WARNING: ConstBufferPtr is shared_ptr<const Buffer>
177  // This function takes a constant reference of a shared pointer.
178  // It MUST NOT change the reference count of that shared pointer.
179 
180  return this->setKeyDigest(makeBinaryBlock(tlv::KeyDigest, keyDigest->data(), keyDigest->size()));
181 }
182 
183 bool
185 {
186  return wireEncode() == other.wireEncode();
187 }
188 
189 std::ostream&
190 operator<<(std::ostream& os, const KeyLocator& keyLocator)
191 {
192  switch (keyLocator.getType()) {
194  return os << "Name=" << keyLocator.getName();
195  }
197  const size_t MAX_DIGEST_OCTETS_TO_SHOW = 5;
198  const Block& digest = keyLocator.getKeyDigest();
199  os << "KeyDigest=" << toHex(digest.value(), digest.value_size()).substr(0, MAX_DIGEST_OCTETS_TO_SHOW * 2);
200  if (digest.value_size() > MAX_DIGEST_OCTETS_TO_SHOW) {
201  os << "...";
202  }
203  return os;
204  }
206  return os << "None";
207  }
209  return os << "Unknown";
210  }
211  }
212  return os << "Unknown";
213 }
214 
215 } // namespace ndn
size_t wireEncode(EncodingImpl< TAG > &encoder) const
prepend wire encoding
Definition: key-locator.cpp:52
Copyright (c) 2013-2017 Regents of the University of California.
Definition: common.hpp:66
const element_container & elements() const
Get container of sub elements.
Definition: block.hpp:347
std::string toHex(const uint8_t *buffer, size_t length, bool wantUpperCase)
Return a string containing the hex representation of the bytes in buffer.
std::ostream & operator<<(std::ostream &os, const Data &data)
Definition: data.cpp:274
KeyLocator & setName(const Name &name)
set Name element
void wireDecode(const Block &wire)
decode from wire encoding
Definition: key-locator.cpp:96
KeyLocator & setKeyDigest(const Block &keyDigest)
set KeyDigest element
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
Definition: name.cpp:131
Represents a TLV element of NDN packet format.
Definition: block.hpp:42
KeyLocator()
construct an empty KeyLocator
Definition: key-locator.cpp:35
indicates KeyLocator contains a Name
Definition: key-locator.hpp:49
const Name & getName() const
get Name element
const Block & getKeyDigest() const
get KeyDigest element
Type getType() const
Block makeBinaryBlock(uint32_t type, const uint8_t *value, size_t length)
Create a TLV block copying TLV-VALUE from raw buffer.
indicates KeyLocator is empty (internal use only)
Definition: key-locator.hpp:46
#define NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(ClassName)
void reset()
Reset wire buffer of the element.
Definition: block.cpp:257
Represents an absolute name.
Definition: name.hpp:42
size_t value_size() const
Get size of TLV-VALUE aka TLV-LENGTH.
Definition: block.cpp:318
indicates KeyLocator contains an unknown element
Definition: key-locator.hpp:55
void parse() const
Parse TLV-VALUE into sub elements.
Definition: block.cpp:335
uint32_t type() const
Get TLV-TYPE.
Definition: block.hpp:235
KeyLocator & clear()
clear KeyLocator
const Block & wireEncode() const
Definition: key-locator.cpp:80
indicates KeyLocator contains a KeyDigest
Definition: key-locator.hpp:52
bool hasWire() const
Check if the Block has fully encoded wire.
Definition: block.cpp:251
const uint8_t * value() const
Get pointer to TLV-VALUE.
Definition: block.cpp:312
bool operator==(const KeyLocator &other) const
element_const_iterator elements_begin() const
Equivalent to elements().begin()
Definition: block.hpp:355
void wireDecode(const Block &wire)
Decode name from wire encoding.
Definition: name.cpp:164
void clear()
Remove all components.
Definition: name.hpp:450
EncodingImpl< EncoderTag > EncodingBuffer
EncodingImpl< EstimatorTag > EncodingEstimator
shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:89