blob: c4fcb42a782acc319731667544a3865ccda1de57 [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"
Alexander Afanasyev15f67312014-07-22 15:11:09 -070029#include "encoding/block-helpers.hpp"
Alexander Afanasyevc348f832014-02-17 16:35:17 -080030
31namespace ndn {
Junxiao Shib332e782014-03-31 14:23:46 -070032
Alexander Afanasyevc348f832014-02-17 16:35:17 -080033/**
34 * @brief Abstraction implementing Interest selectors
35 */
36class Selectors
37{
Junxiao Shib332e782014-03-31 14:23:46 -070038public:
39 Selectors()
Alexander Afanasyevc348f832014-02-17 16:35:17 -080040 : m_minSuffixComponents(-1)
41 , m_maxSuffixComponents(-1)
42 , m_childSelector(-1)
43 , m_mustBeFresh(false)
44 {
45 }
46
Junxiao Shib332e782014-03-31 14:23:46 -070047 /** @deprecated Selectors().setX(...).setY(...)
48 */
Alexander Afanasyev9c578182014-05-14 17:28:28 -070049 DEPRECATED(
Junxiao Shib332e782014-03-31 14:23:46 -070050 Selectors(int minSuffixComponents, int maxSuffixComponents,
Alexander Afanasyevc348f832014-02-17 16:35:17 -080051 const Exclude& exclude,
52 int childSelector,
Alexander Afanasyev9c578182014-05-14 17:28:28 -070053 bool mustBeFresh))
Alexander Afanasyevc348f832014-02-17 16:35:17 -080054 : m_minSuffixComponents(minSuffixComponents)
55 , m_maxSuffixComponents(maxSuffixComponents)
56 , m_exclude(exclude)
57 , m_childSelector(childSelector)
58 , m_mustBeFresh(mustBeFresh)
59 {
60 }
Junxiao Shib332e782014-03-31 14:23:46 -070061
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070062 /**
63 * @brief Create from wire encoding
64 */
Junxiao Shib332e782014-03-31 14:23:46 -070065 Selectors(const Block& wire)
Alexander Afanasyevc348f832014-02-17 16:35:17 -080066 {
67 wireDecode(wire);
68 }
69
70 bool
71 empty() const;
Junxiao Shib332e782014-03-31 14:23:46 -070072
Alexander Afanasyevc348f832014-02-17 16:35:17 -080073 /**
74 * @brief Fast encoding or block size estimation
75 */
76 template<bool T>
77 size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070078 wireEncode(EncodingImpl<T>& block) const;
Junxiao Shib332e782014-03-31 14:23:46 -070079
Alexander Afanasyevc348f832014-02-17 16:35:17 -080080 /**
81 * @brief Encode to a wire format
82 */
83 const Block&
84 wireEncode() const;
85
86 /**
87 * @brief Decode the input from wire format
88 */
Junxiao Shib332e782014-03-31 14:23:46 -070089 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070090 wireDecode(const Block& wire);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080091
92 ///////////////////////////////////////////////////////////////////////////////
93 ///////////////////////////////////////////////////////////////////////////////
94 ///////////////////////////////////////////////////////////////////////////////
Junxiao Shib332e782014-03-31 14:23:46 -070095
96 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -080097 getMinSuffixComponents() const
98 {
99 return m_minSuffixComponents;
100 }
Junxiao Shib332e782014-03-31 14:23:46 -0700101
102 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800103 setMinSuffixComponents(int minSuffixComponents)
104 {
105 m_minSuffixComponents = minSuffixComponents;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700106 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800107 return *this;
108 }
109
110 //
Junxiao Shib332e782014-03-31 14:23:46 -0700111
112 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800113 getMaxSuffixComponents() const
114 {
115 return m_maxSuffixComponents;
116 }
117
Junxiao Shib332e782014-03-31 14:23:46 -0700118 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800119 setMaxSuffixComponents(int maxSuffixComponents)
120 {
121 m_maxSuffixComponents = maxSuffixComponents;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700122 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800123 return *this;
124 }
Junxiao Shib332e782014-03-31 14:23:46 -0700125
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800126 //
127
Junxiao Shib332e782014-03-31 14:23:46 -0700128 const KeyLocator&
129 getPublisherPublicKeyLocator() const
130 {
131 return m_publisherPublicKeyLocator;
132 }
133
134 Selectors&
135 setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
136 {
137 m_publisherPublicKeyLocator = keyLocator;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700138 m_wire.reset();
Junxiao Shib332e782014-03-31 14:23:46 -0700139 return *this;
140 }
141
142 //
143
144 const Exclude&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800145 getExclude() const
146 {
147 return m_exclude;
148 }
149
Junxiao Shib332e782014-03-31 14:23:46 -0700150 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800151 setExclude(const Exclude& exclude)
152 {
153 m_exclude = exclude;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700154 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800155 return *this;
156 }
157
158 //
Junxiao Shib332e782014-03-31 14:23:46 -0700159
160 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800161 getChildSelector() const
162 {
163 return m_childSelector;
164 }
165
Junxiao Shib332e782014-03-31 14:23:46 -0700166 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800167 setChildSelector(int childSelector)
168 {
169 m_childSelector = childSelector;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700170 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800171 return *this;
172 }
173
174 //
175
Junxiao Shib332e782014-03-31 14:23:46 -0700176 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800177 getMustBeFresh() const
178 {
179 return m_mustBeFresh;
180 }
181
Junxiao Shib332e782014-03-31 14:23:46 -0700182 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800183 setMustBeFresh(bool mustBeFresh)
184 {
185 m_mustBeFresh = mustBeFresh;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700186 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800187 return *this;
188 }
189
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700190public: // EqualityComparable concept
191 bool
192 operator==(const Selectors& other) const
193 {
194 return wireEncode() == other.wireEncode();
195 }
196
197 bool
198 operator!=(const Selectors& other) const
199 {
200 return !(*this == other);
201 }
202
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800203private:
204 int m_minSuffixComponents;
Junxiao Shib332e782014-03-31 14:23:46 -0700205 int m_maxSuffixComponents;
206 KeyLocator m_publisherPublicKeyLocator;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800207 Exclude m_exclude;
208 int m_childSelector;
209 bool m_mustBeFresh;
210
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700211 mutable Block m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800212};
213
214inline bool
215Selectors::empty() const
216{
217 return
218 (m_minSuffixComponents < 0 &&
219 m_maxSuffixComponents < 0 &&
Junxiao Shib332e782014-03-31 14:23:46 -0700220 m_publisherPublicKeyLocator.empty() &&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800221 m_exclude.empty() &&
222 m_childSelector < 0 &&
223 !m_mustBeFresh);
224}
225
226template<bool T>
227inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700228Selectors::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800229{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700230 size_t totalLength = 0;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800231
232 // Selectors ::= SELECTORS-TYPE TLV-LENGTH
233 // MinSuffixComponents?
234 // MaxSuffixComponents?
235 // PublisherPublicKeyLocator?
236 // Exclude?
237 // ChildSelector?
Junxiao Shib332e782014-03-31 14:23:46 -0700238 // MustBeFresh?
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800239
240 // (reverse encoding)
241
242 // MustBeFresh
243 if (getMustBeFresh())
244 {
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600245 totalLength += prependBooleanBlock(block, tlv::MustBeFresh);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800246 }
247
248 // ChildSelector
249 if (getChildSelector() >= 0)
250 {
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600251 totalLength += prependNonNegativeIntegerBlock(block, tlv::ChildSelector, getChildSelector());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800252 }
253
254 // Exclude
255 if (!getExclude().empty())
256 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700257 totalLength += getExclude().wireEncode(block);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800258 }
Junxiao Shib332e782014-03-31 14:23:46 -0700259
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800260 // PublisherPublicKeyLocator
Junxiao Shib332e782014-03-31 14:23:46 -0700261 if (!getPublisherPublicKeyLocator().empty())
262 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700263 totalLength += getPublisherPublicKeyLocator().wireEncode(block);
Junxiao Shib332e782014-03-31 14:23:46 -0700264 }
265
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800266 // MaxSuffixComponents
267 if (getMaxSuffixComponents() >= 0)
268 {
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600269 totalLength += prependNonNegativeIntegerBlock(block, tlv::MaxSuffixComponents,
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700270 getMaxSuffixComponents());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800271 }
272
273 // MinSuffixComponents
274 if (getMinSuffixComponents() >= 0)
275 {
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600276 totalLength += prependNonNegativeIntegerBlock(block, tlv::MinSuffixComponents,
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700277 getMinSuffixComponents());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800278 }
Junxiao Shib332e782014-03-31 14:23:46 -0700279
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700280 totalLength += block.prependVarNumber(totalLength);
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600281 totalLength += block.prependVarNumber(tlv::Selectors);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700282 return totalLength;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800283}
284
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700285inline const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800286Selectors::wireEncode() const
287{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700288 if (m_wire.hasWire())
289 return m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800290
291 EncodingEstimator estimator;
292 size_t estimatedSize = wireEncode(estimator);
Junxiao Shib332e782014-03-31 14:23:46 -0700293
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800294 EncodingBuffer buffer(estimatedSize, 0);
295 wireEncode(buffer);
296
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700297 m_wire = buffer.block();
298 return m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800299}
300
301inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700302Selectors::wireDecode(const Block& wire)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800303{
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600304 if (wire.type() != tlv::Selectors)
305 throw tlv::Error("Unexpected TLV type when decoding Selectors");
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800306
307 *this = Selectors();
Junxiao Shib332e782014-03-31 14:23:46 -0700308
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700309 m_wire = wire;
310 m_wire.parse();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800311
312 // MinSuffixComponents
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600313 Block::element_const_iterator val = m_wire.find(tlv::MinSuffixComponents);
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700314 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800315 {
316 m_minSuffixComponents = readNonNegativeInteger(*val);
317 }
318
319 // MaxSuffixComponents
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600320 val = m_wire.find(tlv::MaxSuffixComponents);
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700321 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800322 {
323 m_maxSuffixComponents = readNonNegativeInteger(*val);
324 }
325
Junxiao Shib332e782014-03-31 14:23:46 -0700326 // PublisherPublicKeyLocator
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600327 val = m_wire.find(tlv::KeyLocator);
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700328 if (val != m_wire.elements_end())
Junxiao Shib332e782014-03-31 14:23:46 -0700329 {
330 m_publisherPublicKeyLocator.wireDecode(*val);
331 }
332
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800333 // Exclude
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600334 val = m_wire.find(tlv::Exclude);
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700335 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800336 {
337 m_exclude.wireDecode(*val);
338 }
339
340 // ChildSelector
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600341 val = m_wire.find(tlv::ChildSelector);
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700342 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800343 {
344 m_childSelector = readNonNegativeInteger(*val);
345 }
346
347 //MustBeFresh aka AnswerOriginKind
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600348 val = m_wire.find(tlv::MustBeFresh);
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700349 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800350 {
351 m_mustBeFresh = true;
352 }
353}
Junxiao Shib332e782014-03-31 14:23:46 -0700354
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800355} // namespace ndn
356
357#endif // NDN_SELECTORS_HPP