blob: dd37e56f339da54fdd65f2626d1166e6dad354f6 [file] [log] [blame]
Alexander Afanasyevc348f832014-02-17 16:35:17 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -07003 * Copyright (C) 2013-2014 Regents of the University of California.
Alexander Afanasyevc348f832014-02-17 16:35:17 -08004 * See COPYING for copyright and distribution information.
5 */
6
7#ifndef NDN_SELECTORS_HPP
8#define NDN_SELECTORS_HPP
9
10#include "common.hpp"
Junxiao Shib332e782014-03-31 14:23:46 -070011#include "key-locator.hpp"
Alexander Afanasyevc348f832014-02-17 16:35:17 -080012#include "exclude.hpp"
13#include "encoding/encoding-buffer.hpp"
14
15namespace ndn {
Junxiao Shib332e782014-03-31 14:23:46 -070016
Alexander Afanasyevc348f832014-02-17 16:35:17 -080017/**
18 * @brief Abstraction implementing Interest selectors
19 */
20class Selectors
21{
Junxiao Shib332e782014-03-31 14:23:46 -070022public:
23 Selectors()
Alexander Afanasyevc348f832014-02-17 16:35:17 -080024 : m_minSuffixComponents(-1)
25 , m_maxSuffixComponents(-1)
26 , m_childSelector(-1)
27 , m_mustBeFresh(false)
28 {
29 }
30
Junxiao Shib332e782014-03-31 14:23:46 -070031 /** @deprecated Selectors().setX(...).setY(...)
32 */
33 Selectors(int minSuffixComponents, int maxSuffixComponents,
Alexander Afanasyevc348f832014-02-17 16:35:17 -080034 const Exclude& exclude,
35 int childSelector,
Junxiao Shib332e782014-03-31 14:23:46 -070036 bool mustBeFresh)
Alexander Afanasyevc348f832014-02-17 16:35:17 -080037 : m_minSuffixComponents(minSuffixComponents)
38 , m_maxSuffixComponents(maxSuffixComponents)
39 , m_exclude(exclude)
40 , m_childSelector(childSelector)
41 , m_mustBeFresh(mustBeFresh)
42 {
43 }
Junxiao Shib332e782014-03-31 14:23:46 -070044
45 Selectors(const Block& wire)
Alexander Afanasyevc348f832014-02-17 16:35:17 -080046 {
47 wireDecode(wire);
48 }
49
50 bool
51 empty() const;
Junxiao Shib332e782014-03-31 14:23:46 -070052
Alexander Afanasyevc348f832014-02-17 16:35:17 -080053 /**
54 * @brief Fast encoding or block size estimation
55 */
56 template<bool T>
57 size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070058 wireEncode(EncodingImpl<T>& block) const;
Junxiao Shib332e782014-03-31 14:23:46 -070059
Alexander Afanasyevc348f832014-02-17 16:35:17 -080060 /**
61 * @brief Encode to a wire format
62 */
63 const Block&
64 wireEncode() const;
65
66 /**
67 * @brief Decode the input from wire format
68 */
Junxiao Shib332e782014-03-31 14:23:46 -070069 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070070 wireDecode(const Block& wire);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080071
72 ///////////////////////////////////////////////////////////////////////////////
73 ///////////////////////////////////////////////////////////////////////////////
74 ///////////////////////////////////////////////////////////////////////////////
Junxiao Shib332e782014-03-31 14:23:46 -070075
76 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -080077 getMinSuffixComponents() const
78 {
79 return m_minSuffixComponents;
80 }
Junxiao Shib332e782014-03-31 14:23:46 -070081
82 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -080083 setMinSuffixComponents(int minSuffixComponents)
84 {
85 m_minSuffixComponents = minSuffixComponents;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070086 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -080087 return *this;
88 }
89
90 //
Junxiao Shib332e782014-03-31 14:23:46 -070091
92 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -080093 getMaxSuffixComponents() const
94 {
95 return m_maxSuffixComponents;
96 }
97
Junxiao Shib332e782014-03-31 14:23:46 -070098 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -080099 setMaxSuffixComponents(int maxSuffixComponents)
100 {
101 m_maxSuffixComponents = maxSuffixComponents;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700102 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800103 return *this;
104 }
Junxiao Shib332e782014-03-31 14:23:46 -0700105
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800106 //
107
Junxiao Shib332e782014-03-31 14:23:46 -0700108 const KeyLocator&
109 getPublisherPublicKeyLocator() const
110 {
111 return m_publisherPublicKeyLocator;
112 }
113
114 Selectors&
115 setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
116 {
117 m_publisherPublicKeyLocator = keyLocator;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700118 m_wire.reset();
Junxiao Shib332e782014-03-31 14:23:46 -0700119 return *this;
120 }
121
122 //
123
124 const Exclude&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800125 getExclude() const
126 {
127 return m_exclude;
128 }
129
Junxiao Shib332e782014-03-31 14:23:46 -0700130 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800131 setExclude(const Exclude& exclude)
132 {
133 m_exclude = exclude;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700134 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800135 return *this;
136 }
137
138 //
Junxiao Shib332e782014-03-31 14:23:46 -0700139
140 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800141 getChildSelector() const
142 {
143 return m_childSelector;
144 }
145
Junxiao Shib332e782014-03-31 14:23:46 -0700146 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800147 setChildSelector(int childSelector)
148 {
149 m_childSelector = childSelector;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700150 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800151 return *this;
152 }
153
154 //
155
Junxiao Shib332e782014-03-31 14:23:46 -0700156 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800157 getMustBeFresh() const
158 {
159 return m_mustBeFresh;
160 }
161
Junxiao Shib332e782014-03-31 14:23:46 -0700162 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800163 setMustBeFresh(bool mustBeFresh)
164 {
165 m_mustBeFresh = mustBeFresh;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700166 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800167 return *this;
168 }
169
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700170public: // EqualityComparable concept
171 bool
172 operator==(const Selectors& other) const
173 {
174 return wireEncode() == other.wireEncode();
175 }
176
177 bool
178 operator!=(const Selectors& other) const
179 {
180 return !(*this == other);
181 }
182
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800183private:
184 int m_minSuffixComponents;
Junxiao Shib332e782014-03-31 14:23:46 -0700185 int m_maxSuffixComponents;
186 KeyLocator m_publisherPublicKeyLocator;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800187 Exclude m_exclude;
188 int m_childSelector;
189 bool m_mustBeFresh;
190
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700191 mutable Block m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800192};
193
194inline bool
195Selectors::empty() const
196{
197 return
198 (m_minSuffixComponents < 0 &&
199 m_maxSuffixComponents < 0 &&
Junxiao Shib332e782014-03-31 14:23:46 -0700200 m_publisherPublicKeyLocator.empty() &&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800201 m_exclude.empty() &&
202 m_childSelector < 0 &&
203 !m_mustBeFresh);
204}
205
206template<bool T>
207inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700208Selectors::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800209{
210 size_t total_len = 0;
211
212 // Selectors ::= SELECTORS-TYPE TLV-LENGTH
213 // MinSuffixComponents?
214 // MaxSuffixComponents?
215 // PublisherPublicKeyLocator?
216 // Exclude?
217 // ChildSelector?
Junxiao Shib332e782014-03-31 14:23:46 -0700218 // MustBeFresh?
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800219
220 // (reverse encoding)
221
222 // MustBeFresh
223 if (getMustBeFresh())
224 {
225 total_len += prependBooleanBlock(block, Tlv::MustBeFresh);
226 }
227
228 // ChildSelector
229 if (getChildSelector() >= 0)
230 {
231 total_len += prependNonNegativeIntegerBlock(block, Tlv::ChildSelector, getChildSelector());
232 }
233
234 // Exclude
235 if (!getExclude().empty())
236 {
237 total_len += getExclude().wireEncode(block);
238 }
Junxiao Shib332e782014-03-31 14:23:46 -0700239
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800240 // PublisherPublicKeyLocator
Junxiao Shib332e782014-03-31 14:23:46 -0700241 if (!getPublisherPublicKeyLocator().empty())
242 {
243 total_len += getPublisherPublicKeyLocator().wireEncode(block);
244 }
245
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800246 // MaxSuffixComponents
247 if (getMaxSuffixComponents() >= 0)
248 {
249 total_len += prependNonNegativeIntegerBlock(block, Tlv::MaxSuffixComponents,
250 getMaxSuffixComponents());
251 }
252
253 // MinSuffixComponents
254 if (getMinSuffixComponents() >= 0)
255 {
256 total_len += prependNonNegativeIntegerBlock(block, Tlv::MinSuffixComponents,
257 getMinSuffixComponents());
258 }
Junxiao Shib332e782014-03-31 14:23:46 -0700259
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800260 total_len += block.prependVarNumber(total_len);
261 total_len += block.prependVarNumber(Tlv::Selectors);
262 return total_len;
263}
264
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700265inline const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800266Selectors::wireEncode() const
267{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700268 if (m_wire.hasWire())
269 return m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800270
271 EncodingEstimator estimator;
272 size_t estimatedSize = wireEncode(estimator);
Junxiao Shib332e782014-03-31 14:23:46 -0700273
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800274 EncodingBuffer buffer(estimatedSize, 0);
275 wireEncode(buffer);
276
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700277 m_wire = buffer.block();
278 return m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800279}
280
281inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700282Selectors::wireDecode(const Block& wire)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800283{
284 if (wire.type() != Tlv::Selectors)
285 throw Tlv::Error("Unexpected TLV type when decoding Selectors");
286
287 *this = Selectors();
Junxiao Shib332e782014-03-31 14:23:46 -0700288
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700289 m_wire = wire;
290 m_wire.parse();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800291
292 // MinSuffixComponents
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700293 Block::element_const_iterator val = m_wire.find(Tlv::MinSuffixComponents);
294 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800295 {
296 m_minSuffixComponents = readNonNegativeInteger(*val);
297 }
298
299 // MaxSuffixComponents
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700300 val = m_wire.find(Tlv::MaxSuffixComponents);
301 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800302 {
303 m_maxSuffixComponents = readNonNegativeInteger(*val);
304 }
305
Junxiao Shib332e782014-03-31 14:23:46 -0700306 // PublisherPublicKeyLocator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700307 val = m_wire.find(Tlv::KeyLocator);
308 if (val != m_wire.elements_end())
Junxiao Shib332e782014-03-31 14:23:46 -0700309 {
310 m_publisherPublicKeyLocator.wireDecode(*val);
311 }
312
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800313 // Exclude
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700314 val = m_wire.find(Tlv::Exclude);
315 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800316 {
317 m_exclude.wireDecode(*val);
318 }
319
320 // ChildSelector
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700321 val = m_wire.find(Tlv::ChildSelector);
322 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800323 {
324 m_childSelector = readNonNegativeInteger(*val);
325 }
326
327 //MustBeFresh aka AnswerOriginKind
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700328 val = m_wire.find(Tlv::MustBeFresh);
329 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800330 {
331 m_mustBeFresh = true;
332 }
333}
Junxiao Shib332e782014-03-31 14:23:46 -0700334
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800335} // namespace ndn
336
337#endif // NDN_SELECTORS_HPP