blob: 361ad6a8a4cf40a85e0e47db5ed81373827bfb59 [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
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070045 /**
46 * @brief Create from wire encoding
47 */
Junxiao Shib332e782014-03-31 14:23:46 -070048 Selectors(const Block& wire)
Alexander Afanasyevc348f832014-02-17 16:35:17 -080049 {
50 wireDecode(wire);
51 }
52
53 bool
54 empty() const;
Junxiao Shib332e782014-03-31 14:23:46 -070055
Alexander Afanasyevc348f832014-02-17 16:35:17 -080056 /**
57 * @brief Fast encoding or block size estimation
58 */
59 template<bool T>
60 size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070061 wireEncode(EncodingImpl<T>& block) const;
Junxiao Shib332e782014-03-31 14:23:46 -070062
Alexander Afanasyevc348f832014-02-17 16:35:17 -080063 /**
64 * @brief Encode to a wire format
65 */
66 const Block&
67 wireEncode() const;
68
69 /**
70 * @brief Decode the input from wire format
71 */
Junxiao Shib332e782014-03-31 14:23:46 -070072 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070073 wireDecode(const Block& wire);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080074
75 ///////////////////////////////////////////////////////////////////////////////
76 ///////////////////////////////////////////////////////////////////////////////
77 ///////////////////////////////////////////////////////////////////////////////
Junxiao Shib332e782014-03-31 14:23:46 -070078
79 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -080080 getMinSuffixComponents() const
81 {
82 return m_minSuffixComponents;
83 }
Junxiao Shib332e782014-03-31 14:23:46 -070084
85 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -080086 setMinSuffixComponents(int minSuffixComponents)
87 {
88 m_minSuffixComponents = minSuffixComponents;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070089 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -080090 return *this;
91 }
92
93 //
Junxiao Shib332e782014-03-31 14:23:46 -070094
95 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -080096 getMaxSuffixComponents() const
97 {
98 return m_maxSuffixComponents;
99 }
100
Junxiao Shib332e782014-03-31 14:23:46 -0700101 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800102 setMaxSuffixComponents(int maxSuffixComponents)
103 {
104 m_maxSuffixComponents = maxSuffixComponents;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700105 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800106 return *this;
107 }
Junxiao Shib332e782014-03-31 14:23:46 -0700108
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800109 //
110
Junxiao Shib332e782014-03-31 14:23:46 -0700111 const KeyLocator&
112 getPublisherPublicKeyLocator() const
113 {
114 return m_publisherPublicKeyLocator;
115 }
116
117 Selectors&
118 setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
119 {
120 m_publisherPublicKeyLocator = keyLocator;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700121 m_wire.reset();
Junxiao Shib332e782014-03-31 14:23:46 -0700122 return *this;
123 }
124
125 //
126
127 const Exclude&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800128 getExclude() const
129 {
130 return m_exclude;
131 }
132
Junxiao Shib332e782014-03-31 14:23:46 -0700133 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800134 setExclude(const Exclude& exclude)
135 {
136 m_exclude = exclude;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700137 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800138 return *this;
139 }
140
141 //
Junxiao Shib332e782014-03-31 14:23:46 -0700142
143 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800144 getChildSelector() const
145 {
146 return m_childSelector;
147 }
148
Junxiao Shib332e782014-03-31 14:23:46 -0700149 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800150 setChildSelector(int childSelector)
151 {
152 m_childSelector = childSelector;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700153 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800154 return *this;
155 }
156
157 //
158
Junxiao Shib332e782014-03-31 14:23:46 -0700159 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800160 getMustBeFresh() const
161 {
162 return m_mustBeFresh;
163 }
164
Junxiao Shib332e782014-03-31 14:23:46 -0700165 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800166 setMustBeFresh(bool mustBeFresh)
167 {
168 m_mustBeFresh = mustBeFresh;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700169 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800170 return *this;
171 }
172
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700173public: // EqualityComparable concept
174 bool
175 operator==(const Selectors& other) const
176 {
177 return wireEncode() == other.wireEncode();
178 }
179
180 bool
181 operator!=(const Selectors& other) const
182 {
183 return !(*this == other);
184 }
185
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800186private:
187 int m_minSuffixComponents;
Junxiao Shib332e782014-03-31 14:23:46 -0700188 int m_maxSuffixComponents;
189 KeyLocator m_publisherPublicKeyLocator;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800190 Exclude m_exclude;
191 int m_childSelector;
192 bool m_mustBeFresh;
193
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700194 mutable Block m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800195};
196
197inline bool
198Selectors::empty() const
199{
200 return
201 (m_minSuffixComponents < 0 &&
202 m_maxSuffixComponents < 0 &&
Junxiao Shib332e782014-03-31 14:23:46 -0700203 m_publisherPublicKeyLocator.empty() &&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800204 m_exclude.empty() &&
205 m_childSelector < 0 &&
206 !m_mustBeFresh);
207}
208
209template<bool T>
210inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700211Selectors::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800212{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700213 size_t totalLength = 0;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800214
215 // Selectors ::= SELECTORS-TYPE TLV-LENGTH
216 // MinSuffixComponents?
217 // MaxSuffixComponents?
218 // PublisherPublicKeyLocator?
219 // Exclude?
220 // ChildSelector?
Junxiao Shib332e782014-03-31 14:23:46 -0700221 // MustBeFresh?
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800222
223 // (reverse encoding)
224
225 // MustBeFresh
226 if (getMustBeFresh())
227 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700228 totalLength += prependBooleanBlock(block, Tlv::MustBeFresh);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800229 }
230
231 // ChildSelector
232 if (getChildSelector() >= 0)
233 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700234 totalLength += prependNonNegativeIntegerBlock(block, Tlv::ChildSelector, getChildSelector());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800235 }
236
237 // Exclude
238 if (!getExclude().empty())
239 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700240 totalLength += getExclude().wireEncode(block);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800241 }
Junxiao Shib332e782014-03-31 14:23:46 -0700242
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800243 // PublisherPublicKeyLocator
Junxiao Shib332e782014-03-31 14:23:46 -0700244 if (!getPublisherPublicKeyLocator().empty())
245 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700246 totalLength += getPublisherPublicKeyLocator().wireEncode(block);
Junxiao Shib332e782014-03-31 14:23:46 -0700247 }
248
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800249 // MaxSuffixComponents
250 if (getMaxSuffixComponents() >= 0)
251 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700252 totalLength += prependNonNegativeIntegerBlock(block, Tlv::MaxSuffixComponents,
253 getMaxSuffixComponents());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800254 }
255
256 // MinSuffixComponents
257 if (getMinSuffixComponents() >= 0)
258 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700259 totalLength += prependNonNegativeIntegerBlock(block, Tlv::MinSuffixComponents,
260 getMinSuffixComponents());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800261 }
Junxiao Shib332e782014-03-31 14:23:46 -0700262
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700263 totalLength += block.prependVarNumber(totalLength);
264 totalLength += block.prependVarNumber(Tlv::Selectors);
265 return totalLength;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800266}
267
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700268inline const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800269Selectors::wireEncode() const
270{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700271 if (m_wire.hasWire())
272 return m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800273
274 EncodingEstimator estimator;
275 size_t estimatedSize = wireEncode(estimator);
Junxiao Shib332e782014-03-31 14:23:46 -0700276
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800277 EncodingBuffer buffer(estimatedSize, 0);
278 wireEncode(buffer);
279
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700280 m_wire = buffer.block();
281 return m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800282}
283
284inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700285Selectors::wireDecode(const Block& wire)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800286{
287 if (wire.type() != Tlv::Selectors)
288 throw Tlv::Error("Unexpected TLV type when decoding Selectors");
289
290 *this = Selectors();
Junxiao Shib332e782014-03-31 14:23:46 -0700291
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700292 m_wire = wire;
293 m_wire.parse();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800294
295 // MinSuffixComponents
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700296 Block::element_const_iterator val = m_wire.find(Tlv::MinSuffixComponents);
297 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800298 {
299 m_minSuffixComponents = readNonNegativeInteger(*val);
300 }
301
302 // MaxSuffixComponents
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700303 val = m_wire.find(Tlv::MaxSuffixComponents);
304 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800305 {
306 m_maxSuffixComponents = readNonNegativeInteger(*val);
307 }
308
Junxiao Shib332e782014-03-31 14:23:46 -0700309 // PublisherPublicKeyLocator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700310 val = m_wire.find(Tlv::KeyLocator);
311 if (val != m_wire.elements_end())
Junxiao Shib332e782014-03-31 14:23:46 -0700312 {
313 m_publisherPublicKeyLocator.wireDecode(*val);
314 }
315
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800316 // Exclude
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700317 val = m_wire.find(Tlv::Exclude);
318 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800319 {
320 m_exclude.wireDecode(*val);
321 }
322
323 // ChildSelector
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700324 val = m_wire.find(Tlv::ChildSelector);
325 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800326 {
327 m_childSelector = readNonNegativeInteger(*val);
328 }
329
330 //MustBeFresh aka AnswerOriginKind
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700331 val = m_wire.find(Tlv::MustBeFresh);
332 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800333 {
334 m_mustBeFresh = true;
335 }
336}
Junxiao Shib332e782014-03-31 14:23:46 -0700337
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800338} // namespace ndn
339
340#endif // NDN_SELECTORS_HPP