blob: fcc0ccc82b0c5e5975a32070e27dfe9312c2c13d [file] [log] [blame]
Yingdi Yu5e974202014-01-29 16:59:06 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07003 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
5 *
6 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
7 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
8 *
9 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
11 *
12 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
Yingdi Yu5e974202014-01-29 16:59:06 -080013 */
14
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080015#ifndef NDN_UTIL_REGEX_REGEX_COMPONENT_MATCHER_HPP
16#define NDN_UTIL_REGEX_REGEX_COMPONENT_MATCHER_HPP
Yingdi Yu5e974202014-01-29 16:59:06 -080017
18#include <boost/regex.hpp>
19
20#include "regex-matcher.hpp"
21#include "regex-pseudo-matcher.hpp"
22
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080023namespace ndn {
24
Yingdi Yu5e974202014-01-29 16:59:06 -080025class RegexComponentMatcher : public RegexMatcher
26{
27public:
28 /**
29 * @brief Create a RegexComponent matcher from expr
30 * @param expr The standard regular expression to match a component
Alexander Afanasyevb6b21b32014-04-28 22:38:03 -070031 * @param backrefManager The back reference manager
32 * @param isExactMatch The flag to provide exact match
Yingdi Yu5e974202014-01-29 16:59:06 -080033 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070034 RegexComponentMatcher(const std::string& expr,
Alexander Afanasyevb6b21b32014-04-28 22:38:03 -070035 shared_ptr<RegexBackrefManager> backrefManager,
36 bool isExactMatch = true);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070037
Alexander Afanasyevb6b21b32014-04-28 22:38:03 -070038 virtual
39 ~RegexComponentMatcher()
40 {
41 };
Yingdi Yu5e974202014-01-29 16:59:06 -080042
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070043 virtual bool
Alexander Afanasyevb6b21b32014-04-28 22:38:03 -070044 match(const Name& name, size_t offset, size_t len = 1);
Yingdi Yu5e974202014-01-29 16:59:06 -080045
46protected:
47 /**
48 * @brief Compile the regular expression to generate the more matchers when necessary
49 * @returns true if compiling succeeds
50 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070051 virtual void
Yingdi Yu5e974202014-01-29 16:59:06 -080052 compile();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070053
Yingdi Yu5e974202014-01-29 16:59:06 -080054private:
Alexander Afanasyevb6b21b32014-04-28 22:38:03 -070055 bool m_isExactMatch;
Yingdi Yu5e974202014-01-29 16:59:06 -080056 boost::regex m_componentRegex;
Alexander Afanasyevb6b21b32014-04-28 22:38:03 -070057 std::vector<shared_ptr<RegexPseudoMatcher> > m_pseudoMatchers;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070058
Yingdi Yu5e974202014-01-29 16:59:06 -080059};
Yingdi Yu5e974202014-01-29 16:59:06 -080060
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080061
62inline
Alexander Afanasyevb6b21b32014-04-28 22:38:03 -070063RegexComponentMatcher::RegexComponentMatcher(const std::string& expr,
64 shared_ptr<RegexBackrefManager> backrefManager,
65 bool isExactMatch)
66 : RegexMatcher(expr, EXPR_COMPONENT, backrefManager)
67 , m_isExactMatch(isExactMatch)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080068{
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080069 compile();
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080070}
71
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070072inline void
Alexander Afanasyevb6b21b32014-04-28 22:38:03 -070073RegexComponentMatcher::compile()
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080074{
Alexander Afanasyevb6b21b32014-04-28 22:38:03 -070075 m_componentRegex = boost::regex(m_expr);
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080076
Alexander Afanasyevb6b21b32014-04-28 22:38:03 -070077 m_pseudoMatchers.clear();
78 m_pseudoMatchers.push_back(make_shared<RegexPseudoMatcher>());
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080079
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070080 for (size_t i = 1; i < m_componentRegex.mark_count(); i++)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080081 {
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070082 shared_ptr<RegexPseudoMatcher> pMatcher = make_shared<RegexPseudoMatcher>();
Alexander Afanasyevb6b21b32014-04-28 22:38:03 -070083 m_pseudoMatchers.push_back(pMatcher);
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070084 m_backrefManager->pushRef(static_pointer_cast<RegexMatcher>(pMatcher));
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080085 }
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080086}
87
88inline bool
Alexander Afanasyevb6b21b32014-04-28 22:38:03 -070089RegexComponentMatcher::match(const Name& name, size_t offset, size_t len)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080090{
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080091 m_matchResult.clear();
92
Alexander Afanasyevb6b21b32014-04-28 22:38:03 -070093 if (m_expr.empty())
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080094 {
95 m_matchResult.push_back(name.get(offset));
96 return true;
97 }
98
Alexander Afanasyevb6b21b32014-04-28 22:38:03 -070099 if (m_isExactMatch)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800100 {
101 boost::smatch subResult;
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700102 std::string targetStr = name.get(offset).toUri();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700103 if (boost::regex_match(targetStr, subResult, m_componentRegex))
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800104 {
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700105 for (size_t i = 1; i < m_componentRegex.mark_count(); i++)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800106 {
Alexander Afanasyevb6b21b32014-04-28 22:38:03 -0700107 m_pseudoMatchers[i]->resetMatchResult();
108 m_pseudoMatchers[i]->setMatchResult(subResult[i]);
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800109 }
110 m_matchResult.push_back(name.get(offset));
111 return true;
112 }
113 }
114 else
115 {
116 throw RegexMatcher::Error("Non-exact component search is not supported yet!");
117 }
118
119 return false;
120}
121
122
123} // namespace ndn
124
125#endif // NDN_UTIL_REGEX_REGEX_COMPONENT_MATCHER_HPP