blob: 9692ecc5bf89071ec3c0648dd56fa07e5d9fb9b4 [file] [log] [blame]
Junxiao Shibc5030d2014-09-01 11:53:12 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento88a0d812017-08-19 21:31:42 -04002/*
Alexander Afanasyev5f1820e2017-01-04 18:12:42 -08003 * Copyright (c) 2013-2017 Regents of the University of California.
Junxiao Shibc5030d2014-09-01 11:53:12 -07004 *
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"
23#include "encoding/block-helpers.hpp"
Alexander Afanasyev5f1820e2017-01-04 18:12:42 -080024#include "util/string-helper.hpp"
Junxiao Shibc5030d2014-09-01 11:53:12 -070025
26namespace ndn {
27
Junxiao Shic2b8d242014-11-04 08:35:29 -070028BOOST_CONCEPT_ASSERT((boost::EqualityComparable<KeyLocator>));
29BOOST_CONCEPT_ASSERT((WireEncodable<KeyLocator>));
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070030BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<KeyLocator>));
Junxiao Shic2b8d242014-11-04 08:35:29 -070031BOOST_CONCEPT_ASSERT((WireDecodable<KeyLocator>));
32static_assert(std::is_base_of<tlv::Error, KeyLocator::Error>::value,
33 "KeyLocator::Error must inherit from tlv::Error");
34
Junxiao Shibc5030d2014-09-01 11:53:12 -070035KeyLocator::KeyLocator()
36 : m_type(KeyLocator_None)
37{
38}
39
40KeyLocator::KeyLocator(const Block& wire)
41{
42 wireDecode(wire);
43}
44
45KeyLocator::KeyLocator(const Name& name)
46{
47 setName(name);
48}
49
Alexander Afanasyev74633892015-02-08 18:08:46 -080050template<encoding::Tag TAG>
Junxiao Shibc5030d2014-09-01 11:53:12 -070051size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070052KeyLocator::wireEncode(EncodingImpl<TAG>& encoder) const
Junxiao Shibc5030d2014-09-01 11:53:12 -070053{
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:
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070063 totalLength += m_name.wireEncode(encoder);
Junxiao Shibc5030d2014-09-01 11:53:12 -070064 break;
65 case KeyLocator_KeyDigest:
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070066 totalLength += encoder.prependBlock(m_keyDigest);
Junxiao Shibc5030d2014-09-01 11:53:12 -070067 break;
68 default:
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -070069 BOOST_THROW_EXCEPTION(Error("Unsupported KeyLocator type"));
Junxiao Shibc5030d2014-09-01 11:53:12 -070070 }
71
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070072 totalLength += encoder.prependVarNumber(totalLength);
73 totalLength += encoder.prependVarNumber(tlv::KeyLocator);
Junxiao Shibc5030d2014-09-01 11:53:12 -070074 return totalLength;
75}
76
Davide Pesavento88a0d812017-08-19 21:31:42 -040077NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(KeyLocator);
Junxiao Shibc5030d2014-09-01 11:53:12 -070078
79const Block&
80KeyLocator::wireEncode() const
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
95void
96KeyLocator::wireDecode(const Block& wire)
97{
98 if (wire.type() != tlv::KeyLocator)
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -070099 BOOST_THROW_EXCEPTION(Error("Unexpected TLV type during KeyLocator decoding"));
Junxiao Shibc5030d2014-09-01 11:53:12 -0700100
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
124KeyLocator&
125KeyLocator::clear()
126{
127 m_wire.reset();
128 m_type = KeyLocator_None;
129 m_name.clear();
130 m_keyDigest.reset();
131 return *this;
132}
133
134const Name&
135KeyLocator::getName() const
136{
137 if (m_type != KeyLocator_Name)
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700138 BOOST_THROW_EXCEPTION(Error("KeyLocator type is not Name"));
Junxiao Shibc5030d2014-09-01 11:53:12 -0700139
140 return m_name;
141}
142
143KeyLocator&
144KeyLocator::setName(const Name& name)
145{
146 this->clear();
147 m_type = KeyLocator_Name;
148 m_name = name;
149 return *this;
150}
151
152const Block&
153KeyLocator::getKeyDigest() const
154{
155 if (m_type != KeyLocator_KeyDigest)
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700156 BOOST_THROW_EXCEPTION(Error("KeyLocator type is not KeyDigest"));
Junxiao Shibc5030d2014-09-01 11:53:12 -0700157
158 return m_keyDigest;
159}
160
161KeyLocator&
162KeyLocator::setKeyDigest(const Block& keyDigest)
163{
164 if (keyDigest.type() != tlv::KeyDigest)
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700165 BOOST_THROW_EXCEPTION(Error("expecting KeyDigest block"));
Junxiao Shibc5030d2014-09-01 11:53:12 -0700166
167 this->clear();
168 m_type = KeyLocator_KeyDigest;
169 m_keyDigest = keyDigest;
170 return *this;
171}
172
173KeyLocator&
174KeyLocator::setKeyDigest(const ConstBufferPtr& keyDigest)
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
Davide Pesavento5d0b0102017-10-07 13:43:16 -0400180 return this->setKeyDigest(makeBinaryBlock(tlv::KeyDigest, keyDigest->data(), keyDigest->size()));
Junxiao Shibc5030d2014-09-01 11:53:12 -0700181}
182
183bool
184KeyLocator::operator==(const KeyLocator& other) const
185{
186 return wireEncode() == other.wireEncode();
187}
188
Alexander Afanasyev5f1820e2017-01-04 18:12:42 -0800189std::ostream&
190operator<<(std::ostream& os, const KeyLocator& keyLocator)
191{
192 switch (keyLocator.getType()) {
193 case KeyLocator::KeyLocator_Name: {
194 return os << "Name=" << keyLocator.getName();
195 }
196 case KeyLocator::KeyLocator_KeyDigest: {
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 }
205 case KeyLocator::KeyLocator_None: {
206 return os << "None";
207 }
208 case KeyLocator::KeyLocator_Unknown: {
209 return os << "Unknown";
210 }
211 }
212 return os << "Unknown";
213}
214
Junxiao Shibc5030d2014-09-01 11:53:12 -0700215} // namespace ndn