blob: 22dc929144ef94999a6a6adc39659f9a7a9405f0 [file] [log] [blame]
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013, Regents of the University of California
4 * Alexander Afanasyev
5 *
6 * BSD license, See the LICENSE file for more information
7 *
8 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
9 */
10
11#ifndef NDN_EXCLUDE_H
12#define NDN_EXCLUDE_H
13
Alexander Afanasyevc348f832014-02-17 16:35:17 -080014#include "name-component.hpp"
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080015
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080016namespace ndn {
17
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080018/**
19 * @brief Class to represent Exclude component in NDN interests
20 */
21class Exclude
22{
23public:
Alexander Afanasyev993a0e12014-01-03 13:51:37 -080024 struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
25
26
Alexander Afanasyevc348f832014-02-17 16:35:17 -080027 typedef std::map< name::Component, bool /*any*/, std::greater<name::Component> > exclude_type;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080028
29 typedef exclude_type::iterator iterator;
30 typedef exclude_type::const_iterator const_iterator;
31 typedef exclude_type::reverse_iterator reverse_iterator;
32 typedef exclude_type::const_reverse_iterator const_reverse_iterator;
33
34 /**
35 * @brief Default constructor an empty exclude
36 */
37 Exclude ();
38
39 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -080040 * @brief Fast encoding or block size estimation
41 */
42 template<bool T>
43 inline size_t
44 wireEncode(EncodingImpl<T> &block) const;
45
46 /**
47 * @brief Encode to a wire format
48 */
49 inline const Block&
50 wireEncode() const;
51
52 /**
53 * @brief Decode from the wire format
54 */
55 inline void
56 wireDecode(const Block &wire);
57
58 ///////////////////////////////////////////////////////////////////////////////
59
60
61 /**
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080062 * @brief Check if name component is excluded
63 * @param comp Name component to check against exclude filter
64 */
65 bool
Alexander Afanasyevc348f832014-02-17 16:35:17 -080066 isExcluded (const name::Component &comp) const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080067
68 /**
69 * @brief Exclude specific name component
70 * @param comp component to exclude
71 * @returns *this to allow chaining
72 */
73 Exclude &
Alexander Afanasyevc348f832014-02-17 16:35:17 -080074 excludeOne (const name::Component &comp);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080075
76 /**
77 * @brief Exclude components from range [from, to]
78 * @param from first element of the range
79 * @param to last element of the range
80 * @returns *this to allow chaining
81 */
82 Exclude &
Alexander Afanasyevc348f832014-02-17 16:35:17 -080083 excludeRange (const name::Component &from, const name::Component &to);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080084
85 /**
86 * @brief Exclude all components from range [/, to]
87 * @param to last element of the range
88 * @returns *this to allow chaining
89 */
90 inline Exclude &
Alexander Afanasyevc348f832014-02-17 16:35:17 -080091 excludeBefore (const name::Component &to);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080092
93 /**
94 * @brief Exclude all components from range [from, +Inf]
95 * @param to last element of the range
96 * @returns *this to allow chaining
97 */
98 Exclude &
Alexander Afanasyevc348f832014-02-17 16:35:17 -080099 excludeAfter (const name::Component &from);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800100
101 /**
102 * @brief Method to directly append exclude element
103 * @param name excluded name component
104 * @param any flag indicating if there is a postfix ANY component after the name
105 *
106 * This method is used during conversion from wire format of exclude filter
107 *
108 * If there is an error with ranges (e.g., order of components is wrong) an exception is thrown
109 */
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800110 inline void
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800111 appendExclude (const name::Component &name, bool any);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800112
113 /**
114 * @brief Check if exclude filter is empty
115 */
116 inline bool
117 empty () const;
Alexander Afanasyev85480842014-01-06 14:46:54 -0800118
119 /**
120 * @brief Clear the exclude filter
121 */
122 inline void
123 clear();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800124
125 /**
126 * @brief Get number of exclude terms
127 */
128 inline size_t
129 size () const;
130
131 /**
132 * @brief Get begin iterator of the exclude terms
133 */
134 inline const_iterator
135 begin () const;
136
137 /**
138 * @brief Get end iterator of the exclude terms
139 */
140 inline const_iterator
141 end () const;
142
143 /**
144 * @brief Get begin iterator of the exclude terms
145 */
146 inline const_reverse_iterator
147 rbegin () const;
148
149 /**
150 * @brief Get end iterator of the exclude terms
151 */
152 inline const_reverse_iterator
153 rend () const;
154
155 /**
156 * @brief Get escaped string representation (e.g., for use in URI) of the exclude filter
157 */
158 inline std::string
159 toUri () const;
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800160
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800161private:
162 Exclude &
163 excludeRange (iterator fromLowerBound, iterator toLowerBound);
164
165private:
166 exclude_type m_exclude;
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800167
168 mutable Block wire_;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800169};
170
171std::ostream&
172operator << (std::ostream &os, const Exclude &name);
173
174inline Exclude &
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800175Exclude::excludeBefore (const name::Component &to)
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800176{
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800177 return excludeRange (name::Component (), to);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800178}
179
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800180inline void
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800181Exclude::appendExclude (const name::Component &name, bool any)
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800182{
183 m_exclude[name] = any;
184}
185
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800186inline bool
187Exclude::empty () const
188{
189 return m_exclude.empty ();
190}
191
Alexander Afanasyev85480842014-01-06 14:46:54 -0800192inline void
193Exclude::clear ()
194{
195 m_exclude.clear ();
196}
197
198
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800199inline size_t
200Exclude::size () const
201{
202 return m_exclude.size ();
203}
204
205inline Exclude::const_iterator
206Exclude::begin () const
207{
208 return m_exclude.begin ();
209}
210
211inline Exclude::const_iterator
212Exclude::end () const
213{
214 return m_exclude.end ();
215}
216
217inline Exclude::const_reverse_iterator
218Exclude::rbegin () const
219{
220 return m_exclude.rbegin ();
221}
222
223inline Exclude::const_reverse_iterator
224Exclude::rend () const
225{
226 return m_exclude.rend ();
227}
228
229inline std::string
230Exclude::toUri () const
231{
232 std::ostringstream os;
233 os << *this;
234 return os.str();
235}
236
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800237template<bool T>
238inline size_t
239Exclude::wireEncode(EncodingImpl<T> &block) const
240{
241 size_t total_len = 0;
242
243 // Exclude ::= EXCLUDE-TYPE TLV-LENGTH Any? (NameComponent (Any)?)+
244 // Any ::= ANY-TYPE TLV-LENGTH(=0)
245
246 for (Exclude::const_iterator i = m_exclude.begin (); i != m_exclude.end (); i++)
247 {
248 if (i->second)
249 {
250 total_len += prependBooleanBlock(block, Tlv::Any);
251 }
252 if (!i->first.empty())
253 {
254 total_len += i->first.wireEncode(block);
255 }
256 }
257
258 total_len += block.prependVarNumber(total_len);
259 total_len += block.prependVarNumber(Tlv::Exclude);
260 return total_len;
261}
262
263inline const Block &
264Exclude::wireEncode() const
265{
266 if (wire_.hasWire())
267 return wire_;
268
269 EncodingEstimator estimator;
270 size_t estimatedSize = wireEncode(estimator);
271
272 EncodingBuffer buffer(estimatedSize, 0);
273 wireEncode(buffer);
274
275 wire_ = buffer.block();
276 return wire_;
277}
278
279inline void
280Exclude::wireDecode(const Block &wire)
281{
282 wire_ = wire;
283 wire_.parse();
284
285 // Exclude ::= EXCLUDE-TYPE TLV-LENGTH Any? (NameComponent (Any)?)+
286 // Any ::= ANY-TYPE TLV-LENGTH(=0)
287
288 Block::element_const_iterator i = wire_.elements_begin();
289 if (i->type() == Tlv::Any)
290 {
291 appendExclude(name::Component(), true);
292 ++i;
293 }
294
295 while (i != wire_.elements_end())
296 {
297 if (i->type() != Tlv::NameComponent)
298 throw Error("Incorrect format of Exclude filter");
299
300 name::Component excludedComponent (i->value(), i->value_size());
301 ++i;
302
303 if (i != wire_.elements_end())
304 {
305 if (i->type() == Tlv::Any)
306 {
307 appendExclude(excludedComponent, true);
308 ++i;
309 }
310 else
311 {
312 appendExclude(excludedComponent, false);
313 }
314 }
315 else
316 {
317 appendExclude(excludedComponent, false);
318 }
319 }
320}
321
322
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800323} // ndn
324
325#endif // NDN_EXCLUDE_H