⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reimpl2.h

📁 代理服务器原代码
💻 H
📖 第 1 页 / 共 3 页
字号:

                if( first )
                    str.replace( itstrpos, itstrlen, itsubpos2, itsublen2 );
                else
                    str.insert( itstrpos, itsubpos2, itsublen2 );
                sublen = std::distance( itsubpos2, itsublen2 );
                break;

            case subst_node::SUBST_BACKREF:
                switch( isubst->subst_backref )
                {
                case subst_node::PREMATCH:
                    itsubpos1 = results.backref_str().begin();
                    itsublen1 = itsubpos1;
                    std::advance( itsublen1, sublen = results.rstart() );
                    break;
                case subst_node::POSTMATCH:
                    itsubpos1 = results.backref_str().begin();
                    std::advance( itsubpos1, results.rstart() + results.rlength() );
                    itsublen1 = results.backref_str().end();
                    break;
                default:
                    itsubpos1 = results.backref_str().begin();
                    std::advance( itsubpos1, results.rstart( isubst->subst_backref ) );
                    itsublen1 = itsubpos1;
                    std::advance( itsublen1, results.rlength( isubst->subst_backref ) );
                    break;
                }

                if( first )
                    str.replace( itstrpos, itstrlen, itsubpos1, itsublen1 );
                else
                    str.insert( itstrpos, itsubpos1, itsublen1 );
                sublen = std::distance( itsubpos1, itsublen1 );
                break;

            case subst_node::SUBST_OP:
                switch( isubst->op )
                {
                case subst_node::UPPER_ON:
                    rest = UPPER;
                    break;
                case subst_node::UPPER_NEXT:
                    next = UPPER;
                    break;
                case subst_node::LOWER_ON:
                    rest = LOWER;
                    break;
                case subst_node::LOWER_NEXT:
                    next = LOWER;
                    break;
                case subst_node::ALL_OFF:
                    rest = NIL;
                    break;
                default:
                    __assume( 0 );
                }
                continue; // jump to the next item in the list

                default:
                    __assume( 0 );
            }

            first = false;

            // Are we upper- or lower-casing this string?
            if( rest )
            {
                typename std::basic_string<CH, TR, AL>::iterator istart = str.begin();
                std::advance( istart, strpos );
                typename std::basic_string<CH, TR, AL>::const_iterator istop = istart;
                std::advance( istop, sublen );
                switch( rest )
                {
                case UPPER:
                    regex_toupper( istart, istop );
                    break;
                case LOWER:
                    regex_tolower( istart, istop );
                    break;
                default:
                    __assume( 0 );
                }
            }

            // Are we upper- or lower-casing the next character?
            if( next )
            {
                switch( next )
                {
                case UPPER:
                    str[strpos] = regex_toupper( str[strpos] );
                    break;
                case LOWER:
                    str[strpos] = regex_tolower( str[strpos] );
                    break;
                default:
                    __assume( 0 );
                }
                next = NIL;
            }

            strpos += sublen;
        }

        // If *first* is still true, then we never called str.replace, and the substitution
        // string is empty. Erase the part of the string that the pattern matched.
        if( first )
            str.erase( strpos, strlen );

        // return length of the substitution
        return strpos - old_strpos;
    }

    template< typename CH, typename TR, typename AL >
    static size_t _Do_subst(
        rpattern_type const & pat,
        std::basic_string<CH, TR, AL> & str,
        basic_subst_results<CH, TR, AL> & results,
        size_type pos,
        size_type len )
    {
        typedef std::basic_string<CH, TR, AL> string_type;

        results.m_pbackref_str = pat._save_backrefs() ? &( results.m_backref_str = str ) : &str;
        results.ibegin = results.m_pbackref_str->begin();

        size_t csubst = 0;
        size_type stop_offset = results.m_pbackref_str->size();
        if( len != rpattern_type::npos )
            stop_offset = (std::min)( size_t( pos + len ), stop_offset );

        match_param<CI> param( results.ibegin, results.ibegin, & results.m_rgbackrefs );
        std::advance( param.istart, pos );
        std::advance( param.istop, stop_offset );
        param.ibegin = param.istart;

        if( GLOBAL & pat.flags() )
        {
            bool const fAll   = ( ALLBACKREFS   == ( ALLBACKREFS   & pat.flags() ) );
            bool const fFirst = ( FIRSTBACKREFS == ( FIRSTBACKREFS & pat.flags() ) );
            backref_vector rgtempbackrefs; // temporary vector used if fsave_backrefs

            size_type pos_offset = 0; // keep track of how much the backref_str and
                                    // the current string are out of sync

            while( _Do_match( pat, param, false ) )
            {
                backref_type const & br = results.m_rgbackrefs[0];
                ++csubst;
                size_type match_length = std::distance( br.first, br.second );
                pos = std::distance( results.ibegin, br.first );
                size_type subst_length = _Do_subst_internal( str, results, pat, pos + pos_offset, match_length );

                if( pat._save_backrefs() )
                {
                    pos += match_length;
                    pos_offset += ( subst_length - match_length );

                    // Handle specially the backref flags
                    if( fFirst )
                        rgtempbackrefs.push_back( br );
                    else if( fAll )
                        rgtempbackrefs.insert( rgtempbackrefs.end(),
                                            param.prgbackrefs->begin(),
                                            param.prgbackrefs->end() );
                    else
                        rgtempbackrefs.swap( *param.prgbackrefs );
                }
                else
                {
                    pos += subst_length;
                    stop_offset += ( subst_length - match_length );
                    results.ibegin = results.m_pbackref_str->begin();

                    // we're not saving backref information, so we don't
                    // need to do any special backref maintenance here
                }

                // prevent a pattern that matches 0 characters from matching
                // again at the same point in the string
                param.no0len = ( 0 == match_length );

                param.istart = results.ibegin;
                std::advance( param.istart, pos ); // ineffecient for bidirectional iterators.

                param.istop = results.ibegin;
                std::advance( param.istop, stop_offset ); // ineffecient for bidirectional iterators.
            }

            // If we did special backref handling, swap the backref vectors
            if( pat._save_backrefs() )
            {
                param.prgbackrefs->swap( rgtempbackrefs );
            }
            else if( ! ( *param.prgbackrefs )[0].matched )
            {
                param.prgbackrefs->clear();

            }
        }
        else if( _Do_match( pat, param, false ) )
        {
            backref_type const & br = results.m_rgbackrefs[0];
            ++csubst;
            _Do_subst_internal(
                str, results, pat,
                std::distance( results.ibegin, br.first ),
                std::distance( br.first, br.second ) );
            results.ibegin = results.m_pbackref_str->begin();
        }

        if( NOBACKREFS == ( pat.flags() & NOBACKREFS ) )
        {
            param.prgbackrefs->clear();
        }

        return csubst;
    }
};

