blob: 3801649e343e003004d9cce145a8c05f6090a4c8 [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 Afanasyevb3a6af42014-01-03 13:08:28 -080020namespace ndn {
21
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080022/**
23 * @brief Class to represent Exclude component in NDN interests
24 */
25class Exclude
26{
27public:
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070028 class Error : public Tlv::Error
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070029 {
30 public:
31 explicit
32 Error(const std::string& what)
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070033 : Tlv::Error(what)
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070034 {
35 }
36 };
Alexander Afanasyev993a0e12014-01-03 13:51:37 -080037
Alexander Afanasyevc348f832014-02-17 16:35:17 -080038 typedef std::map< name::Component, bool /*any*/, std::greater<name::Component> > exclude_type;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080039
40 typedef exclude_type::iterator iterator;
41 typedef exclude_type::const_iterator const_iterator;
42 typedef exclude_type::reverse_iterator reverse_iterator;
43 typedef exclude_type::const_reverse_iterator const_reverse_iterator;
44
45 /**
46 * @brief Default constructor an empty exclude
47 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070048 Exclude();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080049
50 /**
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070051 * @brief Create from wire encoding
52 */
53 explicit
54 Exclude(const Block& wire)
55 {
56 wireDecode(wire);
57 }
58
59 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -080060 * @brief Fast encoding or block size estimation
61 */
62 template<bool T>
63 inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070064 wireEncode(EncodingImpl<T>& block) const;
65
Alexander Afanasyevc348f832014-02-17 16:35:17 -080066 /**
67 * @brief Encode to a wire format
68 */
69 inline const Block&
70 wireEncode() const;
71
72 /**
73 * @brief Decode from the wire format
74 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070075 inline void
76 wireDecode(const Block& wire);
77
Alexander Afanasyevc348f832014-02-17 16:35:17 -080078 ///////////////////////////////////////////////////////////////////////////////
79
80
81 /**
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080082 * @brief Check if name component is excluded
83 * @param comp Name component to check against exclude filter
84 */
85 bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070086 isExcluded(const name::Component& comp) const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080087
88 /**
89 * @brief Exclude specific name component
90 * @param comp component to exclude
91 * @returns *this to allow chaining
92 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070093 Exclude&
94 excludeOne(const name::Component& comp);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080095
96 /**
97 * @brief Exclude components from range [from, to]
98 * @param from first element of the range
99 * @param to last element of the range
100 * @returns *this to allow chaining
101 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700102 Exclude&
103 excludeRange(const name::Component& from, const name::Component& to);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800104
105 /**
106 * @brief Exclude all components from range [/, to]
107 * @param to last element of the range
108 * @returns *this to allow chaining
109 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700110 inline Exclude&
111 excludeBefore(const name::Component& to);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800112
113 /**
114 * @brief Exclude all components from range [from, +Inf]
115 * @param to last element of the range
116 * @returns *this to allow chaining
117 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700118 Exclude&
119 excludeAfter(const name::Component& from);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800120
121 /**
122 * @brief Method to directly append exclude element
123 * @param name excluded name component
124 * @param any flag indicating if there is a postfix ANY component after the name
125 *
126 * This method is used during conversion from wire format of exclude filter
127 *
128 * If there is an error with ranges (e.g., order of components is wrong) an exception is thrown
129 */
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800130 inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700131 appendExclude(const name::Component& name, bool any);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800132
133 /**
134 * @brief Check if exclude filter is empty
135 */
136 inline bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700137 empty() const;
Alexander Afanasyev85480842014-01-06 14:46:54 -0800138
139 /**
140 * @brief Clear the exclude filter
141 */
142 inline void
143 clear();
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700144
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800145 /**
146 * @brief Get number of exclude terms
147 */
148 inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700149 size() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800150
151 /**
152 * @brief Get begin iterator of the exclude terms
153 */
154 inline const_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700155 begin() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800156
157 /**
158 * @brief Get end iterator of the exclude terms
159 */
160 inline const_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700161 end() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800162
163 /**
164 * @brief Get begin iterator of the exclude terms
165 */
166 inline const_reverse_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700167 rbegin() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800168
169 /**
170 * @brief Get end iterator of the exclude terms
171 */
172 inline const_reverse_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700173 rend() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800174
175 /**
176 * @brief Get escaped string representation (e.g., for use in URI) of the exclude filter
177 */
178 inline std::string
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700179 toUri() const;
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800180
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800181private:
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700182 Exclude&
183 excludeRange(iterator fromLowerBound, iterator toLowerBound);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800184
185private:
186 exclude_type m_exclude;
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800187
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700188 mutable Block m_wire;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800189};
190
191std::ostream&
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700192operator<<(std::ostream& os, const Exclude& name);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800193
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700194inline Exclude&
195Exclude::excludeBefore(const name::Component& to)
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800196{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700197 return excludeRange(name::Component(), to);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800198}
199
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800200inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700201Exclude::appendExclude(const name::Component& name, bool any)
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800202{
203 m_exclude[name] = any;
204}
205
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800206inline bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700207Exclude::empty() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800208{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700209 return m_exclude.empty();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800210}
211
Alexander Afanasyev85480842014-01-06 14:46:54 -0800212inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700213Exclude::clear()
Alexander Afanasyev85480842014-01-06 14:46:54 -0800214{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700215 m_exclude.clear();
Alexander Afanasyev85480842014-01-06 14:46:54 -0800216}
217
218
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800219inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700220Exclude::size() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800221{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700222 return m_exclude.size();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800223}
224
225inline Exclude::const_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700226Exclude::begin() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800227{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700228 return m_exclude.begin();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800229}
230
231inline Exclude::const_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700232Exclude::end() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800233{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700234 return m_exclude.end();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800235}
236
237inline Exclude::const_reverse_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700238Exclude::rbegin() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800239{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700240 return m_exclude.rbegin();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800241}
242
243inline Exclude::const_reverse_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700244Exclude::rend() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800245{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700246 return m_exclude.rend();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800247}
248
249inline std::string
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700250Exclude::toUri() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800251{
252 std::ostringstream os;
253 os << *this;
254 return os.str();
255}
256
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800257template<bool T>
258inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700259Exclude::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800260{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700261 size_t totalLength = 0;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800262
263 // Exclude ::= EXCLUDE-TYPE TLV-LENGTH Any? (NameComponent (Any)?)+
264 // Any ::= ANY-TYPE TLV-LENGTH(=0)
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700265
266 for (Exclude::const_iterator i = m_exclude.begin(); i != m_exclude.end(); i++)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800267 {
268 if (i->second)
269 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700270 totalLength += prependBooleanBlock(block, Tlv::Any);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800271 }
272 if (!i->first.empty())
273 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700274 totalLength += i->first.wireEncode(block);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800275 }
276 }
277
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700278 totalLength += block.prependVarNumber(totalLength);
279 totalLength += block.prependVarNumber(Tlv::Exclude);
280 return totalLength;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800281}
282
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700283inline const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800284Exclude::wireEncode() const
285{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700286 if (m_wire.hasWire())
287 return m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800288
289 EncodingEstimator estimator;
290 size_t estimatedSize = wireEncode(estimator);
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700291
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800292 EncodingBuffer buffer(estimatedSize, 0);
293 wireEncode(buffer);
294
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700295 m_wire = buffer.block();
296 return m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800297}
298
299inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700300Exclude::wireDecode(const Block& wire)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800301{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700302 m_wire = wire;
303 m_wire.parse();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800304
305 // Exclude ::= EXCLUDE-TYPE TLV-LENGTH Any? (NameComponent (Any)?)+
306 // Any ::= ANY-TYPE TLV-LENGTH(=0)
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700307
308 Block::element_const_iterator i = m_wire.elements_begin();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800309 if (i->type() == Tlv::Any)
310 {
311 appendExclude(name::Component(), true);
312 ++i;
313 }
314
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700315 while (i != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800316 {
317 if (i->type() != Tlv::NameComponent)
318 throw Error("Incorrect format of Exclude filter");
319
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700320 name::Component excludedComponent(i->value(), i->value_size());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800321 ++i;
322
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700323 if (i != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800324 {
325 if (i->type() == Tlv::Any)
326 {
327 appendExclude(excludedComponent, true);
328 ++i;
329 }
330 else
331 {
332 appendExclude(excludedComponent, false);
333 }
334 }
335 else
336 {
337 appendExclude(excludedComponent, false);
338 }
339 }
340}
341
342
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800343} // ndn
344
345#endif // NDN_EXCLUDE_H