blob: d086f14f748dc2950f065feccb8ef0ad20e574b2 [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 Afanasyev2a7f7202014-04-23 14:25:29 -070024 class Error : public Tlv::Error
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070025 {
26 public:
27 explicit
28 Error(const std::string& what)
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -070029 : Tlv::Error(what)
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070030 {
31 }
32 };
Alexander Afanasyev993a0e12014-01-03 13:51:37 -080033
Alexander Afanasyevc348f832014-02-17 16:35:17 -080034 typedef std::map< name::Component, bool /*any*/, std::greater<name::Component> > exclude_type;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080035
36 typedef exclude_type::iterator iterator;
37 typedef exclude_type::const_iterator const_iterator;
38 typedef exclude_type::reverse_iterator reverse_iterator;
39 typedef exclude_type::const_reverse_iterator const_reverse_iterator;
40
41 /**
42 * @brief Default constructor an empty exclude
43 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070044 Exclude();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080045
46 /**
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070047 * @brief Create from wire encoding
48 */
49 explicit
50 Exclude(const Block& wire)
51 {
52 wireDecode(wire);
53 }
54
55 /**
Alexander Afanasyevc348f832014-02-17 16:35:17 -080056 * @brief Fast encoding or block size estimation
57 */
58 template<bool T>
59 inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070060 wireEncode(EncodingImpl<T>& block) const;
61
Alexander Afanasyevc348f832014-02-17 16:35:17 -080062 /**
63 * @brief Encode to a wire format
64 */
65 inline const Block&
66 wireEncode() const;
67
68 /**
69 * @brief Decode from the wire format
70 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070071 inline void
72 wireDecode(const Block& wire);
73
Alexander Afanasyevc348f832014-02-17 16:35:17 -080074 ///////////////////////////////////////////////////////////////////////////////
75
76
77 /**
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080078 * @brief Check if name component is excluded
79 * @param comp Name component to check against exclude filter
80 */
81 bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070082 isExcluded(const name::Component& comp) const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080083
84 /**
85 * @brief Exclude specific name component
86 * @param comp component to exclude
87 * @returns *this to allow chaining
88 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070089 Exclude&
90 excludeOne(const name::Component& comp);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080091
92 /**
93 * @brief Exclude components from range [from, to]
94 * @param from first element of the range
95 * @param to last element of the range
96 * @returns *this to allow chaining
97 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070098 Exclude&
99 excludeRange(const name::Component& from, const name::Component& to);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800100
101 /**
102 * @brief Exclude all components from range [/, to]
103 * @param to last element of the range
104 * @returns *this to allow chaining
105 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700106 inline Exclude&
107 excludeBefore(const name::Component& to);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800108
109 /**
110 * @brief Exclude all components from range [from, +Inf]
111 * @param to last element of the range
112 * @returns *this to allow chaining
113 */
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700114 Exclude&
115 excludeAfter(const name::Component& from);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800116
117 /**
118 * @brief Method to directly append exclude element
119 * @param name excluded name component
120 * @param any flag indicating if there is a postfix ANY component after the name
121 *
122 * This method is used during conversion from wire format of exclude filter
123 *
124 * If there is an error with ranges (e.g., order of components is wrong) an exception is thrown
125 */
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800126 inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700127 appendExclude(const name::Component& name, bool any);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800128
129 /**
130 * @brief Check if exclude filter is empty
131 */
132 inline bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700133 empty() const;
Alexander Afanasyev85480842014-01-06 14:46:54 -0800134
135 /**
136 * @brief Clear the exclude filter
137 */
138 inline void
139 clear();
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700140
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800141 /**
142 * @brief Get number of exclude terms
143 */
144 inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700145 size() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800146
147 /**
148 * @brief Get begin iterator of the exclude terms
149 */
150 inline const_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700151 begin() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800152
153 /**
154 * @brief Get end iterator of the exclude terms
155 */
156 inline const_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700157 end() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800158
159 /**
160 * @brief Get begin iterator of the exclude terms
161 */
162 inline const_reverse_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700163 rbegin() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800164
165 /**
166 * @brief Get end iterator of the exclude terms
167 */
168 inline const_reverse_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700169 rend() const;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800170
171 /**
172 * @brief Get escaped string representation (e.g., for use in URI) of the exclude filter
173 */
174 inline std::string
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700175 toUri() const;
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800176
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800177private:
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700178 Exclude&
179 excludeRange(iterator fromLowerBound, iterator toLowerBound);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800180
181private:
182 exclude_type m_exclude;
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800183
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700184 mutable Block m_wire;
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800185};
186
187std::ostream&
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700188operator<<(std::ostream& os, const Exclude& name);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800189
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700190inline Exclude&
191Exclude::excludeBefore(const name::Component& to)
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800192{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700193 return excludeRange(name::Component(), to);
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800194}
195
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800196inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700197Exclude::appendExclude(const name::Component& name, bool any)
Alexander Afanasyev993a0e12014-01-03 13:51:37 -0800198{
199 m_exclude[name] = any;
200}
201
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800202inline bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700203Exclude::empty() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800204{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700205 return m_exclude.empty();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800206}
207
Alexander Afanasyev85480842014-01-06 14:46:54 -0800208inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700209Exclude::clear()
Alexander Afanasyev85480842014-01-06 14:46:54 -0800210{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700211 m_exclude.clear();
Alexander Afanasyev85480842014-01-06 14:46:54 -0800212}
213
214
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800215inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700216Exclude::size() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800217{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700218 return m_exclude.size();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800219}
220
221inline Exclude::const_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700222Exclude::begin() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800223{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700224 return m_exclude.begin();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800225}
226
227inline Exclude::const_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700228Exclude::end() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800229{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700230 return m_exclude.end();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800231}
232
233inline Exclude::const_reverse_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700234Exclude::rbegin() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800235{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700236 return m_exclude.rbegin();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800237}
238
239inline Exclude::const_reverse_iterator
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700240Exclude::rend() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800241{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700242 return m_exclude.rend();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800243}
244
245inline std::string
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700246Exclude::toUri() const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800247{
248 std::ostringstream os;
249 os << *this;
250 return os.str();
251}
252
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800253template<bool T>
254inline size_t
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700255Exclude::wireEncode(EncodingImpl<T>& block) const
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800256{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700257 size_t totalLength = 0;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800258
259 // Exclude ::= EXCLUDE-TYPE TLV-LENGTH Any? (NameComponent (Any)?)+
260 // Any ::= ANY-TYPE TLV-LENGTH(=0)
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700261
262 for (Exclude::const_iterator i = m_exclude.begin(); i != m_exclude.end(); i++)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800263 {
264 if (i->second)
265 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700266 totalLength += prependBooleanBlock(block, Tlv::Any);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800267 }
268 if (!i->first.empty())
269 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700270 totalLength += i->first.wireEncode(block);
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800271 }
272 }
273
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700274 totalLength += block.prependVarNumber(totalLength);
275 totalLength += block.prependVarNumber(Tlv::Exclude);
276 return totalLength;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800277}
278
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700279inline const Block&
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800280Exclude::wireEncode() const
281{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700282 if (m_wire.hasWire())
283 return m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800284
285 EncodingEstimator estimator;
286 size_t estimatedSize = wireEncode(estimator);
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700287
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800288 EncodingBuffer buffer(estimatedSize, 0);
289 wireEncode(buffer);
290
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700291 m_wire = buffer.block();
292 return m_wire;
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800293}
294
295inline void
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700296Exclude::wireDecode(const Block& wire)
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800297{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700298 m_wire = wire;
299 m_wire.parse();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800300
301 // Exclude ::= EXCLUDE-TYPE TLV-LENGTH Any? (NameComponent (Any)?)+
302 // Any ::= ANY-TYPE TLV-LENGTH(=0)
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700303
304 Block::element_const_iterator i = m_wire.elements_begin();
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800305 if (i->type() == Tlv::Any)
306 {
307 appendExclude(name::Component(), true);
308 ++i;
309 }
310
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700311 while (i != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800312 {
313 if (i->type() != Tlv::NameComponent)
314 throw Error("Incorrect format of Exclude filter");
315
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700316 name::Component excludedComponent(i->value(), i->value_size());
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800317 ++i;
318
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700319 if (i != m_wire.elements_end())
Alexander Afanasyevc348f832014-02-17 16:35:17 -0800320 {
321 if (i->type() == Tlv::Any)
322 {
323 appendExclude(excludedComponent, true);
324 ++i;
325 }
326 else
327 {
328 appendExclude(excludedComponent, false);
329 }
330 }
331 else
332 {
333 appendExclude(excludedComponent, false);
334 }
335 }
336}
337
338
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800339} // ndn
340
341#endif // NDN_EXCLUDE_H