blob: d0a663eeddd7f6d5fee733b35acc3495b26e1bd8 [file] [log] [blame]
Junxiao Shi70911652014-08-12 10:14:24 -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 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
22#include "nfd-control-parameters.hpp"
Junxiao Shi65f1a712014-11-20 14:59:36 -070023#include "encoding/tlv-nfd.hpp"
24#include "encoding/block-helpers.hpp"
25#include "util/concepts.hpp"
Junxiao Shi70911652014-08-12 10:14:24 -070026
27namespace ndn {
28namespace nfd {
29
Junxiao Shi65f1a712014-11-20 14:59:36 -070030//BOOST_CONCEPT_ASSERT((boost::EqualityComparable<ControlParameters>));
31BOOST_CONCEPT_ASSERT((WireEncodable<ControlParameters>));
32BOOST_CONCEPT_ASSERT((WireDecodable<ControlParameters>));
33static_assert(std::is_base_of<tlv::Error, ControlParameters::Error>::value,
34 "ControlParameters::Error must inherit from tlv::Error");
35
Junxiao Shi70911652014-08-12 10:14:24 -070036ControlParameters::ControlParameters()
37 : m_hasFields(CONTROL_PARAMETER_UBOUND)
38{
39}
40
41ControlParameters::ControlParameters(const Block& block)
42 : m_hasFields(CONTROL_PARAMETER_UBOUND)
43{
44 wireDecode(block);
45}
46
Alexander Afanasyev74633892015-02-08 18:08:46 -080047template<encoding::Tag TAG>
Junxiao Shi70911652014-08-12 10:14:24 -070048size_t
Alexander Afanasyev74633892015-02-08 18:08:46 -080049ControlParameters::wireEncode(EncodingImpl<TAG>& encoder) const
Junxiao Shi70911652014-08-12 10:14:24 -070050{
51 size_t totalLength = 0;
52
Yukai Tud93c5fc2015-08-25 11:37:16 +080053 if (this->hasFacePersistency()) {
54 totalLength += prependNonNegativeIntegerBlock(encoder,
55 tlv::nfd::FacePersistency, m_facePersistency);
56 }
Junxiao Shi70911652014-08-12 10:14:24 -070057 if (this->hasExpirationPeriod()) {
58 totalLength += prependNonNegativeIntegerBlock(encoder,
59 tlv::nfd::ExpirationPeriod, m_expirationPeriod.count());
60 }
61 if (this->hasStrategy()) {
62 totalLength += prependNestedBlock(encoder, tlv::nfd::Strategy, m_strategy);
63 }
64 if (this->hasFlags()) {
65 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Flags, m_flags);
66 }
67 if (this->hasCost()) {
68 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Cost, m_cost);
69 }
70 if (this->hasOrigin()) {
71 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Origin, m_origin);
72 }
73 if (this->hasLocalControlFeature()) {
74 totalLength += prependNonNegativeIntegerBlock(encoder,
75 tlv::nfd::LocalControlFeature, m_localControlFeature);
76 }
77 if (this->hasUri()) {
78 size_t valLength = encoder.prependByteArray(
79 reinterpret_cast<const uint8_t*>(m_uri.c_str()), m_uri.size());
80 totalLength += valLength;
81 totalLength += encoder.prependVarNumber(valLength);
82 totalLength += encoder.prependVarNumber(tlv::nfd::Uri);
83 }
84 if (this->hasFaceId()) {
85 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::FaceId, m_faceId);
86 }
87 if (this->hasName()) {
88 totalLength += m_name.wireEncode(encoder);
89 }
90
91 totalLength += encoder.prependVarNumber(totalLength);
92 totalLength += encoder.prependVarNumber(tlv::nfd::ControlParameters);
93 return totalLength;
94}
95
96template size_t
Alexander Afanasyev74633892015-02-08 18:08:46 -080097ControlParameters::wireEncode<encoding::EncoderTag>(EncodingImpl<encoding::EncoderTag>&) const;
Junxiao Shi70911652014-08-12 10:14:24 -070098
99template size_t
Alexander Afanasyev74633892015-02-08 18:08:46 -0800100ControlParameters::wireEncode<encoding::EstimatorTag>(EncodingImpl<encoding::EstimatorTag>&) const;
Junxiao Shi70911652014-08-12 10:14:24 -0700101
Yanbiao Li8ee37ed2015-05-19 12:44:04 -0700102Block
Junxiao Shi70911652014-08-12 10:14:24 -0700103ControlParameters::wireEncode() const
104{
105 if (m_wire.hasWire())
106 return m_wire;
107
108 EncodingEstimator estimator;
109 size_t estimatedSize = wireEncode(estimator);
110
111 EncodingBuffer buffer(estimatedSize, 0);
112 wireEncode(buffer);
113
114 m_wire = buffer.block();
115 return m_wire;
116}
117
118void
119ControlParameters::wireDecode(const Block& block)
120{
121 if (block.type() != tlv::nfd::ControlParameters) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700122 BOOST_THROW_EXCEPTION(Error("Expecting TLV-TYPE ControlParameters"));
Junxiao Shi70911652014-08-12 10:14:24 -0700123 }
124 m_wire = block;
125 m_wire.parse();
126 Block::element_const_iterator val;
127
128 val = m_wire.find(tlv::Name);
129 m_hasFields[CONTROL_PARAMETER_NAME] = val != m_wire.elements_end();
130 if (this->hasName()) {
131 m_name.wireDecode(*val);
132 }
133
134 val = m_wire.find(tlv::nfd::FaceId);
135 m_hasFields[CONTROL_PARAMETER_FACE_ID] = val != m_wire.elements_end();
136 if (this->hasFaceId()) {
137 m_faceId = static_cast<uint64_t>(readNonNegativeInteger(*val));
138 }
139
140 val = m_wire.find(tlv::nfd::Uri);
141 m_hasFields[CONTROL_PARAMETER_URI] = val != m_wire.elements_end();
142 if (this->hasUri()) {
143 m_uri.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
144 }
145
146 val = m_wire.find(tlv::nfd::LocalControlFeature);
147 m_hasFields[CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE] = val != m_wire.elements_end();
148 if (this->hasLocalControlFeature()) {
149 m_localControlFeature = static_cast<LocalControlFeature>(readNonNegativeInteger(*val));
150 }
151
152 val = m_wire.find(tlv::nfd::Origin);
153 m_hasFields[CONTROL_PARAMETER_ORIGIN] = val != m_wire.elements_end();
154 if (this->hasOrigin()) {
155 m_origin = static_cast<uint64_t>(readNonNegativeInteger(*val));
156 }
157
158 val = m_wire.find(tlv::nfd::Cost);
159 m_hasFields[CONTROL_PARAMETER_COST] = val != m_wire.elements_end();
160 if (this->hasCost()) {
161 m_cost = static_cast<uint64_t>(readNonNegativeInteger(*val));
162 }
163
164 val = m_wire.find(tlv::nfd::Flags);
165 m_hasFields[CONTROL_PARAMETER_FLAGS] = val != m_wire.elements_end();
166 if (this->hasFlags()) {
167 m_flags = static_cast<uint64_t>(readNonNegativeInteger(*val));
168 }
169
170 val = m_wire.find(tlv::nfd::Strategy);
171 m_hasFields[CONTROL_PARAMETER_STRATEGY] = val != m_wire.elements_end();
172 if (this->hasStrategy()) {
173 val->parse();
174 if (val->elements().empty()) {
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700175 BOOST_THROW_EXCEPTION(Error("Expecting Strategy/Name"));
Junxiao Shi70911652014-08-12 10:14:24 -0700176 }
177 else {
178 m_strategy.wireDecode(*val->elements_begin());
179 }
180 }
181
182 val = m_wire.find(tlv::nfd::ExpirationPeriod);
183 m_hasFields[CONTROL_PARAMETER_EXPIRATION_PERIOD] = val != m_wire.elements_end();
184 if (this->hasExpirationPeriod()) {
185 m_expirationPeriod = time::milliseconds(readNonNegativeInteger(*val));
186 }
Yukai Tud93c5fc2015-08-25 11:37:16 +0800187
188 val = m_wire.find(tlv::nfd::FacePersistency);
189 m_hasFields[CONTROL_PARAMETER_FACE_PERSISTENCY] = val != m_wire.elements_end();
190 if (this->hasFacePersistency()) {
191 m_facePersistency = static_cast<FacePersistency>(readNonNegativeInteger(*val));
192 }
Junxiao Shi70911652014-08-12 10:14:24 -0700193}
194
195std::ostream&
196operator<<(std::ostream& os, const ControlParameters& parameters)
197{
198 os << "ControlParameters(";
199
200 if (parameters.hasName()) {
201 os << "Name: " << parameters.getName() << ", ";
202 }
203
204 if (parameters.hasFaceId()) {
205 os << "FaceId: " << parameters.getFaceId() << ", ";
206 }
207
208 if (parameters.hasUri()) {
209 os << "Uri: " << parameters.getUri() << ", ";
210 }
211
212 if (parameters.hasLocalControlFeature()) {
213 os << "LocalControlFeature: " << parameters.getLocalControlFeature() << ", ";
214 }
215
216 if (parameters.hasOrigin()) {
217 os << "Origin: " << parameters.getOrigin() << ", ";
218 }
219
220 if (parameters.hasCost()) {
221 os << "Cost: " << parameters.getCost() << ", ";
222 }
223
224 if (parameters.hasFlags()) {
225 os << "Flags: " << parameters.getFlags() << ", ";
226 }
227
228 if (parameters.hasStrategy()) {
229 os << "Strategy: " << parameters.getStrategy() << ", ";
230 }
231
232 if (parameters.hasExpirationPeriod()) {
233 os << "ExpirationPeriod: " << parameters.getExpirationPeriod() << ", ";
234 }
235
236 os << ")";
237 return os;
238}
239
240} // namespace nfd
241} // namespace ndn