binpac: Adding a new binpac::init() function that must be called by the host

before anything else.

Internally, this function compiles all regular expressions, avoiding
to that inside the regexp constructore. The code is a bit hackish due
to the way the regexp code depends on the Bro header.
This commit is contained in:
Robin Sommer 2014-10-31 17:42:21 -07:00 committed by Tim Wojtulewicz
parent 498a5314ed
commit 434f147932
3 changed files with 50 additions and 6 deletions

View file

@ -22,6 +22,7 @@ set(binpac_headers
set(binpac_lib_SRCS set(binpac_lib_SRCS
binpac_buffer.cc binpac_buffer.cc
binpac_bytestring.cc binpac_bytestring.cc
binpac_regex.cc
${binpac_headers} ${binpac_headers}
) )

View file

@ -0,0 +1,10 @@
#include <vector>
class RE_Matcher;
namespace binpac {
std::vector<RE_Matcher*>* uncompiled_re_matchers = 0;
}

View file

@ -9,12 +9,19 @@ class RE_Matcher;
namespace binpac namespace binpac
{ {
// Internal vector recording not yet compiled matchers.
extern std::vector<RE_Matcher*>* uncompiled_re_matchers;
class RegExMatcher { class RegExMatcher {
public: public:
RegExMatcher(const char *pattern) RegExMatcher(const char *pattern)
: pattern_(pattern) : pattern_(pattern)
{ {
re_matcher_ = 0; if ( ! uncompiled_re_matchers )
uncompiled_re_matchers = new std::vector<RE_Matcher*>;
re_matcher_ = new RE_Matcher(pattern_.c_str());
uncompiled_re_matchers->push_back(re_matcher_);
} }
~RegExMatcher() ~RegExMatcher()
@ -25,19 +32,45 @@ public:
// Returns the length of longest match, or -1 on mismatch. // Returns the length of longest match, or -1 on mismatch.
int MatchPrefix(const_byteptr data, int len) int MatchPrefix(const_byteptr data, int len)
{ {
if ( ! re_matcher_ )
{
re_matcher_ = new RE_Matcher(pattern_.c_str());
re_matcher_->Compile();
}
return re_matcher_->MatchPrefix(data, len); return re_matcher_->MatchPrefix(data, len);
} }
private: private:
friend void ::binpac::init();
// Function, and state, for compiling matchers.
static void init();
string pattern_; string pattern_;
RE_Matcher *re_matcher_; RE_Matcher *re_matcher_;
}; };
inline void RegExMatcher::init()
{
if ( ! uncompiled_re_matchers )
return;
for ( size_t i = 0; i < uncompiled_re_matchers->size(); ++i )
{
if ( ! (*uncompiled_re_matchers)[i]->Compile() )
{
fprintf(stderr, "binpac: cannot compile regular expression\n");
exit(1);
}
}
uncompiled_re_matchers->clear();
}
// Must be called before any binpac functionality is used.
//
// Note, this must be defined here, and inline, because the RE functionality
// can only be used when compiling from inside Bro.
inline void init()
{
RegExMatcher::init();
}
} // namespace binpac } // namespace binpac
#endif // binpac_regex_h #endif // binpac_regex_h