33
44namespace EE { namespace System {
55
6- RegEx::RegEx ( const std::string_view& pattern ) :
6+ SINGLETON_DECLARE_IMPLEMENTATION ( RegExCache )
7+
8+ RegExCache::~RegExCache () {
9+ clear ();
10+ }
11+
12+ void RegExCache::insert ( std::string_view key, void * cache ) {
13+ mCache .insert ( { String::hash ( key ), cache } );
14+ }
15+
16+ void * RegExCache::find ( const std::string_view& key ) {
17+ auto it = mCache .find ( String::hash ( key ) );
18+ return ( it != mCache .end () ) ? it->second : nullptr ;
19+ }
20+
21+ void RegExCache::clear () {
22+ for ( auto & cache : mCache )
23+ pcre2_code_free ( reinterpret_cast <pcre2_code*>( cache.second ) );
24+ mCache .clear ();
25+ }
26+
27+ RegEx::RegEx ( const std::string_view& pattern, bool useCache, bool initRegEx ) :
728 PatternMatcher ( PatternType::PCRE ),
829 mPattern ( pattern ),
930 mMatchNum ( 0 ),
1031 mCompiledPattern ( nullptr ),
1132 mCaptureCount ( 0 ),
1233 mValid ( true ) {
34+ if ( initRegEx )
35+ init ( pattern, useCache );
36+ }
37+
38+ RegEx::RegEx ( const std::string_view& pattern, bool useCache ) : RegEx( pattern, useCache, true ) {}
39+
40+ RegEx::~RegEx () {
41+ if ( !mCached && mCompiledPattern != nullptr ) {
42+ pcre2_code_free ( reinterpret_cast <pcre2_code*>( mCompiledPattern ) );
43+ }
44+ }
45+
46+ void RegEx::init ( const std::string_view& pattern, bool useCache ) {
1347 int errornumber;
1448 PCRE2_SIZE erroroffset;
1549 PCRE2_SPTR pattern_sptr = reinterpret_cast <PCRE2_SPTR>( pattern.data () );
1650
51+ if ( useCache && RegExCache::instance ()->isEnabled () &&
52+ ( mCompiledPattern = RegExCache::instance ()->find ( pattern ) ) ) {
53+ mValid = true ;
54+ mCached = true ;
55+ return ;
56+ }
57+
1758 mCompiledPattern = pcre2_compile ( pattern_sptr, // the pattern
1859 pattern.size (), // the length of the pattern
19- 0 , // default options
60+ PCRE2_UTF, // default options
2061 &errornumber, // for error number
2162 &erroroffset, // for error offset
2263 NULL // use default compile context
@@ -31,18 +72,17 @@ RegEx::RegEx( const std::string_view& pattern ) :
3172 // reinterpret_cast<const char*>( buffer ) );
3273 }
3374
75+ pcre2_jit_compile ( reinterpret_cast <pcre2_code*>( mCompiledPattern ), PCRE2_JIT_COMPLETE );
76+
3477 int rc = pcre2_pattern_info ( reinterpret_cast <pcre2_code*>( mCompiledPattern ),
3578 PCRE2_INFO_CAPTURECOUNT, &mCaptureCount );
3679 if ( rc != 0 ) {
3780 // throw std::runtime_error( "PCRE2 pattern info failed with error code " +
3881 // std::to_string( rc ) );
3982 mValid = false ;
40- }
41- }
42-
43- RegEx::~RegEx () {
44- if ( mCompiledPattern != nullptr ) {
45- pcre2_code_free ( reinterpret_cast <pcre2_code*>( mCompiledPattern ) );
83+ } else if ( useCache && RegExCache::instance ()->isEnabled () ) {
84+ RegExCache::instance ()->insert ( pattern, mCompiledPattern );
85+ mCached = true ;
4686 }
4787}
4888
@@ -78,11 +118,16 @@ bool RegEx::matches( const char* stringSearch, int stringStartOffset,
78118 for ( size_t i = 0 ; i < static_cast <size_t >( rc ); ++i ) {
79119 matchList[i].start = static_cast <int >( ovector[2 * i] );
80120 matchList[i].end = static_cast <int >( ovector[2 * i + 1 ] );
121+ if ( matchList[i].start >= matchList[i].end ) {
122+ matchList[i].start = matchList[i].end = -1 ;
123+ mMatchNum --;
124+ break ;
125+ }
81126 }
82127 }
83128
84129 pcre2_match_data_free ( match_data );
85- return true ;
130+ return mMatchNum > 0 ;
86131}
87132
88133bool RegEx::matches ( const std::string& str, PatternMatcher::Range* matchList,
@@ -94,13 +139,4 @@ const size_t& RegEx::getNumMatches() const {
94139 return mMatchNum ;
95140}
96141
97- RegExStorage::RegExStorage ( const std::string& pattern ) : RegEx( " " ), mPatternStorage ( pattern ) {
98- mPattern = std::string_view{ mPatternStorage };
99- }
100-
101- RegExStorage::RegExStorage ( std::string&& pattern ) :
102- RegEx ( " " ), mPatternStorage ( std::move( pattern ) ) {
103- mPattern = std::string_view{ mPatternStorage };
104- }
105-
106142}} // namespace EE::System
0 commit comments