blob: d187a1ae02df61c034130c0291db1b8e1dd3461f [file] [log] [blame]
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07002/**
3 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -08005 *
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 * 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.
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -08008 *
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07009 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
11 *
12 * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080013 */
14
15#ifndef NDN_EXCLUDE_H
16#define NDN_EXCLUDE_H
17
Alexander Afanasyevc348f832014-02-17 16:35:17 -080018#include "name-component.hpp"
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080019
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070020#include <map>
21
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080022namespace ndn {
23
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080024/**
25 * @brief Class to represent Exclude component in NDN interests
26 */
27class Exclude
28{
29public:
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070030 class Error : public Tlv::Error
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070031 {
32 public:
33 explicit
34 Error(const std::string& what)
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070035 : Tlv::Error(what)
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070036 {
37 }
38 };
Alexander Afanasyev993a0e12014-01-03 13:51:37 -080039
Alexander Afanasyevc348f832014-02-17 16:35:17 -080040 typedef std::map< name::Component, bool /*any*/, std::greater<name::Component> > exclude_type;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080041
42 typedef exclude_type::iterator iterator;
43 typedef exclude_type::const_iterator const_iterator;
44 typedef exclude_type::reverse_iterator reverse_iterator;
45 typedef exclude_type::const_reverse_iterator const_reverse_iterator;
46
47 /**
48 * @brief Default constructor an empty exclude
49 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070050 Exclude();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080051
52 /**
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070053 * @brief Create from wire encoding
54 */
55 explicit
56 Exclude(const Block& wire)
57 {
58 wireDecode(wire);
59 }
60
61 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -080062 * @brief Fast encoding or block size estimation
63 */
64 template<bool T>
65 inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070066 wireEncode(EncodingImpl<T>& block) const;
67
Alexander Afanasyevc348f832014-02-17 16:35:17 -080068 /**
69 * @brief Encode to a wire format
70 */
71 inline const Block&
72 wireEncode() const;
73
74 /**
75 * @brief Decode from the wire format
76 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070077 inline void
78 wireDecode(const Block& wire);
79
Alexander Afanasyevc348f832014-02-17 16:35:17 -080080 ///////////////////////////////////////////////////////////////////////////////
81
82
83 /**
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080084 * @brief Check if name component is excluded
85 * @param comp Name component to check against exclude filter
86 */
87 bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070088 isExcluded(const name::Component& comp) const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080089
90 /**
91 * @brief Exclude specific name component
92 * @param comp component to exclude
93 * @returns *this to allow chaining
94 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070095 Exclude&
96 excludeOne(const name::Component& comp);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080097
98 /**
99 * @brief Exclude components from range [from, to]
100 * @param from first element of the range
101 * @param to last element of the range
102 * @returns *this to allow chaining
103 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700104 Exclude&
105 excludeRange(const name::Component& from, const name::Component& to);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800106
107 /**
108 * @brief Exclude all components from range [/, to]
109 * @param to last element of the range
110 * @returns *this to allow chaining
111 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700112 inline Exclude&
113 excludeBefore(const name::Component& to);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800114
115 /**
116 * @brief Exclude all components from range [from, +Inf]
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700117 * @param from the first element of the range
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800118 * @returns *this to allow chaining
119 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700120 Exclude&
121 excludeAfter(const name::Component& from);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800122
123 /**
124 * @brief Method to directly append exclude element
125 * @param name excluded name component
126 * @param any flag indicating if there is a postfix ANY component after the name
127 *
128 * This method is used during conversion from wire format of exclude filter
129 *
130 * If there is an error with ranges (e.g., order of components is wrong) an exception is thrown
131 */
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800132 inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700133 appendExclude(const name::Component& name, bool any);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800134
135 /**
136 * @brief Check if exclude filter is empty
137 */
138 inline bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700139 empty() const;
Alexander Afanasyev85480842014-01-06 14:46:54 -0800140
141 /**
142 * @brief Clear the exclude filter
143 */
144 inline void
145 clear();
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700146
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800147 /**
148 * @brief Get number of exclude terms
149 */
150 inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700151 size() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800152
153 /**
154 * @brief Get begin iterator of the exclude terms
155 */
156 inline const_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700157 begin() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800158
159 /**
160 * @brief Get end iterator of the exclude terms
161 */
162 inline const_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700163 end() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800164
165 /**
166 * @brief Get begin iterator of the exclude terms
167 */
168 inline const_reverse_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700169 rbegin() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800170
171 /**
172 * @brief Get end iterator of the exclude terms
173 */
174 inline const_reverse_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700175 rend() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800176
177 /**
178 * @brief Get escaped string representation (e.g., for use in URI) of the exclude filter
179 */
180 inline std::string
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700181 toUri() const;
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800182
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800183private:
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700184 Exclude&
185 excludeRange(iterator fromLowerBound, iterator toLowerBound);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800186
187private:
188 exclude_type m_exclude;
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800189
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700190 mutable Block m_wire;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800191};
192
193std::ostream&
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700194operator<<(std::ostream& os, const Exclude& name);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800195
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700196inline Exclude&
197Exclude::excludeBefore(const name::Component& to)
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800198{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700199 return excludeRange(name::Component(), to);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800200}
201
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800202inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700203Exclude::appendExclude(const name::Component& name, bool any)
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800204{
205 m_exclude[name] = any;
206}
207
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800208inline bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700209Exclude::empty() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800210{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700211 return m_exclude.empty();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800212}
213
Alexander Afanasyev85480842014-01-06 14:46:54 -0800214inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700215Exclude::clear()
Alexander Afanasyev85480842014-01-06 14:46:54 -0800216{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700217 m_exclude.clear();
Alexander Afanasyev85480842014-01-06 14:46:54 -0800218}
219
220
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800221inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700222Exclude::size() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800223{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700224 return m_exclude.size();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800225}
226
227inline Exclude::const_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700228Exclude::begin() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800229{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700230 return m_exclude.begin();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800231}
232
233inline Exclude::const_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700234Exclude::end() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800235{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700236 return m_exclude.end();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800237}
238
239inline Exclude::const_reverse_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700240Exclude::rbegin() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800241{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700242 return m_exclude.rbegin();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800243}
244
245inline Exclude::const_reverse_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700246Exclude::rend() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800247{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700248 return m_exclude.rend();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800249}
250
251inline std::string
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700252Exclude::toUri() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800253{
254 std::ostringstream os;
255 os << *this;
256 return os.str();
257}
258
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800259template<bool T>
260inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700261Exclude::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800262{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700263 size_t totalLength = 0;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800264
265 // Exclude ::= EXCLUDE-TYPE TLV-LENGTH Any? (NameComponent (Any)?)+
266 // Any ::= ANY-TYPE TLV-LENGTH(=0)
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700267
268 for (Exclude::const_iterator i = m_exclude.begin(); i != m_exclude.end(); i++)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800269 {
270 if (i->second)
271 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700272 totalLength += prependBooleanBlock(block, Tlv::Any);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800273 }
274 if (!i->first.empty())
275 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700276 totalLength += i->first.wireEncode(block);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800277 }
278 }
279
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700280 totalLength += block.prependVarNumber(totalLength);
281 totalLength += block.prependVarNumber(Tlv::Exclude);
282 return totalLength;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800283}
284
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700285inline const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800286Exclude::wireEncode() const
287{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700288 if (m_wire.hasWire())
289 return m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800290
291 EncodingEstimator estimator;
292 size_t estimatedSize = wireEncode(estimator);
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700293
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800294 EncodingBuffer buffer(estimatedSize, 0);
295 wireEncode(buffer);
296
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700297 m_wire = buffer.block();
298 return m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800299}
300
301inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700302Exclude::wireDecode(const Block& wire)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800303{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700304 m_wire = wire;
305 m_wire.parse();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800306
307 // Exclude ::= EXCLUDE-TYPE TLV-LENGTH Any? (NameComponent (Any)?)+
308 // Any ::= ANY-TYPE TLV-LENGTH(=0)
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700309
310 Block::element_const_iterator i = m_wire.elements_begin();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800311 if (i->type() == Tlv::Any)
312 {
313 appendExclude(name::Component(), true);
314 ++i;
315 }
316
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700317 while (i != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800318 {
319 if (i->type() != Tlv::NameComponent)
320 throw Error("Incorrect format of Exclude filter");
321
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700322 name::Component excludedComponent(i->value(), i->value_size());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800323 ++i;
324
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700325 if (i != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800326 {
327 if (i->type() == Tlv::Any)
328 {
329 appendExclude(excludedComponent, true);
330 ++i;
331 }
332 else
333 {
334 appendExclude(excludedComponent, false);
335 }
336 }
337 else
338 {
339 appendExclude(excludedComponent, false);
340 }
341 }
342}
343
344
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800345} // ndn
346
347#endif // NDN_EXCLUDE_H