blob: f39cd2738a20629d4b999a17bc9607d04bb638fe [file] [log] [blame]
Jiewen Tan7a56d1c2015-01-26 23:26:51 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyev67758b12018-03-06 18:36:44 -05002/*
laqinfan35731852017-08-08 06:17:39 -05003 * Copyright (c) 2014-2018, The University of Memphis,
Jiewen Tan7a56d1c2015-01-26 23:26:51 -08004 * Regents of the University of California,
5 * Arizona Board of Regents.
6 *
7 * This file is part of NLSR (Named-data Link State Routing).
8 * See AUTHORS.md for complete list of NLSR authors and contributors.
9 *
10 * NLSR is free software: you can redistribute it and/or modify it under the terms
11 * of the GNU General Public License as published by the Free Software Foundation,
12 * either version 3 of the License, or (at your option) any later version.
13 *
14 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Alexander Afanasyev67758b12018-03-06 18:36:44 -050020 */
Jiewen Tan7a56d1c2015-01-26 23:26:51 -080021
22#include "lsdb-status.hpp"
23#include "tlv-nlsr.hpp"
24
25#include <ndn-cxx/util/concepts.hpp>
26#include <ndn-cxx/encoding/block-helpers.hpp>
27
28namespace nlsr {
laqinfan35731852017-08-08 06:17:39 -050029namespace tlv {
Jiewen Tan7a56d1c2015-01-26 23:26:51 -080030
31BOOST_CONCEPT_ASSERT((ndn::WireEncodable<LsdbStatus>));
32BOOST_CONCEPT_ASSERT((ndn::WireDecodable<LsdbStatus>));
33static_assert(std::is_base_of<ndn::tlv::Error, LsdbStatus::Error>::value,
34 "LsdbStatus::Error must inherit from tlv::Error");
35
36LsdbStatus::LsdbStatus()
37 : m_hasAdjacencyLsas(false)
38 , m_hasCoordinateLsas(false)
39 , m_hasNameLsas(false)
40{
41}
42
43LsdbStatus::LsdbStatus(const ndn::Block& block)
44{
45 wireDecode(block);
46}
47
laqinfan35731852017-08-08 06:17:39 -050048LsdbStatus&
49LsdbStatus::addAdjacencyLsa(const AdjacencyLsa& adjacencyLsa)
50{
51 m_adjacencyLsas.push_back(adjacencyLsa);
52 m_wire.reset();
53 m_hasAdjacencyLsas = true;
54 return *this;
55}
56
57LsdbStatus&
58LsdbStatus::clearAdjacencyLsas()
59{
60 m_adjacencyLsas.clear();
61 m_hasAdjacencyLsas = false;
62 return *this;
63}
64
65LsdbStatus&
66LsdbStatus::addCoordinateLsa(const CoordinateLsa& coordinateLsa)
67{
68 m_coordinateLsas.push_back(coordinateLsa);
69 m_wire.reset();
70 m_hasCoordinateLsas = true;
71 return *this;
72}
73
74LsdbStatus&
75LsdbStatus::clearCoordinateLsas()
76{
77 m_coordinateLsas.clear();
78 m_hasCoordinateLsas = false;
79 return *this;
80}
81
82LsdbStatus&
83LsdbStatus::addNameLsa(const NameLsa& nameLsa)
84{
85 m_nameLsas.push_back(nameLsa);
86 m_wire.reset();
87 m_hasNameLsas = true;
88 return *this;
89}
90
91LsdbStatus&
92LsdbStatus::clearNameLsas()
93{
94 m_nameLsas.clear();
95 m_hasNameLsas = false;
96 return *this;
97}
98
Alexander Afanasyevf9f39102015-12-01 17:43:40 -080099template<ndn::encoding::Tag TAG>
Jiewen Tan7a56d1c2015-01-26 23:26:51 -0800100size_t
Alexander Afanasyevf9f39102015-12-01 17:43:40 -0800101LsdbStatus::wireEncode(ndn::EncodingImpl<TAG>& block) const
Jiewen Tan7a56d1c2015-01-26 23:26:51 -0800102{
103 size_t totalLength = 0;
104
105 for (std::list<NameLsa>::const_reverse_iterator it = m_nameLsas.rbegin();
106 it != m_nameLsas.rend(); ++it) {
107 totalLength += it->wireEncode(block);
108 }
109
110 for (std::list<CoordinateLsa>::const_reverse_iterator it = m_coordinateLsas.rbegin();
111 it != m_coordinateLsas.rend(); ++it) {
112 totalLength += it->wireEncode(block);
113 }
114
115 for (std::list<AdjacencyLsa>::const_reverse_iterator it = m_adjacencyLsas.rbegin();
116 it != m_adjacencyLsas.rend(); ++it) {
117 totalLength += it->wireEncode(block);
118 }
119
120 totalLength += block.prependVarNumber(totalLength);
121 totalLength += block.prependVarNumber(ndn::tlv::nlsr::LsdbStatus);
122
123 return totalLength;
124}
125
Alexander Afanasyev67758b12018-03-06 18:36:44 -0500126NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(LsdbStatus);
Jiewen Tan7a56d1c2015-01-26 23:26:51 -0800127
128const ndn::Block&
129LsdbStatus::wireEncode() const
130{
131 if (m_wire.hasWire()) {
132 return m_wire;
133 }
134
135 ndn::EncodingEstimator estimator;
136 size_t estimatedSize = wireEncode(estimator);
137
138 ndn::EncodingBuffer buffer(estimatedSize, 0);
139 wireEncode(buffer);
140
141 m_wire = buffer.block();
142
143 return m_wire;
144}
145
146void
147LsdbStatus::wireDecode(const ndn::Block& wire)
148{
149 m_adjacencyLsas.clear();
150 m_coordinateLsas.clear();
151 m_nameLsas.clear();
152
153 m_hasAdjacencyLsas = false;
154 m_hasCoordinateLsas = false;
155 m_hasNameLsas = false;
156
157 m_wire = wire;
158
159 if (m_wire.type() != ndn::tlv::nlsr::LsdbStatus) {
160 std::stringstream error;
161 error << "Expected LsdbStatus Block, but Block is of a different type: #"
162 << m_wire.type();
laqinfan35731852017-08-08 06:17:39 -0500163 BOOST_THROW_EXCEPTION(Error(error.str()));
Jiewen Tan7a56d1c2015-01-26 23:26:51 -0800164 }
165
166 m_wire.parse();
167
168 ndn::Block::element_const_iterator val = m_wire.elements_begin();
169
170 for (; val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::AdjacencyLsa; ++val) {
171 m_adjacencyLsas.push_back(AdjacencyLsa(*val));
172 m_hasAdjacencyLsas = true;
173 }
174
175 for (; val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::CoordinateLsa; ++val) {
176 m_coordinateLsas.push_back(CoordinateLsa(*val));
177 m_hasCoordinateLsas = true;
178 }
179
180 for (; val != m_wire.elements_end() && val->type() == ndn::tlv::nlsr::NameLsa; ++val) {
181 m_nameLsas.push_back(NameLsa(*val));
182 m_hasNameLsas = true;
183 }
184
185 if (val != m_wire.elements_end()) {
186 std::stringstream error;
187 error << "Expected the end of elements, but Block is of a different type: #"
188 << val->type();
laqinfan35731852017-08-08 06:17:39 -0500189 BOOST_THROW_EXCEPTION(Error(error.str()));
Jiewen Tan7a56d1c2015-01-26 23:26:51 -0800190 }
191}
192
193std::ostream&
194operator<<(std::ostream& os, const LsdbStatus& lsdbStatus)
195{
196 os << "LsdbStatus(";
197
198 bool isFirst = true;
199
200 for (const auto& adjacencyLsa : lsdbStatus.getAdjacencyLsas()) {
201 if (isFirst) {
202 isFirst = false;
203 }
204 else {
205 os << ", ";
206 }
207
208 os << adjacencyLsa;
209 }
210
211 for (const auto& coordinateLsa : lsdbStatus.getCoordinateLsas()) {
212 if (isFirst) {
213 isFirst = false;
214 }
215 else {
216 os << ", ";
217 }
218
219 os << coordinateLsa;
220 }
221
222 for (const auto& nameLsa : lsdbStatus.getNameLsas()) {
223 if (isFirst) {
224 isFirst = false;
225 }
226 else {
227 os << ", ";
228 }
229
230 os << nameLsa;
231 }
232
233 os << ")";
234
235 return os;
236}
237
238} // namespace tlv
239} // namespace nlsr