blob: 74a2b5ea805c6f82c18c4e7e144ede6d36dae554 [file] [log] [blame]
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Steve DiBenedetto6d792d72014-03-15 19:01:36 -06002/**
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07003 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
5 *
6 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
7 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
8 *
9 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
Steve DiBenedetto6d792d72014-03-15 19:01:36 -060011 */
12
13#ifndef NDN_MANAGEMENT_NFD_FIB_ENTRY_HPP
14#define NDN_MANAGEMENT_NFD_FIB_ENTRY_HPP
15
16#include "../encoding/block.hpp"
17#include "../encoding/encoding-buffer.hpp"
18#include "../encoding/tlv-nfd.hpp"
19#include "../name.hpp"
20
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070021#include <list>
22
Steve DiBenedetto6d792d72014-03-15 19:01:36 -060023namespace ndn {
24namespace nfd {
25
26// NextHopRecord := NEXT-HOP-RECORD TLV-LENGTH
27// FaceId
28// Cost
29
Alexander Afanasyev4671bf72014-05-19 09:01:37 -040030/**
31 * @ingroup management
32 */
Steve DiBenedetto6d792d72014-03-15 19:01:36 -060033class NextHopRecord
34{
35public:
36 class Error : public Tlv::Error
37 {
38 public:
Alexander Afanasyev1c5a1a92014-03-21 13:32:36 -070039 Error(const std::string& what) : Tlv::Error(what) {}
Steve DiBenedetto6d792d72014-03-15 19:01:36 -060040 };
41
42 NextHopRecord()
43 : m_faceId(std::numeric_limits<uint64_t>::max())
44 , m_cost(0)
45 {
46 }
47
Alexander Afanasyev44b438a2014-03-19 12:51:49 -070048 explicit
Steve DiBenedetto6d792d72014-03-15 19:01:36 -060049 NextHopRecord(const Block& block)
50 {
51 wireDecode(block);
52 }
53
54 uint64_t
55 getFaceId() const
56 {
57 return m_faceId;
58 }
59
60 NextHopRecord&
61 setFaceId(uint64_t faceId)
62 {
63 m_faceId = faceId;
64 m_wire.reset();
65 return *this;
66 }
67
68 uint64_t
69 getCost() const
70 {
71 return m_cost;
72 }
73
74 NextHopRecord&
75 setCost(uint64_t cost)
76 {
77 m_cost = cost;
78 m_wire.reset();
79 return *this;
80 }
81
82 template<bool T>
83 size_t
84 wireEncode(EncodingImpl<T>& block) const
85 {
86 size_t totalLength = 0;
87 totalLength += prependNonNegativeIntegerBlock(block,
88 ndn::tlv::nfd::Cost,
89 m_cost);
90
91 totalLength += prependNonNegativeIntegerBlock(block,
92 ndn::tlv::nfd::FaceId,
93 m_faceId);
94
95 totalLength += block.prependVarNumber(totalLength);
96 totalLength += block.prependVarNumber(ndn::tlv::nfd::NextHopRecord);
97 return totalLength;
98 }
99
100 const Block&
101 wireEncode() const
102 {
103 if (m_wire.hasWire())
104 {
105 return m_wire;
106 }
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
118 void
119 wireDecode(const Block& wire)
120 {
121 m_faceId = std::numeric_limits<uint64_t>::max();
122 m_cost = 0;
123
124 m_wire = wire;
125
126 if (m_wire.type() != tlv::nfd::NextHopRecord)
127 {
128 std::stringstream error;
129 error << "Requested decoding of NextHopRecord, but Block is of a different type: #"
130 << m_wire.type();
131 throw Error(error.str());
132 }
133 m_wire.parse();
134
135 Block::element_const_iterator val = m_wire.elements_begin();
136 if (val == m_wire.elements_end())
137 {
138 throw Error("Unexpected end of NextHopRecord");
139 }
140 else if (val->type() != tlv::nfd::FaceId)
141 {
142 std::stringstream error;
143 error << "Expected FaceId, but Block is of a different type: #"
144 << val->type();
145 throw Error(error.str());
146 }
147 m_faceId = readNonNegativeInteger(*val);
148 ++val;
149
150 if (val == m_wire.elements_end())
151 {
152 throw Error("Unexpected end of NextHopRecord");
153 }
154 else if (val->type() != tlv::nfd::Cost)
155 {
156 std::stringstream error;
157 error << "Expected Cost, but Block is of a different type: #"
Alexander Afanasyev1c5a1a92014-03-21 13:32:36 -0700158 << m_wire.type();
Steve DiBenedetto6d792d72014-03-15 19:01:36 -0600159 throw Error(error.str());
160 }
161 m_cost = readNonNegativeInteger(*val);
162 }
163
164
165private:
166 uint64_t m_faceId;
167 uint64_t m_cost;
168
169 mutable Block m_wire;
170};
171
172
173// FibEntry := FIB-ENTRY-TYPE TLV-LENGTH
174// Name
175// NextHopRecord*
176
Alexander Afanasyev4671bf72014-05-19 09:01:37 -0400177/**
178 * @ingroup management
179 */
Steve DiBenedetto6d792d72014-03-15 19:01:36 -0600180class FibEntry
181{
182public:
183 class Error : public Tlv::Error
184 {
185 public:
186 Error(const std::string& what) : Tlv::Error(what)
187 {
188 }
189 };
190
191 FibEntry()
192 {
Alexander Afanasyev44b438a2014-03-19 12:51:49 -0700193 }
Steve DiBenedetto6d792d72014-03-15 19:01:36 -0600194
Alexander Afanasyev44b438a2014-03-19 12:51:49 -0700195 explicit
196 FibEntry(const Block& block)
197 {
198 wireDecode(block);
Steve DiBenedetto6d792d72014-03-15 19:01:36 -0600199 }
200
201 const Name&
202 getPrefix() const
203 {
204 return m_prefix;
205 }
206
207 FibEntry&
208 setPrefix(const Name& prefix)
209 {
210 m_prefix = prefix;
211 m_wire.reset();
212 return *this;
213 }
214
215 const std::list<NextHopRecord>&
216 getNextHopRecords() const
217 {
218 return m_nextHopRecords;
219 }
220
221 FibEntry&
222 addNextHopRecord(const NextHopRecord& nextHopRecord)
223 {
224 m_nextHopRecords.push_back(nextHopRecord);
225 m_wire.reset();
226 return *this;
227 }
228
229 template<typename T>
230 FibEntry&
231 setNextHopRecords(const T& begin, const T& end)
232 {
233 m_nextHopRecords.clear();
234 m_nextHopRecords.assign(begin, end);
235 m_wire.reset();
236 return *this;
237 }
238
239 template<bool T>
240 size_t
241 wireEncode(EncodingImpl<T>& block) const
242 {
243 size_t totalLength = 0;
244
Alexander Afanasyev1c5a1a92014-03-21 13:32:36 -0700245 for (std::list<NextHopRecord>::const_reverse_iterator i = m_nextHopRecords.rbegin();
246 i != m_nextHopRecords.rend();
Steve DiBenedetto6d792d72014-03-15 19:01:36 -0600247 ++i)
248 {
249 totalLength += i->wireEncode(block);
250 }
251
252 totalLength += m_prefix.wireEncode(block);
253 totalLength += block.prependVarNumber(totalLength);
254 totalLength += block.prependVarNumber(tlv::nfd::FibEntry);
255
256 return totalLength;
257 }
258
259 const Block&
260 wireEncode() const
261 {
262 if (m_wire.hasWire())
263 {
264 return m_wire;
265 }
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
275 return m_wire;
276 }
277
278 void
279 wireDecode(const Block& wire)
280 {
281 m_prefix.clear();
282 m_nextHopRecords.clear();
283
284 m_wire = wire;
285
286 if (m_wire.type() != tlv::nfd::FibEntry)
287 {
288 std::stringstream error;
289 error << "Requested decoding of FibEntry, but Block is of a different type: #"
290 << m_wire.type();
291 throw Error(error.str());
292 }
293
294 m_wire.parse();
295
296 Block::element_const_iterator val = m_wire.elements_begin();
297 if (val == m_wire.elements_end())
298 {
299 throw Error("Unexpected end of FibEntry");
300 }
301 else if (val->type() != Tlv::Name)
302 {
303 std::stringstream error;
304 error << "Expected Name, but Block is of a different type: #"
305 << val->type();
306 throw Error(error.str());
307 }
308 m_prefix.wireDecode(*val);
309 ++val;
310
311 for (; val != m_wire.elements_end(); ++val)
312 {
313 if (val->type() != tlv::nfd::NextHopRecord)
314 {
315 std::stringstream error;
316 error << "Expected NextHopRecords, but Block is of a different type: #"
317 << val->type();
318 throw Error(error.str());
319 }
Alexander Afanasyev44b438a2014-03-19 12:51:49 -0700320 m_nextHopRecords.push_back(NextHopRecord(*val));
Steve DiBenedetto6d792d72014-03-15 19:01:36 -0600321 }
322 }
323
324private:
325 Name m_prefix;
326 std::list<NextHopRecord> m_nextHopRecords;
327
328 mutable Block m_wire;
329};
330
331} // namespace nfd
332} // namespace ndn
333
334#endif // NDN_MANAGEMENT_NFD_FIB_ENTRY_HPP