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