blob: ba177717d6c2f5ba839512c2b16a9e039e85050f [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"
24
25namespace ndn {
26
27KeyLocator::KeyLocator()
28 : m_type(KeyLocator_None)
29{
30}
31
32KeyLocator::KeyLocator(const Block& wire)
33{
34 wireDecode(wire);
35}
36
37KeyLocator::KeyLocator(const Name& name)
38{
39 setName(name);
40}
41
42template<bool T>
43size_t
44KeyLocator::wireEncode(EncodingImpl<T>& block) const
45{
46 // KeyLocator ::= KEY-LOCATOR-TYPE TLV-LENGTH (Name | KeyDigest)
47 // KeyDigest ::= KEY-DIGEST-TYPE TLV-LENGTH BYTE+
48
49 size_t totalLength = 0;
50
51 switch (m_type) {
52 case KeyLocator_None:
53 break;
54 case KeyLocator_Name:
55 totalLength += m_name.wireEncode(block);
56 break;
57 case KeyLocator_KeyDigest:
58 totalLength += block.prependBlock(m_keyDigest);
59 break;
60 default:
61 throw Error("Unsupported KeyLocator type");
62 }
63
64 totalLength += block.prependVarNumber(totalLength);
65 totalLength += block.prependVarNumber(tlv::KeyLocator);
66 return totalLength;
67}
68
69template size_t
70KeyLocator::wireEncode<true>(EncodingImpl<true>& estimator) const;
71
72template size_t
73KeyLocator::wireEncode<false>(EncodingImpl<false>& encoder) const;
74
75const Block&
76KeyLocator::wireEncode() const
77{
78 if (m_wire.hasWire())
79 return m_wire;
80
81 EncodingEstimator estimator;
82 size_t estimatedSize = wireEncode(estimator);
83
84 EncodingBuffer buffer(estimatedSize, 0);
85 wireEncode(buffer);
86
87 m_wire = buffer.block();
88 return m_wire;
89}
90
91void
92KeyLocator::wireDecode(const Block& wire)
93{
94 if (wire.type() != tlv::KeyLocator)
95 throw Error("Unexpected TLV type during KeyLocator decoding");
96
97 m_wire = wire;
98 m_wire.parse();
99
100 if (m_wire.elements().empty()) {
101 m_type = KeyLocator_None;
102 return;
103 }
104
105 switch (m_wire.elements_begin()->type()) {
106 case tlv::Name:
107 m_type = KeyLocator_Name;
108 m_name.wireDecode(*m_wire.elements_begin());
109 break;
110 case tlv::KeyDigest:
111 m_type = KeyLocator_KeyDigest;
112 m_keyDigest = *m_wire.elements_begin();
113 break;
114 default:
115 m_type = KeyLocator_Unknown;
116 break;
117 }
118}
119
120KeyLocator&
121KeyLocator::clear()
122{
123 m_wire.reset();
124 m_type = KeyLocator_None;
125 m_name.clear();
126 m_keyDigest.reset();
127 return *this;
128}
129
130const Name&
131KeyLocator::getName() const
132{
133 if (m_type != KeyLocator_Name)
134 throw Error("KeyLocator type is not Name");
135
136 return m_name;
137}
138
139KeyLocator&
140KeyLocator::setName(const Name& name)
141{
142 this->clear();
143 m_type = KeyLocator_Name;
144 m_name = name;
145 return *this;
146}
147
148const Block&
149KeyLocator::getKeyDigest() const
150{
151 if (m_type != KeyLocator_KeyDigest)
152 throw Error("KeyLocator type is not KeyDigest");
153
154 return m_keyDigest;
155}
156
157KeyLocator&
158KeyLocator::setKeyDigest(const Block& keyDigest)
159{
160 if (keyDigest.type() != tlv::KeyDigest)
161 throw Error("expecting KeyDigest block");
162
163 this->clear();
164 m_type = KeyLocator_KeyDigest;
165 m_keyDigest = keyDigest;
166 return *this;
167}
168
169KeyLocator&
170KeyLocator::setKeyDigest(const ConstBufferPtr& keyDigest)
171{
172 // WARNING: ConstBufferPtr is shared_ptr<const Buffer>
173 // This function takes a constant reference of a shared pointer.
174 // It MUST NOT change the reference count of that shared pointer.
175
176 return this->setKeyDigest(dataBlock(tlv::KeyDigest, keyDigest->get(), keyDigest->size()));
177}
178
179bool
180KeyLocator::operator==(const KeyLocator& other) const
181{
182 return wireEncode() == other.wireEncode();
183}
184
185} // namespace ndn