blob: 0d343112702951b63a7dff19bccb04eb77e608d3 [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 Afanasyev36b84cf2014-02-17 19:34:18 -080021 struct Error : public std::runtime_error { Error(const std::string& what) : std::runtime_error(what) {} };
Yingdi Yu5e974202014-01-29 16:59:06 -080022
23 enum RegexExprType{
24 EXPR_TOP,
25
26 EXPR_PATTERNLIST,
27
28 EXPR_REPEAT_PATTERN,
29
30 EXPR_BACKREF,
31 EXPR_COMPONENT_SET,
32 EXPR_COMPONENT,
33
34 EXPR_PSEUDO
35 };
36
37 RegexMatcher(const std::string& expr,
38 const RegexExprType& type,
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080039 shared_ptr<RegexBackrefManager> backrefManager = shared_ptr<RegexBackrefManager>());
Yingdi Yu5e974202014-01-29 16:59:06 -080040
41 virtual
42 ~RegexMatcher();
43
44 virtual bool
45 match(const Name& name, const int& offset, const int& len);
46
47 /**
48 * @brief get the matched name components
49 * @returns the matched name components
50 */
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080051 const std::vector<name::Component>&
Yingdi Yu5e974202014-01-29 16:59:06 -080052 getMatchResult() const
53 { return m_matchResult; }
54
55 const std::string&
56 getExpr() const
57 { return m_expr; }
58
59protected:
60 /**
61 * @brief Compile the regular expression to generate the more matchers when necessary
62 * @returns true if compiling succeeds
63 */
64 virtual void
65 compile() = 0;
66
67private:
68 bool
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -070069 recursiveMatch(size_t mId, const Name& name, size_t offset, size_t len);
Yingdi Yu5e974202014-01-29 16:59:06 -080070
71
72protected:
73 const std::string m_expr;
74 const RegexExprType m_type;
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080075 shared_ptr<RegexBackrefManager> m_backrefManager;
76 std::vector<shared_ptr<RegexMatcher> > m_matcherList;
77 std::vector<name::Component> m_matchResult;
Yingdi Yu5e974202014-01-29 16:59:06 -080078};
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080079
80} // namespace ndn
81
82#include "regex-backref-manager.hpp"
83
84namespace ndn {
85
86inline
87RegexMatcher::RegexMatcher(const std::string& expr,
88 const RegexExprType& type,
89 shared_ptr<RegexBackrefManager> backrefManager)
90 : m_expr(expr),
91 m_type(type),
92 m_backrefManager(backrefManager)
93{
94 if(NULL == m_backrefManager)
95 m_backrefManager = make_shared<RegexBackrefManager>();
96}
97
98inline
99RegexMatcher::~RegexMatcher()
100{
101}
102
103inline bool
104RegexMatcher::match (const Name& name, const int& offset, const int& len)
105{
106 // _LOG_TRACE ("Enter RegexMatcher::match");
107 bool result = false;
108
109 m_matchResult.clear();
110
111 if(recursiveMatch(0, name, offset, len))
112 {
113 for(int i = offset; i < offset + len ; i++)
114 m_matchResult.push_back(name.get(i));
115 result = true;
116 }
117 else
118 {
119 result = false;
120 }
121
122 // _LOG_TRACE ("Exit RegexMatcher::match");
123 return result;
124}
125
126inline bool
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700127RegexMatcher::recursiveMatch(size_t mId, const Name& name, size_t offset, size_t len)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800128{
129 // _LOG_TRACE ("Enter RegexMatcher::recursiveMatch");
130
131 int tried = len;
132
133 if(mId >= m_matcherList.size())
134 return (len != 0 ? false : true);
135
136 shared_ptr<RegexMatcher> matcher = m_matcherList[mId];
137
138 while(tried >= 0)
139 {
140 if(matcher->match(name, offset, tried) && recursiveMatch(mId + 1, name, offset + tried, len - tried))
141 return true;
142 tried--;
143 }
144
145 return false;
146}
Yingdi Yu5e974202014-01-29 16:59:06 -0800147
148
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800149} // namespace ndn
150
151
152#endif // NDN_UTIL_REGEX_REGEX_MATCHER_H