NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.0: NDN, CCN, CCNx, content centric networks
API Documentation
regex-repeat-matcher.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
24 #ifndef NDN_UTIL_REGEX_REGEX_REPEAT_MATCHER_HPP
25 #define NDN_UTIL_REGEX_REGEX_REPEAT_MATCHER_HPP
26 
27 #include "../../common.hpp"
28 
29 #include <boost/regex.hpp>
30 
31 #include "regex-matcher.hpp"
32 
33 namespace ndn {
34 
36 {
37 public:
38  RegexRepeatMatcher(const std::string& expr,
39  shared_ptr<RegexBackrefManager> backrefManager,
40  size_t indicator);
41 
42  virtual
44  {
45  }
46 
47  virtual bool
48  match(const Name& name, size_t offset, size_t len);
49 
50 protected:
55  virtual void
56  compile();
57 
58 private:
59  bool
60  parseRepetition();
61 
62  bool
63  recursiveMatch(size_t repeat,
64  const Name& name,
65  size_t offset, size_t len);
66 
67 private:
68  size_t m_indicator;
69  size_t m_repeatMin;
70  size_t m_repeatMax;
71 };
72 
73 } // namespace ndn
74 
77 
78 namespace ndn {
79 
80 inline
82  shared_ptr<RegexBackrefManager> backrefManager,
83  size_t indicator)
84  : RegexMatcher(expr, EXPR_REPEAT_PATTERN, backrefManager)
85  , m_indicator(indicator)
86 {
87  compile();
88 }
89 
90 inline void
92 {
93  shared_ptr<RegexMatcher> matcher;
94 
95  if ('(' == m_expr[0]) {
96  matcher = make_shared<RegexBackrefMatcher>(m_expr.substr(0, m_indicator), m_backrefManager);
97  m_backrefManager->pushRef(matcher);
98  dynamic_pointer_cast<RegexBackrefMatcher>(matcher)->lateCompile();
99  }
100  else{
101  matcher = make_shared<RegexComponentSetMatcher>(m_expr.substr(0, m_indicator),
103  }
104  m_matchers.push_back(matcher);
105 
106  parseRepetition();
107 }
108 
109 inline bool
110 RegexRepeatMatcher::parseRepetition()
111 {
112  size_t exprSize = m_expr.size();
113  const size_t MAX_REPETITIONS = std::numeric_limits<size_t>::max();
114 
115  if (exprSize == m_indicator) {
116  m_repeatMin = 1;
117  m_repeatMax = 1;
118 
119  return true;
120  }
121  else {
122  if (exprSize == (m_indicator + 1)) {
123  if ('?' == m_expr[m_indicator]) {
124  m_repeatMin = 0;
125  m_repeatMax = 1;
126  return true;
127  }
128  if ('+' == m_expr[m_indicator]) {
129  m_repeatMin = 1;
130  m_repeatMax = MAX_REPETITIONS;
131  return true;
132  }
133  if ('*' == m_expr[m_indicator]) {
134  m_repeatMin = 0;
135  m_repeatMax = MAX_REPETITIONS;
136  return true;
137  }
138  }
139  else {
140  std::string repeatStruct = m_expr.substr(m_indicator, exprSize - m_indicator);
141  size_t rsSize = repeatStruct.size();
142  size_t min = 0;
143  size_t max = 0;
144 
145  if (boost::regex_match(repeatStruct, boost::regex("\\{[0-9]+,[0-9]+\\}"))) {
146  size_t separator = repeatStruct.find_first_of(',', 0);
147  min = atoi(repeatStruct.substr(1, separator - 1).c_str());
148  max = atoi(repeatStruct.substr(separator + 1, rsSize - separator - 2).c_str());
149  }
150  else if (boost::regex_match(repeatStruct, boost::regex("\\{,[0-9]+\\}"))) {
151  size_t separator = repeatStruct.find_first_of(',', 0);
152  min = 0;
153  max = atoi(repeatStruct.substr(separator + 1, rsSize - separator - 2).c_str());
154  }
155  else if (boost::regex_match(repeatStruct, boost::regex("\\{[0-9]+,\\}"))) {
156  size_t separator = repeatStruct.find_first_of(',', 0);
157  min = atoi(repeatStruct.substr(1, separator).c_str());
158  max = MAX_REPETITIONS;
159  }
160  else if (boost::regex_match(repeatStruct, boost::regex("\\{[0-9]+\\}"))) {
161  min = atoi(repeatStruct.substr(1, rsSize - 1).c_str());
162  max = min;
163  }
164  else
165  BOOST_THROW_EXCEPTION(RegexMatcher::Error(std::string("Error: RegexRepeatMatcher.ParseRepetition():")
166  + " Unrecognized format "+ m_expr));
167 
168  if (min > MAX_REPETITIONS || max > MAX_REPETITIONS || min > max)
169  BOOST_THROW_EXCEPTION(RegexMatcher::Error(std::string("Error: RegexRepeatMatcher.ParseRepetition():")
170  + " Wrong number " + m_expr));
171 
172  m_repeatMin = min;
173  m_repeatMax = max;
174 
175  return true;
176  }
177  }
178  return false;
179 }
180 
181 inline bool
182 RegexRepeatMatcher::match(const Name& name, size_t offset, size_t len)
183 {
184  m_matchResult.clear();
185 
186  if (0 == m_repeatMin)
187  if (0 == len)
188  return true;
189 
190  if (recursiveMatch(0, name, offset, len))
191  {
192  for (size_t i = offset; i < offset + len; i++)
193  m_matchResult.push_back(name.get(i));
194  return true;
195  }
196  else
197  return false;
198 }
199 
200 inline bool
201 RegexRepeatMatcher::recursiveMatch(size_t repeat, const Name& name, size_t offset, size_t len)
202 {
203  ssize_t tried = len;
204  shared_ptr<RegexMatcher> matcher = m_matchers[0];
205 
206  if (0 < len && repeat >= m_repeatMax)
207  {
208  return false;
209  }
210 
211  if (0 == len && repeat < m_repeatMin)
212  {
213  return false;
214  }
215 
216  if (0 == len && repeat >= m_repeatMin)
217  {
218  return true;
219  }
220 
221  while (tried >= 0)
222  {
223  if (matcher->match(name, offset, tried) &&
224  recursiveMatch(repeat + 1, name, offset + tried, len - tried))
225  return true;
226  tried--;
227  }
228 
229  return false;
230 }
231 
232 
233 } // namespace ndn
234 
235 #endif // NDN_UTIL_REGEX_REGEX_REPEAT_MATCHER_HPP
Copyright (c) 2011-2015 Regents of the University of California.
RegexRepeatMatcher(const std::string &expr, shared_ptr< RegexBackrefManager > backrefManager, size_t indicator)
virtual void compile()
Compile the regular expression to generate the more matchers when necessary.
shared_ptr< RegexBackrefManager > m_backrefManager
std::vector< shared_ptr< RegexMatcher > > m_matchers
std::vector< name::Component > m_matchResult
Name abstraction to represent an absolute name.
Definition: name.hpp:46
const std::string m_expr
virtual bool match(const Name &name, size_t offset, size_t len)
const Component & get(ssize_t i) const
Get the component at the given index.
Definition: name.hpp:419