template< typename CI >
REGEX_NOINLINE bool matcher_helper<CI>::_Do_match_with_stack( rpattern_type const & pat, match_param<CI> & param, bool const use_null )
{
    unsafe_stack s;
    param.pstack = &s;
    return _Do_match_impl( pat, param, use_null );
}

//
// Some helper functions needed by process_escapes
//
template< typename CH >
inline bool regex_isxdigit( CH ch )
{
    return ( REGEX_CHAR(CH,'0') <= ch && REGEX_CHAR(CH,'9') >= ch )
        || ( REGEX_CHAR(CH,'a') <= ch && REGEX_CHAR(CH,'f') >= ch )
        || ( REGEX_CHAR(CH,'A') <= ch && REGEX_CHAR(CH,'F') >= ch );
}

template< typename CH >
inline int regex_xdigit2int( CH ch )
{
    if( REGEX_CHAR(CH,'a') <= ch && REGEX_CHAR(CH,'f') >= ch )
        return ch - REGEX_CHAR(CH,'a') + 10;
    if( REGEX_CHAR(CH,'A') <= ch && REGEX_CHAR(CH,'F') >= ch )
        return ch - REGEX_CHAR(CH,'A') + 10;
    return ch - REGEX_CHAR(CH,'0');
}

} // namespace detail

