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-2021 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 {
33  compile();
34 }
35 
36 void
37 RegexComponentSetMatcher::compile()
38 {
39  if (m_expr.size() < 2) {
40  NDN_THROW(Error("Invalid component set syntax: " + m_expr));
41  }
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("Missing ']' in regex: " + m_expr));
50  }
51 
52  if ('^' == m_expr[1]) {
53  m_isInclusion = false;
54  compileMultipleComponents(2, lastIndex);
55  }
56  else {
57  compileMultipleComponents(1, lastIndex);
58  }
59  break;
60  }
61  default:
62  NDN_THROW(Error("Invalid component set syntax: " + m_expr));
63  }
64 }
65 
66 void
67 RegexComponentSetMatcher::compileSingleComponent()
68 {
69  size_t end = extractComponent(1);
70  if (m_expr.size() != end)
71  NDN_THROW(Error("Component expr error: " + m_expr));
72 
73  m_components.push_back(make_shared<RegexComponentMatcher>(m_expr.substr(1, end - 2), m_backrefManager));
74 }
75 
76 void
77 RegexComponentSetMatcher::compileMultipleComponents(size_t start, size_t lastIndex)
78 {
79  size_t index = start;
80  size_t tempIndex = start;
81 
82  while (index < lastIndex) {
83  if ('<' != m_expr[index])
84  NDN_THROW(Error("Component expr error: " + m_expr));
85 
86  tempIndex = index + 1;
87  index = extractComponent(tempIndex);
88  m_components.push_back(make_shared<RegexComponentMatcher>(m_expr.substr(tempIndex, index - tempIndex - 1),
90  }
91 
92  if (index != lastIndex)
93  NDN_THROW(Error("Not sufficient expr to parse " + m_expr));
94 }
95 
96 bool
97 RegexComponentSetMatcher::match(const Name& name, size_t offset, size_t len)
98 {
99  // componentset only matches one component
100  if (len != 1)
101  return false;
102 
103  bool isMatched = false;
104  for (const auto& comp : m_components) {
105  if (comp->match(name, offset, len)) {
106  isMatched = true;
107  break;
108  }
109  }
110 
111  m_matchResult.clear();
112 
113  if (m_isInclusion ? isMatched : !isMatched) {
114  m_matchResult.push_back(name.get(offset));
115  return true;
116  }
117 
118  return false;
119 }
120 
121 size_t
122 RegexComponentSetMatcher::extractComponent(size_t index) const
123 {
124  size_t lcount = 1;
125  size_t rcount = 0;
126 
127  while (lcount > rcount) {
128  switch (m_expr[index]) {
129  case '<':
130  lcount++;
131  break;
132  case '>':
133  rcount++;
134  break;
135  case 0:
136  NDN_THROW(Error("Angle brackets mismatch: " + m_expr));
137  }
138  index++;
139  }
140 
141  return index;
142 }
143 
144 } // namespace ndn
Represents an absolute name.
Definition: name.hpp:45
const Component & get(ssize_t i) const noexcept
Returns an immutable reference to the component at the specified index.
Definition: name.hpp:192
bool match(const Name &name, size_t offset, size_t len=1) override
RegexComponentSetMatcher(const std::string &expr, shared_ptr< RegexBackrefManager > backrefManager)
Create a RegexComponentSetMatcher matcher from expr.
std::vector< name::Component > m_matchResult
shared_ptr< RegexBackrefManager > m_backrefManager
const std::string m_expr
#define NDN_THROW(e)
Definition: exception.hpp:56
Definition: data.cpp:25