NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.3: NDN, CCN, CCNx, content centric networks
API Documentation
fib-entry.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
22 #include "fib-entry.hpp"
23 #include <sstream>
24 #include "encoding/tlv-nfd.hpp"
26 #include "util/concepts.hpp"
27 
28 namespace ndn {
29 namespace nfd {
30 
31 //BOOST_CONCEPT_ASSERT((boost::EqualityComparable<NextHopRecord>));
32 BOOST_CONCEPT_ASSERT((WireEncodable<NextHopRecord>));
33 BOOST_CONCEPT_ASSERT((WireDecodable<NextHopRecord>));
34 static_assert(std::is_base_of<tlv::Error, NextHopRecord::Error>::value,
35  "NextHopRecord::Error must inherit from tlv::Error");
36 
37 //BOOST_CONCEPT_ASSERT((boost::EqualityComparable<FibEntry>));
38 BOOST_CONCEPT_ASSERT((WireEncodable<FibEntry>));
39 BOOST_CONCEPT_ASSERT((WireDecodable<FibEntry>));
40 static_assert(std::is_base_of<tlv::Error, FibEntry::Error>::value,
41  "FibEntry::Error must inherit from tlv::Error");
42 
43 // NextHopRecord := NEXT-HOP-RECORD TLV-LENGTH
44 // FaceId
45 // Cost
46 
48  : m_faceId(std::numeric_limits<uint64_t>::max())
49  , m_cost(0)
50 {
51 }
52 
54 {
55  this->wireDecode(block);
56 }
57 
59 NextHopRecord::setFaceId(uint64_t faceId)
60 {
61  m_faceId = faceId;
62  m_wire.reset();
63  return *this;
64 }
65 
67 NextHopRecord::setCost(uint64_t cost)
68 {
69  m_cost = cost;
70  m_wire.reset();
71  return *this;
72 }
73 
74 template<encoding::Tag TAG>
75 size_t
77 {
78  size_t totalLength = 0;
79  totalLength += prependNonNegativeIntegerBlock(block,
81  m_cost);
82 
83  totalLength += prependNonNegativeIntegerBlock(block,
85  m_faceId);
86 
87  totalLength += block.prependVarNumber(totalLength);
88  totalLength += block.prependVarNumber(ndn::tlv::nfd::NextHopRecord);
89  return totalLength;
90 }
91 
92 template size_t
93 NextHopRecord::wireEncode<encoding::EncoderTag>(EncodingImpl<encoding::EncoderTag>& block) const;
94 
95 template size_t
96 NextHopRecord::wireEncode<encoding::EstimatorTag>(EncodingImpl<encoding::EstimatorTag>& block) const;
97 
98 const Block&
100 {
101  if (m_wire.hasWire()) {
102  return m_wire;
103  }
104 
105  EncodingEstimator estimator;
106  size_t estimatedSize = wireEncode(estimator);
107 
108  EncodingBuffer buffer(estimatedSize, 0);
109  wireEncode(buffer);
110 
111  m_wire = buffer.block();
112  return m_wire;
113 }
114 
115 void
117 {
118  m_faceId = std::numeric_limits<uint64_t>::max();
119  m_cost = 0;
120 
121  m_wire = wire;
122 
123  if (m_wire.type() != tlv::nfd::NextHopRecord) {
124  std::stringstream error;
125  error << "Requested decoding of NextHopRecord, but Block is of a different type: #"
126  << m_wire.type();
127  BOOST_THROW_EXCEPTION(Error(error.str()));
128  }
129  m_wire.parse();
130 
132  if (val == m_wire.elements_end()) {
133  BOOST_THROW_EXCEPTION(Error("Unexpected end of NextHopRecord"));
134  }
135  else if (val->type() != tlv::nfd::FaceId) {
136  std::stringstream error;
137  error << "Expected FaceId, but Block is of a different type: #"
138  << val->type();
139  BOOST_THROW_EXCEPTION(Error(error.str()));
140  }
141  m_faceId = readNonNegativeInteger(*val);
142  ++val;
143 
144  if (val == m_wire.elements_end()) {
145  BOOST_THROW_EXCEPTION(Error("Unexpected end of NextHopRecord"));
146  }
147  else if (val->type() != tlv::nfd::Cost) {
148  std::stringstream error;
149  error << "Expected Cost, but Block is of a different type: #"
150  << m_wire.type();
151  BOOST_THROW_EXCEPTION(Error(error.str()));
152  }
153  m_cost = readNonNegativeInteger(*val);
154 }
155 
156 // FibEntry := FIB-ENTRY-TYPE TLV-LENGTH
157 // Name
158 // NextHopRecord*
159 
161 {
162 }
163 
165 {
166  this->wireDecode(block);
167 }
168 
169 FibEntry&
170 FibEntry::setPrefix(const Name& prefix)
171 {
172  m_prefix = prefix;
173  m_wire.reset();
174  return *this;
175 }
176 
177 FibEntry&
179 {
180  m_nextHopRecords.push_back(nextHopRecord);
181  m_wire.reset();
182  return *this;
183 }
184 
185 template<encoding::Tag TAG>
186 size_t
188 {
189  size_t totalLength = 0;
190 
191  for (auto i = m_nextHopRecords.rbegin(); i != m_nextHopRecords.rend(); ++i) {
192  totalLength += i->wireEncode(block);
193  }
194 
195  totalLength += m_prefix.wireEncode(block);
196  totalLength += block.prependVarNumber(totalLength);
197  totalLength += block.prependVarNumber(tlv::nfd::FibEntry);
198 
199  return totalLength;
200 }
201 
202 template size_t
203 FibEntry::wireEncode<encoding::EncoderTag>(EncodingImpl<encoding::EncoderTag>& block) const;
204 
205 template size_t
206 FibEntry::wireEncode<encoding::EstimatorTag>(EncodingImpl<encoding::EstimatorTag>& block) const;
207 
208 const Block&
210 {
211  if (m_wire.hasWire()) {
212  return m_wire;
213  }
214 
215  EncodingEstimator estimator;
216  size_t estimatedSize = wireEncode(estimator);
217 
218  EncodingBuffer buffer(estimatedSize, 0);
219  wireEncode(buffer);
220 
221  m_wire = buffer.block();
222 
223  return m_wire;
224 }
225 
226 void
228 {
229  m_prefix.clear();
230  m_nextHopRecords.clear();
231 
232  m_wire = wire;
233 
234  if (m_wire.type() != tlv::nfd::FibEntry) {
235  std::stringstream error;
236  error << "Requested decoding of FibEntry, but Block is of a different type: #"
237  << m_wire.type();
238  BOOST_THROW_EXCEPTION(Error(error.str()));
239  }
240 
241  m_wire.parse();
242 
244  if (val == m_wire.elements_end()) {
245  BOOST_THROW_EXCEPTION(Error("Unexpected end of FibEntry"));
246  }
247  else if (val->type() != tlv::Name) {
248  std::stringstream error;
249  error << "Expected Name, but Block is of a different type: #"
250  << val->type();
251  BOOST_THROW_EXCEPTION(Error(error.str()));
252  }
253  m_prefix.wireDecode(*val);
254  ++val;
255 
256  for (; val != m_wire.elements_end(); ++val) {
257  if (val->type() != tlv::nfd::NextHopRecord) {
258  std::stringstream error;
259  error << "Expected NextHopRecords, but Block is of a different type: #"
260  << val->type();
261  BOOST_THROW_EXCEPTION(Error(error.str()));
262  }
263  m_nextHopRecords.push_back(NextHopRecord(*val));
264  }
265 }
266 
267 } // namespace nfd
268 } // namespace ndn
element_const_iterator elements_begin() const
Definition: block.cpp:589
bool hasWire() const
Check if the Block has fully encoded wire.
Definition: block.cpp:471
Copyright (c) 2011-2015 Regents of the University of California.
size_t prependNonNegativeIntegerBlock(EncodingImpl< TAG > &encoder, uint32_t type, uint64_t value)
Helper to prepend TLV block type type containing non-negative integer value.
void wireDecode(const Block &wire)
Definition: fib-entry.cpp:227
NextHopRecord & setFaceId(uint64_t faceId)
Definition: fib-entry.cpp:59
FibEntry & setPrefix(const Name &prefix)
Definition: fib-entry.cpp:170
EncodingImpl< EstimatorTag > EncodingEstimator
element_const_iterator elements_end() const
Definition: block.cpp:595
STL namespace.
void parse() const
Parse wire buffer into subblocks.
Definition: block.cpp:322
Class representing a wire element of NDN-TLV packet format.
Definition: block.hpp:43
uint64_t readNonNegativeInteger(const Block &block)
Helper to read a non-negative integer from a block.
void wireDecode(const Block &wire)
Definition: fib-entry.cpp:116
EncodingImpl< EncoderTag > EncodingBuffer
Copyright (c) 2011-2015 Regents of the University of California.
Definition: ndn-common.hpp:40
element_container::const_iterator element_const_iterator
Definition: block.hpp:48
NextHopRecord & setCost(uint64_t cost)
Definition: fib-entry.cpp:67
void reset()
Reset wire buffer of the element.
Definition: block.cpp:302
Name abstraction to represent an absolute name.
Definition: name.hpp:46
FibEntry & addNextHopRecord(const NextHopRecord &nextHopRecord)
Definition: fib-entry.cpp:178
const Block & wireEncode() const
Definition: fib-entry.cpp:209
a concept check for TLV abstraction with .wireEncode method
Definition: concepts.hpp:34
a concept check for TLV abstraction with .wireDecode method and constructible from Block ...
Definition: concepts.hpp:70
uint32_t type() const
Definition: block.hpp:324
const Block & wireEncode() const
Definition: fib-entry.cpp:99