blob: a20777564c42b2b7ec0b08b06edcb277ddfcf038 [file] [log] [blame]
Junxiao Shic2b8d242014-11-04 08:35:29 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi51742322017-08-13 17:04:52 +00002/*
Eric Newberryb555b002017-05-17 00:30:44 -07003 * Copyright (c) 2013-2017 Regents of the University of California.
Junxiao Shic2b8d242014-11-04 08:35:29 -07004 *
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 "selectors.hpp"
23#include "encoding/encoding-buffer.hpp"
24#include "encoding/block-helpers.hpp"
Junxiao Shic2b8d242014-11-04 08:35:29 -070025
26namespace ndn {
27
28BOOST_CONCEPT_ASSERT((boost::EqualityComparable<Selectors>));
29BOOST_CONCEPT_ASSERT((WireEncodable<Selectors>));
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070030BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<Selectors>));
Junxiao Shic2b8d242014-11-04 08:35:29 -070031BOOST_CONCEPT_ASSERT((WireDecodable<Selectors>));
32static_assert(std::is_base_of<tlv::Error, Selectors::Error>::value,
33 "Selectors::Error must inherit from tlv::Error");
34
35Selectors::Selectors()
36 : m_minSuffixComponents(-1)
37 , m_maxSuffixComponents(-1)
Eric Newberryb555b002017-05-17 00:30:44 -070038 , m_childSelector(DEFAULT_CHILD_SELECTOR)
Junxiao Shic2b8d242014-11-04 08:35:29 -070039 , m_mustBeFresh(false)
40{
41}
42
Junxiao Shic2b8d242014-11-04 08:35:29 -070043Selectors::Selectors(const Block& wire)
44{
45 wireDecode(wire);
46}
47
48bool
49Selectors::empty() const
50{
51 return m_minSuffixComponents < 0 &&
52 m_maxSuffixComponents < 0 &&
53 m_publisherPublicKeyLocator.empty() &&
54 m_exclude.empty() &&
Junxiao Shi9bf55812017-07-05 15:04:37 +000055 m_childSelector == DEFAULT_CHILD_SELECTOR &&
Junxiao Shic2b8d242014-11-04 08:35:29 -070056 !m_mustBeFresh;
57}
58
Alexander Afanasyev74633892015-02-08 18:08:46 -080059template<encoding::Tag TAG>
Junxiao Shic2b8d242014-11-04 08:35:29 -070060size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070061Selectors::wireEncode(EncodingImpl<TAG>& encoder) const
Junxiao Shic2b8d242014-11-04 08:35:29 -070062{
63 size_t totalLength = 0;
64
65 // Selectors ::= SELECTORS-TYPE TLV-LENGTH
66 // MinSuffixComponents?
67 // MaxSuffixComponents?
68 // PublisherPublicKeyLocator?
69 // Exclude?
70 // ChildSelector?
71 // MustBeFresh?
72
73 // (reverse encoding)
74
75 // MustBeFresh
76 if (getMustBeFresh()) {
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070077 totalLength += prependEmptyBlock(encoder, tlv::MustBeFresh);
Junxiao Shic2b8d242014-11-04 08:35:29 -070078 }
79
80 // ChildSelector
Eric Newberryb555b002017-05-17 00:30:44 -070081 if (getChildSelector() != DEFAULT_CHILD_SELECTOR) {
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070082 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::ChildSelector, getChildSelector());
Junxiao Shic2b8d242014-11-04 08:35:29 -070083 }
84
85 // Exclude
86 if (!getExclude().empty()) {
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070087 totalLength += getExclude().wireEncode(encoder);
Junxiao Shic2b8d242014-11-04 08:35:29 -070088 }
89
90 // PublisherPublicKeyLocator
91 if (!getPublisherPublicKeyLocator().empty()) {
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070092 totalLength += getPublisherPublicKeyLocator().wireEncode(encoder);
Junxiao Shic2b8d242014-11-04 08:35:29 -070093 }
94
95 // MaxSuffixComponents
96 if (getMaxSuffixComponents() >= 0) {
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070097 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::MaxSuffixComponents,
Junxiao Shic2b8d242014-11-04 08:35:29 -070098 getMaxSuffixComponents());
99 }
100
101 // MinSuffixComponents
102 if (getMinSuffixComponents() >= 0) {
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700103 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::MinSuffixComponents,
Junxiao Shic2b8d242014-11-04 08:35:29 -0700104 getMinSuffixComponents());
105 }
106
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700107 totalLength += encoder.prependVarNumber(totalLength);
108 totalLength += encoder.prependVarNumber(tlv::Selectors);
Junxiao Shic2b8d242014-11-04 08:35:29 -0700109 return totalLength;
110}
111
112template size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -0700113Selectors::wireEncode<encoding::EncoderTag>(EncodingImpl<encoding::EncoderTag>& encoder) const;
Junxiao Shic2b8d242014-11-04 08:35:29 -0700114
115template size_t
Alexander Afanasyev74633892015-02-08 18:08:46 -0800116Selectors::wireEncode<encoding::EstimatorTag>(EncodingImpl<encoding::EstimatorTag>& encoder) const;
Junxiao Shic2b8d242014-11-04 08:35:29 -0700117
118const Block&
119Selectors::wireEncode() const
120{
121 if (m_wire.hasWire())
122 return m_wire;
123
124 EncodingEstimator estimator;
125 size_t estimatedSize = wireEncode(estimator);
126
127 EncodingBuffer buffer(estimatedSize, 0);
128 wireEncode(buffer);
129
130 m_wire = buffer.block();
131 return m_wire;
132}
133
134void
135Selectors::wireDecode(const Block& wire)
136{
137 if (wire.type() != tlv::Selectors)
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700138 BOOST_THROW_EXCEPTION(tlv::Error("Unexpected TLV type when decoding Selectors"));
Junxiao Shic2b8d242014-11-04 08:35:29 -0700139
140 *this = Selectors();
141
142 m_wire = wire;
143 m_wire.parse();
144
145 // MinSuffixComponents
146 Block::element_const_iterator val = m_wire.find(tlv::MinSuffixComponents);
147 if (val != m_wire.elements_end()) {
Junxiao Shi51742322017-08-13 17:04:52 +0000148 m_minSuffixComponents = readNonNegativeIntegerAs<int>(*val);
Junxiao Shic2b8d242014-11-04 08:35:29 -0700149 }
150
151 // MaxSuffixComponents
152 val = m_wire.find(tlv::MaxSuffixComponents);
153 if (val != m_wire.elements_end()) {
Junxiao Shi51742322017-08-13 17:04:52 +0000154 m_maxSuffixComponents = readNonNegativeIntegerAs<int>(*val);
Junxiao Shic2b8d242014-11-04 08:35:29 -0700155 }
156
157 // PublisherPublicKeyLocator
158 val = m_wire.find(tlv::KeyLocator);
159 if (val != m_wire.elements_end()) {
160 m_publisherPublicKeyLocator.wireDecode(*val);
161 }
162
163 // Exclude
164 val = m_wire.find(tlv::Exclude);
165 if (val != m_wire.elements_end()) {
166 m_exclude.wireDecode(*val);
167 }
168
169 // ChildSelector
170 val = m_wire.find(tlv::ChildSelector);
171 if (val != m_wire.elements_end()) {
Junxiao Shi51742322017-08-13 17:04:52 +0000172 m_childSelector = readNonNegativeIntegerAs<bool>(*val);
Junxiao Shic2b8d242014-11-04 08:35:29 -0700173 }
Eric Newberryb555b002017-05-17 00:30:44 -0700174 else {
175 m_childSelector = DEFAULT_CHILD_SELECTOR;
176 }
Junxiao Shic2b8d242014-11-04 08:35:29 -0700177
178 // MustBeFresh
179 val = m_wire.find(tlv::MustBeFresh);
180 if (val != m_wire.elements_end()) {
181 m_mustBeFresh = true;
182 }
183}
184
185Selectors&
186Selectors::setMinSuffixComponents(int minSuffixComponents)
187{
188 m_minSuffixComponents = minSuffixComponents;
189 m_wire.reset();
190 return *this;
191}
192
193Selectors&
194Selectors::setMaxSuffixComponents(int maxSuffixComponents)
195{
196 m_maxSuffixComponents = maxSuffixComponents;
197 m_wire.reset();
198 return *this;
199}
200
201Selectors&
202Selectors::setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
203{
204 m_publisherPublicKeyLocator = keyLocator;
205 m_wire.reset();
206 return *this;
207}
208
209Selectors&
210Selectors::setExclude(const Exclude& exclude)
211{
212 m_exclude = exclude;
213 m_wire.reset();
214 return *this;
215}
216
217Selectors&
218Selectors::setChildSelector(int childSelector)
219{
Eric Newberryb555b002017-05-17 00:30:44 -0700220 if (childSelector != 0 && childSelector != 1) {
221 BOOST_THROW_EXCEPTION(std::invalid_argument("ChildSelector must be 0 or 1"));
222 }
Junxiao Shic2b8d242014-11-04 08:35:29 -0700223 m_childSelector = childSelector;
224 m_wire.reset();
225 return *this;
226}
227
228Selectors&
229Selectors::setMustBeFresh(bool mustBeFresh)
230{
231 m_mustBeFresh = mustBeFresh;
232 m_wire.reset();
233 return *this;
234}
235
236bool
237Selectors::operator==(const Selectors& other) const
238{
239 return wireEncode() == other.wireEncode();
240}
241
242} // namespace ndn