blob: ddc00291d0084dd7313a43c66e0ba2e7bcfe40d5 [file] [log] [blame]
Junxiao Shibc5030d2014-09-01 11:53:12 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2014 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"
23#include "encoding/block-helpers.hpp"
Junxiao Shic2b8d242014-11-04 08:35:29 -070024#include "util/concepts.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>));
30BOOST_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
49template<bool T>
50size_t
51KeyLocator::wireEncode(EncodingImpl<T>& block) const
52{
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:
62 totalLength += m_name.wireEncode(block);
63 break;
64 case KeyLocator_KeyDigest:
65 totalLength += block.prependBlock(m_keyDigest);
66 break;
67 default:
68 throw Error("Unsupported KeyLocator type");
69 }
70
71 totalLength += block.prependVarNumber(totalLength);
72 totalLength += block.prependVarNumber(tlv::KeyLocator);
73 return totalLength;
74}
75
76template size_t
77KeyLocator::wireEncode<true>(EncodingImpl<true>& estimator) const;
78
79template size_t
80KeyLocator::wireEncode<false>(EncodingImpl<false>& encoder) const;
81
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)
102 throw Error("Unexpected TLV type during KeyLocator decoding");
103
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)
141 throw Error("KeyLocator type is not Name");
142
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)
159 throw Error("KeyLocator type is not KeyDigest");
160
161 return m_keyDigest;
162}
163
164KeyLocator&
165KeyLocator::setKeyDigest(const Block& keyDigest)
166{
167 if (keyDigest.type() != tlv::KeyDigest)
168 throw Error("expecting KeyDigest block");
169
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
183 return this->setKeyDigest(dataBlock(tlv::KeyDigest, keyDigest->get(), keyDigest->size()));
184}
185
186bool
187KeyLocator::operator==(const KeyLocator& other) const
188{
189 return wireEncode() == other.wireEncode();
190}
191
192} // namespace ndn