blob: e850cf716171a21a7e197ae9bf93684bfe8dc6a3 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07002/**
Junxiao Shidf4b24e2016-07-14 21:41:43 +00003 * Copyright (c) 2013-2016 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
24#ifndef NDN_EXCLUDE_H
25#define NDN_EXCLUDE_H
26
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 Afanasyev15f67312014-07-22 15:11:09 -070030#include <sstream>
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070031#include <map>
32
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080033namespace ndn {
34
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080035/**
Junxiao Shidf4b24e2016-07-14 21:41:43 +000036 * @brief Represents Exclude selector in NDN Interest
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080037 */
38class Exclude
39{
40public:
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060041 class Error : public tlv::Error
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070042 {
43 public:
44 explicit
45 Error(const std::string& what)
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060046 : tlv::Error(what)
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070047 {
48 }
49 };
Alexander Afanasyev993a0e12014-01-03 13:51:37 -080050
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080051 /**
Junxiao Shidf4b24e2016-07-14 21:41:43 +000052 * @brief Constructs an empty Exclude
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080053 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070054 Exclude();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080055
56 /**
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070057 * @brief Create from wire encoding
58 */
59 explicit
Junxiao Shi75203022014-09-11 10:01:50 -070060 Exclude(const Block& wire);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070061
62 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -080063 * @brief Fast encoding or block size estimation
64 */
Alexander Afanasyev74633892015-02-08 18:08:46 -080065 template<encoding::Tag TAG>
Junxiao Shi75203022014-09-11 10:01:50 -070066 size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070067 wireEncode(EncodingImpl<TAG>& encoder) const;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070068
Alexander Afanasyevc348f832014-02-17 16:35:17 -080069 /**
70 * @brief Encode to a wire format
71 */
Junxiao Shi75203022014-09-11 10:01:50 -070072 const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -080073 wireEncode() const;
74
75 /**
76 * @brief Decode from the wire format
77 */
Junxiao Shi75203022014-09-11 10:01:50 -070078 void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070079 wireDecode(const Block& wire);
80
Junxiao Shi75203022014-09-11 10:01:50 -070081 /**
82 * @brief Get escaped string representation (e.g., for use in URI) of the exclude filter
83 */
84 std::string
85 toUri() const;
Alexander Afanasyevc348f832014-02-17 16:35:17 -080086
Junxiao Shi75203022014-09-11 10:01:50 -070087public: // high-level API
Alexander Afanasyevc348f832014-02-17 16:35:17 -080088 /**
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080089 * @brief Check if name component is excluded
90 * @param comp Name component to check against exclude filter
91 */
92 bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070093 isExcluded(const name::Component& comp) const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080094
95 /**
96 * @brief Exclude specific name component
97 * @param comp component to exclude
98 * @returns *this to allow chaining
99 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700100 Exclude&
101 excludeOne(const name::Component& comp);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800102
103 /**
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000104 * @brief Exclude components in range [from, to]
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800105 * @param from first element of the range
106 * @param to last element of the range
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000107 * @throw Error \p from equals or comes after \p to in canonical ordering
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800108 * @returns *this to allow chaining
109 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700110 Exclude&
111 excludeRange(const name::Component& from, const name::Component& to);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800112
113 /**
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000114 * @brief Exclude all components in range (-Inf, to]
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800115 * @param to last element of the range
116 * @returns *this to allow chaining
117 */
Junxiao Shi75203022014-09-11 10:01:50 -0700118 Exclude&
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700119 excludeBefore(const name::Component& to);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800120
121 /**
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000122 * @brief Exclude all components in range [from, +Inf)
Alexander Afanasyev770827c2014-05-13 17:42:55 -0700123 * @param from the first element of the range
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800124 * @returns *this to allow chaining
125 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700126 Exclude&
127 excludeAfter(const name::Component& from);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800128
129 /**
Junxiao Shi75203022014-09-11 10:01:50 -0700130 * @brief Check if exclude filter is empty
131 */
132 bool
133 empty() const;
134
135 /**
136 * @brief Clear the exclude filter
137 */
138 void
139 clear();
140
Alexander Afanasyevba096052014-09-19 15:36:37 -0700141public: // EqualityComparable concept
142 bool
143 operator==(const Exclude& other) const;
144
145 bool
146 operator!=(const Exclude& other) const;
147
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000148public: // low-level exclude entry API
149 /**
150 * @brief either a name::Component or "negative infinity"
151 */
152 class ExcludeComponent
153 {
154 public:
155 /**
156 * @brief implicitly construct a regular infinity ExcludeComponent
157 * @param component a name component which is excluded
158 */
159 ExcludeComponent(const name::Component& component);
Junxiao Shi75203022014-09-11 10:01:50 -0700160
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000161 /**
162 * @brief construct a negative infinity ExcludeComponent
163 * @param isNegInf must be true
164 */
165 explicit
166 ExcludeComponent(bool isNegInf);
167
168 public:
169 bool isNegInf;
170 name::Component component;
171 };
Junxiao Shi75203022014-09-11 10:01:50 -0700172
173 /**
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000174 * @brief a map of exclude entries
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800175 *
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000176 * Each key, except "negative infinity", is a name component that is excluded.
177 * The mapped boolean indicates whether the range between a key and the next greater key
178 * is also excluded. If true, the wire encoding shall have an ANY element.
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800179 *
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000180 * The map is ordered in descending order to simplify \p isExcluded.
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800181 */
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000182 typedef std::map<ExcludeComponent, bool, std::greater<ExcludeComponent>> ExcludeType;
183 typedef ExcludeType::value_type Entry;
184 typedef ExcludeType::iterator iterator;
185 typedef ExcludeType::const_iterator const_iterator;
186 typedef ExcludeType::reverse_iterator reverse_iterator;
187 typedef ExcludeType::const_reverse_iterator const_reverse_iterator;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800188
189 /**
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800190 * @brief Get number of exclude terms
191 */
Junxiao Shi75203022014-09-11 10:01:50 -0700192 size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700193 size() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800194
195 /**
196 * @brief Get begin iterator of the exclude terms
197 */
Junxiao Shi75203022014-09-11 10:01:50 -0700198 const_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700199 begin() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800200
201 /**
202 * @brief Get end iterator of the exclude terms
203 */
Junxiao Shi75203022014-09-11 10:01:50 -0700204 const_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700205 end() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800206
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800207private:
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000208 /**
209 * @brief directly append exclude element
210 * @tparam T either name::Component or bool
211 *
212 * This method is used during conversion from wire format of exclude filter
213 */
214 template<typename T>
215 void
216 appendEntry(const T& component, bool hasAny);
217
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700218 Exclude&
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000219 excludeRange(const ExcludeComponent& from, const name::Component& to);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800220
221private:
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000222 ExcludeType m_entries;
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800223
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700224 mutable Block m_wire;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800225};
226
227std::ostream&
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700228operator<<(std::ostream& os, const Exclude& name);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800229
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000230bool
231operator>(const Exclude::ExcludeComponent& a, const Exclude::ExcludeComponent& b);
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800232
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800233inline bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700234Exclude::empty() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800235{
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000236 return m_entries.empty();
Alexander Afanasyev85480842014-01-06 14:46:54 -0800237}
238
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800239inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700240Exclude::size() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800241{
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000242 return m_entries.size();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800243}
244
245inline Exclude::const_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700246Exclude::begin() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800247{
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000248 return m_entries.begin();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800249}
250
251inline Exclude::const_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700252Exclude::end() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800253{
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000254 return m_entries.end();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800255}
256
Alexander Afanasyevba096052014-09-19 15:36:37 -0700257inline bool
258Exclude::operator!=(const Exclude& other) const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800259{
Alexander Afanasyevba096052014-09-19 15:36:37 -0700260 return !(*this == other);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800261}
262
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000263} // namespace ndn
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800264
265#endif // NDN_EXCLUDE_H