All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
regex-top-matcher.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
8 #include "regex-top-matcher.hpp"
9 
12 
13 namespace ndn {
14 
15 RegexTopMatcher::RegexTopMatcher(const std::string& expr, const std::string& expand)
16  : RegexMatcher(expr, EXPR_TOP),
17  m_expand(expand),
18  m_secondaryUsed(false)
19 {
20  m_primaryBackRefManager = make_shared<RegexBackrefManager>();
21  m_secondaryBackRefManager = make_shared<RegexBackrefManager>();
22  compile();
23 }
24 
26 {
27  // delete m_backRefManager;
28 }
29 
30 void
32 {
33  std::string errMsg = "Error: RegexTopMatcher.Compile(): ";
34 
35  std::string expr = m_expr;
36 
37  if ('$' != expr[expr.size() - 1])
38  expr = expr + "<.*>*";
39  else
40  expr = expr.substr(0, expr.size()-1);
41 
42  if ('^' != expr[0])
43  m_secondaryMatcher = make_shared<RegexPatternListMatcher>(boost::cref("<.*>*" + expr),
44  boost::cref(m_secondaryBackRefManager));
45  else
46  expr = expr.substr(1, expr.size()-1);
47 
48  m_primaryMatcher = make_shared<RegexPatternListMatcher>(boost::cref(expr),
49  boost::cref(m_primaryBackRefManager));
50 }
51 
52 bool
54 {
55  m_secondaryUsed = false;
56 
57  m_matchResult.clear();
58 
59  if (m_primaryMatcher->match(name, 0, name.size()))
60  {
61  m_matchResult = m_primaryMatcher->getMatchResult();
62  return true;
63  }
64  else
65  {
66  if (NULL != m_secondaryMatcher && m_secondaryMatcher->match(name, 0, name.size()))
67  {
68  m_matchResult = m_secondaryMatcher->getMatchResult();
69  m_secondaryUsed = true;
70  return true;
71  }
72  return false;
73  }
74 }
75 
76 bool
77 RegexTopMatcher::match (const Name& name, const int& offset, const int& len)
78 {
79  return match(name);
80 }
81 
82 Name
83 RegexTopMatcher::expand (const std::string& expandStr)
84 {
85  Name result;
86 
87  shared_ptr<RegexBackrefManager> backRefManager = (m_secondaryUsed ? m_secondaryBackRefManager : m_primaryBackRefManager);
88 
89  int backRefNum = backRefManager->size();
90 
91  std::string expand;
92 
93  if (expandStr != "")
94  expand = expandStr;
95  else
96  expand = m_expand;
97 
98  size_t offset = 0;
99  while (offset < expand.size())
100  {
101  std::string item = getItemFromExpand(expand, offset);
102  if (item[0] == '<')
103  {
104  result.append(item.substr(1, item.size() - 2));
105  }
106  if (item[0] == '\\')
107  {
108 
109  int index = atoi(item.substr(1, item.size() - 1).c_str());
110 
111  if (0 == index){
112  std::vector<name::Component>::iterator it = m_matchResult.begin();
113  std::vector<name::Component>::iterator end = m_matchResult.end();
114  for(; it != end; it++)
115  result.append (*it);
116  }
117  else if (index <= backRefNum)
118  {
119  std::vector<name::Component>::const_iterator it = backRefManager->getBackRef (index - 1)->getMatchResult ().begin();
120  std::vector<name::Component>::const_iterator end = backRefManager->getBackRef (index - 1)->getMatchResult ().end();
121  for(; it != end; it++)
122  result.append (*it);
123  }
124  else
125  throw RegexMatcher::Error("Exceed the range of back reference!");
126  }
127  }
128  return result;
129 }
130 
131 std::string
132 RegexTopMatcher::getItemFromExpand(const std::string& expand, size_t& offset)
133 {
134  size_t begin = offset;
135 
136  if (expand[offset] == '\\')
137  {
138  offset++;
139  if (offset >= expand.size())
140  throw RegexMatcher::Error("wrong format of expand string!");
141 
142  while(expand[offset] <= '9' and expand[offset] >= '0'){
143  offset++;
144  if (offset > expand.size())
145  throw RegexMatcher::Error("wrong format of expand string!");
146  }
147  if (offset > begin + 1)
148  return expand.substr(begin, offset - begin);
149  else
150  throw RegexMatcher::Error("wrong format of expand string!");
151  }
152  else if (expand[offset] == '<')
153  {
154  offset++;
155  if (offset >= expand.size())
156  throw RegexMatcher::Error("wrong format of expand string!");
157 
158  size_t left = 1;
159  size_t right = 0;
160  while(right < left)
161  {
162  if (expand[offset] == '<')
163  left++;
164  if (expand[offset] == '>')
165  right++;
166  offset++;
167  if (offset >= expand.size())
168  throw RegexMatcher::Error("wrong format of expand string!");
169  }
170  return expand.substr(begin, offset - begin);
171  }
172  else
173  throw RegexMatcher::Error("wrong format of expand string!");
174 }
175 
176 shared_ptr<RegexTopMatcher>
177 RegexTopMatcher::fromName(const Name& name, bool hasAnchor)
178 {
179  Name::const_iterator it = name.begin();
180  std::string regexStr("^");
181 
182  for(; it != name.end(); it++)
183  {
184  regexStr.append("<");
185  regexStr.append(convertSpecialChar(it->toEscapedString()));
186  regexStr.append(">");
187  }
188 
189  if (hasAnchor)
190  regexStr.append("$");
191 
192  return make_shared<RegexTopMatcher>(boost::cref(regexStr));
193 }
194 
195 std::string
196 RegexTopMatcher::convertSpecialChar(const std::string& str)
197 {
198  std::string newStr;
199  for(size_t i = 0; i < str.size(); i++)
200  {
201  char c = str[i];
202  switch (c)
203  {
204  case '.':
205  case '[':
206  case '{':
207  case '}':
208  case '(':
209  case ')':
210  case '\\':
211  case '*':
212  case '+':
213  case '?':
214  case '|':
215  case '^':
216  case '$':
217  newStr.push_back('\\');
218  default:
219  newStr.push_back(c);
220  }
221  }
222 
223  return newStr;
224 }
225 
226 }//ndn
const_iterator begin() const
Begin iterator (const).
Definition: name.hpp:480
void toEscapedString(std::ostream &result) const
Write the value to result, escaping characters according to the NDN URI Scheme.
static shared_ptr< RegexTopMatcher > fromName(const Name &name, bool hasAnchor=false)
Buffer::const_iterator end() const
Definition: block.hpp:406
const_iterator end() const
End iterator (const).
Definition: name.hpp:491
virtual void compile()
Compile the regular expression to generate the more matchers when necessary.
size_t size() const
Get the number of components.
Definition: name.hpp:329
std::vector< name::Component > m_matchResult
A Name holds an array of Name::Component and represents an NDN name.
Definition: name.hpp:26
virtual Name expand(const std::string &expand="")
const std::string m_expr
Component holds a read-only name component value.
Name & append(const uint8_t *value, size_t valueLength)
Append a new component, copying from value of length valueLength.
Definition: name.hpp:142
bool match(const Name &name)
RegexTopMatcher(const std::string &expr, const std::string &expand="")