util: Adding regex support.
Change-Id: I33d84f4ae9076ff5a9db5232f2955f4be0ed820c
diff --git a/src/util/regex/regex-component-set-matcher.cpp b/src/util/regex/regex-component-set-matcher.cpp
new file mode 100644
index 0000000..dddebfc
--- /dev/null
+++ b/src/util/regex/regex-component-set-matcher.cpp
@@ -0,0 +1,179 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "regex-component-set-matcher.hpp"
+
+#include "../logging.hpp"
+
+INIT_LOGGER ("RegexComponentSetMatcher");
+
+using namespace std;
+
+namespace ndn
+{
+RegexComponentSetMatcher::RegexComponentSetMatcher(const string expr, ptr_lib::shared_ptr<RegexBackrefManager> backRefManager)
+ : RegexMatcher(expr, EXPR_COMPONENT_SET, backRefManager),
+ m_include(true)
+{
+ // _LOG_TRACE ("Enter RegexComponentSetMatcher Constructor");
+ compile();
+ // _LOG_TRACE ("Exit RegexComponentSetMatcher Constructor");
+}
+
+RegexComponentSetMatcher::~RegexComponentSetMatcher()
+{
+ // set<Ptr<RegexComponent> >::iterator it = m_components.begin();
+
+ // for(; it != m_components.end(); it++)
+ // delete *it;
+}
+
+void
+RegexComponentSetMatcher::compile()
+{
+ // _LOG_TRACE ("Enter RegexComponentSetMatcher::compile");
+
+ string errMsg = "Error: RegexComponentSetMatcher.compile(): ";
+ int index = 0;
+
+
+ switch(m_expr[0]){
+ case '<':
+ return compileSingleComponent();
+ case '[':
+ {
+ int lastIndex = m_expr.size() - 1;
+ if(']' != m_expr[lastIndex])
+ throw RegexMatcher::Error(errMsg + " No matched ']' " + m_expr);
+
+ if('^' == m_expr[1]){
+ m_include = false;
+ compileMultipleComponents(2, lastIndex);
+ }
+ else
+ compileMultipleComponents(1, lastIndex);
+ break;
+ }
+ default:
+ throw RegexMatcher::Error(errMsg + "Parsing error in expr " + m_expr);
+ }
+
+ // _LOG_TRACE ("Exit RegexComponentSetMatcher::compile");
+}
+
+void
+RegexComponentSetMatcher::compileSingleComponent()
+{
+ // _LOG_TRACE ("Enter RegexComponentSetMatcher::compileSingleComponent");
+
+ string errMsg = "Error: RegexComponentSetMatcher.compileSingleComponent: ";
+
+ int end = extractComponent(1);
+
+ if(m_expr.size() != end)
+ throw RegexMatcher::Error(errMsg + m_expr);
+ else{
+ // _LOG_DEBUG ("RegexComponentSetMatcher::compileSingleComponent expr: " << m_expr.substr(1, end - 2));
+ ptr_lib::shared_ptr<RegexComponentMatcher> component = ptr_lib::make_shared<RegexComponentMatcher>(m_expr.substr(1, end - 2), m_backrefManager);
+ m_components.insert(component);
+
+ }
+
+ // _LOG_TRACE ("Exit RegexComponentSetMatcher::compileSingleComponent");
+}
+
+void
+RegexComponentSetMatcher::compileMultipleComponents(const int start, const int lastIndex)
+{
+ // _LOG_TRACE ("Enter RegexComponentSetMatcher::compileMultipleComponents");
+
+ string errMsg = "Error: RegexComponentSetMatcher.compileMultipleComponents: ";
+
+ int index = start;
+ int tmp_index = start;
+
+ while(index < lastIndex){
+ if('<' != m_expr[index])
+ throw RegexMatcher::Error(errMsg + "Component expr error " + m_expr);
+
+ tmp_index = index + 1;
+ index = extractComponent(tmp_index);
+
+ ptr_lib::shared_ptr<RegexComponentMatcher> component = ptr_lib::make_shared<RegexComponentMatcher>(m_expr.substr(tmp_index, index - tmp_index - 1), m_backrefManager);
+ m_components.insert(component);
+ }
+
+ if(index != lastIndex)
+ throw RegexMatcher::Error(errMsg + "Not sufficient expr to parse " + m_expr);
+
+ // _LOG_TRACE ("Exit RegexComponentSetMatcher::compileMultipleComponents");
+}
+
+bool
+RegexComponentSetMatcher::match(const Name & name, const int & offset, const int & len)
+{
+ // _LOG_TRACE ("Enter RegexComponentSetMatcher::match");
+
+ bool matched = false;
+
+ /* componentset only matches one component */
+ if(len != 1){
+ // _LOG_DEBUG ("Match Fail: ComponentSet matches only one component");
+ return false;
+ }
+
+ set<ptr_lib::shared_ptr<RegexComponentMatcher> >::iterator it = m_components.begin();
+
+ for(; it != m_components.end(); it++){
+ if((*it)->match(name, offset, len)){
+ matched = true;
+ break;
+ }
+ }
+
+ m_matchResult.clear();
+
+ if(m_include ? matched : !matched){
+ m_matchResult.push_back(name.get(offset));
+ return true;
+ }
+ else
+ return false;
+}
+
+int
+RegexComponentSetMatcher::extractComponent(int index)
+{
+ // _LOG_TRACE ("Enter RegexComponentSetMatcher::extractComponent");
+
+ int lcount = 1;
+ int rcount = 0;
+
+ while(lcount > rcount){
+ switch(m_expr[index]){
+ case '<':
+ lcount++;
+ break;
+
+ case '>':
+ rcount++;
+ break;
+
+ case 0:
+ throw RegexMatcher::Error("Error: square brackets mismatch");
+ break;
+ }
+ index++;
+
+ }
+
+ // _LOG_TRACE ("Exit RegexComponentSetMatcher::extractComponent");
+ return index;
+
+}
+
+}//ndn