control-parameters.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2017 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 "control-parameters.hpp"
24 #include "encoding/tlv-nfd.hpp"
25 #include "util/concepts.hpp"
26 #include "util/string-helper.hpp"
27 
28 namespace ndn {
29 namespace nfd {
30 
31 //BOOST_CONCEPT_ASSERT((boost::EqualityComparable<ControlParameters>));
32 BOOST_CONCEPT_ASSERT((WireEncodable<ControlParameters>));
33 BOOST_CONCEPT_ASSERT((WireDecodable<ControlParameters>));
34 static_assert(std::is_base_of<tlv::Error, ControlParameters::Error>::value,
35  "ControlParameters::Error must inherit from tlv::Error");
36 
38  : m_hasFields(CONTROL_PARAMETER_UBOUND)
39 {
40 }
41 
43  : m_hasFields(CONTROL_PARAMETER_UBOUND)
44 {
45  wireDecode(block);
46 }
47 
48 template<encoding::Tag TAG>
49 size_t
50 ControlParameters::wireEncode(EncodingImpl<TAG>& encoder) const
51 {
52  size_t totalLength = 0;
53 
54  if (this->hasFacePersistency()) {
55  totalLength += prependNonNegativeIntegerBlock(encoder,
56  tlv::nfd::FacePersistency, m_facePersistency);
57  }
58  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  }
65  if (this->hasMask()) {
66  totalLength += prependNonNegativeIntegerBlock(encoder, tlv::nfd::Mask, m_mask);
67  }
68  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  }
77  if (this->hasLocalUri()) {
78  totalLength += prependStringBlock(encoder, tlv::nfd::LocalUri, m_localUri);
79  }
80  if (this->hasUri()) {
81  totalLength += prependStringBlock(encoder, tlv::nfd::Uri, m_uri);
82  }
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 
96 
97 Block
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 
113 void
115 {
116  if (block.type() != tlv::nfd::ControlParameters) {
117  BOOST_THROW_EXCEPTION(Error("Expecting TLV-TYPE ControlParameters"));
118  }
119  m_wire = block;
120  m_wire.parse();
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()) {
132  m_faceId = readNonNegativeInteger(*val);
133  }
134 
135  val = m_wire.find(tlv::nfd::Uri);
136  m_hasFields[CONTROL_PARAMETER_URI] = val != m_wire.elements_end();
137  if (this->hasUri()) {
138  m_uri = readString(*val);
139  }
140 
141  val = m_wire.find(tlv::nfd::LocalUri);
142  m_hasFields[CONTROL_PARAMETER_LOCAL_URI] = val != m_wire.elements_end();
143  if (this->hasLocalUri()) {
144  m_localUri = readString(*val);
145  }
146 
147  val = m_wire.find(tlv::nfd::Origin);
148  m_hasFields[CONTROL_PARAMETER_ORIGIN] = val != m_wire.elements_end();
149  if (this->hasOrigin()) {
150  m_origin = readNonNegativeIntegerAs<RouteOrigin>(*val);
151  }
152 
153  val = m_wire.find(tlv::nfd::Cost);
154  m_hasFields[CONTROL_PARAMETER_COST] = val != m_wire.elements_end();
155  if (this->hasCost()) {
156  m_cost = readNonNegativeInteger(*val);
157  }
158 
159  val = m_wire.find(tlv::nfd::Flags);
160  m_hasFields[CONTROL_PARAMETER_FLAGS] = val != m_wire.elements_end();
161  if (this->hasFlags()) {
162  m_flags = readNonNegativeInteger(*val);
163  }
164 
165  val = m_wire.find(tlv::nfd::Mask);
166  m_hasFields[CONTROL_PARAMETER_MASK] = val != m_wire.elements_end();
167  if (this->hasMask()) {
168  m_mask = readNonNegativeInteger(*val);
169  }
170 
171  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()) {
176  BOOST_THROW_EXCEPTION(Error("Expecting Strategy/Name"));
177  }
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  }
188 
189  val = m_wire.find(tlv::nfd::FacePersistency);
190  m_hasFields[CONTROL_PARAMETER_FACE_PERSISTENCY] = val != m_wire.elements_end();
191  if (this->hasFacePersistency()) {
192  m_facePersistency = readNonNegativeIntegerAs<FacePersistency>(*val);
193  }
194 }
195 
196 bool
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 
210 bool
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 
225 ControlParameters::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 
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 
269 std::ostream&
270 operator<<(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 
286  if (parameters.hasLocalUri()) {
287  os << "LocalUri: " << parameters.getLocalUri() << ", ";
288  }
289 
290  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()) {
299  os << "Flags: " << AsHex{parameters.getFlags()} << ", ";
300  }
301 
302  if (parameters.hasMask()) {
303  os << "Mask: " << AsHex{parameters.getMask()} << ", ";
304  }
305 
306  if (parameters.hasStrategy()) {
307  os << "Strategy: " << parameters.getStrategy() << ", ";
308  }
309 
310  if (parameters.hasExpirationPeriod()) {
311  os << "ExpirationPeriod: " << parameters.getExpirationPeriod() << ", ";
312  }
313 
314  if (parameters.hasFacePersistency()) {
315  os << "FacePersistency: " << parameters.getFacePersistency() << ", ";
316  }
317 
318  os << ")";
319  return os;
320 }
321 
322 } // namespace nfd
323 } // namespace ndn
void wireDecode(const Block &wire) final
Copyright (c) 2013-2017 Regents of the University of California.
Definition: common.hpp:66
const std::string & getLocalUri() const
size_t prependNonNegativeIntegerBlock(EncodingImpl< TAG > &encoder, uint32_t type, uint64_t value)
Prepend a TLV element containing a non-negative integer.
represents parameters in a ControlCommand request or response
element_const_iterator find(uint32_t type) const
Find the first sub element of specified TLV-TYPE.
Definition: block.cpp:428
element_container::const_iterator element_const_iterator
Definition: block.hpp:47
Helper class to convert a number to hexadecimal format, for use with stream insertion operators...
size_t prependNestedBlock(EncodingImpl< TAG > &encoder, uint32_t type, const U &value)
Prepend a TLV element containing a nested TLV element.
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
Definition: name.cpp:131
ControlParameters & setFlags(uint64_t flags)
Represents a TLV element of NDN packet format.
Definition: block.hpp:42
size_t prependStringBlock(EncodingImpl< TAG > &encoder, uint32_t type, const std::string &value)
Prepend a TLV element containing a string.
std::string readString(const Block &block)
Read TLV-VALUE of a TLV element as a string.
uint64_t readNonNegativeInteger(const Block &block)
Read a non-negative integer from a TLV element.
ControlParameters & unsetFlagBit(size_t bit)
disable a bit in Mask
BOOST_CONCEPT_ASSERT((StatusDatasetItem< ChannelStatus >))
bool getFlagBit(size_t bit) const
#define NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(ClassName)
std::ostream & operator<<(std::ostream &os, FaceScope faceScope)
FacePersistency getFacePersistency() const
void parse() const
Parse TLV-VALUE into sub elements.
Definition: block.cpp:334
uint32_t type() const
Get TLV-TYPE.
Definition: block.hpp:235
const time::milliseconds & getExpirationPeriod() const
bool hasWire() const
Check if the Block has fully encoded wire.
Definition: block.cpp:250
bool hasFlagBit(size_t bit) const
element_const_iterator elements_end() const
Equivalent to elements().end()
Definition: block.hpp:363
void wireDecode(const Block &wire)
Decode name from wire encoding.
Definition: name.cpp:164
ControlParameters & setMask(uint64_t mask)
ControlParameters & setFlagBit(size_t bit, bool value, bool wantMask=true)
set a bit in Flags
EncodingImpl< EncoderTag > EncodingBuffer
const std::string & getUri() const
EncodingImpl< EstimatorTag > EncodingEstimator