blob: b18030975d7faf717a38d729981db87ecfb61d41 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyevc348f832014-02-17 16:35:17 -08002/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * 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.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080020 */
21
22#ifndef NDN_SELECTORS_HPP
23#define NDN_SELECTORS_HPP
24
25#include "common.hpp"
Junxiao Shib332e782014-03-31 14:23:46 -070026#include "key-locator.hpp"
Alexander Afanasyevc348f832014-02-17 16:35:17 -080027#include "exclude.hpp"
28#include "encoding/encoding-buffer.hpp"
29
30namespace ndn {
Junxiao Shib332e782014-03-31 14:23:46 -070031
Alexander Afanasyevc348f832014-02-17 16:35:17 -080032/**
33 * @brief Abstraction implementing Interest selectors
34 */
35class Selectors
36{
Junxiao Shib332e782014-03-31 14:23:46 -070037public:
38 Selectors()
Alexander Afanasyevc348f832014-02-17 16:35:17 -080039 : m_minSuffixComponents(-1)
40 , m_maxSuffixComponents(-1)
41 , m_childSelector(-1)
42 , m_mustBeFresh(false)
43 {
44 }
45
Junxiao Shib332e782014-03-31 14:23:46 -070046 /** @deprecated Selectors().setX(...).setY(...)
47 */
Alexander Afanasyev9c578182014-05-14 17:28:28 -070048 DEPRECATED(
Junxiao Shib332e782014-03-31 14:23:46 -070049 Selectors(int minSuffixComponents, int maxSuffixComponents,
Alexander Afanasyevc348f832014-02-17 16:35:17 -080050 const Exclude& exclude,
51 int childSelector,
Alexander Afanasyev9c578182014-05-14 17:28:28 -070052 bool mustBeFresh))
Alexander Afanasyevc348f832014-02-17 16:35:17 -080053 : m_minSuffixComponents(minSuffixComponents)
54 , m_maxSuffixComponents(maxSuffixComponents)
55 , m_exclude(exclude)
56 , m_childSelector(childSelector)
57 , m_mustBeFresh(mustBeFresh)
58 {
59 }
Junxiao Shib332e782014-03-31 14:23:46 -070060
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070061 /**
62 * @brief Create from wire encoding
63 */
Junxiao Shib332e782014-03-31 14:23:46 -070064 Selectors(const Block& wire)
Alexander Afanasyevc348f832014-02-17 16:35:17 -080065 {
66 wireDecode(wire);
67 }
68
69 bool
70 empty() const;
Junxiao Shib332e782014-03-31 14:23:46 -070071
Alexander Afanasyevc348f832014-02-17 16:35:17 -080072 /**
73 * @brief Fast encoding or block size estimation
74 */
75 template<bool T>
76 size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070077 wireEncode(EncodingImpl<T>& block) const;
Junxiao Shib332e782014-03-31 14:23:46 -070078
Alexander Afanasyevc348f832014-02-17 16:35:17 -080079 /**
80 * @brief Encode to a wire format
81 */
82 const Block&
83 wireEncode() const;
84
85 /**
86 * @brief Decode the input from wire format
87 */
Junxiao Shib332e782014-03-31 14:23:46 -070088 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070089 wireDecode(const Block& wire);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080090
91 ///////////////////////////////////////////////////////////////////////////////
92 ///////////////////////////////////////////////////////////////////////////////
93 ///////////////////////////////////////////////////////////////////////////////
Junxiao Shib332e782014-03-31 14:23:46 -070094
95 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -080096 getMinSuffixComponents() const
97 {
98 return m_minSuffixComponents;
99 }
Junxiao Shib332e782014-03-31 14:23:46 -0700100
101 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800102 setMinSuffixComponents(int minSuffixComponents)
103 {
104 m_minSuffixComponents = minSuffixComponents;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700105 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800106 return *this;
107 }
108
109 //
Junxiao Shib332e782014-03-31 14:23:46 -0700110
111 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800112 getMaxSuffixComponents() const
113 {
114 return m_maxSuffixComponents;
115 }
116
Junxiao Shib332e782014-03-31 14:23:46 -0700117 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800118 setMaxSuffixComponents(int maxSuffixComponents)
119 {
120 m_maxSuffixComponents = maxSuffixComponents;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700121 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800122 return *this;
123 }
Junxiao Shib332e782014-03-31 14:23:46 -0700124
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800125 //
126
Junxiao Shib332e782014-03-31 14:23:46 -0700127 const KeyLocator&
128 getPublisherPublicKeyLocator() const
129 {
130 return m_publisherPublicKeyLocator;
131 }
132
133 Selectors&
134 setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
135 {
136 m_publisherPublicKeyLocator = keyLocator;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700137 m_wire.reset();
Junxiao Shib332e782014-03-31 14:23:46 -0700138 return *this;
139 }
140
141 //
142
143 const Exclude&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800144 getExclude() const
145 {
146 return m_exclude;
147 }
148
Junxiao Shib332e782014-03-31 14:23:46 -0700149 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800150 setExclude(const Exclude& exclude)
151 {
152 m_exclude = exclude;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700153 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800154 return *this;
155 }
156
157 //
Junxiao Shib332e782014-03-31 14:23:46 -0700158
159 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800160 getChildSelector() const
161 {
162 return m_childSelector;
163 }
164
Junxiao Shib332e782014-03-31 14:23:46 -0700165 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800166 setChildSelector(int childSelector)
167 {
168 m_childSelector = childSelector;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700169 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800170 return *this;
171 }
172
173 //
174
Junxiao Shib332e782014-03-31 14:23:46 -0700175 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800176 getMustBeFresh() const
177 {
178 return m_mustBeFresh;
179 }
180
Junxiao Shib332e782014-03-31 14:23:46 -0700181 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800182 setMustBeFresh(bool mustBeFresh)
183 {
184 m_mustBeFresh = mustBeFresh;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700185 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800186 return *this;
187 }
188
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700189public: // EqualityComparable concept
190 bool
191 operator==(const Selectors& other) const
192 {
193 return wireEncode() == other.wireEncode();
194 }
195
196 bool
197 operator!=(const Selectors& other) const
198 {
199 return !(*this == other);
200 }
201
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800202private:
203 int m_minSuffixComponents;
Junxiao Shib332e782014-03-31 14:23:46 -0700204 int m_maxSuffixComponents;
205 KeyLocator m_publisherPublicKeyLocator;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800206 Exclude m_exclude;
207 int m_childSelector;
208 bool m_mustBeFresh;
209
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700210 mutable Block m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800211};
212
213inline bool
214Selectors::empty() const
215{
216 return
217 (m_minSuffixComponents < 0 &&
218 m_maxSuffixComponents < 0 &&
Junxiao Shib332e782014-03-31 14:23:46 -0700219 m_publisherPublicKeyLocator.empty() &&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800220 m_exclude.empty() &&
221 m_childSelector < 0 &&
222 !m_mustBeFresh);
223}
224
225template<bool T>
226inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700227Selectors::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800228{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700229 size_t totalLength = 0;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800230
231 // Selectors ::= SELECTORS-TYPE TLV-LENGTH
232 // MinSuffixComponents?
233 // MaxSuffixComponents?
234 // PublisherPublicKeyLocator?
235 // Exclude?
236 // ChildSelector?
Junxiao Shib332e782014-03-31 14:23:46 -0700237 // MustBeFresh?
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800238
239 // (reverse encoding)
240
241 // MustBeFresh
242 if (getMustBeFresh())
243 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700244 totalLength += prependBooleanBlock(block, Tlv::MustBeFresh);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800245 }
246
247 // ChildSelector
248 if (getChildSelector() >= 0)
249 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700250 totalLength += prependNonNegativeIntegerBlock(block, Tlv::ChildSelector, getChildSelector());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800251 }
252
253 // Exclude
254 if (!getExclude().empty())
255 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700256 totalLength += getExclude().wireEncode(block);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800257 }
Junxiao Shib332e782014-03-31 14:23:46 -0700258
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800259 // PublisherPublicKeyLocator
Junxiao Shib332e782014-03-31 14:23:46 -0700260 if (!getPublisherPublicKeyLocator().empty())
261 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700262 totalLength += getPublisherPublicKeyLocator().wireEncode(block);
Junxiao Shib332e782014-03-31 14:23:46 -0700263 }
264
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800265 // MaxSuffixComponents
266 if (getMaxSuffixComponents() >= 0)
267 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700268 totalLength += prependNonNegativeIntegerBlock(block, Tlv::MaxSuffixComponents,
269 getMaxSuffixComponents());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800270 }
271
272 // MinSuffixComponents
273 if (getMinSuffixComponents() >= 0)
274 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700275 totalLength += prependNonNegativeIntegerBlock(block, Tlv::MinSuffixComponents,
276 getMinSuffixComponents());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800277 }
Junxiao Shib332e782014-03-31 14:23:46 -0700278
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700279 totalLength += block.prependVarNumber(totalLength);
280 totalLength += block.prependVarNumber(Tlv::Selectors);
281 return totalLength;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800282}
283
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700284inline const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800285Selectors::wireEncode() const
286{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700287 if (m_wire.hasWire())
288 return m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800289
290 EncodingEstimator estimator;
291 size_t estimatedSize = wireEncode(estimator);
Junxiao Shib332e782014-03-31 14:23:46 -0700292
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800293 EncodingBuffer buffer(estimatedSize, 0);
294 wireEncode(buffer);
295
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700296 m_wire = buffer.block();
297 return m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800298}
299
300inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700301Selectors::wireDecode(const Block& wire)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800302{
303 if (wire.type() != Tlv::Selectors)
304 throw Tlv::Error("Unexpected TLV type when decoding Selectors");
305
306 *this = Selectors();
Junxiao Shib332e782014-03-31 14:23:46 -0700307
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700308 m_wire = wire;
309 m_wire.parse();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800310
311 // MinSuffixComponents
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700312 Block::element_const_iterator val = m_wire.find(Tlv::MinSuffixComponents);
313 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800314 {
315 m_minSuffixComponents = readNonNegativeInteger(*val);
316 }
317
318 // MaxSuffixComponents
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700319 val = m_wire.find(Tlv::MaxSuffixComponents);
320 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800321 {
322 m_maxSuffixComponents = readNonNegativeInteger(*val);
323 }
324
Junxiao Shib332e782014-03-31 14:23:46 -0700325 // PublisherPublicKeyLocator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700326 val = m_wire.find(Tlv::KeyLocator);
327 if (val != m_wire.elements_end())
Junxiao Shib332e782014-03-31 14:23:46 -0700328 {
329 m_publisherPublicKeyLocator.wireDecode(*val);
330 }
331
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800332 // Exclude
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700333 val = m_wire.find(Tlv::Exclude);
334 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800335 {
336 m_exclude.wireDecode(*val);
337 }
338
339 // ChildSelector
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700340 val = m_wire.find(Tlv::ChildSelector);
341 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800342 {
343 m_childSelector = readNonNegativeInteger(*val);
344 }
345
346 //MustBeFresh aka AnswerOriginKind
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700347 val = m_wire.find(Tlv::MustBeFresh);
348 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800349 {
350 m_mustBeFresh = true;
351 }
352}
Junxiao Shib332e782014-03-31 14:23:46 -0700353
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800354} // namespace ndn
355
356#endif // NDN_SELECTORS_HPP