blob: be9dcc195ad6bf8391da518c3d8806c6150fa3c4 [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
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080011#include "common.hpp"
12
Alexander Afanasyev09c613f2014-01-29 00:23:58 -080013#include "exclude.hpp"
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080014
15namespace ndn
16{
17
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070018Exclude::Exclude()
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080019{
20}
21
22// example: ANY /b /d ANY /f
23//
24// ordered in map as:
25//
26// /f (false); /d (true); /b (false); / (true)
27//
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070028// lower_bound(/) -> / (true) <-- excluded (equal)
29// lower_bound(/a) -> / (true) <-- excluded (any)
30// lower_bound(/b) -> /b (false) <--- excluded (equal)
31// lower_bound(/c) -> /b (false) <--- not excluded (not equal and no ANY)
32// lower_bound(/d) -> /d (true) <- excluded
33// lower_bound(/e) -> /d (true) <- excluded
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080034bool
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070035Exclude::isExcluded(const name::Component& comp) const
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080036{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070037 const_iterator lowerBound = m_exclude.lower_bound(comp);
38 if (lowerBound == end())
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080039 return false;
40
41 if (lowerBound->second)
42 return true;
43 else
44 return lowerBound->first == comp;
45
46 return false;
47}
48
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070049Exclude&
50Exclude::excludeOne(const name::Component& comp)
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080051{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070052 if (!isExcluded(comp))
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080053 {
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070054 m_exclude.insert(std::make_pair(comp, false));
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080055 }
56 return *this;
57}
58
59
60// example: ANY /b0 /d0 ANY /f0
61//
62// ordered in map as:
63//
64// /f0 (false); /d0 (true); /b0 (false); / (true)
65//
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070066// lower_bound(/) -> / (true) <-- excluded (equal)
67// lower_bound(/a0) -> / (true) <-- excluded (any)
68// lower_bound(/b0) -> /b0 (false) <--- excluded (equal)
69// lower_bound(/c0) -> /b0 (false) <--- not excluded (not equal and no ANY)
70// lower_bound(/d0) -> /d0 (true) <- excluded
71// lower_bound(/e0) -> /d0 (true) <- excluded
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080072
73
74// examples with desired outcomes
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070075// excludeRange(/, /f0) -> ANY /f0
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080076// /f0 (false); / (true)
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070077// excludeRange(/, /f1) -> ANY /f1
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080078// /f1 (false); / (true)
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070079// excludeRange(/a0, /e0) -> ANY /f0
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080080// /f0 (false); / (true)
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070081// excludeRange(/a0, /e0) -> ANY /f0
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080082// /f0 (false); / (true)
83
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070084// excludeRange(/b1, /c0) -> ANY /b0 /b1 ANY /c0 /d0 ANY /f0
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080085// /f0 (false); /d0 (true); /c0 (false); /b1 (true); /b0 (false); / (true)
86
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070087Exclude&
88Exclude::excludeRange(const name::Component& from, const name::Component& to)
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080089{
90 if (from >= to)
91 {
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070092 throw Error("Invalid exclude range [" +
93 from.toEscapedString() + ", " +
94 to.toEscapedString() +
95 "] (for single name exclude use Exclude::excludeOne)");
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -080096 }
97
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -070098 iterator newFrom = m_exclude.lower_bound(from);
99 if (newFrom == end() || !newFrom->second /*without ANY*/)
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800100 {
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700101 std::pair<iterator, bool> fromResult = m_exclude.insert(std::make_pair(from, true));
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800102 newFrom = fromResult.first;
103 if (!fromResult.second)
104 {
105 // this means that the lower bound is equal to the item itself. So, just update ANY flag
106 newFrom->second = true;
107 }
108 }
109 // else
110 // nothing special if start of the range already exists with ANY flag set
111
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700112 iterator newTo = m_exclude.lower_bound(to); // !newTo cannot be end()
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800113 if (newTo == newFrom || !newTo->second)
114 {
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700115 std::pair<iterator, bool> toResult = m_exclude.insert(std::make_pair(to, false));
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800116 newTo = toResult.first;
117 ++ newTo;
118 }
119 else
120 {
121 // nothing to do really
122 }
123
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700124 m_exclude.erase(newTo, newFrom); // remove any intermediate node, since all of the are excluded
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800125
126 return *this;
127}
128
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700129Exclude&
130Exclude::excludeAfter(const name::Component& from)
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800131{
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700132 iterator newFrom = m_exclude.lower_bound(from);
133 if (newFrom == end() || !newFrom->second /*without ANY*/)
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800134 {
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700135 std::pair<iterator, bool> fromResult = m_exclude.insert(std::make_pair(from, true));
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800136 newFrom = fromResult.first;
137 if (!fromResult.second)
138 {
139 // this means that the lower bound is equal to the item itself. So, just update ANY flag
140 newFrom->second = true;
141 }
142 }
143 // else
144 // nothing special if start of the range already exists with ANY flag set
145
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700146 if (newFrom != m_exclude.begin())
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800147 {
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700148 m_exclude.erase(m_exclude.begin(), newFrom); // remove any intermediate node, since all of the are excluded
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800149 }
150
151 return *this;
152}
153
154
155std::ostream&
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700156operator<<(std::ostream& os, const Exclude& exclude)
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800157{
158 bool empty = true;
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700159 for (Exclude::const_reverse_iterator i = exclude.rbegin(); i != exclude.rend(); i++)
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800160 {
161 if (!i->first.empty())
162 {
163 if (!empty) os << ",";
Alexander Afanasyevff2d08f2014-04-07 18:28:25 -0700164 os << i->first.toEscapedString();
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800165 empty = false;
166 }
167 if (i->second)
168 {
169 if (!empty) os << ",";
170 os << "*";
171 empty = false;
172 }
173 }
174 return os;
175}
176
Alexander Afanasyevb3a6af42014-01-03 13:08:28 -0800177
178} // ndn