blob: 773d65ab5b980793592a910dfd06714279380dc5 [file] [log] [blame]
Junxiao Shi70911652014-08-12 10:14:24 -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 "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
47template<bool T>
48size_t
49ControlParameters::wireEncode(EncodingImpl<T>& encoder) const
50{
51 size_t totalLength = 0;
52
53 if (this->hasExpirationPeriod()) {
54 totalLength += prependNonNegativeIntegerBlock(encoder,
55 tlv::nfd::ExpirationPeriod, m_expirationPeriod.count());
56 }
57 if (this->hasStrategy()) {
58 totalLength += prependNestedBlock(encoder, tlv::nfd::Strategy, m_strategy);
59 }
60 if (this->hasFlags()) {
61 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Flags, m_flags);
62 }
63 if (this->hasCost()) {
64 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Cost, m_cost);
65 }
66 if (this->hasOrigin()) {
67 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Origin, m_origin);
68 }
69 if (this->hasLocalControlFeature()) {
70 totalLength += prependNonNegativeIntegerBlock(encoder,
71 tlv::nfd::LocalControlFeature, m_localControlFeature);
72 }
73 if (this->hasUri()) {
74 size_t valLength = encoder.prependByteArray(
75 reinterpret_cast<const uint8_t*>(m_uri.c_str()), m_uri.size());
76 totalLength += valLength;
77 totalLength += encoder.prependVarNumber(valLength);
78 totalLength += encoder.prependVarNumber(tlv::nfd::Uri);
79 }
80 if (this->hasFaceId()) {
81 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::FaceId, m_faceId);
82 }
83 if (this->hasName()) {
84 totalLength += m_name.wireEncode(encoder);
85 }
86
87 totalLength += encoder.prependVarNumber(totalLength);
88 totalLength += encoder.prependVarNumber(tlv::nfd::ControlParameters);
89 return totalLength;
90}
91
92template size_t
93ControlParameters::wireEncode<true>(EncodingImpl<true>& encoder) const;
94
95template size_t
96ControlParameters::wireEncode<false>(EncodingImpl<false>& estimator) const;
97
98const Block&
99ControlParameters::wireEncode() const
100{
101 if (m_wire.hasWire())
102 return m_wire;
103
104 EncodingEstimator estimator;
105 size_t estimatedSize = wireEncode(estimator);
106
107 EncodingBuffer buffer(estimatedSize, 0);
108 wireEncode(buffer);
109
110 m_wire = buffer.block();
111 return m_wire;
112}
113
114void
115ControlParameters::wireDecode(const Block& block)
116{
117 if (block.type() != tlv::nfd::ControlParameters) {
118 throw Error("expecting TLV-TYPE ControlParameters");
119 }
120 m_wire = block;
121 m_wire.parse();
122 Block::element_const_iterator val;
123
124 val = m_wire.find(tlv::Name);
125 m_hasFields[CONTROL_PARAMETER_NAME] = val != m_wire.elements_end();
126 if (this->hasName()) {
127 m_name.wireDecode(*val);
128 }
129
130 val = m_wire.find(tlv::nfd::FaceId);
131 m_hasFields[CONTROL_PARAMETER_FACE_ID] = val != m_wire.elements_end();
132 if (this->hasFaceId()) {
133 m_faceId = static_cast<uint64_t>(readNonNegativeInteger(*val));
134 }
135
136 val = m_wire.find(tlv::nfd::Uri);
137 m_hasFields[CONTROL_PARAMETER_URI] = val != m_wire.elements_end();
138 if (this->hasUri()) {
139 m_uri.assign(reinterpret_cast<const char*>(val->value()), val->value_size());
140 }
141
142 val = m_wire.find(tlv::nfd::LocalControlFeature);
143 m_hasFields[CONTROL_PARAMETER_LOCAL_CONTROL_FEATURE] = val != m_wire.elements_end();
144 if (this->hasLocalControlFeature()) {
145 m_localControlFeature = static_cast<LocalControlFeature>(readNonNegativeInteger(*val));
146 }
147
148 val = m_wire.find(tlv::nfd::Origin);
149 m_hasFields[CONTROL_PARAMETER_ORIGIN] = val != m_wire.elements_end();
150 if (this->hasOrigin()) {
151 m_origin = static_cast<uint64_t>(readNonNegativeInteger(*val));
152 }
153
154 val = m_wire.find(tlv::nfd::Cost);
155 m_hasFields[CONTROL_PARAMETER_COST] = val != m_wire.elements_end();
156 if (this->hasCost()) {
157 m_cost = static_cast<uint64_t>(readNonNegativeInteger(*val));
158 }
159
160 val = m_wire.find(tlv::nfd::Flags);
161 m_hasFields[CONTROL_PARAMETER_FLAGS] = val != m_wire.elements_end();
162 if (this->hasFlags()) {
163 m_flags = static_cast<uint64_t>(readNonNegativeInteger(*val));
164 }
165
166 val = m_wire.find(tlv::nfd::Strategy);
167 m_hasFields[CONTROL_PARAMETER_STRATEGY] = val != m_wire.elements_end();
168 if (this->hasStrategy()) {
169 val->parse();
170 if (val->elements().empty()) {
171 throw Error("expecting Strategy/Name");
172 }
173 else {
174 m_strategy.wireDecode(*val->elements_begin());
175 }
176 }
177
178 val = m_wire.find(tlv::nfd::ExpirationPeriod);
179 m_hasFields[CONTROL_PARAMETER_EXPIRATION_PERIOD] = val != m_wire.elements_end();
180 if (this->hasExpirationPeriod()) {
181 m_expirationPeriod = time::milliseconds(readNonNegativeInteger(*val));
182 }
183}
184
185std::ostream&
186operator<<(std::ostream& os, const ControlParameters& parameters)
187{
188 os << "ControlParameters(";
189
190 if (parameters.hasName()) {
191 os << "Name: " << parameters.getName() << ", ";
192 }
193
194 if (parameters.hasFaceId()) {
195 os << "FaceId: " << parameters.getFaceId() << ", ";
196 }
197
198 if (parameters.hasUri()) {
199 os << "Uri: " << parameters.getUri() << ", ";
200 }
201
202 if (parameters.hasLocalControlFeature()) {
203 os << "LocalControlFeature: " << parameters.getLocalControlFeature() << ", ";
204 }
205
206 if (parameters.hasOrigin()) {
207 os << "Origin: " << parameters.getOrigin() << ", ";
208 }
209
210 if (parameters.hasCost()) {
211 os << "Cost: " << parameters.getCost() << ", ";
212 }
213
214 if (parameters.hasFlags()) {
215 os << "Flags: " << parameters.getFlags() << ", ";
216 }
217
218 if (parameters.hasStrategy()) {
219 os << "Strategy: " << parameters.getStrategy() << ", ";
220 }
221
222 if (parameters.hasExpirationPeriod()) {
223 os << "ExpirationPeriod: " << parameters.getExpirationPeriod() << ", ";
224 }
225
226 os << ")";
227 return os;
228}
229
230} // namespace nfd
231} // namespace ndn