blob: 4503c17cd3dcbad407b98d39d6fb85a369dd3699 [file] [log] [blame]
Alexander Afanasyevc348f832014-02-17 16:35:17 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07003 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
5 *
6 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
7 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
8 *
9 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
Alexander Afanasyevc348f832014-02-17 16:35:17 -080011 */
12
13#ifndef NDN_SELECTORS_HPP
14#define NDN_SELECTORS_HPP
15
16#include "common.hpp"
Junxiao Shib332e782014-03-31 14:23:46 -070017#include "key-locator.hpp"
Alexander Afanasyevc348f832014-02-17 16:35:17 -080018#include "exclude.hpp"
19#include "encoding/encoding-buffer.hpp"
20
21namespace ndn {
Junxiao Shib332e782014-03-31 14:23:46 -070022
Alexander Afanasyevc348f832014-02-17 16:35:17 -080023/**
24 * @brief Abstraction implementing Interest selectors
25 */
26class Selectors
27{
Junxiao Shib332e782014-03-31 14:23:46 -070028public:
29 Selectors()
Alexander Afanasyevc348f832014-02-17 16:35:17 -080030 : m_minSuffixComponents(-1)
31 , m_maxSuffixComponents(-1)
32 , m_childSelector(-1)
33 , m_mustBeFresh(false)
34 {
35 }
36
Junxiao Shib332e782014-03-31 14:23:46 -070037 /** @deprecated Selectors().setX(...).setY(...)
38 */
39 Selectors(int minSuffixComponents, int maxSuffixComponents,
Alexander Afanasyevc348f832014-02-17 16:35:17 -080040 const Exclude& exclude,
41 int childSelector,
Junxiao Shib332e782014-03-31 14:23:46 -070042 bool mustBeFresh)
Alexander Afanasyevc348f832014-02-17 16:35:17 -080043 : m_minSuffixComponents(minSuffixComponents)
44 , m_maxSuffixComponents(maxSuffixComponents)
45 , m_exclude(exclude)
46 , m_childSelector(childSelector)
47 , m_mustBeFresh(mustBeFresh)
48 {
49 }
Junxiao Shib332e782014-03-31 14:23:46 -070050
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070051 /**
52 * @brief Create from wire encoding
53 */
Junxiao Shib332e782014-03-31 14:23:46 -070054 Selectors(const Block& wire)
Alexander Afanasyevc348f832014-02-17 16:35:17 -080055 {
56 wireDecode(wire);
57 }
58
59 bool
60 empty() const;
Junxiao Shib332e782014-03-31 14:23:46 -070061
Alexander Afanasyevc348f832014-02-17 16:35:17 -080062 /**
63 * @brief Fast encoding or block size estimation
64 */
65 template<bool T>
66 size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070067 wireEncode(EncodingImpl<T>& block) const;
Junxiao Shib332e782014-03-31 14:23:46 -070068
Alexander Afanasyevc348f832014-02-17 16:35:17 -080069 /**
70 * @brief Encode to a wire format
71 */
72 const Block&
73 wireEncode() const;
74
75 /**
76 * @brief Decode the input from wire format
77 */
Junxiao Shib332e782014-03-31 14:23:46 -070078 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070079 wireDecode(const Block& wire);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080080
81 ///////////////////////////////////////////////////////////////////////////////
82 ///////////////////////////////////////////////////////////////////////////////
83 ///////////////////////////////////////////////////////////////////////////////
Junxiao Shib332e782014-03-31 14:23:46 -070084
85 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -080086 getMinSuffixComponents() const
87 {
88 return m_minSuffixComponents;
89 }
Junxiao Shib332e782014-03-31 14:23:46 -070090
91 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -080092 setMinSuffixComponents(int minSuffixComponents)
93 {
94 m_minSuffixComponents = minSuffixComponents;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070095 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -080096 return *this;
97 }
98
99 //
Junxiao Shib332e782014-03-31 14:23:46 -0700100
101 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800102 getMaxSuffixComponents() const
103 {
104 return m_maxSuffixComponents;
105 }
106
Junxiao Shib332e782014-03-31 14:23:46 -0700107 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800108 setMaxSuffixComponents(int maxSuffixComponents)
109 {
110 m_maxSuffixComponents = maxSuffixComponents;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700111 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800112 return *this;
113 }
Junxiao Shib332e782014-03-31 14:23:46 -0700114
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800115 //
116
Junxiao Shib332e782014-03-31 14:23:46 -0700117 const KeyLocator&
118 getPublisherPublicKeyLocator() const
119 {
120 return m_publisherPublicKeyLocator;
121 }
122
123 Selectors&
124 setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
125 {
126 m_publisherPublicKeyLocator = keyLocator;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700127 m_wire.reset();
Junxiao Shib332e782014-03-31 14:23:46 -0700128 return *this;
129 }
130
131 //
132
133 const Exclude&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800134 getExclude() const
135 {
136 return m_exclude;
137 }
138
Junxiao Shib332e782014-03-31 14:23:46 -0700139 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800140 setExclude(const Exclude& exclude)
141 {
142 m_exclude = exclude;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700143 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800144 return *this;
145 }
146
147 //
Junxiao Shib332e782014-03-31 14:23:46 -0700148
149 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800150 getChildSelector() const
151 {
152 return m_childSelector;
153 }
154
Junxiao Shib332e782014-03-31 14:23:46 -0700155 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800156 setChildSelector(int childSelector)
157 {
158 m_childSelector = childSelector;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700159 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800160 return *this;
161 }
162
163 //
164
Junxiao Shib332e782014-03-31 14:23:46 -0700165 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800166 getMustBeFresh() const
167 {
168 return m_mustBeFresh;
169 }
170
Junxiao Shib332e782014-03-31 14:23:46 -0700171 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800172 setMustBeFresh(bool mustBeFresh)
173 {
174 m_mustBeFresh = mustBeFresh;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700175 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800176 return *this;
177 }
178
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700179public: // EqualityComparable concept
180 bool
181 operator==(const Selectors& other) const
182 {
183 return wireEncode() == other.wireEncode();
184 }
185
186 bool
187 operator!=(const Selectors& other) const
188 {
189 return !(*this == other);
190 }
191
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800192private:
193 int m_minSuffixComponents;
Junxiao Shib332e782014-03-31 14:23:46 -0700194 int m_maxSuffixComponents;
195 KeyLocator m_publisherPublicKeyLocator;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800196 Exclude m_exclude;
197 int m_childSelector;
198 bool m_mustBeFresh;
199
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700200 mutable Block m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800201};
202
203inline bool
204Selectors::empty() const
205{
206 return
207 (m_minSuffixComponents < 0 &&
208 m_maxSuffixComponents < 0 &&
Junxiao Shib332e782014-03-31 14:23:46 -0700209 m_publisherPublicKeyLocator.empty() &&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800210 m_exclude.empty() &&
211 m_childSelector < 0 &&
212 !m_mustBeFresh);
213}
214
215template<bool T>
216inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700217Selectors::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800218{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700219 size_t totalLength = 0;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800220
221 // Selectors ::= SELECTORS-TYPE TLV-LENGTH
222 // MinSuffixComponents?
223 // MaxSuffixComponents?
224 // PublisherPublicKeyLocator?
225 // Exclude?
226 // ChildSelector?
Junxiao Shib332e782014-03-31 14:23:46 -0700227 // MustBeFresh?
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800228
229 // (reverse encoding)
230
231 // MustBeFresh
232 if (getMustBeFresh())
233 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700234 totalLength += prependBooleanBlock(block, Tlv::MustBeFresh);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800235 }
236
237 // ChildSelector
238 if (getChildSelector() >= 0)
239 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700240 totalLength += prependNonNegativeIntegerBlock(block, Tlv::ChildSelector, getChildSelector());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800241 }
242
243 // Exclude
244 if (!getExclude().empty())
245 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700246 totalLength += getExclude().wireEncode(block);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800247 }
Junxiao Shib332e782014-03-31 14:23:46 -0700248
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800249 // PublisherPublicKeyLocator
Junxiao Shib332e782014-03-31 14:23:46 -0700250 if (!getPublisherPublicKeyLocator().empty())
251 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700252 totalLength += getPublisherPublicKeyLocator().wireEncode(block);
Junxiao Shib332e782014-03-31 14:23:46 -0700253 }
254
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800255 // MaxSuffixComponents
256 if (getMaxSuffixComponents() >= 0)
257 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700258 totalLength += prependNonNegativeIntegerBlock(block, Tlv::MaxSuffixComponents,
259 getMaxSuffixComponents());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800260 }
261
262 // MinSuffixComponents
263 if (getMinSuffixComponents() >= 0)
264 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700265 totalLength += prependNonNegativeIntegerBlock(block, Tlv::MinSuffixComponents,
266 getMinSuffixComponents());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800267 }
Junxiao Shib332e782014-03-31 14:23:46 -0700268
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700269 totalLength += block.prependVarNumber(totalLength);
270 totalLength += block.prependVarNumber(Tlv::Selectors);
271 return totalLength;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800272}
273
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700274inline const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800275Selectors::wireEncode() const
276{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700277 if (m_wire.hasWire())
278 return m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800279
280 EncodingEstimator estimator;
281 size_t estimatedSize = wireEncode(estimator);
Junxiao Shib332e782014-03-31 14:23:46 -0700282
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800283 EncodingBuffer buffer(estimatedSize, 0);
284 wireEncode(buffer);
285
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700286 m_wire = buffer.block();
287 return m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800288}
289
290inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700291Selectors::wireDecode(const Block& wire)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800292{
293 if (wire.type() != Tlv::Selectors)
294 throw Tlv::Error("Unexpected TLV type when decoding Selectors");
295
296 *this = Selectors();
Junxiao Shib332e782014-03-31 14:23:46 -0700297
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700298 m_wire = wire;
299 m_wire.parse();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800300
301 // MinSuffixComponents
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700302 Block::element_const_iterator val = m_wire.find(Tlv::MinSuffixComponents);
303 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800304 {
305 m_minSuffixComponents = readNonNegativeInteger(*val);
306 }
307
308 // MaxSuffixComponents
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700309 val = m_wire.find(Tlv::MaxSuffixComponents);
310 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800311 {
312 m_maxSuffixComponents = readNonNegativeInteger(*val);
313 }
314
Junxiao Shib332e782014-03-31 14:23:46 -0700315 // PublisherPublicKeyLocator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700316 val = m_wire.find(Tlv::KeyLocator);
317 if (val != m_wire.elements_end())
Junxiao Shib332e782014-03-31 14:23:46 -0700318 {
319 m_publisherPublicKeyLocator.wireDecode(*val);
320 }
321
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800322 // Exclude
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700323 val = m_wire.find(Tlv::Exclude);
324 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800325 {
326 m_exclude.wireDecode(*val);
327 }
328
329 // ChildSelector
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700330 val = m_wire.find(Tlv::ChildSelector);
331 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800332 {
333 m_childSelector = readNonNegativeInteger(*val);
334 }
335
336 //MustBeFresh aka AnswerOriginKind
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700337 val = m_wire.find(Tlv::MustBeFresh);
338 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800339 {
340 m_mustBeFresh = true;
341 }
342}
Junxiao Shib332e782014-03-31 14:23:46 -0700343
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800344} // namespace ndn
345
346#endif // NDN_SELECTORS_HPP