blob: 4e90ee7acf15698955d6daaeb845d54abb2d4645 [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 */
Alexander Afanasyev9c578182014-05-14 17:28:28 -070039 DEPRECATED(
Junxiao Shib332e782014-03-31 14:23:46 -070040 Selectors(int minSuffixComponents, int maxSuffixComponents,
Alexander Afanasyevc348f832014-02-17 16:35:17 -080041 const Exclude& exclude,
42 int childSelector,
Alexander Afanasyev9c578182014-05-14 17:28:28 -070043 bool mustBeFresh))
Alexander Afanasyevc348f832014-02-17 16:35:17 -080044 : m_minSuffixComponents(minSuffixComponents)
45 , m_maxSuffixComponents(maxSuffixComponents)
46 , m_exclude(exclude)
47 , m_childSelector(childSelector)
48 , m_mustBeFresh(mustBeFresh)
49 {
50 }
Junxiao Shib332e782014-03-31 14:23:46 -070051
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070052 /**
53 * @brief Create from wire encoding
54 */
Junxiao Shib332e782014-03-31 14:23:46 -070055 Selectors(const Block& wire)
Alexander Afanasyevc348f832014-02-17 16:35:17 -080056 {
57 wireDecode(wire);
58 }
59
60 bool
61 empty() const;
Junxiao Shib332e782014-03-31 14:23:46 -070062
Alexander Afanasyevc348f832014-02-17 16:35:17 -080063 /**
64 * @brief Fast encoding or block size estimation
65 */
66 template<bool T>
67 size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070068 wireEncode(EncodingImpl<T>& block) const;
Junxiao Shib332e782014-03-31 14:23:46 -070069
Alexander Afanasyevc348f832014-02-17 16:35:17 -080070 /**
71 * @brief Encode to a wire format
72 */
73 const Block&
74 wireEncode() const;
75
76 /**
77 * @brief Decode the input from wire format
78 */
Junxiao Shib332e782014-03-31 14:23:46 -070079 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070080 wireDecode(const Block& wire);
Alexander Afanasyevc348f832014-02-17 16:35:17 -080081
82 ///////////////////////////////////////////////////////////////////////////////
83 ///////////////////////////////////////////////////////////////////////////////
84 ///////////////////////////////////////////////////////////////////////////////
Junxiao Shib332e782014-03-31 14:23:46 -070085
86 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -080087 getMinSuffixComponents() const
88 {
89 return m_minSuffixComponents;
90 }
Junxiao Shib332e782014-03-31 14:23:46 -070091
92 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -080093 setMinSuffixComponents(int minSuffixComponents)
94 {
95 m_minSuffixComponents = minSuffixComponents;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070096 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -080097 return *this;
98 }
99
100 //
Junxiao Shib332e782014-03-31 14:23:46 -0700101
102 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800103 getMaxSuffixComponents() const
104 {
105 return m_maxSuffixComponents;
106 }
107
Junxiao Shib332e782014-03-31 14:23:46 -0700108 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800109 setMaxSuffixComponents(int maxSuffixComponents)
110 {
111 m_maxSuffixComponents = maxSuffixComponents;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700112 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800113 return *this;
114 }
Junxiao Shib332e782014-03-31 14:23:46 -0700115
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800116 //
117
Junxiao Shib332e782014-03-31 14:23:46 -0700118 const KeyLocator&
119 getPublisherPublicKeyLocator() const
120 {
121 return m_publisherPublicKeyLocator;
122 }
123
124 Selectors&
125 setPublisherPublicKeyLocator(const KeyLocator& keyLocator)
126 {
127 m_publisherPublicKeyLocator = keyLocator;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700128 m_wire.reset();
Junxiao Shib332e782014-03-31 14:23:46 -0700129 return *this;
130 }
131
132 //
133
134 const Exclude&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800135 getExclude() const
136 {
137 return m_exclude;
138 }
139
Junxiao Shib332e782014-03-31 14:23:46 -0700140 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800141 setExclude(const Exclude& exclude)
142 {
143 m_exclude = exclude;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700144 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800145 return *this;
146 }
147
148 //
Junxiao Shib332e782014-03-31 14:23:46 -0700149
150 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800151 getChildSelector() const
152 {
153 return m_childSelector;
154 }
155
Junxiao Shib332e782014-03-31 14:23:46 -0700156 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800157 setChildSelector(int childSelector)
158 {
159 m_childSelector = childSelector;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700160 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800161 return *this;
162 }
163
164 //
165
Junxiao Shib332e782014-03-31 14:23:46 -0700166 int
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800167 getMustBeFresh() const
168 {
169 return m_mustBeFresh;
170 }
171
Junxiao Shib332e782014-03-31 14:23:46 -0700172 Selectors&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800173 setMustBeFresh(bool mustBeFresh)
174 {
175 m_mustBeFresh = mustBeFresh;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700176 m_wire.reset();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800177 return *this;
178 }
179
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700180public: // EqualityComparable concept
181 bool
182 operator==(const Selectors& other) const
183 {
184 return wireEncode() == other.wireEncode();
185 }
186
187 bool
188 operator!=(const Selectors& other) const
189 {
190 return !(*this == other);
191 }
192
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800193private:
194 int m_minSuffixComponents;
Junxiao Shib332e782014-03-31 14:23:46 -0700195 int m_maxSuffixComponents;
196 KeyLocator m_publisherPublicKeyLocator;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800197 Exclude m_exclude;
198 int m_childSelector;
199 bool m_mustBeFresh;
200
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700201 mutable Block m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800202};
203
204inline bool
205Selectors::empty() const
206{
207 return
208 (m_minSuffixComponents < 0 &&
209 m_maxSuffixComponents < 0 &&
Junxiao Shib332e782014-03-31 14:23:46 -0700210 m_publisherPublicKeyLocator.empty() &&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800211 m_exclude.empty() &&
212 m_childSelector < 0 &&
213 !m_mustBeFresh);
214}
215
216template<bool T>
217inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700218Selectors::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800219{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700220 size_t totalLength = 0;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800221
222 // Selectors ::= SELECTORS-TYPE TLV-LENGTH
223 // MinSuffixComponents?
224 // MaxSuffixComponents?
225 // PublisherPublicKeyLocator?
226 // Exclude?
227 // ChildSelector?
Junxiao Shib332e782014-03-31 14:23:46 -0700228 // MustBeFresh?
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800229
230 // (reverse encoding)
231
232 // MustBeFresh
233 if (getMustBeFresh())
234 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700235 totalLength += prependBooleanBlock(block, Tlv::MustBeFresh);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800236 }
237
238 // ChildSelector
239 if (getChildSelector() >= 0)
240 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700241 totalLength += prependNonNegativeIntegerBlock(block, Tlv::ChildSelector, getChildSelector());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800242 }
243
244 // Exclude
245 if (!getExclude().empty())
246 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700247 totalLength += getExclude().wireEncode(block);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800248 }
Junxiao Shib332e782014-03-31 14:23:46 -0700249
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800250 // PublisherPublicKeyLocator
Junxiao Shib332e782014-03-31 14:23:46 -0700251 if (!getPublisherPublicKeyLocator().empty())
252 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700253 totalLength += getPublisherPublicKeyLocator().wireEncode(block);
Junxiao Shib332e782014-03-31 14:23:46 -0700254 }
255
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800256 // MaxSuffixComponents
257 if (getMaxSuffixComponents() >= 0)
258 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700259 totalLength += prependNonNegativeIntegerBlock(block, Tlv::MaxSuffixComponents,
260 getMaxSuffixComponents());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800261 }
262
263 // MinSuffixComponents
264 if (getMinSuffixComponents() >= 0)
265 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700266 totalLength += prependNonNegativeIntegerBlock(block, Tlv::MinSuffixComponents,
267 getMinSuffixComponents());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800268 }
Junxiao Shib332e782014-03-31 14:23:46 -0700269
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700270 totalLength += block.prependVarNumber(totalLength);
271 totalLength += block.prependVarNumber(Tlv::Selectors);
272 return totalLength;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800273}
274
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700275inline const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800276Selectors::wireEncode() const
277{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700278 if (m_wire.hasWire())
279 return m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800280
281 EncodingEstimator estimator;
282 size_t estimatedSize = wireEncode(estimator);
Junxiao Shib332e782014-03-31 14:23:46 -0700283
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800284 EncodingBuffer buffer(estimatedSize, 0);
285 wireEncode(buffer);
286
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700287 m_wire = buffer.block();
288 return m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800289}
290
291inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700292Selectors::wireDecode(const Block& wire)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800293{
294 if (wire.type() != Tlv::Selectors)
295 throw Tlv::Error("Unexpected TLV type when decoding Selectors");
296
297 *this = Selectors();
Junxiao Shib332e782014-03-31 14:23:46 -0700298
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700299 m_wire = wire;
300 m_wire.parse();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800301
302 // MinSuffixComponents
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700303 Block::element_const_iterator val = m_wire.find(Tlv::MinSuffixComponents);
304 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800305 {
306 m_minSuffixComponents = readNonNegativeInteger(*val);
307 }
308
309 // MaxSuffixComponents
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700310 val = m_wire.find(Tlv::MaxSuffixComponents);
311 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800312 {
313 m_maxSuffixComponents = readNonNegativeInteger(*val);
314 }
315
Junxiao Shib332e782014-03-31 14:23:46 -0700316 // PublisherPublicKeyLocator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700317 val = m_wire.find(Tlv::KeyLocator);
318 if (val != m_wire.elements_end())
Junxiao Shib332e782014-03-31 14:23:46 -0700319 {
320 m_publisherPublicKeyLocator.wireDecode(*val);
321 }
322
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800323 // Exclude
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700324 val = m_wire.find(Tlv::Exclude);
325 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800326 {
327 m_exclude.wireDecode(*val);
328 }
329
330 // ChildSelector
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700331 val = m_wire.find(Tlv::ChildSelector);
332 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800333 {
334 m_childSelector = readNonNegativeInteger(*val);
335 }
336
337 //MustBeFresh aka AnswerOriginKind
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700338 val = m_wire.find(Tlv::MustBeFresh);
339 if (val != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800340 {
341 m_mustBeFresh = true;
342 }
343}
Junxiao Shib332e782014-03-31 14:23:46 -0700344
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800345} // namespace ndn
346
347#endif // NDN_SELECTORS_HPP