blob: d5b704197917e11260bd708c0fe89ca16327b4d2 [file] [log] [blame]
Yingdi Yu77627ab2015-07-21 16:13:49 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Yingdi Yu0a312e52015-07-22 13:14:53 -07003 * Copyright (c) 2014-2015, Regents of the University of California.
Yingdi Yu77627ab2015-07-21 16:13:49 -07004 *
Yingdi Yu0a312e52015-07-22 13:14:53 -07005 * This file is part of ndn-tools (Named Data Networking Essential Tools).
6 * See AUTHORS.md for complete list of ndn-tools authors and contributors.
Yingdi Yu77627ab2015-07-21 16:13:49 -07007 *
Yingdi Yu0a312e52015-07-22 13:14:53 -07008 * ndn-tools is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
Yingdi Yu77627ab2015-07-21 16:13:49 -070011 *
Yingdi Yu0a312e52015-07-22 13:14:53 -070012 * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
Yingdi Yu77627ab2015-07-21 16:13:49 -070015 *
Yingdi Yu0a312e52015-07-22 13:14:53 -070016 * You should have received a copy of the GNU General Public License along with
17 * ndn-tools, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Yingdi Yu77627ab2015-07-21 16:13:49 -070018 *
Yingdi Yu0a312e52015-07-22 13:14:53 -070019 * @author Yingdi Yu <yingdi@cs.ucla.edu>
Yingdi Yu77627ab2015-07-21 16:13:49 -070020 */
21
22#include "update-param.hpp"
23#include <ndn-cxx/encoding/block-helpers.hpp>
24#include <boost/lexical_cast.hpp>
25
26namespace ndn {
27namespace pib {
28
29static_assert(std::is_base_of<tlv::Error, UpdateParam::Error>::value,
30 "UpdateParam::Error must inherit from tlv::Error");
31
32const std::string UpdateParam::VERB("update");
33
34UpdateParam::UpdateParam()
35 : m_defaultOpt(DEFAULT_OPT_NO)
36{
37}
38
39UpdateParam::UpdateParam(const PibUser& user)
40 : m_entityType(tlv::pib::User)
41 , m_user(user)
42 , m_defaultOpt(DEFAULT_OPT_NO)
43{
44}
45
46UpdateParam::UpdateParam(const Name& identity, DefaultOpt defaultOpt)
47 : m_entityType(tlv::pib::Identity)
48 , m_identity(identity)
49 , m_defaultOpt(defaultOpt)
50{
51}
52
53UpdateParam::UpdateParam(const Name& keyName, const PublicKey& key, DefaultOpt defaultOpt)
54 : m_entityType(tlv::pib::PublicKey)
55 , m_key(keyName, key)
56 , m_defaultOpt(defaultOpt)
57{
58}
59
60UpdateParam::UpdateParam(const IdentityCertificate& certificate, DefaultOpt defaultOpt)
61 : m_entityType(tlv::pib::Certificate)
62 , m_certificate(certificate)
63 , m_defaultOpt(defaultOpt)
64{
65}
66
67UpdateParam::UpdateParam(const Block& wire)
68{
69 wireDecode(wire);
70}
71
72const PibUser&
73UpdateParam::getUser() const
74{
75 if (m_entityType == tlv::pib::User)
76 return m_user;
77 else
78 throw Error("UpdateParam::getUser: entityType must be User");
79}
80
81const PibIdentity&
82UpdateParam::getIdentity() const
83{
84 if (m_entityType == tlv::pib::Identity)
85 return m_identity;
86 else
87 throw Error("UpdateParam::getIdentity: entityType must be Identity");
88}
89
90const PibPublicKey&
91UpdateParam::getPublicKey() const
92{
93 if (m_entityType == tlv::pib::PublicKey)
94 return m_key;
95 else
96 throw Error("UpdateParam::getPublicKey: entityType must be PublicKey");
97}
98
99const PibCertificate&
100UpdateParam::getCertificate() const
101{
102 if (m_entityType == tlv::pib::Certificate)
103 return m_certificate;
104 else
105 throw Error("UpdateParam::getCertificate: entityType must be Certificate");
106}
107
108template<bool T>
109size_t
110UpdateParam::wireEncode(EncodingImpl<T>& block) const
111{
112 size_t totalLength = 0;
113
114 totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::DefaultOpt, m_defaultOpt);
115
116 // Encode Entity
117 switch (m_entityType) {
118 case tlv::pib::Identity:
119 {
120 totalLength += m_identity.wireEncode(block);
121 break;
122 }
123 case tlv::pib::PublicKey:
124 {
125 totalLength += m_key.wireEncode(block);
126 break;
127 }
128 case tlv::pib::Certificate:
129 {
130 totalLength += m_certificate.wireEncode(block);
131 break;
132 }
133 case tlv::pib::User:
134 {
135 totalLength += m_user.wireEncode(block);
136 break;
137 }
138 default:
139 throw Error("UpdateParam::wireEncode: unsupported entity type: " +
140 boost::lexical_cast<std::string>(m_entityType));
141 }
142
143 totalLength += block.prependVarNumber(totalLength);
144 totalLength += block.prependVarNumber(tlv::pib::UpdateParam);
145
146 return totalLength;
147}
148
149template size_t
150UpdateParam::wireEncode<true>(EncodingImpl<true>& block) const;
151
152template size_t
153UpdateParam::wireEncode<false>(EncodingImpl<false>& block) const;
154
155const Block&
156UpdateParam::wireEncode() const
157{
158 if (m_wire.hasWire())
159 return m_wire;
160
161 EncodingEstimator estimator;
162 size_t estimatedSize = wireEncode(estimator);
163
164 EncodingBuffer buffer(estimatedSize, 0);
165 wireEncode(buffer);
166
167 m_wire = buffer.block();
168 return m_wire;
169}
170
171void
172UpdateParam::wireDecode(const Block& wire)
173{
174 if (!wire.hasWire()) {
175 throw Error("The supplied block does not contain wire format");
176 }
177
178 m_wire = wire;
179 m_wire.parse();
180
181 if (m_wire.type() != tlv::pib::UpdateParam)
182 throw Error("Unexpected TLV type when decoding UpdateParam");
183
184 Block::element_const_iterator it = m_wire.elements_begin();
185
186 // the first block must be Entity
187 if (it != m_wire.elements_end()) {
188 switch (it->type()) {
189 case tlv::pib::Identity:
190 {
191 m_entityType = tlv::pib::Identity;
192 m_identity.wireDecode(*it);
193 break;
194 }
195 case tlv::pib::PublicKey:
196 {
197 m_entityType = tlv::pib::PublicKey;
198 m_key.wireDecode(*it);
199 break;
200 }
201 case tlv::pib::Certificate:
202 {
203 m_entityType = tlv::pib::Certificate;
204 m_certificate.wireDecode(*it);
205 break;
206 }
207 case tlv::pib::User:
208 {
209 m_entityType = tlv::pib::User;
210 m_user.wireDecode(*it);
211 break;
212 }
213 default:
214 throw Error("The first sub-TLV of UpdateParam is not an entity type");
215 }
216
217 it++;
218 }
219 else
220 throw Error("UpdateParam requires the first sub-TLV to be an entity type");
221
222 // the second block must be DefaultOpt
223 if (it != m_wire.elements_end() && it->type() == tlv::pib::DefaultOpt) {
224 m_defaultOpt = static_cast<pib::DefaultOpt>(readNonNegativeInteger(*it));
225 it++;
226 }
227 else
228 throw Error("UpdateParam requires the second sub-TLV to be DefaultOpt");
229
230 if (it != m_wire.elements_end())
231 throw Error("UpdateParam must not contain more than two sub-TLVs");
232}
233
234} // namespace pib
235} // namespace ndn