regex: move functions out of headers

Change-Id: I6a3ea61a6564195e297288d514c5a805a832e0e6
This commit is contained in:
Qiuhan Ding authored and Alexander Afanasyev committed 2015-08-06 15:28:51 -07:00
1 parent b56c54ebc1
commit 699725dae1
16 files changed
+915 -808

No files matched your search

+62
View File
@@ -0,0 +1,62 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "regex-backref-matcher.hpp"
#include "regex-pattern-list-matcher.hpp"
namespace ndn {
RegexBackrefMatcher::RegexBackrefMatcher(const std::string& expr,
shared_ptr<RegexBackrefManager> backrefManager)
: RegexMatcher(expr, EXPR_BACKREF, backrefManager)
{
}
RegexBackrefMatcher::~RegexBackrefMatcher()
{
}
void
RegexBackrefMatcher::lateCompile()
{
compile();
}
void
RegexBackrefMatcher::compile()
{
if (m_expr.size() < 2)
throw Error("Unrecognized format: " + m_expr);
size_t lastIndex = m_expr.size() - 1;
if ('(' == m_expr[0] && ')' == m_expr[lastIndex]) {
// m_backRefManager->pushRef(this);
auto matcher = make_shared<RegexPatternListMatcher>(m_expr.substr(1, lastIndex - 1),
m_backrefManager);
m_matchers.push_back(matcher);
}
else
throw Error("Unrecognized format: " + m_expr);
}
} // namespace ndn
+4 -44
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -17,8 +17,6 @@
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*
* @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
*/
#ifndef NDN_UTIL_REGEX_REGEX_BACKREF_MATCHER_HPP
@@ -36,54 +34,16 @@ public:
RegexBackrefMatcher(const std::string& expr, shared_ptr<RegexBackrefManager> backrefManager);
virtual
~RegexBackrefMatcher()
{
}
~RegexBackrefMatcher() NDN_CXX_DECL_FINAL;
void
lateCompile()
{
compile();
}
lateCompile();
protected:
virtual void
compile();
compile() NDN_CXX_DECL_FINAL;
};
} // namespace ndn
#include "regex-pattern-list-matcher.hpp"
namespace ndn {
inline
RegexBackrefMatcher::RegexBackrefMatcher(const std::string& expr,
shared_ptr<RegexBackrefManager> backrefManager)
: RegexMatcher(expr, EXPR_BACKREF, backrefManager)
{
// compile();
}
inline void
RegexBackrefMatcher::compile()
{
if (m_expr.size() < 2)
throw RegexMatcher::Error("Unrecognized format: " + m_expr);
size_t lastIndex = m_expr.size() - 1;
if ('(' == m_expr[0] && ')' == m_expr[lastIndex]) {
// m_backRefManager->pushRef(this);
shared_ptr<RegexMatcher> matcher(new RegexPatternListMatcher(m_expr.substr(1, lastIndex - 1),
m_backrefManager));
m_matchers.push_back(matcher);
}
else
throw RegexMatcher::Error("Unrecognized format: " + m_expr);
}
} // namespace ndn
#endif // NDN_UTIL_REGEX_REGEX_BACKREF_MATCHER_HPP
@@ -0,0 +1,97 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "regex-component-matcher.hpp"
namespace ndn {
// Re: http://www.boost.org/users/history/version_1_56_0.html
//
// Breaking change: corrected behavior of basic_regex<>::mark_count() to match existing
// documentation, basic_regex<>::subexpression(n) changed to match, see
// https://svn.boost.org/trac/boost/ticket/9227
static const size_t BOOST_REGEXP_MARK_COUNT_CORRECTION =
#if BOOST_VERSION < 105600
1;
#else
0;
#endif
RegexComponentMatcher::RegexComponentMatcher(const std::string& expr,
shared_ptr<RegexBackrefManager> backrefManager,
bool isExactMatch)
: RegexMatcher(expr, EXPR_COMPONENT, backrefManager)
, m_isExactMatch(isExactMatch)
{
compile();
}
RegexComponentMatcher::~RegexComponentMatcher()
{
}
bool
RegexComponentMatcher::match(const Name& name, size_t offset, size_t len)
{
m_matchResult.clear();
if (m_expr.empty()) {
m_matchResult.push_back(name.get(offset));
return true;
}
if (m_isExactMatch) {
boost::smatch subResult;
std::string targetStr = name.get(offset).toUri();
if (boost::regex_match(targetStr, subResult, m_componentRegex)) {
for (size_t i = 1;
i <= m_componentRegex.mark_count() - BOOST_REGEXP_MARK_COUNT_CORRECTION; i++) {
m_pseudoMatchers[i]->resetMatchResult();
m_pseudoMatchers[i]->setMatchResult(subResult[i]);
}
m_matchResult.push_back(name.get(offset));
return true;
}
}
else {
throw Error("Non-exact component search is not supported yet!");
}
return false;
}
void
RegexComponentMatcher::compile()
{
m_componentRegex = boost::regex(m_expr);
m_pseudoMatchers.clear();
m_pseudoMatchers.push_back(make_shared<RegexPseudoMatcher>());
for (size_t i = 1;
i <= m_componentRegex.mark_count() - BOOST_REGEXP_MARK_COUNT_CORRECTION; i++) {
auto pMatcher = make_shared<RegexPseudoMatcher>();
m_pseudoMatchers.push_back(pMatcher);
m_backrefManager->pushRef(static_pointer_cast<RegexMatcher>(pMatcher));
}
}
} // namespace ndn
+4 -84
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -17,8 +17,6 @@
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*
* @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
*/
#ifndef NDN_UTIL_REGEX_REGEX_COMPONENT_MATCHER_HPP
@@ -45,12 +43,10 @@ public:
bool isExactMatch = true);
virtual
~RegexComponentMatcher()
{
};
~RegexComponentMatcher() NDN_CXX_DECL_FINAL;
virtual bool
match(const Name& name, size_t offset, size_t len = 1);
match(const Name& name, size_t offset, size_t len = 1) NDN_CXX_DECL_FINAL;
protected:
/**
@@ -58,7 +54,7 @@ protected:
* @returns true if compiling succeeds
*/
virtual void
compile();
compile() NDN_CXX_DECL_FINAL;
private:
bool m_isExactMatch;
@@ -67,82 +63,6 @@ private:
};
inline
RegexComponentMatcher::RegexComponentMatcher(const std::string& expr,
shared_ptr<RegexBackrefManager> backrefManager,
bool isExactMatch)
: RegexMatcher(expr, EXPR_COMPONENT, backrefManager)
, m_isExactMatch(isExactMatch)
{
compile();
}
// Re: http://www.boost.org/users/history/version_1_56_0.html
//
// Breaking change: corrected behavior of basic_regex<>::mark_count() to match existing
// documentation, basic_regex<>::subexpression(n) changed to match, see
// https://svn.boost.org/trac/boost/ticket/9227
static const size_t BOOST_REGEXP_MARK_COUNT_CORRECTION =
#if BOOST_VERSION < 105600
1;
#else
0;
#endif
inline void
RegexComponentMatcher::compile()
{
m_componentRegex = boost::regex(m_expr);
m_pseudoMatchers.clear();
m_pseudoMatchers.push_back(make_shared<RegexPseudoMatcher>());
for (size_t i = 1;
i <= m_componentRegex.mark_count() - BOOST_REGEXP_MARK_COUNT_CORRECTION; i++)
{
shared_ptr<RegexPseudoMatcher> pMatcher = make_shared<RegexPseudoMatcher>();
m_pseudoMatchers.push_back(pMatcher);
m_backrefManager->pushRef(static_pointer_cast<RegexMatcher>(pMatcher));
}
}
inline bool
RegexComponentMatcher::match(const Name& name, size_t offset, size_t len)
{
m_matchResult.clear();
if (m_expr.empty())
{
m_matchResult.push_back(name.get(offset));
return true;
}
if (m_isExactMatch)
{
boost::smatch subResult;
std::string targetStr = name.get(offset).toUri();
if (boost::regex_match(targetStr, subResult, m_componentRegex))
{
for (size_t i = 1;
i <= m_componentRegex.mark_count() - BOOST_REGEXP_MARK_COUNT_CORRECTION; i++)
{
m_pseudoMatchers[i]->resetMatchResult();
m_pseudoMatchers[i]->setMatchResult(subResult[i]);
}
m_matchResult.push_back(name.get(offset));
return true;
}
}
else
{
throw RegexMatcher::Error("Non-exact component search is not supported yet!");
}
return false;
}
} // namespace ndn
#endif // NDN_UTIL_REGEX_REGEX_COMPONENT_MATCHER_HPP
@@ -0,0 +1,161 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "regex-component-set-matcher.hpp"
namespace ndn {
RegexComponentSetMatcher::RegexComponentSetMatcher(const std::string& expr,
shared_ptr<RegexBackrefManager> backrefManager)
: RegexMatcher(expr, EXPR_COMPONENT_SET, backrefManager)
, m_isInclusion(true)
{
compile();
}
RegexComponentSetMatcher::~RegexComponentSetMatcher()
{
}
bool
RegexComponentSetMatcher::match(const Name& name, size_t offset, size_t len)
{
bool isMatched = false;
/* componentset only matches one component */
if (len != 1)
{
return false;
}
for (auto& component : m_components) {
if (component->match(name, offset, len)) {
isMatched = true;
break;
}
}
m_matchResult.clear();
if (m_isInclusion ? isMatched : !isMatched) {
m_matchResult.push_back(name.get(offset));
return true;
}
else
return false;
}
void
RegexComponentSetMatcher::compile()
{
if (m_expr.size() < 2)
throw Error("Regexp compile error (cannot parse " + m_expr + ")");
switch (m_expr[0]) {
case '<':
return compileSingleComponent();
case '[':
{
size_t lastIndex = m_expr.size() - 1;
if (']' != m_expr[lastIndex])
throw Error("Regexp compile error (no matching ']' in " + m_expr + ")");
if ('^' == m_expr[1]) {
m_isInclusion = false;
compileMultipleComponents(2, lastIndex);
}
else
compileMultipleComponents(1, lastIndex);
break;
}
default:
throw Error("Regexp compile error (cannot parse " + m_expr + ")");
}
}
void
RegexComponentSetMatcher::compileSingleComponent()
{
size_t end = extractComponent(1);
if (m_expr.size() != end) {
throw Error("Component expr error " + m_expr);
}
else {
auto component = make_shared<RegexComponentMatcher>(m_expr.substr(1, end - 2),
m_backrefManager);
m_components.insert(component);
}
}
void
RegexComponentSetMatcher::compileMultipleComponents(size_t start, size_t lastIndex)
{
size_t index = start;
size_t tempIndex = start;
while (index < lastIndex) {
if ('<' != m_expr[index])
throw Error("Component expr error " + m_expr);
tempIndex = index + 1;
index = extractComponent(tempIndex);
auto component = make_shared<RegexComponentMatcher>(m_expr.substr(tempIndex,
index - tempIndex - 1),
m_backrefManager);
m_components.insert(component);
}
if (index != lastIndex)
throw Error("Not sufficient expr to parse " + m_expr);
}
size_t
RegexComponentSetMatcher::extractComponent(size_t index)
{
size_t lcount = 1;
size_t rcount = 0;
while (lcount > rcount) {
switch (m_expr[index]) {
case '<':
lcount++;
break;
case '>':
rcount++;
break;
case 0:
throw Error("Error: square brackets mismatch");
break;
}
index++;
}
return index;
}
} // namespace ndn
+4 -151
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -17,8 +17,6 @@
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*
* @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
*/
#ifndef NDN_UTIL_REGEX_COMPONENT_SET_MATCHER_HPP
@@ -44,10 +42,10 @@ public:
RegexComponentSetMatcher(const std::string& expr, shared_ptr<RegexBackrefManager> backrefManager);
virtual
~RegexComponentSetMatcher();
~RegexComponentSetMatcher() NDN_CXX_DECL_FINAL;
virtual bool
match(const Name& name, size_t offset, size_t len = 1);
match(const Name& name, size_t offset, size_t len = 1) NDN_CXX_DECL_FINAL;
protected:
/**
@@ -55,7 +53,7 @@ protected:
* @returns true if compiling succeeds
*/
virtual void
compile();
compile() NDN_CXX_DECL_FINAL;
private:
size_t
@@ -73,151 +71,6 @@ private:
bool m_isInclusion;
};
inline
RegexComponentSetMatcher::RegexComponentSetMatcher(const std::string& expr,
shared_ptr<RegexBackrefManager> backrefManager)
: RegexMatcher(expr, EXPR_COMPONENT_SET, backrefManager)
, m_isInclusion(true)
{
compile();
}
inline
RegexComponentSetMatcher::~RegexComponentSetMatcher()
{
}
inline void
RegexComponentSetMatcher::compile()
{
if (m_expr.size() < 2)
throw RegexMatcher::Error("Regexp compile error (cannot parse " + m_expr + ")");
switch (m_expr[0]) {
case '<':
return compileSingleComponent();
case '[':
{
size_t lastIndex = m_expr.size() - 1;
if (']' != m_expr[lastIndex])
throw RegexMatcher::Error("Regexp compile error (no matching ']' in " + m_expr + ")");
if ('^' == m_expr[1]) {
m_isInclusion = false;
compileMultipleComponents(2, lastIndex);
}
else
compileMultipleComponents(1, lastIndex);
break;
}
default:
throw RegexMatcher::Error("Regexp compile error (cannot parse " + m_expr + ")");
}
}
inline void
RegexComponentSetMatcher::compileSingleComponent()
{
size_t end = extractComponent(1);
if (m_expr.size() != end)
{
throw RegexMatcher::Error("Component expr error " + m_expr);
}
else
{
shared_ptr<RegexComponentMatcher> component =
make_shared<RegexComponentMatcher>(m_expr.substr(1, end - 2), m_backrefManager);
m_components.insert(component);
}
}
inline void
RegexComponentSetMatcher::compileMultipleComponents(size_t start, size_t lastIndex)
{
size_t index = start;
size_t tempIndex = start;
while (index < lastIndex) {
if ('<' != m_expr[index])
throw RegexMatcher::Error("Component expr error " + m_expr);
tempIndex = index + 1;
index = extractComponent(tempIndex);
shared_ptr<RegexComponentMatcher> component =
make_shared<RegexComponentMatcher>(m_expr.substr(tempIndex, index - tempIndex - 1),
m_backrefManager);
m_components.insert(component);
}
if (index != lastIndex)
throw RegexMatcher::Error("Not sufficient expr to parse " + m_expr);
}
inline bool
RegexComponentSetMatcher::match(const Name& name, size_t offset, size_t len)
{
bool isMatched = false;
/* componentset only matches one component */
if (len != 1)
{
return false;
}
for (ComponentsSet::iterator it = m_components.begin();
it != m_components.end();
++it)
{
if ((*it)->match(name, offset, len))
{
isMatched = true;
break;
}
}
m_matchResult.clear();
if (m_isInclusion ? isMatched : !isMatched)
{
m_matchResult.push_back(name.get(offset));
return true;
}
else
return false;
}
inline size_t
RegexComponentSetMatcher::extractComponent(size_t index)
{
size_t lcount = 1;
size_t rcount = 0;
while (lcount > rcount) {
switch (m_expr[index]) {
case '<':
lcount++;
break;
case '>':
rcount++;
break;
case 0:
throw RegexMatcher::Error("Error: square brackets mismatch");
break;
}
index++;
}
return index;
}
} // namespace ndn
#endif // NDN_UTIL_REGEX_COMPONENT_SET_MATCHER_HPP
+80
View File
@@ -0,0 +1,80 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "regex-matcher.hpp"
namespace ndn {
RegexMatcher::RegexMatcher(const std::string& expr,
const RegexExprType& type,
shared_ptr<RegexBackrefManager> backrefManager)
: m_expr(expr)
, m_type(type)
, m_backrefManager(backrefManager)
{
if (!static_cast<bool>(m_backrefManager))
m_backrefManager = make_shared<RegexBackrefManager>();
}
RegexMatcher::~RegexMatcher()
{
}
bool
RegexMatcher::match(const Name& name, size_t offset, size_t len)
{
bool result = false;
m_matchResult.clear();
if (recursiveMatch(0, name, offset, len)) {
for (size_t i = offset; i < offset + len ; i++)
m_matchResult.push_back(name.get(i));
result = true;
}
else {
result = false;
}
return result;
}
bool
RegexMatcher::recursiveMatch(size_t matcherNo, const Name& name, size_t offset, size_t len)
{
ssize_t tried = len;
if (matcherNo >= m_matchers.size())
return (len == 0);
shared_ptr<RegexMatcher> matcher = m_matchers[matcherNo];
while (tried >= 0) {
if (matcher->match(name, offset, tried) &&
recursiveMatch(matcherNo + 1, name, offset + tried, len - tried))
return true;
tried--;
}
return false;
}
} // namespace ndn
+3 -73
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -17,8 +17,6 @@
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*
* @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
*/
#ifndef NDN_UTIL_REGEX_REGEX_MATCHER_H
@@ -26,11 +24,10 @@
#include "../../common.hpp"
#include "../../name.hpp"
#include "regex-backref-manager.hpp"
namespace ndn {
class RegexBackrefManager;
class RegexMatcher
{
public:
@@ -56,7 +53,7 @@ public:
RegexMatcher(const std::string& expr,
const RegexExprType& type,
shared_ptr<RegexBackrefManager> backrefManager = shared_ptr<RegexBackrefManager>());
shared_ptr<RegexBackrefManager> backrefManager = nullptr);
virtual
~RegexMatcher();
@@ -110,71 +107,4 @@ operator<<(std::ostream& os, const RegexMatcher& regex)
} // namespace ndn
#include "regex-backref-manager.hpp"
namespace ndn {
inline
RegexMatcher::RegexMatcher(const std::string& expr,
const RegexExprType& type,
shared_ptr<RegexBackrefManager> backrefManager)
: m_expr(expr)
, m_type(type)
, m_backrefManager(backrefManager)
{
if (!static_cast<bool>(m_backrefManager))
m_backrefManager = make_shared<RegexBackrefManager>();
}
inline
RegexMatcher::~RegexMatcher()
{
}
inline bool
RegexMatcher::match(const Name& name, size_t offset, size_t len)
{
bool result = false;
m_matchResult.clear();
if (recursiveMatch(0, name, offset, len))
{
for (size_t i = offset; i < offset + len ; i++)
m_matchResult.push_back(name.get(i));
result = true;
}
else
{
result = false;
}
return result;
}
inline bool
RegexMatcher::recursiveMatch(size_t matcherNo, const Name& name, size_t offset, size_t len)
{
ssize_t tried = len;
if (matcherNo >= m_matchers.size())
return (len == 0);
shared_ptr<RegexMatcher> matcher = m_matchers[matcherNo];
while (tried >= 0)
{
if (matcher->match(name, offset, tried) &&
recursiveMatch(matcherNo + 1, name, offset + tried, len - tried))
return true;
tried--;
}
return false;
}
} // namespace ndn
#endif // NDN_UTIL_REGEX_REGEX_MATCHER_H
@@ -0,0 +1,159 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "regex-pattern-list-matcher.hpp"
#include "regex-repeat-matcher.hpp"
#include "regex-backref-matcher.hpp"
namespace ndn {
RegexPatternListMatcher::RegexPatternListMatcher(const std::string& expr,
shared_ptr<RegexBackrefManager> backrefManager)
: RegexMatcher(expr, EXPR_PATTERN_LIST, backrefManager)
{
compile();
}
RegexPatternListMatcher::~RegexPatternListMatcher()
{
}
void
RegexPatternListMatcher::compile()
{
size_t len = m_expr.size();
size_t index = 0;
size_t subHead = index;
while (index < len) {
subHead = index;
if (!extractPattern(subHead, &index))
throw Error("Compile error");
}
}
bool
RegexPatternListMatcher::extractPattern(size_t index, size_t* next)
{
size_t start = index;
size_t end = index;
size_t indicator = index;
switch (m_expr[index]) {
case '(':
index++;
index = extractSubPattern('(', ')', index);
indicator = index;
end = extractRepetition(index);
if (indicator == end) {
auto matcher = make_shared<RegexBackrefMatcher>(m_expr.substr(start, end - start),
m_backrefManager);
m_backrefManager->pushRef(matcher);
dynamic_pointer_cast<RegexBackrefMatcher>(matcher)->lateCompile();
m_matchers.push_back(matcher);
}
else
m_matchers.push_back(make_shared<RegexRepeatMatcher>(m_expr.substr(start, end - start),
m_backrefManager, indicator - start));
break;
case '<':
index++;
index = extractSubPattern('<', '>', index);
indicator = index;
end = extractRepetition(index);
m_matchers.push_back(make_shared<RegexRepeatMatcher>(m_expr.substr(start, end - start),
m_backrefManager, indicator - start));
break;
case '[':
index++;
index = extractSubPattern('[', ']', index);
indicator = index;
end = extractRepetition(index);
m_matchers.push_back(make_shared<RegexRepeatMatcher>(m_expr.substr(start, end - start),
m_backrefManager, indicator - start));
break;
default:
throw Error("Unexpected syntax");
}
*next = end;
return true;
}
int
RegexPatternListMatcher::extractSubPattern(const char left, const char right, size_t index)
{
size_t lcount = 1;
size_t rcount = 0;
while (lcount > rcount) {
if (index >= m_expr.size())
throw Error("Parenthesis mismatch");
if (left == m_expr[index])
lcount++;
if (right == m_expr[index])
rcount++;
index++;
}
return index;
}
int
RegexPatternListMatcher::extractRepetition(size_t index)
{
size_t exprSize = m_expr.size();
if (index == exprSize)
return index;
if (('+' == m_expr[index] || '?' == m_expr[index] || '*' == m_expr[index])) {
return ++index;
}
if ('{' == m_expr[index]) {
while ('}' != m_expr[index]) {
index++;
if (index == exprSize)
break;
}
if (index == exprSize)
throw Error("Missing right brace bracket");
else
return ++index;
}
else {
return index;
}
}
} // namespace ndn
+3 -141
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -17,8 +17,6 @@
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*
* @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
*/
#ifndef NDN_UTIL_REGEX_REGEX_PATTERN_LIST_MATCHER_HPP
@@ -38,13 +36,11 @@ public:
RegexPatternListMatcher(const std::string& expr, shared_ptr<RegexBackrefManager> backrefManager);
virtual
~RegexPatternListMatcher()
{
};
~RegexPatternListMatcher() NDN_CXX_DECL_FINAL;
protected:
virtual void
compile();
compile() NDN_CXX_DECL_FINAL;
private:
bool
@@ -60,140 +56,6 @@ private:
};
} // namespace ndn
#include "regex-repeat-matcher.hpp"
#include "regex-backref-matcher.hpp"
namespace ndn {
inline
RegexPatternListMatcher::RegexPatternListMatcher(const std::string& expr,
shared_ptr<RegexBackrefManager> backrefManager)
: RegexMatcher(expr, EXPR_PATTERN_LIST, backrefManager)
{
compile();
}
inline void
RegexPatternListMatcher::compile()
{
size_t len = m_expr.size();
size_t index = 0;
size_t subHead = index;
while (index < len) {
subHead = index;
if (!extractPattern(subHead, &index))
throw RegexMatcher::Error("Compile error");
}
}
inline bool
RegexPatternListMatcher::extractPattern(size_t index, size_t* next)
{
size_t start = index;
size_t end = index;
size_t indicator = index;
switch (m_expr[index]) {
case '(':
index++;
index = extractSubPattern('(', ')', index);
indicator = index;
end = extractRepetition(index);
if (indicator == end) {
shared_ptr<RegexMatcher> matcher =
make_shared<RegexBackrefMatcher>(m_expr.substr(start, end - start), m_backrefManager);
m_backrefManager->pushRef(matcher);
dynamic_pointer_cast<RegexBackrefMatcher>(matcher)->lateCompile();
m_matchers.push_back(matcher);
}
else
m_matchers.push_back(make_shared<RegexRepeatMatcher>(m_expr.substr(start, end - start),
m_backrefManager, indicator - start));
break;
case '<':
index++;
index = extractSubPattern('<', '>', index);
indicator = index;
end = extractRepetition(index);
m_matchers.push_back(make_shared<RegexRepeatMatcher>(m_expr.substr(start, end - start),
m_backrefManager, indicator - start));
break;
case '[':
index++;
index = extractSubPattern('[', ']', index);
indicator = index;
end = extractRepetition(index);
m_matchers.push_back(make_shared<RegexRepeatMatcher>(m_expr.substr(start, end - start),
m_backrefManager, indicator - start));
break;
default:
throw RegexMatcher::Error("Unexpected syntax");
}
*next = end;
return true;
}
inline int
RegexPatternListMatcher::extractSubPattern(const char left, const char right, size_t index)
{
size_t lcount = 1;
size_t rcount = 0;
while (lcount > rcount) {
if (index >= m_expr.size())
throw RegexMatcher::Error("Parenthesis mismatch");
if (left == m_expr[index])
lcount++;
if (right == m_expr[index])
rcount++;
index++;
}
return index;
}
inline int
RegexPatternListMatcher::extractRepetition(size_t index)
{
size_t exprSize = m_expr.size();
if (index == exprSize)
return index;
if (('+' == m_expr[index] || '?' == m_expr[index] || '*' == m_expr[index])) {
return ++index;
}
if ('{' == m_expr[index]) {
while ('}' != m_expr[index]) {
index++;
if (index == exprSize)
break;
}
if (index == exprSize)
throw RegexMatcher::Error("Missing right brace bracket");
else
return ++index;
}
else {
return index;
}
}
} // namespace ndn
#endif // NDN_UTIL_REGEX_REGEX_PATTERN_LIST_MATCHER_HPP
+53
View File
@@ -0,0 +1,53 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "regex-pseudo-matcher.hpp"
namespace ndn {
RegexPseudoMatcher::RegexPseudoMatcher()
: RegexMatcher("", EXPR_PSEUDO)
{
}
RegexPseudoMatcher::~RegexPseudoMatcher()
{
}
void
RegexPseudoMatcher::compile()
{
}
void
RegexPseudoMatcher::setMatchResult(const std::string& str)
{
m_matchResult.push_back(name::Component(reinterpret_cast<const uint8_t*>(str.c_str()),
str.size()));
}
void
RegexPseudoMatcher::resetMatchResult()
{
m_matchResult.clear();
}
} // namespace ndn
+3 -29
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -17,8 +17,6 @@
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*
* @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
*/
#ifndef NDN_UTIL_REGEX_REGEX_PSEUDO_MATCHER_HPP
@@ -35,14 +33,10 @@ public:
RegexPseudoMatcher();
virtual
~RegexPseudoMatcher()
{
}
~RegexPseudoMatcher() NDN_CXX_DECL_FINAL;
virtual void
compile()
{
}
compile() NDN_CXX_DECL_FINAL;
void
setMatchResult(const std::string& str);
@@ -51,26 +45,6 @@ public:
resetMatchResult();
};
inline
RegexPseudoMatcher::RegexPseudoMatcher()
: RegexMatcher("", EXPR_PSEUDO)
{
}
inline void
RegexPseudoMatcher::setMatchResult(const std::string& str)
{
m_matchResult.push_back(name::Component(reinterpret_cast<const uint8_t*>(str.c_str()),
str.size()));
}
inline void
RegexPseudoMatcher::resetMatchResult()
{
m_matchResult.clear();
}
} // namespace ndn
#endif // NDN_UTIL_REGEX_REGEX_PSEUDO_MATCHER_HPP
+178
View File
@@ -0,0 +1,178 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "regex-repeat-matcher.hpp"
#include "regex-backref-matcher.hpp"
#include "regex-component-set-matcher.hpp"
namespace ndn {
RegexRepeatMatcher::RegexRepeatMatcher(const std::string& expr,
shared_ptr<RegexBackrefManager> backrefManager,
size_t indicator)
: RegexMatcher(expr, EXPR_REPEAT_PATTERN, backrefManager)
, m_indicator(indicator)
{
compile();
}
RegexRepeatMatcher::~RegexRepeatMatcher()
{
}
bool
RegexRepeatMatcher::match(const Name& name, size_t offset, size_t len)
{
m_matchResult.clear();
if (0 == m_repeatMin)
if (0 == len)
return true;
if (recursiveMatch(0, name, offset, len)) {
for (size_t i = offset; i < offset + len; i++)
m_matchResult.push_back(name.get(i));
return true;
}
else
return false;
}
void
RegexRepeatMatcher::compile()
{
shared_ptr<RegexMatcher> matcher;
if ('(' == m_expr[0]) {
matcher = make_shared<RegexBackrefMatcher>(m_expr.substr(0, m_indicator), m_backrefManager);
m_backrefManager->pushRef(matcher);
dynamic_pointer_cast<RegexBackrefMatcher>(matcher)->lateCompile();
}
else{
matcher = make_shared<RegexComponentSetMatcher>(m_expr.substr(0, m_indicator),
m_backrefManager);
}
m_matchers.push_back(matcher);
parseRepetition();
}
bool
RegexRepeatMatcher::parseRepetition()
{
size_t exprSize = m_expr.size();
const size_t MAX_REPETITIONS = std::numeric_limits<size_t>::max();
if (exprSize == m_indicator) {
m_repeatMin = 1;
m_repeatMax = 1;
return true;
}
else {
if (exprSize == (m_indicator + 1)) {
if ('?' == m_expr[m_indicator]) {
m_repeatMin = 0;
m_repeatMax = 1;
return true;
}
if ('+' == m_expr[m_indicator]) {
m_repeatMin = 1;
m_repeatMax = MAX_REPETITIONS;
return true;
}
if ('*' == m_expr[m_indicator]) {
m_repeatMin = 0;
m_repeatMax = MAX_REPETITIONS;
return true;
}
}
else {
std::string repeatStruct = m_expr.substr(m_indicator, exprSize - m_indicator);
size_t rsSize = repeatStruct.size();
size_t min = 0;
size_t max = 0;
if (boost::regex_match(repeatStruct, boost::regex("\\{[0-9]+,[0-9]+\\}"))) {
size_t separator = repeatStruct.find_first_of(',', 0);
min = atoi(repeatStruct.substr(1, separator - 1).c_str());
max = atoi(repeatStruct.substr(separator + 1, rsSize - separator - 2).c_str());
}
else if (boost::regex_match(repeatStruct, boost::regex("\\{,[0-9]+\\}"))) {
size_t separator = repeatStruct.find_first_of(',', 0);
min = 0;
max = atoi(repeatStruct.substr(separator + 1, rsSize - separator - 2).c_str());
}
else if (boost::regex_match(repeatStruct, boost::regex("\\{[0-9]+,\\}"))) {
size_t separator = repeatStruct.find_first_of(',', 0);
min = atoi(repeatStruct.substr(1, separator).c_str());
max = MAX_REPETITIONS;
}
else if (boost::regex_match(repeatStruct, boost::regex("\\{[0-9]+\\}"))) {
min = atoi(repeatStruct.substr(1, rsSize - 1).c_str());
max = min;
}
else
throw Error("Error: RegexRepeatMatcher.ParseRepetition(): Unrecognized format " + m_expr);
if (min > MAX_REPETITIONS || max > MAX_REPETITIONS || min > max)
throw Error("Error: RegexRepeatMatcher.ParseRepetition(): Wrong number " + m_expr);
m_repeatMin = min;
m_repeatMax = max;
return true;
}
}
return false;
}
bool
RegexRepeatMatcher::recursiveMatch(size_t repeat, const Name& name, size_t offset, size_t len)
{
ssize_t tried = len;
shared_ptr<RegexMatcher> matcher = m_matchers[0];
if (0 < len && repeat >= m_repeatMax) {
return false;
}
if (0 == len && repeat < m_repeatMin) {
return false;
}
if (0 == len && repeat >= m_repeatMin) {
return true;
}
while (tried >= 0) {
if (matcher->match(name, offset, tried) &&
recursiveMatch(repeat + 1, name, offset + tried, len - tried))
return true;
tried--;
}
return false;
}
} // namespace ndn
+4 -168
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -17,8 +17,6 @@
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*
* @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
*/
#ifndef NDN_UTIL_REGEX_REGEX_REPEAT_MATCHER_HPP
@@ -40,12 +38,10 @@ public:
size_t indicator);
virtual
~RegexRepeatMatcher()
{
}
~RegexRepeatMatcher() NDN_CXX_DECL_FINAL;
virtual bool
match(const Name& name, size_t offset, size_t len);
match(const Name& name, size_t offset, size_t len) NDN_CXX_DECL_FINAL;
protected:
/**
@@ -53,7 +49,7 @@ protected:
* @returns true if compiling succeeds
*/
virtual void
compile();
compile() NDN_CXX_DECL_FINAL;
private:
bool
@@ -70,166 +66,6 @@ private:
size_t m_repeatMax;
};
} // namespace ndn
#include "regex-backref-matcher.hpp"
#include "regex-component-set-matcher.hpp"
namespace ndn {
inline
RegexRepeatMatcher::RegexRepeatMatcher(const std::string& expr,
shared_ptr<RegexBackrefManager> backrefManager,
size_t indicator)
: RegexMatcher(expr, EXPR_REPEAT_PATTERN, backrefManager)
, m_indicator(indicator)
{
compile();
}
inline void
RegexRepeatMatcher::compile()
{
shared_ptr<RegexMatcher> matcher;
if ('(' == m_expr[0]) {
matcher = make_shared<RegexBackrefMatcher>(m_expr.substr(0, m_indicator), m_backrefManager);
m_backrefManager->pushRef(matcher);
dynamic_pointer_cast<RegexBackrefMatcher>(matcher)->lateCompile();
}
else{
matcher = make_shared<RegexComponentSetMatcher>(m_expr.substr(0, m_indicator),
m_backrefManager);
}
m_matchers.push_back(matcher);
parseRepetition();
}
inline bool
RegexRepeatMatcher::parseRepetition()
{
size_t exprSize = m_expr.size();
const size_t MAX_REPETITIONS = std::numeric_limits<size_t>::max();
if (exprSize == m_indicator) {
m_repeatMin = 1;
m_repeatMax = 1;
return true;
}
else {
if (exprSize == (m_indicator + 1)) {
if ('?' == m_expr[m_indicator]) {
m_repeatMin = 0;
m_repeatMax = 1;
return true;
}
if ('+' == m_expr[m_indicator]) {
m_repeatMin = 1;
m_repeatMax = MAX_REPETITIONS;
return true;
}
if ('*' == m_expr[m_indicator]) {
m_repeatMin = 0;
m_repeatMax = MAX_REPETITIONS;
return true;
}
}
else {
std::string repeatStruct = m_expr.substr(m_indicator, exprSize - m_indicator);
size_t rsSize = repeatStruct.size();
size_t min = 0;
size_t max = 0;
if (boost::regex_match(repeatStruct, boost::regex("\\{[0-9]+,[0-9]+\\}"))) {
size_t separator = repeatStruct.find_first_of(',', 0);
min = atoi(repeatStruct.substr(1, separator - 1).c_str());
max = atoi(repeatStruct.substr(separator + 1, rsSize - separator - 2).c_str());
}
else if (boost::regex_match(repeatStruct, boost::regex("\\{,[0-9]+\\}"))) {
size_t separator = repeatStruct.find_first_of(',', 0);
min = 0;
max = atoi(repeatStruct.substr(separator + 1, rsSize - separator - 2).c_str());
}
else if (boost::regex_match(repeatStruct, boost::regex("\\{[0-9]+,\\}"))) {
size_t separator = repeatStruct.find_first_of(',', 0);
min = atoi(repeatStruct.substr(1, separator).c_str());
max = MAX_REPETITIONS;
}
else if (boost::regex_match(repeatStruct, boost::regex("\\{[0-9]+\\}"))) {
min = atoi(repeatStruct.substr(1, rsSize - 1).c_str());
max = min;
}
else
throw RegexMatcher::Error(std::string("Error: RegexRepeatMatcher.ParseRepetition(): ")
+ "Unrecognized format "+ m_expr);
if (min > MAX_REPETITIONS || max > MAX_REPETITIONS || min > max)
throw RegexMatcher::Error(std::string("Error: RegexRepeatMatcher.ParseRepetition(): ")
+ "Wrong number " + m_expr);
m_repeatMin = min;
m_repeatMax = max;
return true;
}
}
return false;
}
inline bool
RegexRepeatMatcher::match(const Name& name, size_t offset, size_t len)
{
m_matchResult.clear();
if (0 == m_repeatMin)
if (0 == len)
return true;
if (recursiveMatch(0, name, offset, len))
{
for (size_t i = offset; i < offset + len; i++)
m_matchResult.push_back(name.get(i));
return true;
}
else
return false;
}
inline bool
RegexRepeatMatcher::recursiveMatch(size_t repeat, const Name& name, size_t offset, size_t len)
{
ssize_t tried = len;
shared_ptr<RegexMatcher> matcher = m_matchers[0];
if (0 < len && repeat >= m_repeatMax)
{
return false;
}
if (0 == len && repeat < m_repeatMin)
{
return false;
}
if (0 == len && repeat >= m_repeatMin)
{
return true;
}
while (tried >= 0)
{
if (matcher->match(name, offset, tried) &&
recursiveMatch(repeat + 1, name, offset + tried, len - tried))
return true;
tried--;
}
return false;
}
} // namespace ndn
#endif // NDN_UTIL_REGEX_REGEX_REPEAT_MATCHER_HPP
+96 -112
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -17,8 +17,6 @@
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*
* @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
*/
#include "regex-top-matcher.hpp"
@@ -47,8 +45,6 @@ RegexTopMatcher::~RegexTopMatcher()
void
RegexTopMatcher::compile()
{
std::string errMsg = "Error: RegexTopMatcher.Compile(): ";
std::string expr = m_expr;
if ('$' != expr[expr.size() - 1])
@@ -78,21 +74,18 @@ RegexTopMatcher::match(const Name& name)
m_matchResult.clear();
if (m_primaryMatcher->match(name, 0, name.size()))
{
m_matchResult = m_primaryMatcher->getMatchResult();
if (m_primaryMatcher->match(name, 0, name.size())) {
m_matchResult = m_primaryMatcher->getMatchResult();
return true;
}
else {
if (static_cast<bool>(m_secondaryMatcher) && m_secondaryMatcher->match(name, 0, name.size())) {
m_matchResult = m_secondaryMatcher->getMatchResult();
m_isSecondaryUsed = true;
return true;
}
else
{
if (static_cast<bool>(m_secondaryMatcher) && m_secondaryMatcher->match(name, 0, name.size()))
{
m_matchResult = m_secondaryMatcher->getMatchResult();
m_isSecondaryUsed = true;
return true;
}
return false;
}
return false;
}
}
bool
@@ -106,7 +99,7 @@ RegexTopMatcher::expand(const std::string& expandStr)
{
Name result;
shared_ptr<RegexBackrefManager> backrefManager =
auto backrefManager =
(m_isSecondaryUsed ? m_secondaryBackrefManager : m_primaryBackrefManager);
size_t backrefNo = backrefManager->size();
@@ -119,36 +112,32 @@ RegexTopMatcher::expand(const std::string& expandStr)
expand = m_expand;
size_t offset = 0;
while (offset < expand.size())
{
std::string item = getItemFromExpand(expand, offset);
if (item[0] == '<')
{
result.append(item.substr(1, item.size() - 2));
}
if (item[0] == '\\')
{
size_t index = boost::lexical_cast<size_t>(item.substr(1, item.size() - 1));
if (0 == index) {
std::vector<name::Component>::iterator it = m_matchResult.begin();
std::vector<name::Component>::iterator end = m_matchResult.end();
for (; it != end; it++)
result.append(*it);
}
else if (index <= backrefNo)
{
std::vector<name::Component>::const_iterator it =
backrefManager->getBackref(index - 1)->getMatchResult().begin();
std::vector<name::Component>::const_iterator end =
backrefManager->getBackref(index - 1)->getMatchResult().end();
for (; it != end; it++)
result.append(*it);
}
else
throw RegexMatcher::Error("Exceed the range of back reference");
}
while (offset < expand.size()) {
std::string item = getItemFromExpand(expand, offset);
if (item[0] == '<') {
result.append(item.substr(1, item.size() - 2));
}
if (item[0] == '\\') {
size_t index = boost::lexical_cast<size_t>(item.substr(1, item.size() - 1));
if (0 == index) {
std::vector<name::Component>::iterator it = m_matchResult.begin();
std::vector<name::Component>::iterator end = m_matchResult.end();
for (; it != end; it++)
result.append(*it);
}
else if (index <= backrefNo) {
std::vector<name::Component>::const_iterator it =
backrefManager->getBackref(index - 1)->getMatchResult().begin();
std::vector<name::Component>::const_iterator end =
backrefManager->getBackref(index - 1)->getMatchResult().end();
for (; it != end; it++)
result.append(*it);
}
else
throw Error("Exceed the range of back reference");
}
}
return result;
}
@@ -157,44 +146,41 @@ RegexTopMatcher::getItemFromExpand(const std::string& expand, size_t& offset)
{
size_t begin = offset;
if (expand[offset] == '\\')
{
offset++;
if (offset >= expand.size())
throw RegexMatcher::Error("wrong format of expand string!");
if (expand[offset] == '\\') {
offset++;
if (offset >= expand.size())
throw Error("wrong format of expand string!");
while (expand[offset] <= '9' and expand[offset] >= '0') {
offset++;
if (offset > expand.size())
throw RegexMatcher::Error("wrong format of expand string!");
}
if (offset > begin + 1)
return expand.substr(begin, offset - begin);
else
throw RegexMatcher::Error("wrong format of expand string!");
while (expand[offset] <= '9' and expand[offset] >= '0') {
offset++;
if (offset > expand.size())
throw Error("wrong format of expand string!");
}
else if (expand[offset] == '<')
{
offset++;
if (offset >= expand.size())
throw RegexMatcher::Error("wrong format of expand string!");
size_t left = 1;
size_t right = 0;
while (right < left)
{
if (expand[offset] == '<')
left++;
if (expand[offset] == '>')
right++;
offset++;
if (offset >= expand.size())
throw RegexMatcher::Error("wrong format of expand string!");
}
if (offset > begin + 1)
return expand.substr(begin, offset - begin);
else
throw Error("wrong format of expand string!");
}
else if (expand[offset] == '<') {
offset++;
if (offset >= expand.size())
throw Error("wrong format of expand string!");
size_t left = 1;
size_t right = 0;
while (right < left) {
if (expand[offset] == '<')
left++;
if (expand[offset] == '>')
right++;
offset++;
if (offset >= expand.size())
throw Error("wrong format of expand string!");
}
return expand.substr(begin, offset - begin);
}
else
throw RegexMatcher::Error("wrong format of expand string!");
throw Error("wrong format of expand string!");
}
shared_ptr<RegexTopMatcher>
@@ -202,12 +188,11 @@ RegexTopMatcher::fromName(const Name& name, bool hasAnchor)
{
std::string regexStr("^");
for (Name::const_iterator it = name.begin(); it != name.end(); it++)
{
regexStr.append("<");
regexStr.append(convertSpecialChar(it->toUri()));
regexStr.append(">");
}
for (const auto& comp : name) {
regexStr.append("<");
regexStr.append(convertSpecialChar(comp.toUri()));
regexStr.append(">");
}
if (hasAnchor)
regexStr.append("$");
@@ -221,31 +206,30 @@ std::string
RegexTopMatcher::convertSpecialChar(const std::string& str)
{
std::string newStr;
for (size_t i = 0; i < str.size(); i++)
{
char c = str[i];
switch (c)
{
case '.':
case '[':
case '{':
case '}':
case '(':
case ')':
case '\\':
case '*':
case '+':
case '?':
case '|':
case '^':
case '$':
newStr.push_back('\\');
// Fallthrough
default:
newStr.push_back(c);
break;
}
}
for (size_t i = 0; i < str.size(); i++) {
char c = str[i];
switch (c)
{
case '.':
case '[':
case '{':
case '}':
case '(':
case ')':
case '\\':
case '*':
case '+':
case '?':
case '|':
case '^':
case '$':
newStr.push_back('\\');
// Fallthrough
default:
newStr.push_back(c);
break;
}
}
return newStr;
}
+4 -6
View File
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -17,8 +17,6 @@
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*
* @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
*/
#ifndef NDN_UTIL_REGEX_REGEX_TOP_MATCHER_HPP
@@ -39,13 +37,13 @@ public:
RegexTopMatcher(const std::string& expr, const std::string& expand = "");
virtual
~RegexTopMatcher();
~RegexTopMatcher() NDN_CXX_DECL_FINAL;
bool
match(const Name& name);
virtual bool
match(const Name& name, size_t offset, size_t len);
match(const Name& name, size_t offset, size_t len) NDN_CXX_DECL_FINAL;
virtual Name
expand(const std::string& expand = "");
@@ -55,7 +53,7 @@ public:
protected:
virtual void
compile();
compile() NDN_CXX_DECL_FINAL;
private:
std::string