blob: 0bd6155ac4eeaad7fdc2dc4f636206ac11e3f652 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi4f756902017-07-18 03:05:02 +00002/*
3 * Copyright (c) 2013-2017 Regents of the University of California.
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -08004 *
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07005 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -08006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070020 *
21 * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080022 */
23
Junxiao Shi4f756902017-07-18 03:05:02 +000024#ifndef NDN_EXCLUDE_HPP
25#define NDN_EXCLUDE_HPP
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080026
Alexander Afanasyevc348f832014-02-17 16:35:17 -080027#include "name-component.hpp"
Alexander Afanasyev15f67312014-07-22 15:11:09 -070028#include "encoding/encoding-buffer.hpp"
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080029
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070030#include <map>
31
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080032namespace ndn {
33
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080034/**
Junxiao Shidf4b24e2016-07-14 21:41:43 +000035 * @brief Represents Exclude selector in NDN Interest
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080036 */
37class Exclude
38{
39public:
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060040 class Error : public tlv::Error
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070041 {
42 public:
43 explicit
44 Error(const std::string& what)
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060045 : tlv::Error(what)
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070046 {
47 }
48 };
Alexander Afanasyev993a0e12014-01-03 13:51:37 -080049
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080050 /**
Junxiao Shidf4b24e2016-07-14 21:41:43 +000051 * @brief Constructs an empty Exclude
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080052 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070053 Exclude();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080054
55 /**
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070056 * @brief Create from wire encoding
57 */
58 explicit
Junxiao Shi75203022014-09-11 10:01:50 -070059 Exclude(const Block& wire);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070060
61 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -080062 * @brief Fast encoding or block size estimation
63 */
Alexander Afanasyev74633892015-02-08 18:08:46 -080064 template<encoding::Tag TAG>
Junxiao Shi75203022014-09-11 10:01:50 -070065 size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070066 wireEncode(EncodingImpl<TAG>& encoder) const;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070067
Alexander Afanasyevc348f832014-02-17 16:35:17 -080068 /**
69 * @brief Encode to a wire format
70 */
Junxiao Shi75203022014-09-11 10:01:50 -070071 const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -080072 wireEncode() const;
73
74 /**
75 * @brief Decode from the wire format
76 */
Junxiao Shi75203022014-09-11 10:01:50 -070077 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070078 wireDecode(const Block& wire);
79
Junxiao Shi75203022014-09-11 10:01:50 -070080 /**
81 * @brief Get escaped string representation (e.g., for use in URI) of the exclude filter
82 */
83 std::string
84 toUri() const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -080085
Junxiao Shi75203022014-09-11 10:01:50 -070086public: // high-level API
Alexander Afanasyevc348f832014-02-17 16:35:17 -080087 /**
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080088 * @brief Check if name component is excluded
89 * @param comp Name component to check against exclude filter
90 */
91 bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070092 isExcluded(const name::Component& comp) const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080093
94 /**
95 * @brief Exclude specific name component
96 * @param comp component to exclude
97 * @returns *this to allow chaining
98 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070099 Exclude&
100 excludeOne(const name::Component& comp);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800101
102 /**
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000103 * @brief Exclude components in range [from, to]
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800104 * @param from first element of the range
105 * @param to last element of the range
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000106 * @throw Error \p from equals or comes after \p to in canonical ordering
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800107 * @returns *this to allow chaining
108 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700109 Exclude&
110 excludeRange(const name::Component& from, const name::Component& to);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800111
112 /**
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000113 * @brief Exclude all components in range (-Inf, to]
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800114 * @param to last element of the range
115 * @returns *this to allow chaining
116 */
Junxiao Shi75203022014-09-11 10:01:50 -0700117 Exclude&
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700118 excludeBefore(const name::Component& to);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800119
120 /**
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000121 * @brief Exclude all components in range [from, +Inf)
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700122 * @param from the first element of the range
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800123 * @returns *this to allow chaining
124 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700125 Exclude&
126 excludeAfter(const name::Component& from);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800127
Alexander Afanasyevba096052014-09-19 15:36:37 -0700128public: // EqualityComparable concept
129 bool
130 operator==(const Exclude& other) const;
131
132 bool
133 operator!=(const Exclude& other) const;
134
Davide Pesavento88a0d812017-08-19 21:31:42 -0400135public: // internal storage
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000136 /**
137 * @brief either a name::Component or "negative infinity"
138 */
139 class ExcludeComponent
140 {
141 public:
142 /**
143 * @brief implicitly construct a regular infinity ExcludeComponent
144 * @param component a name component which is excluded
145 */
146 ExcludeComponent(const name::Component& component);
Junxiao Shi75203022014-09-11 10:01:50 -0700147
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000148 /**
149 * @brief construct a negative infinity ExcludeComponent
150 * @param isNegInf must be true
151 */
152 explicit
153 ExcludeComponent(bool isNegInf);
154
155 public:
156 bool isNegInf;
157 name::Component component;
158 };
Junxiao Shi75203022014-09-11 10:01:50 -0700159
160 /**
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000161 * @brief a map of exclude entries
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800162 *
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000163 * Each key, except "negative infinity", is a name component that is excluded.
164 * The mapped boolean indicates whether the range between a key and the next greater key
165 * is also excluded. If true, the wire encoding shall have an ANY element.
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800166 *
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000167 * The map is ordered in descending order to simplify \p isExcluded.
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800168 */
Junxiao Shib80e9472016-07-20 13:45:24 +0000169 typedef std::map<ExcludeComponent, bool, std::greater<ExcludeComponent>> ExcludeMap;
170 typedef ExcludeMap::value_type Entry;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800171
Junxiao Shib80e9472016-07-20 13:45:24 +0000172public: // enumeration API
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800173 /**
Junxiao Shib80e9472016-07-20 13:45:24 +0000174 * @brief represent an excluded component or range
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800175 */
Junxiao Shib80e9472016-07-20 13:45:24 +0000176 class Range
177 {
178 public:
Junxiao Shi4f756902017-07-18 03:05:02 +0000179 Range();
180
181 Range(bool fromInfinity, const name::Component& from, bool toInfinity, const name::Component& to);
182
Junxiao Shib80e9472016-07-20 13:45:24 +0000183 /**
184 * @retval true A single component is excluded
185 * @retval false A range of more than one components are excluded
186 */
187 bool
188 isSingular() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800189
Junxiao Shib80e9472016-07-20 13:45:24 +0000190 bool
191 operator==(const Exclude::Range& other) const;
192
193 bool
194 operator!=(const Exclude::Range& other) const;
195
196 public:
197 /**
198 * @brief from negative infinity?
199 */
200 bool fromInfinity;
201
202 /**
203 * @brief from component (inclusive)
204 * @pre valid only if !fromInfinity
205 */
206 name::Component from;
207
208 /**
209 * @brief to positive infinity?
210 */
211 bool toInfinity;
212
213 /**
214 * @brief to component (inclusive)
215 * @pre valid only if !toInfinity
216 */
217 name::Component to;
218 };
219
220 class const_iterator : public std::iterator<std::forward_iterator_tag, const Range>
221 {
222 public:
223 const_iterator() = default;
224
225 const_iterator(ExcludeMap::const_reverse_iterator it, ExcludeMap::const_reverse_iterator rend);
226
227 const Range&
228 operator*() const;
229
230 const Range*
231 operator->() const;
232
233 const_iterator&
234 operator++();
235
236 const_iterator
237 operator++(int);
238
239 bool
240 operator==(const const_iterator& other) const;
241
242 bool
243 operator!=(const const_iterator& other) const;
244
245 private:
246 void
247 update();
248
249 private:
250 ExcludeMap::const_reverse_iterator m_it;
251 ExcludeMap::const_reverse_iterator m_rend;
252 Range m_range;
253 friend class Exclude;
254 };
255
Junxiao Shi75203022014-09-11 10:01:50 -0700256 const_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700257 begin() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800258
Junxiao Shi75203022014-09-11 10:01:50 -0700259 const_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700260 end() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800261
Junxiao Shib80e9472016-07-20 13:45:24 +0000262 bool
263 empty() const;
264
265 size_t
266 size() const;
267
268 /// \todo const_iterator erase(const_iterator i);
269
270 void
271 clear();
272
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800273private:
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000274 /**
275 * @brief directly append exclude element
276 * @tparam T either name::Component or bool
277 *
278 * This method is used during conversion from wire format of exclude filter
279 */
280 template<typename T>
281 void
282 appendEntry(const T& component, bool hasAny);
283
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700284 Exclude&
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000285 excludeRange(const ExcludeComponent& from, const name::Component& to);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800286
287private:
Junxiao Shib80e9472016-07-20 13:45:24 +0000288 ExcludeMap m_entries;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700289 mutable Block m_wire;
Junxiao Shib80e9472016-07-20 13:45:24 +0000290
291 friend std::ostream&
292 operator<<(std::ostream& os, const Exclude& name);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800293};
294
Davide Pesavento88a0d812017-08-19 21:31:42 -0400295NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(Exclude);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800296
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000297bool
Junxiao Shib80e9472016-07-20 13:45:24 +0000298operator==(const Exclude::ExcludeComponent& a, const Exclude::ExcludeComponent& b);
299
300bool
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000301operator>(const Exclude::ExcludeComponent& a, const Exclude::ExcludeComponent& b);
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800302
Junxiao Shib80e9472016-07-20 13:45:24 +0000303std::ostream&
304operator<<(std::ostream& os, const Exclude::Range& range);
305
Davide Pesavento88a0d812017-08-19 21:31:42 -0400306std::ostream&
307operator<<(std::ostream& os, const Exclude& name);
308
Junxiao Shib80e9472016-07-20 13:45:24 +0000309inline Exclude::const_iterator
310Exclude::begin() const
311{
312 return const_iterator(m_entries.rbegin(), m_entries.rend());
313}
314
315inline Exclude::const_iterator
316Exclude::end() const
317{
318 return const_iterator(m_entries.rend(), m_entries.rend());
319}
320
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800321inline bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700322Exclude::empty() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800323{
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000324 return m_entries.empty();
Alexander Afanasyev85480842014-01-06 14:46:54 -0800325}
326
Alexander Afanasyevba096052014-09-19 15:36:37 -0700327inline bool
328Exclude::operator!=(const Exclude& other) const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800329{
Alexander Afanasyevba096052014-09-19 15:36:37 -0700330 return !(*this == other);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800331}
332
Junxiao Shib80e9472016-07-20 13:45:24 +0000333inline bool
334Exclude::Range::isSingular() const
335{
336 return !this->fromInfinity && !this->toInfinity && this->from == this->to;
337}
338
339inline bool
340Exclude::Range::operator!=(const Exclude::Range& other) const
341{
342 return !this->operator==(other);
343}
344
345inline const Exclude::Range&
346Exclude::const_iterator::operator*() const
347{
348 BOOST_ASSERT(m_it != m_rend);
349 return m_range;
350}
351
352inline const Exclude::Range*
353Exclude::const_iterator::operator->() const
354{
355 BOOST_ASSERT(m_it != m_rend);
356 return &m_range;
357}
358
359inline bool
360Exclude::const_iterator::operator==(const const_iterator& other) const
361{
362 return m_it == other.m_it;
363}
364
365inline bool
366Exclude::const_iterator::operator!=(const const_iterator& other) const
367{
368 return !this->operator==(other);
369}
370
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000371} // namespace ndn
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800372
Junxiao Shi4f756902017-07-18 03:05:02 +0000373#endif // NDN_EXCLUDE_HPP