Skip to content
Snippets Groups Projects
Commit dacf7f83 authored by pierre-luc's avatar pierre-luc
Browse files

[#1744] Added regex pattern object built on top of libpcre. To be used

for SDES/RFC4568 parsing.
parent 6b0ab1b5
No related branches found
No related tags found
No related merge requests found
/*
* 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;
}
}
/*
* 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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment