URIType URIHelper::parseURI()

in activemq-cpp/src/main/decaf/internal/net/URIHelper.cpp [57:182]


URIType URIHelper::parseURI( const std::string& uri, bool forceServer ) {

    URIType result( uri );

    std::string temp = uri;

    std::size_t index, index1, index2, index3;
    // parse into Fragment, Scheme, and SchemeSpecificPart
    // then parse SchemeSpecificPart if necessary

    // Fragment
    index = temp.find( '#' );
    if( index != std::string::npos ) {
        // remove the fragment from the end

        result.setFragment( temp.substr( index + 1, std::string::npos ) );
        validateFragment( uri, result.getFragment(), index + 1 );
        temp = temp.substr( 0, index );
    }

    // Scheme and SchemeSpecificPart
    index = index1 = temp.find( ':' );
    index2 = temp.find( '/' );
    index3 = temp.find( '?' );

    // if a '/' or '?' occurs before the first ':' the uri has no
    // specified scheme, and is therefore not absolute
    if( index != std::string::npos &&
        ( index2 >= index || index2 == std::string::npos ) &&
        ( index3 >= index || index3 == std::string::npos ) ) {

        // the characters up to the first ':' comprise the scheme
        result.setAbsolute( true );
        result.setScheme( temp.substr( 0, index ) );

        if( result.getScheme() == "" ) {
            throw URISyntaxException(
                __FILE__, __LINE__,
                uri, "Scheme not specified.", (int)index );
        }

        validateScheme( uri, result.getScheme(), 0 );
        result.setSchemeSpecificPart( temp.substr( index + 1, std::string::npos ) );

        if( result.getSchemeSpecificPart() == "" ) {
            throw URISyntaxException(
                __FILE__, __LINE__,
                uri, "Scheme specific part is invalid..", (int)index + 1 );
        }

    } else {
        result.setAbsolute( false );
        result.setSchemeSpecificPart( temp );
    }

    if( result.getScheme() == "" ||
        ( !result.getSchemeSpecificPart().empty() &&
          result.getSchemeSpecificPart().at( 0 ) == '/' ) ) {

        result.setOpaque( false );
        // the URI is hierarchical

        // Query
        temp = result.getSchemeSpecificPart();
        index = temp.find( '?' );
        if( index != std::string::npos ) {
            result.setQuery( temp.substr( index + 1, std::string::npos ) );
            temp = temp.substr( 0, index );
            validateQuery( uri, result.getQuery(), index2 + 1 + index );
        }

        // Authority and Path
        if( temp.size() >= 2 && temp.at(0) == '/' && temp.at(1) == '/' ) {

            index = temp.find( '/', 2 );
            if( index != std::string::npos ) {
                result.setAuthority( temp.substr( 2, index - 2 ) );
                result.setPath( temp.substr( index, std::string::npos ) );
            } else {
                result.setAuthority( temp.substr( 2, std::string::npos ) );

                if( result.getAuthority() == "" &&
                    result.getQuery() == "" && result.getFragment() == "" ) {

                    throw URISyntaxException(
                        __FILE__, __LINE__,
                        uri, "Scheme specific part is invalid..", (int)uri.length() );
                }
            }

            if( result.getAuthority() != "" ) {
                validateAuthority( uri, result.getAuthority(), index1 + 3 );
            }

        } else { // no authority specified
            result.setPath( temp );
        }

        std::size_t pathIndex = 0;
        if( index2 != std::string::npos ) {
            pathIndex += index2;
        }

        if( index != std::string::npos ) {
            pathIndex += index;
        }

        validatePath( uri, result.getPath(), pathIndex );

    } else { // if not hierarchical, URI is opaque
        result.setOpaque( true );
        validateSsp( uri, result.getSchemeSpecificPart(), index2 + 2 + index );
    }

    URIType authority = parseAuthority( forceServer, result.getAuthority() );

    // Authority was valid, so we capture the results
    if( authority.isValid() ) {
        result.setUserInfo( authority.getUserInfo() );
        result.setHost( authority.getHost() );
        result.setPort( authority.getPort() );
        result.setServerAuthority( true );
    }

    return result;
}