blob: c126e95c9dba08e77dd0c40e030e7793fd332c3f [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_MATCHER_H
16#define NDN_UTIL_REGEX_REGEX_MATCHER_H
Yingdi Yu5e974202014-01-29 16:59:06 -080017
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080018#include "../../common.hpp"
Yingdi Yu5e974202014-01-29 16:59:06 -080019#include "../../name.hpp"
Yingdi Yu5e974202014-01-29 16:59:06 -080020
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080021namespace ndn {
22
23class RegexBackrefManager;
Yingdi Yu5e974202014-01-29 16:59:06 -080024
25class RegexMatcher
26{
27public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070028 class Error : public std::runtime_error
29 {
30 public:
31 explicit
32 Error(const std::string& what)
33 : std::runtime_error(what)
34 {
35 }
36 };
Yingdi Yu5e974202014-01-29 16:59:06 -080037
38 enum RegexExprType{
39 EXPR_TOP,
40
41 EXPR_PATTERNLIST,
42
43 EXPR_REPEAT_PATTERN,
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070044
Yingdi Yu5e974202014-01-29 16:59:06 -080045 EXPR_BACKREF,
46 EXPR_COMPONENT_SET,
47 EXPR_COMPONENT,
48
49 EXPR_PSEUDO
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070050 };
Yingdi Yu5e974202014-01-29 16:59:06 -080051
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070052 RegexMatcher(const std::string& expr,
53 const RegexExprType& type,
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080054 shared_ptr<RegexBackrefManager> backrefManager = shared_ptr<RegexBackrefManager>());
Yingdi Yu5e974202014-01-29 16:59:06 -080055
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070056 virtual
Yingdi Yu5e974202014-01-29 16:59:06 -080057 ~RegexMatcher();
58
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070059 virtual bool
Yingdi Yu5e974202014-01-29 16:59:06 -080060 match(const Name& name, const int& offset, const int& len);
61
62 /**
63 * @brief get the matched name components
64 * @returns the matched name components
65 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070066 const std::vector<name::Component>&
Yingdi Yu5e974202014-01-29 16:59:06 -080067 getMatchResult() const
68 { return m_matchResult; }
69
70 const std::string&
71 getExpr() const
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070072 { return m_expr; }
Yingdi Yu5e974202014-01-29 16:59:06 -080073
74protected:
75 /**
76 * @brief Compile the regular expression to generate the more matchers when necessary
77 * @returns true if compiling succeeds
78 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070079 virtual void
Yingdi Yu5e974202014-01-29 16:59:06 -080080 compile() = 0;
81
82private:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070083 bool
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070084 recursiveMatch(size_t mId, const Name& name, size_t offset, size_t len);
Yingdi Yu5e974202014-01-29 16:59:06 -080085
86
87protected:
88 const std::string m_expr;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070089 const RegexExprType m_type;
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080090 shared_ptr<RegexBackrefManager> m_backrefManager;
91 std::vector<shared_ptr<RegexMatcher> > m_matcherList;
92 std::vector<name::Component> m_matchResult;
Yingdi Yu5e974202014-01-29 16:59:06 -080093};
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080094
95} // namespace ndn
96
97#include "regex-backref-manager.hpp"
98
99namespace ndn {
100
101inline
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700102RegexMatcher::RegexMatcher(const std::string& expr,
103 const RegexExprType& type,
104 shared_ptr<RegexBackrefManager> backrefManager)
105 : m_expr(expr),
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800106 m_type(type),
107 m_backrefManager(backrefManager)
108{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700109 if (NULL == m_backrefManager)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800110 m_backrefManager = make_shared<RegexBackrefManager>();
111}
112
113inline
114RegexMatcher::~RegexMatcher()
115{
116}
117
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700118inline bool
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800119RegexMatcher::match (const Name& name, const int& offset, const int& len)
120{
121 // _LOG_TRACE ("Enter RegexMatcher::match");
122 bool result = false;
123
124 m_matchResult.clear();
125
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700126 if (recursiveMatch(0, name, offset, len))
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800127 {
128 for(int i = offset; i < offset + len ; i++)
129 m_matchResult.push_back(name.get(i));
130 result = true;
131 }
132 else
133 {
134 result = false;
135 }
136
137 // _LOG_TRACE ("Exit RegexMatcher::match");
138 return result;
139}
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700140
141inline bool
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700142RegexMatcher::recursiveMatch(size_t mId, const Name& name, size_t offset, size_t len)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800143{
144 // _LOG_TRACE ("Enter RegexMatcher::recursiveMatch");
145
146 int tried = len;
147
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700148 if (mId >= m_matcherList.size())
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800149 return (len != 0 ? false : true);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700150
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800151 shared_ptr<RegexMatcher> matcher = m_matcherList[mId];
152
153 while(tried >= 0)
154 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700155 if (matcher->match(name, offset, tried) && recursiveMatch(mId + 1, name, offset + tried, len - tried))
156 return true;
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800157 tried--;
158 }
159
160 return false;
161}
Yingdi Yu5e974202014-01-29 16:59:06 -0800162
163
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800164} // namespace ndn
165
166
167#endif // NDN_UTIL_REGEX_REGEX_MATCHER_H