blob: 747662c7b88d1ec42ea70f65e4f426b6bd9ef9cc [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
23
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080024namespace ndn {
25
Yingdi Yu5e974202014-01-29 16:59:06 -080026class RegexComponentMatcher : public RegexMatcher
27{
28public:
29 /**
30 * @brief Create a RegexComponent matcher from expr
31 * @param expr The standard regular expression to match a component
32 * @param backRefManager The back reference manager
33 * @param exact The flag to provide exact match
34 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070035 RegexComponentMatcher(const std::string& expr,
36 ptr_lib::shared_ptr<RegexBackrefManager> backRefManager,
Yingdi Yu5e974202014-01-29 16:59:06 -080037 bool exact = true);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070038
Yingdi Yu5e974202014-01-29 16:59:06 -080039 virtual ~RegexComponentMatcher() {};
40
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070041 virtual bool
Yingdi Yu5e974202014-01-29 16:59:06 -080042 match(const Name & name, const int & offset, const int &len = 1);
43
44protected:
45 /**
46 * @brief Compile the regular expression to generate the more matchers when necessary
47 * @returns true if compiling succeeds
48 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070049 virtual void
Yingdi Yu5e974202014-01-29 16:59:06 -080050 compile();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070051
Yingdi Yu5e974202014-01-29 16:59:06 -080052private:
53 bool m_exact;
54 boost::regex m_componentRegex;
55 std::vector<ptr_lib::shared_ptr<RegexPseudoMatcher> > m_pseudoMatcher;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070056
Yingdi Yu5e974202014-01-29 16:59:06 -080057};
Yingdi Yu5e974202014-01-29 16:59:06 -080058
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080059
60inline
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070061RegexComponentMatcher::RegexComponentMatcher (const std::string& expr,
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070062 shared_ptr<RegexBackrefManager> backRefManager,
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080063 bool exact)
64 : RegexMatcher (expr, EXPR_COMPONENT, backRefManager),
65 m_exact(exact)
66{
67 // _LOG_TRACE ("Enter RegexComponentMatcher Constructor: ");
68 compile();
69 // _LOG_TRACE ("Exit RegexComponentMatcher Constructor: ");
70}
71
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070072inline void
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080073RegexComponentMatcher::compile ()
74{
75 // _LOG_TRACE ("Enter RegexComponentMatcher::compile");
76
77 m_componentRegex = boost::regex (m_expr);
78
79 m_pseudoMatcher.clear();
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070080 m_pseudoMatcher.push_back(make_shared<RegexPseudoMatcher>());
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080081
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070082 for (size_t i = 1; i < m_componentRegex.mark_count(); i++)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080083 {
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070084 shared_ptr<RegexPseudoMatcher> pMatcher = make_shared<RegexPseudoMatcher>();
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080085 m_pseudoMatcher.push_back(pMatcher);
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070086 m_backrefManager->pushRef(static_pointer_cast<RegexMatcher>(pMatcher));
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080087 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070088
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080089
90 // _LOG_TRACE ("Exit RegexComponentMatcher::compile");
91}
92
93inline bool
94RegexComponentMatcher::match (const Name & name, const int & offset, const int & len)
95{
96 // _LOG_TRACE ("Enter RegexComponentMatcher::match ");
97
98 m_matchResult.clear();
99
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700100 if ("" == m_expr)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800101 {
102 m_matchResult.push_back(name.get(offset));
103 return true;
104 }
105
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700106 if (true == m_exact)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800107 {
108 boost::smatch subResult;
109 std::string targetStr = name.get(offset).toEscapedString();
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700110 if (boost::regex_match(targetStr, subResult, m_componentRegex))
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800111 {
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700112 for (size_t i = 1; i < m_componentRegex.mark_count(); i++)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800113 {
114 m_pseudoMatcher[i]->resetMatchResult();
115 m_pseudoMatcher[i]->setMatchResult(subResult[i]);
116 }
117 m_matchResult.push_back(name.get(offset));
118 return true;
119 }
120 }
121 else
122 {
123 throw RegexMatcher::Error("Non-exact component search is not supported yet!");
124 }
125
126 return false;
127}
128
129
130} // namespace ndn
131
132#endif // NDN_UTIL_REGEX_REGEX_COMPONENT_MATCHER_HPP