All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
regex-component-set-matcher.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
8 #ifndef NDN_UTIL_REGEX_COMPONENT_SET_MATCHER_HPP
9 #define NDN_UTIL_REGEX_COMPONENT_SET_MATCHER_HPP
10 
11 #include "../../common.hpp"
12 
13 #include "regex-matcher.hpp"
15 
16 namespace ndn {
17 
19 {
20 
21 public:
28  RegexComponentSetMatcher(const std::string& expr, shared_ptr<RegexBackrefManager> backRefManager);
29 
30  virtual ~RegexComponentSetMatcher();
31 
32  virtual bool
33  match(const Name& name, const int& offset, const int& len = 1);
34 
35 protected:
40  virtual void
41  compile();
42 
43 private:
44  int
45  extractComponent(int index);
46 
47  void
48  compileSingleComponent();
49 
50  void
51  compileMultipleComponents(const int start, const int lastIndex);
52 
53 private:
54  typedef std::set<shared_ptr<RegexComponentMatcher> > ComponentsSet;
55  ComponentsSet m_components;
56  bool m_include;
57 };
58 
59 
60 inline
62  shared_ptr<RegexBackrefManager> backRefManager)
63  : RegexMatcher(expr, EXPR_COMPONENT_SET, backRefManager),
64  m_include(true)
65 {
66  // _LOG_TRACE ("Enter RegexComponentSetMatcher Constructor");
67  compile();
68  // _LOG_TRACE ("Exit RegexComponentSetMatcher Constructor");
69 }
70 
71 inline
73 {
74  // ComponentsSet::iterator it = m_components.begin();
75 
76  // for(; it != m_components.end(); it++)
77  // delete *it;
78 }
79 
80 inline void
82 {
83  switch (m_expr[0]){
84  case '<':
85  return compileSingleComponent();
86  case '[':
87  {
88  int lastIndex = m_expr.size() - 1;
89  if (']' != m_expr[lastIndex])
90  throw RegexMatcher::Error(std::string("Error: RegexComponentSetMatcher.compile(): ")
91  + " No matched ']' " + m_expr);
92 
93  if ('^' == m_expr[1]){
94  m_include = false;
95  compileMultipleComponents(2, lastIndex);
96  }
97  else
98  compileMultipleComponents(1, lastIndex);
99  break;
100  }
101  default:
102  throw RegexMatcher::Error(std::string("Error: RegexComponentSetMatcher.compile(): ")
103  + "Parsing error in expr " + m_expr);
104  }
105 }
106 
107 inline void
108 RegexComponentSetMatcher::compileSingleComponent()
109 {
110  size_t end = extractComponent(1);
111 
112  if (m_expr.size() != end)
113  {
114  throw RegexMatcher::Error(
115  std::string("Error: RegexComponentSetMatcher.compileSingleComponent: ") + m_expr);
116  }
117  else
118  {
119  shared_ptr<RegexComponentMatcher> component =
120  make_shared<RegexComponentMatcher>(m_expr.substr(1, end - 2), m_backrefManager);
121 
122  m_components.insert(component);
123  }
124 }
125 
126 inline void
127 RegexComponentSetMatcher::compileMultipleComponents(const int start, const int lastIndex)
128 {
129  int index = start;
130  int tmp_index = start;
131 
132  while(index < lastIndex){
133  if ('<' != m_expr[index])
134  throw RegexMatcher::Error(
135  std::string("Error: RegexComponentSetMatcher.compileMultipleComponents: ") +
136  "Component expr error " + m_expr);
137 
138  tmp_index = index + 1;
139  index = extractComponent(tmp_index);
140 
141  shared_ptr<RegexComponentMatcher> component =
142  make_shared<RegexComponentMatcher>(m_expr.substr(tmp_index, index - tmp_index - 1),
144 
145  m_components.insert(component);
146  }
147 
148  if (index != lastIndex)
149  throw RegexMatcher::Error(
150  std::string("Error: RegexComponentSetMatcher.compileMultipleComponents: ") +
151  "Not sufficient expr to parse " + m_expr);
152 }
153 
154 inline bool
155 RegexComponentSetMatcher::match(const Name& name, const int& offset, const int& len)
156 {
157  bool matched = false;
158 
159  /* componentset only matches one component */
160  if (len != 1)
161  {
162  return false;
163  }
164 
165  for (ComponentsSet::iterator it = m_components.begin();
166  it != m_components.end();
167  ++it)
168  {
169  if ((*it)->match(name, offset, len))
170  {
171  matched = true;
172  break;
173  }
174  }
175 
176  m_matchResult.clear();
177 
178  if (m_include ? matched : !matched)
179  {
180  m_matchResult.push_back(name.get(offset));
181  return true;
182  }
183  else
184  return false;
185 }
186 
187 inline int
188 RegexComponentSetMatcher::extractComponent(int index)
189 {
190  int lcount = 1;
191  int rcount = 0;
192 
193  while(lcount > rcount){
194  switch (m_expr[index]){
195  case '<':
196  lcount++;
197  break;
198 
199  case '>':
200  rcount++;
201  break;
202 
203  case 0:
204  throw RegexMatcher::Error("Error: square brackets mismatch");
205  break;
206  }
207  index++;
208 
209  }
210 
211  return index;
212 }
213 
214 } // namespace ndn
215 
216 #endif // NDN_UTIL_REGEX_COMPONENT_SET_MATCHER_HPP
RegexComponentSetMatcher(const std::string &expr, shared_ptr< RegexBackrefManager > backRefManager)
Create a RegexComponentSetMatcher matcher from expr.
virtual bool match(const Name &name, const int &offset, const int &len=1)
shared_ptr< RegexBackrefManager > m_backrefManager
std::vector< name::Component > m_matchResult
A Name holds an array of Name::Component and represents an NDN name.
Definition: name.hpp:26
virtual void compile()
Compile the regular expression to generate the more matchers when necessary.
const std::string m_expr
const Component & get(ssize_t i) const
Get the component at the given index.
Definition: name.hpp:340