// --------------------------------------------------------------------------
//
// Function:    process_escapes
//
// Description: Turn the escape sequnces \f \n \r \t \v \\ into their
//              ASCII character equivalents. Also, optionally process
//              perl escape sequences.
//
// Returns:     void
//
// Arguments:   str      - the string to process
//              fPattern - true if the string is to be processed as a regex
//
// Notes:       When fPattern is true, the perl escape sequences are not
//              processed.  If there is an octal or hex excape sequence, we
//              don't want to turn it into a regex metacharacter here.  We
//              leave it unescaped so the regex parser correctly interprests
//              it as a character literal.
//
// History:     8/1/2001 - ericne - Created
//
// --------------------------------------------------------------------------
template< typename CH, typename TR, typename AL >
inline void process_escapes( std::basic_string<CH, TR, AL> & str, bool fPattern ) //throw()
{
    typedef typename std::basic_string<CH, TR, AL>::size_type size_type;

    size_type i = 0;
    size_type const npos = std::basic_string<CH, TR, AL>::npos;

    if( str.empty() )
        return;

    while( npos != ( i = str.find( REGEX_CHAR(CH,'\\'), i ) ) )
    {
        if( str.size() - 1 == i )
            return;

        switch( str[i+1] )
        {
        case REGEX_CHAR(CH,'a'):
            str.replace( i, 2, 1, REGEX_CHAR(CH,'\a') );
            break;
        case REGEX_CHAR(CH,'b'):
            if( ! fPattern )
                str.replace( i, 2, 1, REGEX_CHAR(CH,'\b') );
            else
                ++i;
            break;
        case REGEX_CHAR(CH,'e'):
            str.replace( i, 2, 1, CH( 27 ) );
            break;
        case REGEX_CHAR(CH,'f'):
            str.replace( i, 2, 1, REGEX_CHAR(CH,'\f') );
            break;
        case REGEX_CHAR(CH,'n'):
            str.replace( i, 2, 1, REGEX_CHAR(CH,'\n') );
            break;
        case REGEX_CHAR(CH,'r'):
            str.replace( i, 2, 1, REGEX_CHAR(CH,'\r') );
            break;
        case REGEX_CHAR(CH,'t'):
            str.replace( i, 2, 1, REGEX_CHAR(CH,'\t') );
            break;
        case REGEX_CHAR(CH,'v'):
            str.replace( i, 2, 1, REGEX_CHAR(CH,'\v') );
            break;
        case REGEX_CHAR(CH,'\\'):
            if( fPattern )
            {
                if( i+3 < str.size() && REGEX_CHAR(CH,'\\') == str[i+2] && REGEX_CHAR(CH,'\\') == str[i+3] )
                    str.erase( i, 2 );
                ++i;
            }
            else
                str.erase( i, 1 );
            break;
        case REGEX_CHAR(CH,'0'): case REGEX_CHAR(CH,'1'): case REGEX_CHAR(CH,'2'): case REGEX_CHAR(CH,'3'):
        case REGEX_CHAR(CH,'4'): case REGEX_CHAR(CH,'5'): case REGEX_CHAR(CH,'6'): case REGEX_CHAR(CH,'7'):
            if( ! fPattern )
            {
                size_t j=i+2;
                CH ch = CH( str[i+1] - REGEX_CHAR(CH,'0') );
                for( ; j-i < 4 && j < str.size() && REGEX_CHAR(CH,'0') <= str[j] && REGEX_CHAR(CH,'7') >= str[j]; ++j )
                    ch = CH( ch * 8 + ( str[j] - REGEX_CHAR(CH,'0') ) );
                str.replace( i, j-i, 1, ch );
            }
            break;
        case REGEX_CHAR(CH,'x'):
            if( ! fPattern )
            {
                CH ch = 0;
                size_t j=i+2;
                for( ; j-i < 4 && j < str.size() && detail::regex_isxdigit( str[j] ); ++j )
                    ch = CH( ch * 16 + detail::regex_xdigit2int( str[j] ) );
                str.replace( i, j-i, 1, ch );
            }
            break;
        case REGEX_CHAR(CH,'c'):
            if( ! fPattern && i+2 < str.size() )
            {
                CH ch = str[i+2];
                if( REGEX_CHAR(CH,'a') <= ch && REGEX_CHAR(CH,'z') >= ch )
                    ch = detail::regex_toupper( ch );
                str.replace( i, 3, 1, CH( ch ^ 0x40 ) );
            }
            break;
        default:
            if( fPattern )
                ++i;
            else
                str.erase( i, 1 );
            break;
        }
        ++i;
        if( str.size() <= i )
            return;
    }
}

#ifndef _MSC_VER
#undef __assume
#endif

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -