From dacf7f839b0b43f92a7469f85ec71ff437dbc3cb Mon Sep 17 00:00:00 2001
From: pierre-luc <pierre-luc.bacon@savoirfairelinux.com>
Date: Mon, 7 Sep 2009 01:42:24 -0400
Subject: [PATCH] [#1744] Added regex pattern object built on top of libpcre.
 To be used for SDES/RFC4568 parsing.

---
 sflphone-common/src/sip/Regex.cpp | 135 ++++++++++++++++++++++++++++++
 sflphone-common/src/sip/Regex.h   | 133 +++++++++++++++++++++++++++++
 2 files changed, 268 insertions(+)
 create mode 100644 sflphone-common/src/sip/Regex.cpp
 create mode 100644 sflphone-common/src/sip/Regex.h

diff --git a/sflphone-common/src/sip/Regex.cpp b/sflphone-common/src/sip/Regex.cpp
new file mode 100644
index 0000000000..6ccb881c97
--- /dev/null
+++ b/sflphone-common/src/sip/Regex.cpp
@@ -0,0 +1,135 @@
+/*
+ *  Copyright (C) 2009 Savoir-Faire Linux inc.
+ *  Author: Pierre-Luc Bacon <pierre-luc.bacon@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MEstatusHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ * 
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+ 
+#include "Regex.h"
+
+#include <sstream> 
+
+namespace sfl {
+
+    const int MAX_SUBSTRINGS = 30;
+    
+    Regex::Regex(const std::string& pattern) :
+    _pattern(pattern)
+    ,_re(NULL)
+    ,_pcreOutputVector(NULL)
+    {   
+        // Compile the pattern
+        int offset;
+        const char * error;
+        
+        _re = pcre_compile(_pattern.c_str(), 0, &error, &offset, NULL);
+    
+        if (_re == NULL) {
+            std::string offsetStr;
+            std::stringstream ss;
+            ss << offset;
+            offsetStr = ss.str();
+            
+            std::string msg("PCRE compiling failed at offset ");
+
+            throw compile_error(msg);
+        }
+        
+        // Allocate space for 
+        // the output vector    
+        _pcreOutputVector = new int[MAX_SUBSTRINGS];
+    }
+
+    Regex::~Regex() 
+    {
+        pcre_free(_re);
+        delete[] _pcreOutputVector;
+    }
+    
+    const std::vector<std::string>& Regex::findall(const std::string& subject)
+    {
+        // Execute the PCRE regex
+        int status;
+                
+        status = pcre_exec(_re, NULL, subject.c_str(), subject.length(), 
+                        0, 0, _pcreOutputVector, MAX_SUBSTRINGS);
+
+        // Handle error cases
+        if (status < 0) {
+            
+            // Free the regular expression 
+            pcre_free(_re);
+            
+            // Throw and exception
+            switch(status) {
+                case PCRE_ERROR_NOMATCH: 
+                    throw match_error("No match");
+                    break;
+                default:
+                    std::string statusStr;
+                    std::stringstream ss;
+                    ss << status - 1;
+                    statusStr = ss.str();  
+                    
+                    throw match_error(std::string("Matching error number ") + 
+                                      statusStr + std::string(" occured"));
+                    break;
+            }
+
+        }
+        // Output_vector  isn't big enough
+        if (status == 0) {
+        
+            status = MAX_SUBSTRINGS/3;
+            
+            std::string statusStr;
+            std::stringstream ss;
+            ss << status - 1;
+            statusStr = ss.str(); 
+                     
+            throw std::length_error(std::string("Output vector is not big enough. Has room for") 
+                  +  statusStr + std::string("captured substrings\n"));    
+        }            
+        
+        // Copy the contents to the std::vector that will be 
+        // handed to the user
+        int count = status;      
+        const char **stringlist;     
+        
+        status = pcre_get_substring_list(subject.c_str(), _pcreOutputVector, count, &stringlist);
+        if (status < 0) {
+            fprintf(stderr, "Get substring list failed");
+        } else {
+            _outputVector.clear();
+            
+            int i;
+            for (i = 0; i < count; i++) {
+                _outputVector.push_back(stringlist[i]);
+            }
+                        
+            pcre_free_substring_list(stringlist);
+
+        }        
+        
+        return _outputVector;
+    }
+    
+    std::vector<std::string>::iterator Regex::finditer(const std::string& subject)
+    {
+        findall(subject);   
+        std::vector<std::string>::iterator iter = _outputVector.begin();
+        return iter;
+    }
+
+}
diff --git a/sflphone-common/src/sip/Regex.h b/sflphone-common/src/sip/Regex.h
new file mode 100644
index 0000000000..8babdcfdd1
--- /dev/null
+++ b/sflphone-common/src/sip/Regex.h
@@ -0,0 +1,133 @@
+/*
+ *  Copyright (C) 2009 Savoir-Faire Linux inc.
+ *  Author: Pierre-Luc Bacon <pierre-luc.bacon@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ * 
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __SFL_REGEX_H__
+#define __SFL_REGEX_H__
+
+#include <stdexcept> 
+#include <vector>
+
+#include <pcre.h>
+
+namespace sfl {
+    
+    /** 
+     * Exception object that is throw when
+     * an error occured while compiling the
+     * regular expression.
+     */
+    class compile_error : public std::invalid_argument 
+    {
+        public:     
+        explicit compile_error(const std::string& error) :  
+        std::invalid_argument(error) {}
+    };
+    
+    /** 
+     * Exception object that is throw when
+     * an error occured while mathing a
+     * pattern to an expression.
+     */
+    class match_error : public std::invalid_argument      
+    {
+        public:     
+        match_error(const std::string& error) :
+        std::invalid_argument(error) {}
+    };
+     
+    /**
+     * This class implements in its way
+     * some of the libpcre library.
+     */
+    
+    class Regex {
+    
+        public:
+        
+            /**
+             * Constructor for a regular expression
+             * pattern evaluator/matcher. 
+             *
+             * @param pattern 
+             *      The regular expression to 
+             *      be used for this instance.
+             */
+            Regex(const std::string& pattern);
+            
+            ~Regex();
+            
+            /** 
+             * Match the given expression against
+             * this pattern and returns a vector of
+             * the substrings that were matched.
+             *
+             * @param subject 
+             *      The expression to be evaluated
+             *      by the pattern.
+             *
+             * @return a vector containing the substrings
+             *       in the order that the parentheses were
+             *       defined. Throws a match_error if the 
+             *       expression cannot be matched.
+             */ 
+            const std::vector<std::string>& findall(const std::string& subject);
+
+            /** 
+             * Match the given expression against
+             * this pattern and returns an iterator
+             * to the substrings.
+             *
+             * @param subject 
+             *      The expression to be evaluated
+             *      by the pattern.
+             *
+             * @return an iterator to the output vector
+             *         containing the substrings that 
+             *         were matched.
+             */             
+            std::vector<std::string>::iterator finditer(const std::string& subject);
+            
+        private:
+            
+            /**
+            * The regular expression that represents that pattern
+            */
+
+            std::string _pattern;
+
+            /**
+            * The pcre regular expression structure
+            */
+            pcre * _re;
+
+            /**
+            * The output vector used to contain
+            * substrings that were matched by pcre.
+            */
+            int * _pcreOutputVector;
+
+            /**
+            * The output std::vector used to contain 
+            * substrings that were matched by pcre.
+            */
+
+            std::vector<std::string> _outputVector;
+    };
+    
+}
+
+#endif
-- 
GitLab