blob: 80c891f913c17f778929b9b476938f25a495276b [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
Davide Pesavento88a0d812017-08-19 21:31:42 -0400112NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(Selectors);
Junxiao Shic2b8d242014-11-04 08:35:29 -0700113
114const Block&
115Selectors::wireEncode() const
116{
117 if (m_wire.hasWire())
118 return m_wire;
119
120 EncodingEstimator estimator;
121 size_t estimatedSize = wireEncode(estimator);
122
123 EncodingBuffer buffer(estimatedSize, 0);
124 wireEncode(buffer);
125
126 m_wire = buffer.block();
127 return m_wire;
128}
129
130void
131Selectors::wireDecode(const Block& wire)
132{
133 if (wire.type() != tlv::Selectors)
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700134 BOOST_THROW_EXCEPTION(tlv::Error("Unexpected TLV type when decoding Selectors"));
Junxiao Shic2b8d242014-11-04 08:35:29 -0700135
136 *this = Selectors();
137
138 m_wire = wire;
139 m_wire.parse();
140
141 // MinSuffixComponents
142 Block::element_const_iterator val = m_wire.find(tlv::MinSuffixComponents);
143 if (val != m_wire.elements_end()) {
Junxiao Shi51742322017-08-13 17:04:52 +0000144 m_minSuffixComponents = readNonNegativeIntegerAs<int>(*val);
Junxiao Shic2b8d242014-11-04 08:35:29 -0700145 }
146
147 // MaxSuffixComponents
148 val = m_wire.find(tlv::MaxSuffixComponents);
149 if (val != m_wire.elements_end()) {
Junxiao Shi51742322017-08-13 17:04:52 +0000150 m_maxSuffixComponents = readNonNegativeIntegerAs<int>(*val);
Junxiao Shic2b8d242014-11-04 08:35:29 -0700151 }
152
153 // PublisherPublicKeyLocator
154 val = m_wire.find(tlv::KeyLocator);
155 if (val != m_wire.elements_end()) {
156 m_publisherPublicKeyLocator.wireDecode(*val);
157 }
158
159 // Exclude
160 val = m_wire.find(tlv::Exclude);
161 if (val != m_wire.elements_end()) {
162 m_exclude.wireDecode(*val);
163 }
164
165 // ChildSelector
166 val = m_wire.find(tlv::ChildSelector);
167 if (val != m_wire.elements_end()) {
Junxiao Shi51742322017-08-13 17:04:52 +0000168 m_childSelector = readNonNegativeIntegerAs<bool>(*val);
Junxiao Shic2b8d242014-11-04 08:35:29 -0700169 }
Eric Newberryb555b002017-05-17 00:30:44 -0700170 else {
171 m_childSelector = DEFAULT_CHILD_SELECTOR;
172 }
Junxiao Shic2b8d242014-11-04 08:35:29 -0700173
174 // MustBeFresh
175 val = m_wire.find(tlv::MustBeFresh);
176 if (val != m_wire.elements_end()) {
177 m_mustBeFresh = true;
178 }
179}
180
181Selectors&
182Selectors::setMinSuffixComponents(int minSuffixComponents)
183{
184 m_minSuffixComponents = minSuffixComponents;
185 m_wire.reset();
186 return *this;
187}
188
189Selectors&
190Selectors::setMaxSuffixComponents(int maxSuffixComponents)
191{
192 m_maxSuffixComponents = maxSuffixComponents;
193 m_wire.reset();
194 return *this;
195}
196
197Selectors&
198Selectors::setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
199{
200 m_publisherPublicKeyLocator = keyLocator;
201 m_wire.reset();
202 return *this;
203}
204
205Selectors&
206Selectors::setExclude(const Exclude& exclude)
207{
208 m_exclude = exclude;
209 m_wire.reset();
210 return *this;
211}
212
213Selectors&
214Selectors::setChildSelector(int childSelector)
215{
Eric Newberryb555b002017-05-17 00:30:44 -0700216 if (childSelector != 0 && childSelector != 1) {
217 BOOST_THROW_EXCEPTION(std::invalid_argument("ChildSelector must be 0 or 1"));
218 }
Junxiao Shic2b8d242014-11-04 08:35:29 -0700219 m_childSelector = childSelector;
220 m_wire.reset();
221 return *this;
222}
223
224Selectors&
225Selectors::setMustBeFresh(bool mustBeFresh)
226{
227 m_mustBeFresh = mustBeFresh;
228 m_wire.reset();
229 return *this;
230}
231
232bool
233Selectors::operator==(const Selectors& other) const
234{
235 return wireEncode() == other.wireEncode();
236}
237
238} // namespace ndn