blob: 61fb8237bcbb41a7e679b4fc621203c74cd1b695 [file] [log] [blame]
Junxiao Shi70911652014-08-12 10:14:24 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi5d75fd92017-08-08 18:09:20 +00002/*
Davide Pesaventoe78eeca2017-02-23 23:22:32 -05003 * Copyright (c) 2013-2017 Regents of the University of California.
Junxiao Shi70911652014-08-12 10:14:24 -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
Junxiao Shi7357ef22016-09-07 02:39:37 +000022#include "control-parameters.hpp"
Junxiao Shi65f1a712014-11-20 14:59:36 -070023#include "encoding/block-helpers.hpp"
Junxiao Shi5d75fd92017-08-08 18:09:20 +000024#include "encoding/tlv-nfd.hpp"
Junxiao Shi65f1a712014-11-20 14:59:36 -070025#include "util/concepts.hpp"
Davide Pesaventoe78eeca2017-02-23 23:22:32 -050026#include "util/string-helper.hpp"
Junxiao Shi70911652014-08-12 10:14:24 -070027
28namespace ndn {
29namespace nfd {
30
Junxiao Shi65f1a712014-11-20 14:59:36 -070031//BOOST_CONCEPT_ASSERT((boost::EqualityComparable<ControlParameters>));
32BOOST_CONCEPT_ASSERT((WireEncodable<ControlParameters>));
33BOOST_CONCEPT_ASSERT((WireDecodable<ControlParameters>));
34static_assert(std::is_base_of<tlv::Error, ControlParameters::Error>::value,
35 "ControlParameters::Error must inherit from tlv::Error");
36
Junxiao Shi70911652014-08-12 10:14:24 -070037ControlParameters::ControlParameters()
38 : m_hasFields(CONTROL_PARAMETER_UBOUND)
39{
40}
41
42ControlParameters::ControlParameters(const Block& block)
43 : m_hasFields(CONTROL_PARAMETER_UBOUND)
44{
45 wireDecode(block);
46}
47
Alexander Afanasyev74633892015-02-08 18:08:46 -080048template<encoding::Tag TAG>
Junxiao Shi70911652014-08-12 10:14:24 -070049size_t
Alexander Afanasyev74633892015-02-08 18:08:46 -080050ControlParameters::wireEncode(EncodingImpl<TAG>& encoder) const
Junxiao Shi70911652014-08-12 10:14:24 -070051{
52 size_t totalLength = 0;
53
Yukai Tud93c5fc2015-08-25 11:37:16 +080054 if (this->hasFacePersistency()) {
55 totalLength += prependNonNegativeIntegerBlock(encoder,
56 tlv::nfd::FacePersistency, m_facePersistency);
57 }
Junxiao Shi70911652014-08-12 10:14:24 -070058 if (this->hasExpirationPeriod()) {
59 totalLength += prependNonNegativeIntegerBlock(encoder,
60 tlv::nfd::ExpirationPeriod, m_expirationPeriod.count());
61 }
62 if (this->hasStrategy()) {
63 totalLength += prependNestedBlock(encoder, tlv::nfd::Strategy, m_strategy);
64 }
Eric Newberryda916d62016-08-11 23:04:34 -070065 if (this->hasMask()) {
66 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Mask, m_mask);
67 }
Junxiao Shi70911652014-08-12 10:14:24 -070068 if (this->hasFlags()) {
69 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Flags, m_flags);
70 }
71 if (this->hasCost()) {
72 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Cost, m_cost);
73 }
74 if (this->hasOrigin()) {
75 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Origin, m_origin);
76 }
Eric Newberryd7f5b282017-03-28 19:55:20 -070077 if (this->hasLocalUri()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +000078 totalLength += prependStringBlock(encoder, tlv::nfd::LocalUri, m_localUri);
Eric Newberryd7f5b282017-03-28 19:55:20 -070079 }
Junxiao Shi70911652014-08-12 10:14:24 -070080 if (this->hasUri()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +000081 totalLength += prependStringBlock(encoder, tlv::nfd::Uri, m_uri);
Junxiao Shi70911652014-08-12 10:14:24 -070082 }
83 if (this->hasFaceId()) {
84 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::FaceId, m_faceId);
85 }
86 if (this->hasName()) {
87 totalLength += m_name.wireEncode(encoder);
88 }
89
90 totalLength += encoder.prependVarNumber(totalLength);
91 totalLength += encoder.prependVarNumber(tlv::nfd::ControlParameters);
92 return totalLength;
93}
94
Davide Pesavento88a0d812017-08-19 21:31:42 -040095NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(ControlParameters);
Junxiao Shi70911652014-08-12 10:14:24 -070096
Yanbiao Li8ee37ed2015-05-19 12:44:04 -070097Block
Junxiao Shi70911652014-08-12 10:14:24 -070098ControlParameters::wireEncode() const
99{
100 if (m_wire.hasWire())
101 return m_wire;
102
103 EncodingEstimator estimator;
104 size_t estimatedSize = wireEncode(estimator);
105
106 EncodingBuffer buffer(estimatedSize, 0);
107 wireEncode(buffer);
108
109 m_wire = buffer.block();
110 return m_wire;
111}
112
113void
114ControlParameters::wireDecode(const Block& block)
115{
116 if (block.type() != tlv::nfd::ControlParameters) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700117 BOOST_THROW_EXCEPTION(Error("Expecting TLV-TYPE ControlParameters"));
Junxiao Shi70911652014-08-12 10:14:24 -0700118 }
119 m_wire = block;
120 m_wire.parse();
121 Block::element_const_iterator val;
122
123 val = m_wire.find(tlv::Name);
124 m_hasFields[CONTROL_PARAMETER_NAME] = val != m_wire.elements_end();
125 if (this->hasName()) {
126 m_name.wireDecode(*val);
127 }
128
129 val = m_wire.find(tlv::nfd::FaceId);
130 m_hasFields[CONTROL_PARAMETER_FACE_ID] = val != m_wire.elements_end();
131 if (this->hasFaceId()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000132 m_faceId = readNonNegativeInteger(*val);
Junxiao Shi70911652014-08-12 10:14:24 -0700133 }
134
135 val = m_wire.find(tlv::nfd::Uri);
136 m_hasFields[CONTROL_PARAMETER_URI] = val != m_wire.elements_end();
137 if (this->hasUri()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000138 m_uri = readString(*val);
Junxiao Shi70911652014-08-12 10:14:24 -0700139 }
140
Eric Newberryd7f5b282017-03-28 19:55:20 -0700141 val = m_wire.find(tlv::nfd::LocalUri);
142 m_hasFields[CONTROL_PARAMETER_LOCAL_URI] = val != m_wire.elements_end();
143 if (this->hasLocalUri()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000144 m_localUri = readString(*val);
Eric Newberryd7f5b282017-03-28 19:55:20 -0700145 }
146
Junxiao Shi70911652014-08-12 10:14:24 -0700147 val = m_wire.find(tlv::nfd::Origin);
148 m_hasFields[CONTROL_PARAMETER_ORIGIN] = val != m_wire.elements_end();
149 if (this->hasOrigin()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000150 m_origin = readNonNegativeIntegerAs<RouteOrigin>(*val);
Junxiao Shi70911652014-08-12 10:14:24 -0700151 }
152
153 val = m_wire.find(tlv::nfd::Cost);
154 m_hasFields[CONTROL_PARAMETER_COST] = val != m_wire.elements_end();
155 if (this->hasCost()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000156 m_cost = readNonNegativeInteger(*val);
Junxiao Shi70911652014-08-12 10:14:24 -0700157 }
158
159 val = m_wire.find(tlv::nfd::Flags);
160 m_hasFields[CONTROL_PARAMETER_FLAGS] = val != m_wire.elements_end();
161 if (this->hasFlags()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000162 m_flags = readNonNegativeInteger(*val);
Junxiao Shi70911652014-08-12 10:14:24 -0700163 }
164
Eric Newberryda916d62016-08-11 23:04:34 -0700165 val = m_wire.find(tlv::nfd::Mask);
166 m_hasFields[CONTROL_PARAMETER_MASK] = val != m_wire.elements_end();
167 if (this->hasMask()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000168 m_mask = readNonNegativeInteger(*val);
Eric Newberryda916d62016-08-11 23:04:34 -0700169 }
170
Junxiao Shi70911652014-08-12 10:14:24 -0700171 val = m_wire.find(tlv::nfd::Strategy);
172 m_hasFields[CONTROL_PARAMETER_STRATEGY] = val != m_wire.elements_end();
173 if (this->hasStrategy()) {
174 val->parse();
175 if (val->elements().empty()) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700176 BOOST_THROW_EXCEPTION(Error("Expecting Strategy/Name"));
Junxiao Shi70911652014-08-12 10:14:24 -0700177 }
178 else {
179 m_strategy.wireDecode(*val->elements_begin());
180 }
181 }
182
183 val = m_wire.find(tlv::nfd::ExpirationPeriod);
184 m_hasFields[CONTROL_PARAMETER_EXPIRATION_PERIOD] = val != m_wire.elements_end();
185 if (this->hasExpirationPeriod()) {
186 m_expirationPeriod = time::milliseconds(readNonNegativeInteger(*val));
187 }
Yukai Tud93c5fc2015-08-25 11:37:16 +0800188
189 val = m_wire.find(tlv::nfd::FacePersistency);
190 m_hasFields[CONTROL_PARAMETER_FACE_PERSISTENCY] = val != m_wire.elements_end();
191 if (this->hasFacePersistency()) {
Junxiao Shi5d75fd92017-08-08 18:09:20 +0000192 m_facePersistency = readNonNegativeIntegerAs<FacePersistency>(*val);
Yukai Tud93c5fc2015-08-25 11:37:16 +0800193 }
Junxiao Shi70911652014-08-12 10:14:24 -0700194}
195
Eric Newberryda916d62016-08-11 23:04:34 -0700196bool
197ControlParameters::hasFlagBit(size_t bit) const
198{
199 if (bit >= 64) {
200 BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
201 }
202
203 if (!hasMask()) {
204 return false;
205 }
206
207 return getMask() & (1 << bit);
208}
209
210bool
211ControlParameters::getFlagBit(size_t bit) const
212{
213 if (bit >= 64) {
214 BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
215 }
216
217 if (!hasFlags()) {
218 return false;
219 }
220
221 return getFlags() & (1 << bit);
222}
223
224ControlParameters&
225ControlParameters::setFlagBit(size_t bit, bool value, bool wantMask/* = true*/)
226{
227 if (bit >= 64) {
228 BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
229 }
230
231 uint64_t flags = hasFlags() ? getFlags() : 0;
232 if (value) {
233 flags |= (1 << bit);
234 }
235 else {
236 flags &= ~(1 << bit);
237 }
238 setFlags(flags);
239
240 if (wantMask) {
241 uint64_t mask = hasMask() ? getMask() : 0;
242 mask |= (1 << bit);
243 setMask(mask);
244 }
245
246 return *this;
247}
248
249ControlParameters&
250ControlParameters::unsetFlagBit(size_t bit)
251{
252 if (bit >= 64) {
253 BOOST_THROW_EXCEPTION(std::out_of_range("bit must be within range [0, 64)"));
254 }
255
256 uint64_t mask = hasMask() ? getMask() : 0;
257 mask &= ~(1 << bit);
258 if (mask == 0) {
259 unsetMask();
260 unsetFlags();
261 }
262 else {
263 setMask(mask);
264 }
265
266 return *this;
267}
268
Junxiao Shi70911652014-08-12 10:14:24 -0700269std::ostream&
270operator<<(std::ostream& os, const ControlParameters& parameters)
271{
272 os << "ControlParameters(";
273
274 if (parameters.hasName()) {
275 os << "Name: " << parameters.getName() << ", ";
276 }
277
278 if (parameters.hasFaceId()) {
279 os << "FaceId: " << parameters.getFaceId() << ", ";
280 }
281
282 if (parameters.hasUri()) {
283 os << "Uri: " << parameters.getUri() << ", ";
284 }
285
Eric Newberryd7f5b282017-03-28 19:55:20 -0700286 if (parameters.hasLocalUri()) {
287 os << "LocalUri: " << parameters.getLocalUri() << ", ";
288 }
289
Junxiao Shi70911652014-08-12 10:14:24 -0700290 if (parameters.hasOrigin()) {
291 os << "Origin: " << parameters.getOrigin() << ", ";
292 }
293
294 if (parameters.hasCost()) {
295 os << "Cost: " << parameters.getCost() << ", ";
296 }
297
298 if (parameters.hasFlags()) {
Davide Pesaventoe78eeca2017-02-23 23:22:32 -0500299 os << "Flags: " << AsHex{parameters.getFlags()} << ", ";
Eric Newberryda916d62016-08-11 23:04:34 -0700300 }
301
302 if (parameters.hasMask()) {
Davide Pesaventoe78eeca2017-02-23 23:22:32 -0500303 os << "Mask: " << AsHex{parameters.getMask()} << ", ";
Junxiao Shi70911652014-08-12 10:14:24 -0700304 }
305
306 if (parameters.hasStrategy()) {
307 os << "Strategy: " << parameters.getStrategy() << ", ";
308 }
309
310 if (parameters.hasExpirationPeriod()) {
311 os << "ExpirationPeriod: " << parameters.getExpirationPeriod() << ", ";
312 }
313
Yanbiao Licbdacb22016-08-02 16:02:35 +0800314 if (parameters.hasFacePersistency()) {
315 os << "FacePersistency: " << parameters.getFacePersistency() << ", ";
316 }
317
Junxiao Shi70911652014-08-12 10:14:24 -0700318 os << ")";
319 return os;
320}
321
322} // namespace nfd
323} // namespace ndn