ndn-cxx: NDN C++ Library 0.9.0-33-g832ea91d
Loading...
Searching...
No Matches
rib-entry.cpp
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2013-2023 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
28
29#include <boost/range/adaptor/reversed.hpp>
30
31namespace ndn::nfd {
32
33Route::Route() = default;
34
35Route::Route(const Block& block)
36{
37 this->wireDecode(block);
38}
39
40Route&
41Route::setFaceId(uint64_t faceId)
42{
43 m_faceId = faceId;
44 m_wire.reset();
45 return *this;
46}
47
48Route&
50{
51 m_origin = origin;
52 m_wire.reset();
53 return *this;
54}
55
56Route&
57Route::setCost(uint64_t cost)
58{
59 m_cost = cost;
60 m_wire.reset();
61 return *this;
62}
63
64Route&
65Route::setFlags(uint64_t flags)
66{
67 m_flags = flags;
68 m_wire.reset();
69 return *this;
70}
71
72Route&
74{
75 if (expirationPeriod == time::milliseconds::max())
76 return unsetExpirationPeriod();
77
78 m_expirationPeriod = expirationPeriod;
79 m_wire.reset();
80 return *this;
81}
82
83Route&
85{
86 m_expirationPeriod = std::nullopt;
87 m_wire.reset();
88 return *this;
89}
90
91template<encoding::Tag TAG>
92size_t
94{
95 size_t totalLength = 0;
96
97 if (m_expirationPeriod) {
98 totalLength += prependNonNegativeIntegerBlock(block, ndn::tlv::nfd::ExpirationPeriod,
99 static_cast<uint64_t>(m_expirationPeriod->count()));
100 }
101 totalLength += prependNonNegativeIntegerBlock(block, ndn::tlv::nfd::Flags, m_flags);
102 totalLength += prependNonNegativeIntegerBlock(block, ndn::tlv::nfd::Cost, m_cost);
103 totalLength += prependNonNegativeIntegerBlock(block, ndn::tlv::nfd::Origin, m_origin);
104 totalLength += prependNonNegativeIntegerBlock(block, ndn::tlv::nfd::FaceId, m_faceId);
105
106 totalLength += block.prependVarNumber(totalLength);
107 totalLength += block.prependVarNumber(ndn::tlv::nfd::Route);
108 return totalLength;
109}
110
112
113const Block&
115{
116 if (m_wire.hasWire())
117 return m_wire;
118
119 EncodingEstimator estimator;
120 size_t estimatedSize = wireEncode(estimator);
121
122 EncodingBuffer buffer(estimatedSize, 0);
123 wireEncode(buffer);
124
125 m_wire = buffer.block();
126 return m_wire;
127}
128
129void
131{
132 if (block.type() != tlv::nfd::Route) {
133 NDN_THROW(Error("Route", block.type()));
134 }
135
136 m_wire = block;
137 m_wire.parse();
138 auto val = m_wire.elements_begin();
139
140 if (val != m_wire.elements_end() && val->type() == tlv::nfd::FaceId) {
141 m_faceId = readNonNegativeInteger(*val);
142 ++val;
143 }
144 else {
145 NDN_THROW(Error("missing required FaceId field"));
146 }
147
148 if (val != m_wire.elements_end() && val->type() == tlv::nfd::Origin) {
149 m_origin = readNonNegativeIntegerAs<RouteOrigin>(*val);
150 ++val;
151 }
152 else {
153 NDN_THROW(Error("missing required Origin field"));
154 }
155
156 if (val != m_wire.elements_end() && val->type() == tlv::nfd::Cost) {
157 m_cost = readNonNegativeInteger(*val);
158 ++val;
159 }
160 else {
161 NDN_THROW(Error("missing required Cost field"));
162 }
163
164 if (val != m_wire.elements_end() && val->type() == tlv::nfd::Flags) {
165 m_flags = readNonNegativeInteger(*val);
166 ++val;
167 }
168 else {
169 NDN_THROW(Error("missing required Flags field"));
170 }
171
172 if (val != m_wire.elements_end() && val->type() == tlv::nfd::ExpirationPeriod) {
173 m_expirationPeriod.emplace(readNonNegativeInteger(*val));
174 ++val;
175 }
176 else {
177 m_expirationPeriod = std::nullopt;
178 }
179}
180
181bool
182operator==(const Route& a, const Route& b)
183{
184 return a.getFaceId() == b.getFaceId() &&
185 a.getOrigin() == b.getOrigin() &&
186 a.getCost() == b.getCost() &&
187 a.getFlags() == b.getFlags() &&
189}
190
191std::ostream&
192operator<<(std::ostream& os, const Route& route)
193{
194 os << "Route("
195 << "FaceId: " << route.getFaceId() << ", "
196 << "Origin: " << route.getOrigin() << ", "
197 << "Cost: " << route.getCost() << ", "
198 << "Flags: " << AsHex{route.getFlags()} << ", ";
199
200 if (route.hasExpirationPeriod()) {
201 os << "ExpirationPeriod: " << route.getExpirationPeriod();
202 }
203 else {
204 os << "ExpirationPeriod: infinite";
205 }
206
207 return os << ")";
208}
209
211
212RibEntry::RibEntry() = default;
213
215{
216 this->wireDecode(block);
217}
218
221{
222 m_prefix = prefix;
223 m_wire.reset();
224 return *this;
225}
226
229{
230 m_routes.push_back(route);
231 m_wire.reset();
232 return *this;
233}
234
237{
238 m_routes.clear();
239 m_wire.reset();
240 return *this;
241}
242
243template<encoding::Tag TAG>
244size_t
246{
247 size_t totalLength = 0;
248
249 for (const auto& route : m_routes | boost::adaptors::reversed) {
250 totalLength += route.wireEncode(block);
251 }
252 totalLength += m_prefix.wireEncode(block);
253
254 totalLength += block.prependVarNumber(totalLength);
255 totalLength += block.prependVarNumber(tlv::nfd::RibEntry);
256 return totalLength;
257}
258
260
261const Block&
263{
264 if (m_wire.hasWire())
265 return m_wire;
266
267 EncodingEstimator estimator;
268 size_t estimatedSize = wireEncode(estimator);
269
270 EncodingBuffer buffer(estimatedSize, 0);
271 wireEncode(buffer);
272
273 m_wire = buffer.block();
274 return m_wire;
275}
276
277void
279{
280 if (block.type() != tlv::nfd::RibEntry) {
281 NDN_THROW(Error("RibEntry", block.type()));
282 }
283
284 m_wire = block;
285 m_wire.parse();
286 auto val = m_wire.elements_begin();
287
288 if (val == m_wire.elements_end()) {
289 NDN_THROW(Error("unexpected end of RibEntry"));
290 }
291 else if (val->type() != tlv::Name) {
292 NDN_THROW(Error("Name", val->type()));
293 }
294 m_prefix.wireDecode(*val);
295 ++val;
296
297 m_routes.clear();
298 for (; val != m_wire.elements_end(); ++val) {
299 if (val->type() != tlv::nfd::Route) {
300 NDN_THROW(Error("Route", val->type()));
301 }
302 m_routes.emplace_back(*val);
303 }
304}
305
306bool
307operator==(const RibEntry& a, const RibEntry& b)
308{
309 const auto& aRoutes = a.getRoutes();
310 const auto& bRoutes = b.getRoutes();
311
312 if (a.getName() != b.getName() ||
313 aRoutes.size() != bRoutes.size())
314 return false;
315
316 std::vector<bool> matched(bRoutes.size(), false);
317 return std::all_of(aRoutes.begin(), aRoutes.end(),
318 [&] (const Route& route) {
319 for (size_t i = 0; i < bRoutes.size(); ++i) {
320 if (!matched[i] && bRoutes[i] == route) {
321 matched[i] = true;
322 return true;
323 }
324 }
325 return false;
326 });
327}
328
329std::ostream&
330operator<<(std::ostream& os, const RibEntry& entry)
331{
332 os << "RibEntry(Prefix: " << entry.getName() << ",\n"
333 << " Routes: [";
334
335 std::copy(entry.getRoutes().begin(), entry.getRoutes().end(),
336 make_ostream_joiner(os, ",\n "));
337
338 os << "]\n";
339
340 return os << " )";
341}
342
343} // namespace ndn::nfd
Helper class to convert a number to hexadecimal format, for use with stream insertion operators.
Represents a TLV element of the NDN packet format.
Definition block.hpp:45
element_const_iterator elements_begin() const noexcept
Equivalent to elements().begin().
Definition block.hpp:433
element_const_iterator elements_end() const noexcept
Equivalent to elements().end().
Definition block.hpp:442
bool hasWire() const noexcept
Check if the Block contains a fully encoded wire representation.
Definition block.hpp:205
uint32_t type() const noexcept
Return the TLV-TYPE of the Block.
Definition block.hpp:275
void reset() noexcept
Reset the Block to a default-constructed state.
Definition block.cpp:293
void parse() const
Parse TLV-VALUE into sub-elements.
Definition block.cpp:326
Represents an absolute name.
Definition name.hpp:45
size_t size() const noexcept
Returns the number of components.
Definition name.hpp:180
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Prepend wire encoding to encoder.
Definition name.cpp:92
void wireDecode(const Block &wire)
Decode name from wire encoding.
Definition name.cpp:125
Represents an item in NFD RIB dataset.
const std::vector< Route > & getRoutes() const
const Name & getName() const
RibEntry & addRoute(const Route &route)
RibEntry & clearRoutes()
void wireDecode(const Block &block)
const Block & wireEncode() const
RibEntry & setName(const Name &prefix)
Represents a route in a RibEntry.
Definition rib-entry.hpp:42
Route & unsetExpirationPeriod()
Definition rib-entry.cpp:84
Route & setFlags(uint64_t flags)
Definition rib-entry.cpp:65
bool hasExpirationPeriod() const
Definition rib-entry.hpp:92
RouteOrigin getOrigin() const
Definition rib-entry.hpp:65
Route & setCost(uint64_t cost)
Definition rib-entry.cpp:57
Route & setOrigin(RouteOrigin origin)
Definition rib-entry.cpp:49
uint64_t getFaceId() const
Definition rib-entry.hpp:56
Route & setFaceId(uint64_t faceId)
Definition rib-entry.cpp:41
const Block & wireEncode() const
uint64_t getFlags() const
Definition rib-entry.hpp:83
uint64_t getCost() const
Definition rib-entry.hpp:74
Route & setExpirationPeriod(time::milliseconds expirationPeriod)
Definition rib-entry.cpp:73
time::milliseconds getExpirationPeriod() const
Definition rib-entry.hpp:98
void wireDecode(const Block &block)
#define NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(ClassName)
#define NDN_THROW(e)
Definition exception.hpp:56
Contains classes and functions related to the NFD Management protocol.
std::ostream & operator<<(std::ostream &os, FaceScope faceScope)
bool operator==(const ChannelStatus &a, const ChannelStatus &b)
::boost::chrono::milliseconds milliseconds
Definition time.hpp:52
@ Name
Definition tlv.hpp:71
ostream_joiner< std::decay_t< DelimT >, CharT, Traits > make_ostream_joiner(std::basic_ostream< CharT, Traits > &os, DelimT &&delimiter)
std::ostream & operator<<(std::ostream &os, const Data &data)
Definition data.cpp:377
Backport of ostream_joiner from the Library Fundamentals v2 TS.