regex-component-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_COMPONENT_MATCHER_HPP
25 #define NDN_UTIL_REGEX_REGEX_COMPONENT_MATCHER_HPP
26 
27 #include <boost/regex.hpp>
28 
29 #include "regex-matcher.hpp"
30 #include "regex-pseudo-matcher.hpp"
31 
32 namespace ndn {
33 
35 {
36 public:
43  RegexComponentMatcher(const std::string& expr,
44  shared_ptr<RegexBackrefManager> backrefManager,
45  bool isExactMatch = true);
46 
47  virtual
49  {
50  }
51 
52  virtual bool
53  match(const Name& name, size_t offset, size_t len = 1);
54 
55 protected:
59  virtual void
60  compile();
61 
62 private:
63  bool m_isExactMatch;
64  boost::regex m_componentRegex;
65  std::vector<shared_ptr<RegexPseudoMatcher> > m_pseudoMatchers;
66 
67 };
68 
69 
70 inline
72  shared_ptr<RegexBackrefManager> backrefManager,
73  bool isExactMatch)
74  : RegexMatcher(expr, EXPR_COMPONENT, backrefManager)
75  , m_isExactMatch(isExactMatch)
76 {
77  compile();
78 }
79 
80 // Re: http://www.boost.org/users/history/version_1_56_0.html
81 //
82 // Breaking change: corrected behavior of basic_regex<>::mark_count() to match existing
83 // documentation, basic_regex<>::subexpression(n) changed to match, see
84 // https://svn.boost.org/trac/boost/ticket/9227
86 #if BOOST_VERSION < 105600
87  1;
88 #else
89  0;
90 #endif
91 
92 inline void
94 {
95  m_componentRegex = boost::regex(m_expr);
96 
97  m_pseudoMatchers.clear();
98  m_pseudoMatchers.push_back(make_shared<RegexPseudoMatcher>());
99 
100  for (size_t i = 1;
101  i <= m_componentRegex.mark_count() - BOOST_REGEXP_MARK_COUNT_CORRECTION; i++)
102  {
103  shared_ptr<RegexPseudoMatcher> pMatcher = make_shared<RegexPseudoMatcher>();
104  m_pseudoMatchers.push_back(pMatcher);
105  m_backrefManager->pushRef(static_pointer_cast<RegexMatcher>(pMatcher));
106  }
107 }
108 
109 inline bool
110 RegexComponentMatcher::match(const Name& name, size_t offset, size_t len)
111 {
112  m_matchResult.clear();
113 
114  if (m_expr.empty())
115  {
116  m_matchResult.push_back(name.get(offset));
117  return true;
118  }
119 
120  if (m_isExactMatch)
121  {
122  boost::smatch subResult;
123  std::string targetStr = name.get(offset).toUri();
124  if (boost::regex_match(targetStr, subResult, m_componentRegex))
125  {
126  for (size_t i = 1;
127  i <= m_componentRegex.mark_count() - BOOST_REGEXP_MARK_COUNT_CORRECTION; i++)
128  {
129  m_pseudoMatchers[i]->resetMatchResult();
130  m_pseudoMatchers[i]->setMatchResult(subResult[i]);
131  }
132  m_matchResult.push_back(name.get(offset));
133  return true;
134  }
135  }
136  else
137  {
138  BOOST_THROW_EXCEPTION(RegexMatcher::Error("Non-exact component search is not supported "
139  "yet"));
140  }
141 
142  return false;
143 }
144 
145 
146 } // namespace ndn
147 
148 #endif // NDN_UTIL_REGEX_REGEX_COMPONENT_MATCHER_HPP
Copyright (c) 2013-2017 Regents of the University of California.
Definition: common.hpp:66
virtual bool match(const Name &name, size_t offset, size_t len=1)
RegexComponentMatcher(const std::string &expr, shared_ptr< RegexBackrefManager > backrefManager, bool isExactMatch=true)
Create a RegexComponent matcher from expr.
shared_ptr< RegexBackrefManager > m_backrefManager
virtual void compile()
Compile the regular expression to generate the more matchers when necessary.
void toUri(std::ostream &os) const
Write *this to the output stream, escaping characters according to the NDN URI Scheme.
std::vector< name::Component > m_matchResult
Represents an absolute name.
Definition: name.hpp:42
const std::string m_expr
static const size_t BOOST_REGEXP_MARK_COUNT_CORRECTION
const Component & get(ssize_t i) const
Get the component at the given index.
Definition: name.hpp:164