blob: d62ab41fe1801b85cc40f7b6ad2302ca8fc3b9c9 [file] [log] [blame]
Yingdi Yu5e974202014-01-29 16:59:06 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
5 * See COPYING for copyright and distribution information.
6 */
7
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -08008#ifndef NDN_UTIL_REGEX_REGEX_MATCHER_H
9#define NDN_UTIL_REGEX_REGEX_MATCHER_H
Yingdi Yu5e974202014-01-29 16:59:06 -080010
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080011#include "../../common.hpp"
Yingdi Yu5e974202014-01-29 16:59:06 -080012#include "../../name.hpp"
Yingdi Yu5e974202014-01-29 16:59:06 -080013
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080014namespace ndn {
15
16class RegexBackrefManager;
Yingdi Yu5e974202014-01-29 16:59:06 -080017
18class RegexMatcher
19{
20public:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070021 class Error : public std::runtime_error
22 {
23 public:
24 explicit
25 Error(const std::string& what)
26 : std::runtime_error(what)
27 {
28 }
29 };
Yingdi Yu5e974202014-01-29 16:59:06 -080030
31 enum RegexExprType{
32 EXPR_TOP,
33
34 EXPR_PATTERNLIST,
35
36 EXPR_REPEAT_PATTERN,
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070037
Yingdi Yu5e974202014-01-29 16:59:06 -080038 EXPR_BACKREF,
39 EXPR_COMPONENT_SET,
40 EXPR_COMPONENT,
41
42 EXPR_PSEUDO
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070043 };
Yingdi Yu5e974202014-01-29 16:59:06 -080044
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070045 RegexMatcher(const std::string& expr,
46 const RegexExprType& type,
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080047 shared_ptr<RegexBackrefManager> backrefManager = shared_ptr<RegexBackrefManager>());
Yingdi Yu5e974202014-01-29 16:59:06 -080048
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070049 virtual
Yingdi Yu5e974202014-01-29 16:59:06 -080050 ~RegexMatcher();
51
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070052 virtual bool
Yingdi Yu5e974202014-01-29 16:59:06 -080053 match(const Name& name, const int& offset, const int& len);
54
55 /**
56 * @brief get the matched name components
57 * @returns the matched name components
58 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070059 const std::vector<name::Component>&
Yingdi Yu5e974202014-01-29 16:59:06 -080060 getMatchResult() const
61 { return m_matchResult; }
62
63 const std::string&
64 getExpr() const
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070065 { return m_expr; }
Yingdi Yu5e974202014-01-29 16:59:06 -080066
67protected:
68 /**
69 * @brief Compile the regular expression to generate the more matchers when necessary
70 * @returns true if compiling succeeds
71 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070072 virtual void
Yingdi Yu5e974202014-01-29 16:59:06 -080073 compile() = 0;
74
75private:
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070076 bool
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070077 recursiveMatch(size_t mId, const Name& name, size_t offset, size_t len);
Yingdi Yu5e974202014-01-29 16:59:06 -080078
79
80protected:
81 const std::string m_expr;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070082 const RegexExprType m_type;
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080083 shared_ptr<RegexBackrefManager> m_backrefManager;
84 std::vector<shared_ptr<RegexMatcher> > m_matcherList;
85 std::vector<name::Component> m_matchResult;
Yingdi Yu5e974202014-01-29 16:59:06 -080086};
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080087
88} // namespace ndn
89
90#include "regex-backref-manager.hpp"
91
92namespace ndn {
93
94inline
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070095RegexMatcher::RegexMatcher(const std::string& expr,
96 const RegexExprType& type,
97 shared_ptr<RegexBackrefManager> backrefManager)
98 : m_expr(expr),
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080099 m_type(type),
100 m_backrefManager(backrefManager)
101{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700102 if (NULL == m_backrefManager)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800103 m_backrefManager = make_shared<RegexBackrefManager>();
104}
105
106inline
107RegexMatcher::~RegexMatcher()
108{
109}
110
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700111inline bool
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800112RegexMatcher::match (const Name& name, const int& offset, const int& len)
113{
114 // _LOG_TRACE ("Enter RegexMatcher::match");
115 bool result = false;
116
117 m_matchResult.clear();
118
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700119 if (recursiveMatch(0, name, offset, len))
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800120 {
121 for(int i = offset; i < offset + len ; i++)
122 m_matchResult.push_back(name.get(i));
123 result = true;
124 }
125 else
126 {
127 result = false;
128 }
129
130 // _LOG_TRACE ("Exit RegexMatcher::match");
131 return result;
132}
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700133
134inline bool
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700135RegexMatcher::recursiveMatch(size_t mId, const Name& name, size_t offset, size_t len)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800136{
137 // _LOG_TRACE ("Enter RegexMatcher::recursiveMatch");
138
139 int tried = len;
140
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700141 if (mId >= m_matcherList.size())
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800142 return (len != 0 ? false : true);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700143
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800144 shared_ptr<RegexMatcher> matcher = m_matcherList[mId];
145
146 while(tried >= 0)
147 {
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700148 if (matcher->match(name, offset, tried) && recursiveMatch(mId + 1, name, offset + tried, len - tried))
149 return true;
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800150 tried--;
151 }
152
153 return false;
154}
Yingdi Yu5e974202014-01-29 16:59:06 -0800155
156
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800157} // namespace ndn
158
159
160#endif // NDN_UTIL_REGEX_REGEX_MATCHER_H