blob: 40393889c58c21a8052a002a5b0f19ad85569faa [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_COMPONENT_SET_MATCHER_HPP
9#define NDN_UTIL_REGEX_COMPONENT_SET_MATCHER_HPP
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
13#include "regex-matcher.hpp"
14#include "regex-component-matcher.hpp"
15
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080016namespace ndn {
Yingdi Yu5e974202014-01-29 16:59:06 -080017
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080018class RegexComponentSetMatcher : public RegexMatcher {
Yingdi Yu5e974202014-01-29 16:59:06 -080019
20public:
21 /**
22 * @brief Create a RegexComponentSetMatcher matcher from expr
23 * @param expr The standard regular expression to match a component
24 * @param exact The flag to provide exact match
25 * @param backRefNum The starting back reference number
26 */
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080027 RegexComponentSetMatcher(const std::string& expr, shared_ptr<RegexBackrefManager> backRefManager);
Yingdi Yu5e974202014-01-29 16:59:06 -080028
29 virtual ~RegexComponentSetMatcher();
30
31 virtual bool
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080032 match(const Name& name, const int& offset, const int& len = 1);
Yingdi Yu5e974202014-01-29 16:59:06 -080033
34protected:
35 /**
36 * @brief Compile the regular expression to generate the more matchers when necessary
37 * @returns true if compiling succeeds
38 */
39 virtual void
40 compile();
41
42private:
43 int
44 extractComponent(int index);
45
46 void
47 compileSingleComponent();
48
49 void
50 compileMultipleComponents(const int start, const int lastIndex);
51
52private:
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080053 typedef std::set<shared_ptr<RegexComponentMatcher> > ComponentsSet;
54 ComponentsSet m_components;
Yingdi Yu5e974202014-01-29 16:59:06 -080055 bool m_include;
56};
57
Yingdi Yu5e974202014-01-29 16:59:06 -080058
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080059inline
60RegexComponentSetMatcher::RegexComponentSetMatcher(const std::string& expr, shared_ptr<RegexBackrefManager> backRefManager)
61 : RegexMatcher(expr, EXPR_COMPONENT_SET, backRefManager),
62 m_include(true)
63{
64 // _LOG_TRACE ("Enter RegexComponentSetMatcher Constructor");
65 compile();
66 // _LOG_TRACE ("Exit RegexComponentSetMatcher Constructor");
67}
68
69inline
70RegexComponentSetMatcher::~RegexComponentSetMatcher()
71{
72 // ComponentsSet::iterator it = m_components.begin();
73
74 // for(; it != m_components.end(); it++)
75 // delete *it;
76}
77
78inline void
79RegexComponentSetMatcher::compile()
80{
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -080081 switch(m_expr[0]){
82 case '<':
83 return compileSingleComponent();
84 case '[':
85 {
86 int lastIndex = m_expr.size() - 1;
87 if(']' != m_expr[lastIndex])
88 throw RegexMatcher::Error(std::string("Error: RegexComponentSetMatcher.compile(): ")
89 + " No matched ']' " + m_expr);
90
91 if('^' == m_expr[1]){
92 m_include = false;
93 compileMultipleComponents(2, lastIndex);
94 }
95 else
96 compileMultipleComponents(1, lastIndex);
97 break;
98 }
99 default:
100 throw RegexMatcher::Error(std::string("Error: RegexComponentSetMatcher.compile(): ")
101 + "Parsing error in expr " + m_expr);
102 }
103}
104
105inline void
106RegexComponentSetMatcher::compileSingleComponent()
107{
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700108 size_t end = extractComponent(1);
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800109
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700110 if (m_expr.size() != end)
Alexander Afanasyev36b84cf2014-02-17 19:34:18 -0800111 {
112 throw RegexMatcher::Error(std::string("Error: RegexComponentSetMatcher.compileSingleComponent: ")
113 + m_expr);
114 }
115 else
116 {
117 shared_ptr<RegexComponentMatcher> component =
118 make_shared<RegexComponentMatcher>(m_expr.substr(1, end - 2), m_backrefManager);
119
120 m_components.insert(component);
121 }
122}
123
124inline void
125RegexComponentSetMatcher::compileMultipleComponents(const int start, const int lastIndex)
126{
127 int index = start;
128 int tmp_index = start;
129
130 while(index < lastIndex){
131 if('<' != m_expr[index])
132 throw RegexMatcher::Error(std::string("Error: RegexComponentSetMatcher.compileMultipleComponents: ")
133 + "Component expr error " + m_expr);
134
135 tmp_index = index + 1;
136 index = extractComponent(tmp_index);
137
138 shared_ptr<RegexComponentMatcher> component =
139 make_shared<RegexComponentMatcher>(m_expr.substr(tmp_index, index - tmp_index - 1), m_backrefManager);
140
141 m_components.insert(component);
142 }
143
144 if(index != lastIndex)
145 throw RegexMatcher::Error(std::string("Error: RegexComponentSetMatcher.compileMultipleComponents: ")
146 + "Not sufficient expr to parse " + m_expr);
147}
148
149inline bool
150RegexComponentSetMatcher::match(const Name & name, const int & offset, const int & len)
151{
152 bool matched = false;
153
154 /* componentset only matches one component */
155 if (len != 1)
156 {
157 return false;
158 }
159
160 for (ComponentsSet::iterator it = m_components.begin();
161 it != m_components.end();
162 ++it)
163 {
164 if((*it)->match(name, offset, len))
165 {
166 matched = true;
167 break;
168 }
169 }
170
171 m_matchResult.clear();
172
173 if (m_include ? matched : !matched)
174 {
175 m_matchResult.push_back(name.get(offset));
176 return true;
177 }
178 else
179 return false;
180}
181
182inline int
183RegexComponentSetMatcher::extractComponent(int index)
184{
185 int lcount = 1;
186 int rcount = 0;
187
188 while(lcount > rcount){
189 switch(m_expr[index]){
190 case '<':
191 lcount++;
192 break;
193
194 case '>':
195 rcount++;
196 break;
197
198 case 0:
199 throw RegexMatcher::Error("Error: square brackets mismatch");
200 break;
201 }
202 index++;
203
204 }
205
206 return index;
207}
208
209} // namespace ndn
210
211#endif // NDN_UTIL_REGEX_COMPONENT_SET_MATCHER_HPP