regex-component-set-matcher.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013-2019 Regents of the University of California.
4  *
5  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6  *
7  * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8  * terms of the GNU Lesser General Public License as published by the Free Software
9  * Foundation, either version 3 of the License, or (at your option) any later version.
10  *
11  * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13  * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14  *
15  * You should have received copies of the GNU General Public License and GNU Lesser
16  * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17  * <http://www.gnu.org/licenses/>.
18  *
19  * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20  *
21  * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
22  */
23 
26 
27 namespace ndn {
28 
30  shared_ptr<RegexBackrefManager> backrefManager)
31  : RegexMatcher(expr, EXPR_COMPONENT_SET, std::move(backrefManager))
32  , m_isInclusion(true)
33 {
34  compile();
35 }
36 
37 void
39 {
40  if (m_expr.size() < 2)
41  NDN_THROW(Error("Regexp compile error (cannot parse " + m_expr + ")"));
42 
43  switch (m_expr[0]) {
44  case '<':
45  return compileSingleComponent();
46  case '[': {
47  size_t lastIndex = m_expr.size() - 1;
48  if (']' != m_expr[lastIndex])
49  NDN_THROW(Error("Regexp compile error (no matching ']' in " + m_expr + ")"));
50 
51  if ('^' == m_expr[1]) {
52  m_isInclusion = false;
53  compileMultipleComponents(2, lastIndex);
54  }
55  else
56  compileMultipleComponents(1, lastIndex);
57  break;
58  }
59  default:
60  NDN_THROW(Error("Regexp compile error (cannot parse " + m_expr + ")"));
61  }
62 }
63 
64 void
65 RegexComponentSetMatcher::compileSingleComponent()
66 {
67  size_t end = extractComponent(1);
68  if (m_expr.size() != end)
69  NDN_THROW(Error("Component expr error " + m_expr));
70 
71  m_components.push_back(make_shared<RegexComponentMatcher>(m_expr.substr(1, end - 2), m_backrefManager));
72 }
73 
74 void
75 RegexComponentSetMatcher::compileMultipleComponents(size_t start, size_t lastIndex)
76 {
77  size_t index = start;
78  size_t tempIndex = start;
79 
80  while (index < lastIndex) {
81  if ('<' != m_expr[index])
82  NDN_THROW(Error("Component expr error " + m_expr));
83 
84  tempIndex = index + 1;
85  index = extractComponent(tempIndex);
86  m_components.push_back(make_shared<RegexComponentMatcher>(m_expr.substr(tempIndex, index - tempIndex - 1),
88  }
89 
90  if (index != lastIndex)
91  NDN_THROW(Error("Not sufficient expr to parse " + m_expr));
92 }
93 
94 bool
95 RegexComponentSetMatcher::match(const Name& name, size_t offset, size_t len)
96 {
97  // componentset only matches one component
98  if (len != 1)
99  return false;
100 
101  bool isMatched = false;
102  for (const auto& comp : m_components) {
103  if (comp->match(name, offset, len)) {
104  isMatched = true;
105  break;
106  }
107  }
108 
109  m_matchResult.clear();
110 
111  if (m_isInclusion ? isMatched : !isMatched) {
112  m_matchResult.push_back(name.get(offset));
113  return true;
114  }
115  else
116  return false;
117 }
118 
119 size_t
120 RegexComponentSetMatcher::extractComponent(size_t index) const
121 {
122  size_t lcount = 1;
123  size_t rcount = 0;
124 
125  while (lcount > rcount) {
126  switch (m_expr[index]) {
127  case '<':
128  lcount++;
129  break;
130  case '>':
131  rcount++;
132  break;
133  case 0:
134  NDN_THROW(Error("Square brackets mismatch"));
135  break;
136  }
137  index++;
138  }
139 
140  return index;
141 }
142 
143 } // namespace ndn
Definition: data.cpp:26
const Component & get(ssize_t i) const
Returns an immutable reference to the component at the specified index.
Definition: name.hpp:165
bool match(const Name &name, size_t offset, size_t len=1) override
STL namespace.
#define NDN_THROW(e)
Definition: exception.hpp:61
shared_ptr< RegexBackrefManager > m_backrefManager
void compile() override
Compile the regular expression to generate the more matchers when necessary.
std::vector< name::Component > m_matchResult
Represents an absolute name.
Definition: name.hpp:44
RegexComponentSetMatcher(const std::string &expr, shared_ptr< RegexBackrefManager > backrefManager)
Create a RegexComponentSetMatcher matcher from expr.
const std::string m_expr