blob: 19a996b4738e3a795434c974bd8a055eed611d5e [file] [log] [blame]
Alexander Afanasyevc348f832014-02-17 16:35:17 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
5 * See COPYING for copyright and distribution information.
6 */
7
8#ifndef NDN_SELECTORS_HPP
9#define NDN_SELECTORS_HPP
10
11#include "common.hpp"
12#include "exclude.hpp"
13#include "encoding/encoding-buffer.hpp"
14
15namespace ndn {
16
17/**
18 * @brief Abstraction implementing Interest selectors
19 */
20class Selectors
21{
22public:
23 Selectors()
24 : m_minSuffixComponents(-1)
25 , m_maxSuffixComponents(-1)
26 , m_childSelector(-1)
27 , m_mustBeFresh(false)
28 {
29 }
30
31 Selectors(int minSuffixComponents, int maxSuffixComponents,
32 const Exclude& exclude,
33 int childSelector,
34 bool mustBeFresh)
35 : m_minSuffixComponents(minSuffixComponents)
36 , m_maxSuffixComponents(maxSuffixComponents)
37 , m_exclude(exclude)
38 , m_childSelector(childSelector)
39 , m_mustBeFresh(mustBeFresh)
40 {
41 }
42
43 Selectors(const Block& wire)
44 {
45 wireDecode(wire);
46 }
47
48 bool
49 empty() const;
50
51 /**
52 * @brief Fast encoding or block size estimation
53 */
54 template<bool T>
55 size_t
56 wireEncode(EncodingImpl<T> &block) const;
57
58 /**
59 * @brief Encode to a wire format
60 */
61 const Block&
62 wireEncode() const;
63
64 /**
65 * @brief Decode the input from wire format
66 */
67 void
68 wireDecode(const Block &wire);
69
70 ///////////////////////////////////////////////////////////////////////////////
71 ///////////////////////////////////////////////////////////////////////////////
72 ///////////////////////////////////////////////////////////////////////////////
73
74 int
75 getMinSuffixComponents() const
76 {
77 return m_minSuffixComponents;
78 }
79
80 Selectors&
81 setMinSuffixComponents(int minSuffixComponents)
82 {
83 m_minSuffixComponents = minSuffixComponents;
84 wire_.reset();
85 return *this;
86 }
87
88 //
89
90 int
91 getMaxSuffixComponents() const
92 {
93 return m_maxSuffixComponents;
94 }
95
96 Selectors&
97 setMaxSuffixComponents(int maxSuffixComponents)
98 {
99 m_maxSuffixComponents = maxSuffixComponents;
100 wire_.reset();
101 return *this;
102 }
103
104 //
105
106 const Exclude&
107 getExclude() const
108 {
109 return m_exclude;
110 }
111
112 Selectors&
113 setExclude(const Exclude& exclude)
114 {
115 m_exclude = exclude;
116 wire_.reset();
117 return *this;
118 }
119
120 //
121
122 int
123 getChildSelector() const
124 {
125 return m_childSelector;
126 }
127
128 Selectors&
129 setChildSelector(int childSelector)
130 {
131 m_childSelector = childSelector;
132 wire_.reset();
133 return *this;
134 }
135
136 //
137
138 int
139 getMustBeFresh() const
140 {
141 return m_mustBeFresh;
142 }
143
144 Selectors&
145 setMustBeFresh(bool mustBeFresh)
146 {
147 m_mustBeFresh = mustBeFresh;
148 wire_.reset();
149 return *this;
150 }
151
152private:
153 int m_minSuffixComponents;
154 int m_maxSuffixComponents;
155 Exclude m_exclude;
156 int m_childSelector;
157 bool m_mustBeFresh;
158
159 mutable Block wire_;
160};
161
162inline bool
163Selectors::empty() const
164{
165 return
166 (m_minSuffixComponents < 0 &&
167 m_maxSuffixComponents < 0 &&
168 m_exclude.empty() &&
169 m_childSelector < 0 &&
170 !m_mustBeFresh);
171}
172
173template<bool T>
174inline size_t
175Selectors::wireEncode(EncodingImpl<T> &block) const
176{
177 size_t total_len = 0;
178
179 // Selectors ::= SELECTORS-TYPE TLV-LENGTH
180 // MinSuffixComponents?
181 // MaxSuffixComponents?
182 // PublisherPublicKeyLocator?
183 // Exclude?
184 // ChildSelector?
185 // MustBeFresh?
186
187 // (reverse encoding)
188
189 // MustBeFresh
190 if (getMustBeFresh())
191 {
192 total_len += prependBooleanBlock(block, Tlv::MustBeFresh);
193 }
194
195 // ChildSelector
196 if (getChildSelector() >= 0)
197 {
198 total_len += prependNonNegativeIntegerBlock(block, Tlv::ChildSelector, getChildSelector());
199 }
200
201 // Exclude
202 if (!getExclude().empty())
203 {
204 total_len += getExclude().wireEncode(block);
205 }
206
207 // PublisherPublicKeyLocator
208 /// @todo Implement PublisherPublicKeyLocator selector
209
210 // MaxSuffixComponents
211 if (getMaxSuffixComponents() >= 0)
212 {
213 total_len += prependNonNegativeIntegerBlock(block, Tlv::MaxSuffixComponents,
214 getMaxSuffixComponents());
215 }
216
217 // MinSuffixComponents
218 if (getMinSuffixComponents() >= 0)
219 {
220 total_len += prependNonNegativeIntegerBlock(block, Tlv::MinSuffixComponents,
221 getMinSuffixComponents());
222 }
223
224 total_len += block.prependVarNumber(total_len);
225 total_len += block.prependVarNumber(Tlv::Selectors);
226 return total_len;
227}
228
229inline const Block &
230Selectors::wireEncode() const
231{
232 if (wire_.hasWire())
233 return wire_;
234
235 EncodingEstimator estimator;
236 size_t estimatedSize = wireEncode(estimator);
237
238 EncodingBuffer buffer(estimatedSize, 0);
239 wireEncode(buffer);
240
241 wire_ = buffer.block();
242 return wire_;
243}
244
245inline void
246Selectors::wireDecode(const Block &wire)
247{
248 if (wire.type() != Tlv::Selectors)
249 throw Tlv::Error("Unexpected TLV type when decoding Selectors");
250
251 *this = Selectors();
252
253 wire_ = wire;
254 wire_.parse();
255
256 // MinSuffixComponents
257 Block::element_const_iterator val = wire_.find(Tlv::MinSuffixComponents);
258 if (val != wire_.elements_end())
259 {
260 m_minSuffixComponents = readNonNegativeInteger(*val);
261 }
262
263 // MaxSuffixComponents
264 val = wire_.find(Tlv::MaxSuffixComponents);
265 if (val != wire_.elements_end())
266 {
267 m_maxSuffixComponents = readNonNegativeInteger(*val);
268 }
269
270 // Exclude
271 val = wire_.find(Tlv::Exclude);
272 if (val != wire_.elements_end())
273 {
274 m_exclude.wireDecode(*val);
275 }
276
277 // ChildSelector
278 val = wire_.find(Tlv::ChildSelector);
279 if (val != wire_.elements_end())
280 {
281 m_childSelector = readNonNegativeInteger(*val);
282 }
283
284 //MustBeFresh aka AnswerOriginKind
285 val = wire_.find(Tlv::MustBeFresh);
286 if (val != wire_.elements_end())
287 {
288 m_mustBeFresh = true;
289 }
290}
291
292} // namespace ndn
293
294#endif // NDN_SELECTORS_HPP