blob: 151a7047941c5d51d56c4ffb4c756e0e6865817d [file] [log] [blame]
Junxiao Shibc5030d2014-09-01 11:53:12 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev74633892015-02-08 18:08:46 -08003 * Copyright (c) 2013-2015 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"
24
25namespace ndn {
26
Junxiao Shic2b8d242014-11-04 08:35:29 -070027BOOST_CONCEPT_ASSERT((boost::EqualityComparable<KeyLocator>));
28BOOST_CONCEPT_ASSERT((WireEncodable<KeyLocator>));
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070029BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<KeyLocator>));
Junxiao Shic2b8d242014-11-04 08:35:29 -070030BOOST_CONCEPT_ASSERT((WireDecodable<KeyLocator>));
31static_assert(std::is_base_of<tlv::Error, KeyLocator::Error>::value,
32 "KeyLocator::Error must inherit from tlv::Error");
33
Junxiao Shibc5030d2014-09-01 11:53:12 -070034KeyLocator::KeyLocator()
35 : m_type(KeyLocator_None)
36{
37}
38
39KeyLocator::KeyLocator(const Block& wire)
40{
41 wireDecode(wire);
42}
43
44KeyLocator::KeyLocator(const Name& name)
45{
46 setName(name);
47}
48
Alexander Afanasyev74633892015-02-08 18:08:46 -080049template<encoding::Tag TAG>
Junxiao Shibc5030d2014-09-01 11:53:12 -070050size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070051KeyLocator::wireEncode(EncodingImpl<TAG>& encoder) const
Junxiao Shibc5030d2014-09-01 11:53:12 -070052{
53 // KeyLocator ::= KEY-LOCATOR-TYPE TLV-LENGTH (Name | KeyDigest)
54 // KeyDigest ::= KEY-DIGEST-TYPE TLV-LENGTH BYTE+
55
56 size_t totalLength = 0;
57
58 switch (m_type) {
59 case KeyLocator_None:
60 break;
61 case KeyLocator_Name:
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070062 totalLength += m_name.wireEncode(encoder);
Junxiao Shibc5030d2014-09-01 11:53:12 -070063 break;
64 case KeyLocator_KeyDigest:
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070065 totalLength += encoder.prependBlock(m_keyDigest);
Junxiao Shibc5030d2014-09-01 11:53:12 -070066 break;
67 default:
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -070068 BOOST_THROW_EXCEPTION(Error("Unsupported KeyLocator type"));
Junxiao Shibc5030d2014-09-01 11:53:12 -070069 }
70
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070071 totalLength += encoder.prependVarNumber(totalLength);
72 totalLength += encoder.prependVarNumber(tlv::KeyLocator);
Junxiao Shibc5030d2014-09-01 11:53:12 -070073 return totalLength;
74}
75
76template size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070077KeyLocator::wireEncode<encoding::EncoderTag>(EncodingImpl<encoding::EncoderTag>& encoder) const;
Junxiao Shibc5030d2014-09-01 11:53:12 -070078
79template size_t
Alexander Afanasyev74633892015-02-08 18:08:46 -080080KeyLocator::wireEncode<encoding::EstimatorTag>(EncodingImpl<encoding::EstimatorTag>& encoder) const;
Junxiao Shibc5030d2014-09-01 11:53:12 -070081
82const Block&
83KeyLocator::wireEncode() const
84{
85 if (m_wire.hasWire())
86 return m_wire;
87
88 EncodingEstimator estimator;
89 size_t estimatedSize = wireEncode(estimator);
90
91 EncodingBuffer buffer(estimatedSize, 0);
92 wireEncode(buffer);
93
94 m_wire = buffer.block();
95 return m_wire;
96}
97
98void
99KeyLocator::wireDecode(const Block& wire)
100{
101 if (wire.type() != tlv::KeyLocator)
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700102 BOOST_THROW_EXCEPTION(Error("Unexpected TLV type during KeyLocator decoding"));
Junxiao Shibc5030d2014-09-01 11:53:12 -0700103
104 m_wire = wire;
105 m_wire.parse();
106
107 if (m_wire.elements().empty()) {
108 m_type = KeyLocator_None;
109 return;
110 }
111
112 switch (m_wire.elements_begin()->type()) {
113 case tlv::Name:
114 m_type = KeyLocator_Name;
115 m_name.wireDecode(*m_wire.elements_begin());
116 break;
117 case tlv::KeyDigest:
118 m_type = KeyLocator_KeyDigest;
119 m_keyDigest = *m_wire.elements_begin();
120 break;
121 default:
122 m_type = KeyLocator_Unknown;
123 break;
124 }
125}
126
127KeyLocator&
128KeyLocator::clear()
129{
130 m_wire.reset();
131 m_type = KeyLocator_None;
132 m_name.clear();
133 m_keyDigest.reset();
134 return *this;
135}
136
137const Name&
138KeyLocator::getName() const
139{
140 if (m_type != KeyLocator_Name)
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700141 BOOST_THROW_EXCEPTION(Error("KeyLocator type is not Name"));
Junxiao Shibc5030d2014-09-01 11:53:12 -0700142
143 return m_name;
144}
145
146KeyLocator&
147KeyLocator::setName(const Name& name)
148{
149 this->clear();
150 m_type = KeyLocator_Name;
151 m_name = name;
152 return *this;
153}
154
155const Block&
156KeyLocator::getKeyDigest() const
157{
158 if (m_type != KeyLocator_KeyDigest)
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700159 BOOST_THROW_EXCEPTION(Error("KeyLocator type is not KeyDigest"));
Junxiao Shibc5030d2014-09-01 11:53:12 -0700160
161 return m_keyDigest;
162}
163
164KeyLocator&
165KeyLocator::setKeyDigest(const Block& keyDigest)
166{
167 if (keyDigest.type() != tlv::KeyDigest)
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700168 BOOST_THROW_EXCEPTION(Error("expecting KeyDigest block"));
Junxiao Shibc5030d2014-09-01 11:53:12 -0700169
170 this->clear();
171 m_type = KeyLocator_KeyDigest;
172 m_keyDigest = keyDigest;
173 return *this;
174}
175
176KeyLocator&
177KeyLocator::setKeyDigest(const ConstBufferPtr& keyDigest)
178{
179 // WARNING: ConstBufferPtr is shared_ptr<const Buffer>
180 // This function takes a constant reference of a shared pointer.
181 // It MUST NOT change the reference count of that shared pointer.
182
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700183 return this->setKeyDigest(makeBinaryBlock(tlv::KeyDigest, keyDigest->get(), keyDigest->size()));
Junxiao Shibc5030d2014-09-01 11:53:12 -0700184}
185
186bool
187KeyLocator::operator==(const KeyLocator& other) const
188{
189 return wireEncode() == other.wireEncode();
190}
191
192} // namespace ndn