All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
exclude.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2 /*
3  * Copyright (c) 2013-2014, Regents of the University of California
4  *
5  * BSD license, See the LICENSE file for more information
6  *
7  * @author Alexander Afanasyev <[email protected]>
8  */
9 
10 #include "common.hpp"
11 
12 #include "exclude.hpp"
13 
14 namespace ndn {
15 
17 {
18 }
19 
20 // example: ANY /b /d ANY /f
21 //
22 // ordered in map as:
23 //
24 // /f (false); /d (true); /b (false); / (true)
25 //
26 // lower_bound(/) -> / (true) <-- excluded (equal)
27 // lower_bound(/a) -> / (true) <-- excluded (any)
28 // lower_bound(/b) -> /b (false) <--- excluded (equal)
29 // lower_bound(/c) -> /b (false) <--- not excluded (not equal and no ANY)
30 // lower_bound(/d) -> /d (true) <- excluded
31 // lower_bound(/e) -> /d (true) <- excluded
32 bool
34 {
35  const_iterator lowerBound = m_exclude.lower_bound(comp);
36  if (lowerBound == end())
37  return false;
38 
39  if (lowerBound->second)
40  return true;
41  else
42  return lowerBound->first == comp;
43 
44  return false;
45 }
46 
47 Exclude&
49 {
50  if (!isExcluded(comp))
51  {
52  m_exclude.insert(std::make_pair(comp, false));
53  }
54  return *this;
55 }
56 
57 
58 // example: ANY /b0 /d0 ANY /f0
59 //
60 // ordered in map as:
61 //
62 // /f0 (false); /d0 (true); /b0 (false); / (true)
63 //
64 // lower_bound(/) -> / (true) <-- excluded (equal)
65 // lower_bound(/a0) -> / (true) <-- excluded (any)
66 // lower_bound(/b0) -> /b0 (false) <--- excluded (equal)
67 // lower_bound(/c0) -> /b0 (false) <--- not excluded (not equal and no ANY)
68 // lower_bound(/d0) -> /d0 (true) <- excluded
69 // lower_bound(/e0) -> /d0 (true) <- excluded
70 
71 
72 // examples with desired outcomes
73 // excludeRange(/, /f0) -> ANY /f0
74 // /f0 (false); / (true)
75 // excludeRange(/, /f1) -> ANY /f1
76 // /f1 (false); / (true)
77 // excludeRange(/a0, /e0) -> ANY /f0
78 // /f0 (false); / (true)
79 // excludeRange(/a0, /e0) -> ANY /f0
80 // /f0 (false); / (true)
81 
82 // excludeRange(/b1, /c0) -> ANY /b0 /b1 ANY /c0 /d0 ANY /f0
83 // /f0 (false); /d0 (true); /c0 (false); /b1 (true); /b0 (false); / (true)
84 
85 Exclude&
87 {
88  if (from >= to) {
89  throw Error("Invalid exclude range [" +
90  from.toEscapedString() + ", " +
91  to.toEscapedString() +
92  "] (for single name exclude use Exclude::excludeOne)");
93  }
94 
95  iterator newFrom = m_exclude.lower_bound(from);
96  if (newFrom == end() || !newFrom->second /*without ANY*/) {
97  std::pair<iterator, bool> fromResult = m_exclude.insert(std::make_pair(from, true));
98  newFrom = fromResult.first;
99  if (!fromResult.second) {
100  // this means that the lower bound is equal to the item itself. So, just update ANY flag
101  newFrom->second = true;
102  }
103  }
104  // else
105  // nothing special if start of the range already exists with ANY flag set
106 
107  iterator newTo = m_exclude.lower_bound(to); // !newTo cannot be end()
108  if (newTo == newFrom || !newTo->second) {
109  std::pair<iterator, bool> toResult = m_exclude.insert(std::make_pair(to, false));
110  newTo = toResult.first;
111  ++ newTo;
112  }
113  // else
114  // nothing to do really
115 
116  m_exclude.erase(newTo, newFrom); // remove any intermediate node, since all of the are excluded
117 
118  return *this;
119 }
120 
121 Exclude&
123 {
124  iterator newFrom = m_exclude.lower_bound(from);
125  if (newFrom == end() || !newFrom->second /*without ANY*/) {
126  std::pair<iterator, bool> fromResult = m_exclude.insert(std::make_pair(from, true));
127  newFrom = fromResult.first;
128  if (!fromResult.second) {
129  // this means that the lower bound is equal to the item itself. So, just update ANY flag
130  newFrom->second = true;
131  }
132  }
133  // else
134  // nothing special if start of the range already exists with ANY flag set
135 
136  if (newFrom != m_exclude.begin()) {
137  // remove any intermediate node, since all of the are excluded
138  m_exclude.erase(m_exclude.begin(), newFrom);
139  }
140 
141  return *this;
142 }
143 
144 
145 std::ostream&
146 operator<<(std::ostream& os, const Exclude& exclude)
147 {
148  bool empty = true;
149  for (Exclude::const_reverse_iterator i = exclude.rbegin(); i != exclude.rend(); i++) {
150  if (!i->first.empty()) {
151  if (!empty) os << ",";
152  os << i->first.toEscapedString();
153  empty = false;
154  }
155  if (i->second) {
156  if (!empty) os << ",";
157  os << "*";
158  empty = false;
159  }
160  }
161  return os;
162 }
163 
164 
165 } // namespace ndn
const_reverse_iterator rend() const
Get end iterator of the exclude terms.
Definition: exclude.hpp:240
void toEscapedString(std::ostream &result) const
Write the value to result, escaping characters according to the NDN URI Scheme.
exclude_type::const_iterator const_iterator
Definition: exclude.hpp:37
Exclude()
Default constructor an empty exclude.
Definition: exclude.cpp:16
Exclude & excludeOne(const name::Component &comp)
Exclude specific name component.
Definition: exclude.cpp:48
bool isExcluded(const name::Component &comp) const
Check if name component is excluded.
Definition: exclude.cpp:33
Component holds a read-only name component value.
exclude_type::iterator iterator
Definition: exclude.hpp:36
exclude_type::const_reverse_iterator const_reverse_iterator
Definition: exclude.hpp:39
Exclude & excludeAfter(const name::Component &from)
Exclude all components from range [from, +Inf].
Definition: exclude.cpp:122
Exclude & excludeRange(const name::Component &from, const name::Component &to)
Exclude components from range [from, to].
Definition: exclude.cpp:86
const_reverse_iterator rbegin() const
Get begin iterator of the exclude terms.
Definition: exclude.hpp:234
const_iterator end() const
Get end iterator of the exclude terms.
Definition: exclude.hpp:228
std::ostream & operator<<(std::ostream &os, const Data &data)
Definition: data.hpp:523
Class to represent Exclude component in NDN interests.
Definition: exclude.hpp:21